From 26e696693f183c1c3f12af121331b892e67fd398 Mon Sep 17 00:00:00 2001 From: Patrick Auernig Date: Thu, 17 Aug 2023 21:52:01 +0200 Subject: [PATCH] Implement saving for edited files --- crates/wayfarer/src/tui.rs | 11 +++++ crates/wayfarer/src/tui/events.rs | 12 ++++- crates/wayfarer/src/tui/state.rs | 51 ++++++++++++++-------- crates/wayfarer/src/tui/view/status_bar.rs | 11 +++-- 4 files changed, 64 insertions(+), 21 deletions(-) diff --git a/crates/wayfarer/src/tui.rs b/crates/wayfarer/src/tui.rs index 62c21eb..1ab28e1 100644 --- a/crates/wayfarer/src/tui.rs +++ b/crates/wayfarer/src/tui.rs @@ -69,6 +69,8 @@ pub enum Message { MoveSection(Direction), MoveCur(Direction), + + SaveFile, } @@ -189,6 +191,15 @@ fn handle_message( 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))?; + } _ => (), } diff --git a/crates/wayfarer/src/tui/events.rs b/crates/wayfarer/src/tui/events.rs index 0b980f7..997a1da 100644 --- a/crates/wayfarer/src/tui/events.rs +++ b/crates/wayfarer/src/tui/events.rs @@ -58,7 +58,11 @@ fn handle_keyboard_input( } (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, _) => { @@ -121,6 +125,12 @@ fn handle_keyboard_input( 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) => { msg_tx.send(Message::CommitEditEntry)?; } diff --git a/crates/wayfarer/src/tui/state.rs b/crates/wayfarer/src/tui/state.rs index ef4e022..2a6ea3b 100644 --- a/crates/wayfarer/src/tui/state.rs +++ b/crates/wayfarer/src/tui/state.rs @@ -1,5 +1,5 @@ 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::os::unix::prelude::OsStrExt; use std::path::Path; @@ -52,13 +52,14 @@ pub enum Section { #[derive(Default)] pub struct State { pub savefile: Option, - original_file: Option, + pub original_file: Option, pub active_section: Section, pub stats_table: TableState, pub glyphs_table: TableState, pub murals_table: TableState, pub error_msg: Option<(Instant, String)>, pub mode: Mode, + pub prompt_save: bool, pub edit_input: Option, pub file_select: Input, #[cfg(feature = "watch")] @@ -69,6 +70,21 @@ pub struct State { impl State { const ERROR_MSG_DURATION: Duration = Duration::new(3, 0); + pub fn load() -> Result { + 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(&mut self, msg: S) where S: fmt::Display, @@ -90,21 +106,6 @@ impl State { self.error_msg.take(); } - pub fn load() -> Result { - 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

(&mut self, path: P) -> Result<()> where P: AsRef, @@ -290,6 +291,22 @@ impl State { 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) { let next_section = match (direction, self.active_section) { (Direction::Left, Section::Companions) => Section::General, diff --git a/crates/wayfarer/src/tui/view/status_bar.rs b/crates/wayfarer/src/tui/view/status_bar.rs index e9f0851..c32270e 100644 --- a/crates/wayfarer/src/tui/view/status_bar.rs +++ b/crates/wayfarer/src/tui/view/status_bar.rs @@ -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) { - const PROMPT: &str = "Open file:"; 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 input = Paragraph::new(format!("{} {}", PROMPT, state.file_select.value())) + let input = Paragraph::new(format!("{} {}", prompt, state.file_select.value())) .scroll((0, scroll as u16)) .block(block); frame.render_widget(input, area); 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, ); }