allow cancelling in save path input prompt
This commit is contained in:
parent
ad6e458812
commit
a65a1cc9b8
3 changed files with 47 additions and 14 deletions
|
@ -12,6 +12,8 @@ use termion::{
|
|||
terminal_size,
|
||||
};
|
||||
|
||||
use crate::util::read_line;
|
||||
|
||||
const TAB_SIZE: usize = 4;
|
||||
|
||||
pub struct Editor {
|
||||
|
@ -20,7 +22,7 @@ pub struct Editor {
|
|||
scroll: usize,
|
||||
cursor: Cursor,
|
||||
path: Option<String>,
|
||||
term: RawTerminal<Stdout>,
|
||||
_term: RawTerminal<Stdout>,
|
||||
quit: bool,
|
||||
}
|
||||
|
||||
|
@ -52,7 +54,7 @@ impl Editor {
|
|||
lines: Vec::new(),
|
||||
scroll: 0,
|
||||
cursor: Cursor { line: 0, column: 0 },
|
||||
term,
|
||||
_term: term,
|
||||
path,
|
||||
quit: false,
|
||||
}
|
||||
|
@ -255,20 +257,12 @@ impl Editor {
|
|||
|
||||
fn save(&mut self) {
|
||||
if self.path.is_none() {
|
||||
self.path = Some(self.read_line("Save as: "));
|
||||
self.path = read_line("Enter path: ");
|
||||
if self.path.is_none() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
let mut file = File::create(self.path.as_ref().unwrap()).unwrap();
|
||||
file.write_all(self.text.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
fn read_line(&self, prompt: &str) -> String {
|
||||
// TODO: use events instead and allow cancelling with esc
|
||||
self.term.suspend_raw_mode().unwrap();
|
||||
print!("{}{prompt}", cursor::Goto(1, terminal_size().unwrap().1));
|
||||
stdout().flush().unwrap();
|
||||
let mut response = String::new();
|
||||
stdin().read_line(&mut response).unwrap();
|
||||
self.term.activate_raw_mode().unwrap();
|
||||
response.trim_end().into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::env;
|
||||
|
||||
mod editor;
|
||||
mod util;
|
||||
use editor::Editor;
|
||||
|
||||
fn main() {
|
||||
|
|
38
src/util.rs
Normal file
38
src/util.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use std::io::{stdin, stdout, Write};
|
||||
|
||||
use termion::{
|
||||
cursor,
|
||||
event::{Event, Key},
|
||||
input::TermRead,
|
||||
terminal_size,
|
||||
};
|
||||
|
||||
pub fn read_line(prompt: &str) -> Option<String> {
|
||||
let mut response = String::new();
|
||||
let size = terminal_size().unwrap();
|
||||
let start_pos = cursor::Goto(1, size.1);
|
||||
let width = size.0 as usize;
|
||||
|
||||
print!("{start_pos}{prompt}{response}",);
|
||||
stdout().flush().unwrap();
|
||||
|
||||
for event in stdin().events() {
|
||||
if let Ok(Event::Key(key)) = event {
|
||||
match key {
|
||||
Key::Char('\n') => break,
|
||||
Key::Char(ch) => response.push(ch),
|
||||
Key::Backspace => {
|
||||
if !response.is_empty() {
|
||||
response.remove(response.len() - 1);
|
||||
}
|
||||
print!("{start_pos}{:width$}", " ");
|
||||
}
|
||||
Key::Esc => return None,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
print!("{start_pos}{prompt}{response}",);
|
||||
stdout().flush().unwrap();
|
||||
}
|
||||
Some(response.trim().into())
|
||||
}
|
Loading…
Reference in a new issue