Implement saving for edited files
This commit is contained in:
parent
db431c5d6c
commit
26e696693f
@ -69,6 +69,8 @@ pub enum Message {
|
|||||||
MoveSection(Direction),
|
MoveSection(Direction),
|
||||||
|
|
||||||
MoveCur(Direction),
|
MoveCur(Direction),
|
||||||
|
|
||||||
|
SaveFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -189,6 +191,15 @@ fn handle_message(
|
|||||||
state.show_error_message(err);
|
state.show_error_message(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::SaveFile => {
|
||||||
|
info!("Saving file");
|
||||||
|
if let Err(err) = state.save_edited_file() {
|
||||||
|
state.show_error_message(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.prompt_save = false;
|
||||||
|
msg_tx.send(Message::SetMode(Mode::Normal))?;
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,11 @@ fn handle_keyboard_input(
|
|||||||
}
|
}
|
||||||
|
|
||||||
(Mode::SelectFile, KeyCode::Enter) => {
|
(Mode::SelectFile, KeyCode::Enter) => {
|
||||||
msg_tx.send(Message::LoadFile)?;
|
if state.prompt_save {
|
||||||
|
msg_tx.send(Message::SaveFile)?;
|
||||||
|
} else {
|
||||||
|
msg_tx.send(Message::LoadFile)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(Mode::SelectFile, _) => {
|
(Mode::SelectFile, _) => {
|
||||||
@ -121,6 +125,12 @@ fn handle_keyboard_input(
|
|||||||
msg_tx.send(Message::PreviousEntryValue)?;
|
msg_tx.send(Message::PreviousEntryValue)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(Mode::Edit, KeyCode::Char('s')) => {
|
||||||
|
state.prompt_save = true;
|
||||||
|
state.file_select = Input::default();
|
||||||
|
msg_tx.send(Message::SetMode(Mode::SelectFile))?;
|
||||||
|
}
|
||||||
|
|
||||||
(Mode::Insert, KeyCode::Enter) => {
|
(Mode::Insert, KeyCode::Enter) => {
|
||||||
msg_tx.send(Message::CommitEditEntry)?;
|
msg_tx.send(Message::CommitEditEntry)?;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::fs::{self, create_dir_all, read_to_string};
|
use std::fs::{self, create_dir_all, read_to_string, OpenOptions};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::os::unix::prelude::OsStrExt;
|
use std::os::unix::prelude::OsStrExt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@ -52,13 +52,14 @@ pub enum Section {
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub savefile: Option<Savefile>,
|
pub savefile: Option<Savefile>,
|
||||||
original_file: Option<Savefile>,
|
pub original_file: Option<Savefile>,
|
||||||
pub active_section: Section,
|
pub active_section: Section,
|
||||||
pub stats_table: TableState,
|
pub stats_table: TableState,
|
||||||
pub glyphs_table: TableState,
|
pub glyphs_table: TableState,
|
||||||
pub murals_table: TableState,
|
pub murals_table: TableState,
|
||||||
pub error_msg: Option<(Instant, String)>,
|
pub error_msg: Option<(Instant, String)>,
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
|
pub prompt_save: bool,
|
||||||
pub edit_input: Option<Input>,
|
pub edit_input: Option<Input>,
|
||||||
pub file_select: Input,
|
pub file_select: Input,
|
||||||
#[cfg(feature = "watch")]
|
#[cfg(feature = "watch")]
|
||||||
@ -69,6 +70,21 @@ pub struct State {
|
|||||||
impl State {
|
impl State {
|
||||||
const ERROR_MSG_DURATION: Duration = Duration::new(3, 0);
|
const ERROR_MSG_DURATION: Duration = Duration::new(3, 0);
|
||||||
|
|
||||||
|
pub fn load() -> Result<Self> {
|
||||||
|
let data_dir = DIRS.data_local_dir();
|
||||||
|
|
||||||
|
if !data_dir.exists() {
|
||||||
|
create_dir_all(&data_dir)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let savefile = load_last_active_savefile()?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
savefile,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn show_error_message<S>(&mut self, msg: S)
|
pub fn show_error_message<S>(&mut self, msg: S)
|
||||||
where
|
where
|
||||||
S: fmt::Display,
|
S: fmt::Display,
|
||||||
@ -90,21 +106,6 @@ impl State {
|
|||||||
self.error_msg.take();
|
self.error_msg.take();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load() -> Result<Self> {
|
|
||||||
let data_dir = DIRS.data_local_dir();
|
|
||||||
|
|
||||||
if !data_dir.exists() {
|
|
||||||
create_dir_all(&data_dir)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let savefile = load_last_active_savefile()?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
savefile,
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_savefile_from_path<P>(&mut self, path: P) -> Result<()>
|
pub fn set_savefile_from_path<P>(&mut self, path: P) -> Result<()>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
@ -290,6 +291,22 @@ impl State {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn save_edited_file(&mut self) -> Result<()> {
|
||||||
|
let path = self.file_select.value();
|
||||||
|
|
||||||
|
let savefile = self.savefile.as_ref().context("no active savefile")?;
|
||||||
|
|
||||||
|
let outfile = OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(path)?;
|
||||||
|
|
||||||
|
savefile.write(outfile)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn move_section(&mut self, direction: Direction) {
|
pub fn move_section(&mut self, direction: Direction) {
|
||||||
let next_section = match (direction, self.active_section) {
|
let next_section = match (direction, self.active_section) {
|
||||||
(Direction::Left, Section::Companions) => Section::General,
|
(Direction::Left, Section::Companions) => Section::General,
|
||||||
|
@ -54,16 +54,21 @@ pub fn render_status(state: &State, mut frame: &mut Frame, block: Block, area: R
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render_file_select(state: &State, frame: &mut Frame, block: Block, area: Rect) {
|
fn render_file_select(state: &State, frame: &mut Frame, block: Block, area: Rect) {
|
||||||
const PROMPT: &str = "Open file:";
|
|
||||||
const PADDING: usize = 2;
|
const PADDING: usize = 2;
|
||||||
|
|
||||||
|
let prompt = if state.prompt_save {
|
||||||
|
"Save as:"
|
||||||
|
} else {
|
||||||
|
"Open file:"
|
||||||
|
};
|
||||||
|
|
||||||
let scroll = state.file_select.visual_scroll(area.width as usize);
|
let scroll = state.file_select.visual_scroll(area.width as usize);
|
||||||
let input = Paragraph::new(format!("{} {}", PROMPT, state.file_select.value()))
|
let input = Paragraph::new(format!("{} {}", prompt, state.file_select.value()))
|
||||||
.scroll((0, scroll as u16))
|
.scroll((0, scroll as u16))
|
||||||
.block(block);
|
.block(block);
|
||||||
frame.render_widget(input, area);
|
frame.render_widget(input, area);
|
||||||
frame.set_cursor(
|
frame.set_cursor(
|
||||||
area.x + (state.file_select.visual_cursor() + PROMPT.len() + 1 + PADDING) as u16,
|
area.x + (state.file_select.visual_cursor() + prompt.len() + 1 + PADDING) as u16,
|
||||||
area.y,
|
area.y,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user