navigator skeleton

This commit is contained in:
Crispy 2023-02-28 12:41:34 +01:00
parent a65a1cc9b8
commit 1e827acfdd
3 changed files with 107 additions and 28 deletions

View file

@ -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<String>,
_term: RawTerminal<Stdout>,
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;

View file

@ -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<Editor>,
active: Option<usize>,
selected: Option<usize>,
path: String,
_term: RawTerminal<Stdout>,
}
impl Navigator {
fn new(immediate_file: Option<String>) -> 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);
}
}

View file

@ -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<String> {
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,