diff --git a/src/editor.rs b/src/editor.rs index db2f0e8..7fc8edb 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -1,6 +1,6 @@ use std::{ fs::{self, File}, - io::{stdin, stdout, Stdout, Write}, + io::{stdin, stdout, Write}, ops::Range, process::exit, }; @@ -8,7 +8,6 @@ use termion::{ clear, cursor, event::{Event, Key}, input::TermRead, - raw::{IntoRawMode, RawTerminal}, terminal_size, }; @@ -22,8 +21,7 @@ pub struct Editor { scroll: usize, cursor: Cursor, path: Option, - _term: RawTerminal, - quit: bool, + pub quit: bool, } #[derive(Debug)] @@ -47,33 +45,23 @@ impl Editor { }) .unwrap_or_default(); - let term = stdout().into_raw_mode().unwrap(); - - Editor { + let mut this = Editor { text, lines: Vec::new(), scroll: 0, cursor: Cursor { line: 0, column: 0 }, - _term: term, path, quit: false, - } + }; + this.find_lines(); + this } - pub fn run(mut self) { - print!("{}", clear::All); - stdout().flush().unwrap(); - - self.find_lines(); - - while !self.quit { - self.draw(); - self.input(); - } - print!("{}", clear::All); + pub fn name(&self) -> &str { + self.path.as_ref().map_or("untitled", |s| &s) } - fn input(&mut self) { + pub fn input(&mut self) { for event in stdin().events().take(1).flatten() { // dbg!(&event); if let Event::Key(key) = event { @@ -86,6 +74,8 @@ impl Editor { Key::Right => self.move_right(), Key::Up => self.move_up(), Key::Down => self.move_down(), + Key::Home => self.move_home(), + Key::End => self.move_end(), Key::Ctrl('s') => self.save(), _ => (), } @@ -141,6 +131,15 @@ impl Editor { } } + fn move_home(&mut self) { + self.cursor.column = 0; + } + + fn move_end(&mut self) { + self.cursor.column = self.current_line().len(); + self.ensure_char_boundary(); + } + /// Moves cursor left until it is on a character (in case it was in the middle of a multi-byte character) fn ensure_char_boundary(&mut self) { while !self @@ -169,7 +168,7 @@ impl Editor { self.lines.push(this_line); } - fn draw(&self) { + pub fn draw(&self) { print!("{}", clear::All); let max_rows = terminal_size().unwrap().1 as usize - 1; diff --git a/src/main.rs b/src/main.rs index d93b448..89fe78d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,92 @@ -use std::env; +use std::{ + env, + io::{stdin, stdout, Stdout, Write}, + process::exit, +}; +use termion::{ + clear, color, + cursor::Goto, + event::{Event, Key}, + input::TermRead, + raw::{IntoRawMode, RawTerminal}, +}; mod editor; mod util; use editor::Editor; fn main() { - Editor::new(env::args().nth(1)).run(); + Navigator::new(env::args().nth(1)).run(); +} + +struct Navigator { + editors: Vec, + active: Option, + selected: Option, + path: String, + _term: RawTerminal, +} + +impl Navigator { + fn new(immediate_file: Option) -> Self { + let term = stdout().into_raw_mode().unwrap(); + let editors = vec![Editor::new(immediate_file)]; + Self { + editors, + active: Some(0), + selected: None, + path: String::new(), // TODO + _term: term, + } + } + + fn run(mut self) { + print!("{}", clear::All); + stdout().flush().unwrap(); + + loop { + if let Some(index) = self.active { + self.editors[index].draw(); + self.editors[index].input(); + + if self.editors[index].quit { + self.selected = self.active; + self.active = None; + } + } else { + self.draw(); + self.input(); + } + } + } + + fn draw(&self) { + print!("{}{}Open editors: {}", clear::All, Goto(1,1), self.editors.len()); + + for (index, editor) in self.editors.iter().enumerate() { + if Some(index) == self.selected { + print!("{}{}", color::Fg(color::Black), color::Bg(color::White)); + } + print!("{}{}", Goto(2, index as u16 + 2), editor.name()); + print!("{}{}", color::Fg(color::Reset), color::Bg(color::Reset)); + } + + stdout().flush().unwrap(); + } + + fn input(&mut self) { + for event in stdin().events().take(1).flatten() { + if let Event::Key(key) = event { + match key { + Key::Esc => self.quit(), + _ => (), + } + } + } + } + + fn quit(&self) { + print!("{}", clear::All); + exit(0); + } } diff --git a/src/util.rs b/src/util.rs index 40d96ba..947d7f2 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,5 +1,4 @@ use std::io::{stdin, stdout, Write}; - use termion::{ cursor, event::{Event, Key}, @@ -22,9 +21,7 @@ pub fn read_line(prompt: &str) -> Option { Key::Char('\n') => break, Key::Char(ch) => response.push(ch), Key::Backspace => { - if !response.is_empty() { - response.remove(response.len() - 1); - } + response.pop(); print!("{start_pos}{:width$}", " "); } Key::Esc => return None,