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,
cursor: Cursor,
path: Option<String>,
pub quit: bool,
active: bool,
}
#[derive(Debug)]
@ -51,22 +51,30 @@ impl Editor {
scroll: 0,
cursor: Cursor { line: 0, column: 0 },
path,
quit: false,
active: false,
};
this.find_lines();
this
}
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() {
// dbg!(&event);
if let Event::Key(key) = event {
match key {
Key::Esc => self.quit = true,
Key::Esc => self.active = false,
Key::Char(char) => self.insert_char(char),
Key::Backspace => self.backspace(),
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) {
if self.cursor.column > 0 {
self.cursor.column = self.prev_char_index() - self.current_line().start;
@ -168,38 +212,6 @@ impl Editor {
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) {
// eprintln!("inserting {ch} at {}", self.index());
self.text.insert(self.char_index(), ch);

View file

@ -21,7 +21,6 @@ fn main() {
struct Navigator {
editors: Vec<Editor>,
active: Option<usize>,
selected: Option<usize>,
path: String,
_term: RawTerminal<Stdout>,
@ -33,8 +32,7 @@ impl Navigator {
let editors = vec![Editor::new(immediate_file)];
Self {
editors,
active: Some(0),
selected: None,
selected: Some(0),
path: String::new(), // TODO
_term: term,
}
@ -45,23 +43,18 @@ impl Navigator {
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());
print!(
"{}{}Open editors: {}",
clear::All,
Goto(1, 1),
self.editors.len()
);
for (index, editor) in self.editors.iter().enumerate() {
if Some(index) == self.selected {
@ -79,12 +72,19 @@ impl Navigator {
if let Event::Key(key) = event {
match key {
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) {
print!("{}", clear::All);
exit(0);