diff --git a/src/editor.rs b/src/editor.rs index ea3cff3..5a70558 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -23,6 +23,10 @@ struct StatusMessage { } impl StatusMessage { + fn default() -> Self { + Self::from("") + } + fn from>(message: S) -> Self { Self { time: Instant::now(), @@ -141,17 +145,29 @@ impl Editor { } } + fn save(&mut self) { + if self.document.file_name.is_none() { + let new_name = self.prompt("Save as: ").unwrap_or(None); + if new_name.is_none() { + self.status_message = StatusMessage::from("Save aborted."); + return; + } + + self.document.file_name = new_name; + } + + if self.document.save().is_ok() { + self.status_message = StatusMessage::from("File saved successfully."); + } else { + self.status_message = StatusMessage::from("Error writing file!"); + } + } + fn process_keypress(&mut self) -> Result<(), std::io::Error> { let pressed_key = Terminal::read_key()?; match pressed_key { Key::Ctrl('q') => self.should_quit = true, - Key::Ctrl('s') => { - if self.document.save().is_ok() { - self.status_message = StatusMessage::from("File saved successfully."); - } else { - self.status_message = StatusMessage::from("Error writing file!"); - } - } + Key::Ctrl('s') => self.save(), Key::Char(c) => { self.document.insert(&self.cursor_position, c); self.move_cursor(Key::Right); @@ -179,6 +195,42 @@ impl Editor { Ok(()) } + fn prompt(&mut self, prompt: &str) -> Result, std::io::Error> { + let mut result = String::new(); + + loop { + self.status_message = StatusMessage::from(format!("{}{}", prompt, result)); + self.refresh_screen()?; + + match Terminal::read_key()? { + Key::Backspace => { + if !result.is_empty() { + result.truncate(result.len() - 1); + } + } + Key::Char('\n') => break, + Key::Char(c) => { + if !c.is_control() { + result.push(c); + } + } + Key::Esc => { + result.truncate(0); + break; + } + _ => (), + } + } + + self.status_message = StatusMessage::default(); + + if result.is_empty() { + return Ok(None); + } + + Ok(Some(result)) + } + fn scroll(&mut self) { let Position { x, y } = self.cursor_position; let width = self.terminal.size().width as usize;