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,
|
terminal_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::util::read_line;
|
||||||
|
|
||||||
const TAB_SIZE: usize = 4;
|
const TAB_SIZE: usize = 4;
|
||||||
|
|
||||||
pub struct Editor {
|
pub struct Editor {
|
||||||
|
@ -20,7 +22,7 @@ pub struct Editor {
|
||||||
scroll: usize,
|
scroll: usize,
|
||||||
cursor: Cursor,
|
cursor: Cursor,
|
||||||
path: Option<String>,
|
path: Option<String>,
|
||||||
term: RawTerminal<Stdout>,
|
_term: RawTerminal<Stdout>,
|
||||||
quit: bool,
|
quit: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +54,7 @@ impl Editor {
|
||||||
lines: Vec::new(),
|
lines: Vec::new(),
|
||||||
scroll: 0,
|
scroll: 0,
|
||||||
cursor: Cursor { line: 0, column: 0 },
|
cursor: Cursor { line: 0, column: 0 },
|
||||||
term,
|
_term: term,
|
||||||
path,
|
path,
|
||||||
quit: false,
|
quit: false,
|
||||||
}
|
}
|
||||||
|
@ -255,20 +257,12 @@ impl Editor {
|
||||||
|
|
||||||
fn save(&mut self) {
|
fn save(&mut self) {
|
||||||
if self.path.is_none() {
|
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();
|
let mut file = File::create(self.path.as_ref().unwrap()).unwrap();
|
||||||
file.write_all(self.text.as_bytes()).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;
|
use std::env;
|
||||||
|
|
||||||
mod editor;
|
mod editor;
|
||||||
|
mod util;
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
|
|
||||||
fn main() {
|
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