better event loop :)
This commit is contained in:
parent
1e827acfdd
commit
7d1a2bc412
2 changed files with 66 additions and 54 deletions
|
@ -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);
|
||||
|
|
28
src/main.rs
28
src/main.rs
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue