better event loop :)

This commit is contained in:
Crispy 2023-02-28 20:21:20 +01:00
parent 1e827acfdd
commit 7d1a2bc412
2 changed files with 66 additions and 54 deletions

View file

@ -21,7 +21,7 @@ pub struct Editor {
scroll: usize, scroll: usize,
cursor: Cursor, cursor: Cursor,
path: Option<String>, path: Option<String>,
pub quit: bool, active: bool,
} }
#[derive(Debug)] #[derive(Debug)]
@ -51,22 +51,30 @@ impl Editor {
scroll: 0, scroll: 0,
cursor: Cursor { line: 0, column: 0 }, cursor: Cursor { line: 0, column: 0 },
path, path,
quit: false, active: false,
}; };
this.find_lines(); this.find_lines();
this this
} }
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
self.path.as_ref().map_or("untitled", |s| &s) self.path.as_ref().map_or("untitled", |s| s)
} }
pub fn input(&mut self) { pub fn open(&mut self) {
self.active = true;
while self.active {
self.draw();
self.input();
}
}
fn input(&mut self) {
for event in stdin().events().take(1).flatten() { for event in stdin().events().take(1).flatten() {
// dbg!(&event);
if let Event::Key(key) = event { if let Event::Key(key) = event {
match key { match key {
Key::Esc => self.quit = true, Key::Esc => self.active = false,
Key::Char(char) => self.insert_char(char), Key::Char(char) => self.insert_char(char),
Key::Backspace => self.backspace(), Key::Backspace => self.backspace(),
Key::Delete => self.delete(), Key::Delete => self.delete(),
@ -83,6 +91,42 @@ impl Editor {
} }
} }
fn draw(&self) {
print!("{}", clear::All);
let max_rows = terminal_size().unwrap().1 as usize - 1;
let end = (self.scroll + max_rows).min(self.lines.len());
let visible_rows = self.scroll..end;
for (line_index, line) in self.lines[visible_rows].iter().enumerate() {
let text = &self.text[line.clone()];
print!(
"{}{}",
cursor::Goto(1, line_index as u16 + 1),
text.replace('\t', &" ".repeat(TAB_SIZE))
);
}
self.status_line();
print!(
"{}",
cursor::Goto(
self.physical_column() as u16 + 1,
(self.cursor.line - self.scroll) as u16 + 1
)
);
stdout().flush().unwrap();
}
fn status_line(&self) {
print!(
"{}({}, {}) {}",
cursor::Goto(1, terminal_size().unwrap().1),
self.cursor.line,
self.physical_column(),
self.name(),
);
}
fn move_left(&mut self) { fn move_left(&mut self) {
if self.cursor.column > 0 { if self.cursor.column > 0 {
self.cursor.column = self.prev_char_index() - self.current_line().start; self.cursor.column = self.prev_char_index() - self.current_line().start;
@ -168,38 +212,6 @@ impl Editor {
self.lines.push(this_line); self.lines.push(this_line);
} }
pub fn draw(&self) {
print!("{}", clear::All);
let max_rows = terminal_size().unwrap().1 as usize - 1;
let end = (self.scroll + max_rows).min(self.lines.len());
let visible_rows = self.scroll..end;
for (line_index, line) in self.lines[visible_rows].iter().enumerate() {
let text = &self.text[line.clone()];
print!(
"{}{}",
cursor::Goto(1, line_index as u16 + 1),
text.replace('\t', &" ".repeat(TAB_SIZE))
);
}
print!(
"{}({}, {})",
cursor::Goto(1, terminal_size().unwrap().1),
self.cursor.line,
self.cursor.column
);
print!(
"{}",
cursor::Goto(
self.physical_column() as u16 + 1,
(self.cursor.line - self.scroll) as u16 + 1
)
);
stdout().flush().unwrap();
}
fn insert_char(&mut self, ch: char) { fn insert_char(&mut self, ch: char) {
// eprintln!("inserting {ch} at {}", self.index()); // eprintln!("inserting {ch} at {}", self.index());
self.text.insert(self.char_index(), ch); self.text.insert(self.char_index(), ch);

View file

@ -21,7 +21,6 @@ fn main() {
struct Navigator { struct Navigator {
editors: Vec<Editor>, editors: Vec<Editor>,
active: Option<usize>,
selected: Option<usize>, selected: Option<usize>,
path: String, path: String,
_term: RawTerminal<Stdout>, _term: RawTerminal<Stdout>,
@ -33,8 +32,7 @@ impl Navigator {
let editors = vec![Editor::new(immediate_file)]; let editors = vec![Editor::new(immediate_file)];
Self { Self {
editors, editors,
active: Some(0), selected: Some(0),
selected: None,
path: String::new(), // TODO path: String::new(), // TODO
_term: term, _term: term,
} }
@ -45,23 +43,18 @@ impl Navigator {
stdout().flush().unwrap(); stdout().flush().unwrap();
loop { loop {
if let Some(index) = self.active { self.draw();
self.editors[index].draw(); self.input();
self.editors[index].input();
if self.editors[index].quit {
self.selected = self.active;
self.active = None;
}
} else {
self.draw();
self.input();
}
} }
} }
fn draw(&self) { fn draw(&self) {
print!("{}{}Open editors: {}", clear::All, Goto(1,1), self.editors.len()); print!(
"{}{}Open editors: {}",
clear::All,
Goto(1, 1),
self.editors.len()
);
for (index, editor) in self.editors.iter().enumerate() { for (index, editor) in self.editors.iter().enumerate() {
if Some(index) == self.selected { if Some(index) == self.selected {
@ -79,12 +72,19 @@ impl Navigator {
if let Event::Key(key) = event { if let Event::Key(key) = event {
match key { match key {
Key::Esc => self.quit(), Key::Esc => self.quit(),
Key::Char('\n') => self.open_selected(),
_ => (), _ => (),
} }
} }
} }
} }
fn open_selected(&mut self) {
if let Some(index) = self.selected {
self.editors[index].open();
}
}
fn quit(&self) { fn quit(&self) {
print!("{}", clear::All); print!("{}", clear::All);
exit(0); exit(0);