aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs213
1 files changed, 49 insertions, 164 deletions
diff --git a/src/main.rs b/src/main.rs
index 9286653..e0d9e84 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,6 +13,7 @@ use std::sync::{Arc, Mutex};
use std::thread::sleep;
use std::time::Duration;
+pub mod ansi;
pub mod basedir;
pub mod completion;
pub mod ctrlc;
@@ -273,12 +274,6 @@ impl Session {
}
}
-fn read1() -> u8 {
- let mut buf = [0];
- io::stdin().lock().read_exact(&mut buf).unwrap();
- buf[0]
-}
-
fn event_loop() {
history::setup();
@@ -316,56 +311,31 @@ fn event_loop() {
let _ctrlc = ctrlc::setup(session.clone());
loop {
- let mut buf = [0u8; 1];
-
- let Ok(_) = stdin.lock().read_exact(&mut buf) else {
- break;
- };
-
let mut se = session.lock().unwrap();
- if se.debug_keystrokes {
- println!("{}", buf.escape_ascii());
- }
-
- match buf[0] {
- // Ctrl+A
- 1 => {
- se.move_to_begin();
- }
+ use ansi::KeyboardInput as Kb;
- // Ctrl+E
- 5 => {
- se.move_to_end();
- }
-
- // Ctrl+C
- 3 => {
+ match ansi::read(se.debug_keystrokes) {
+ Kb::Eof => todo!(),
+ Kb::CtrlA => se.move_to_begin(),
+ Kb::CtrlB => todo!(),
+ Kb::CtrlC => {
se.clear_prompt();
se.history_visit = 0;
}
-
- // EOF
- 4 => {
- break;
- }
-
- // apparently another backspace, don't do anything.
- 8 => {}
-
- // Ctrl+L
- 12 => {
+ Kb::CtrlE => se.move_to_end(),
+ Kb::CtrlD => break,
+ Kb::CtrlL => {
clear_screen();
print!("{}", se.prompt());
io::stdout().write_all(&se.line.into_bytes()).unwrap();
cursor::move_cursor(Direction::Left, se.line.distance_from_right_end());
io::stdout().lock().flush().unwrap();
}
-
- // Ctrl+R
- 18 => {}
-
- // Enter
- b'\r' => {
+ Kb::CtrlR => {
+ println!("search is not yet implemented");
+ se.reprint_prompt();
+ }
+ Kb::Key(b'\r' | b'\n') => {
let line = se.line.into_bytes();
if !line.is_empty() {
@@ -391,19 +361,7 @@ fn event_loop() {
run::run(session.clone(), parsed);
}
}
-
- // Backspace (127 on most systems)
- 127 => {
- if se.line.is_empty() && !se.line.is_dirty() && !se.history.is_empty() {
- // take previous command for editing
- let cmd = se.history[se.history.len() - 1].cmd.clone();
- se.type_bytes(&cmd);
- } else {
- se.del_left();
- }
- }
-
- b'\t' => {
+ Kb::Key(b'\t') => {
let cmd = se.line.pre().to_vec();
drop(se);
@@ -422,117 +380,44 @@ fn event_loop() {
se.reprint_prompt();
}
}
-
- // Escape sequence
- 27 => {
- let mut seq = vec![read1()];
-
- if seq[0] == b'[' {
- // still more
- while {
- let last = seq[seq.len() - 1];
- !(0x40..=0x7E).contains(&last) || seq.len() == 1
- } {
- seq.push(read1());
- }
-
- if se.debug_keystrokes {
- println!("escape: {}", seq.escape_ascii());
+ Kb::Arrow(dir) => match dir {
+ Direction::Up => se.history_up(),
+ Direction::Down => se.history_down(),
+ Direction::Left => {
+ if se.line.left() {
+ move_cursor(Direction::Left, 1);
+ io::stdout().lock().flush().unwrap();
}
-
- match seq[1] {
- b'A' => {
- // up
- se.history_up();
- }
- b'B' => {
- // down
- se.history_down();
- }
- b'C' => {
- if se.line.right() {
- move_cursor(Direction::Right, 1);
- io::stdout().lock().flush().unwrap();
- }
- }
- b'D' => {
- if se.line.left() {
- move_cursor(Direction::Left, 1);
- io::stdout().lock().flush().unwrap();
- }
- }
- b'3' => {
- if seq.len() > 2 && seq[2] == b'~' {
- se.del_right();
- } else {
- todo!("unhandled: {}", seq.escape_ascii());
- }
- }
-
- // HOME button
- b'H' => {
- se.move_to_begin();
- }
-
- // END button
- b'F' => {
- se.move_to_end();
- }
-
- // Ctrl Arrow
- b'1' => {
- if seq[1..].starts_with(b"1;5") {
- if seq.len() == 4 {
- todo!("idk what this is.");
- }
- match seq[4] {
- b'A' => {
- println!("Ctrl+Up");
- se.reprint_prompt();
- continue;
- }
- b'B' => {
- println!("Ctrl+Down");
- se.reprint_prompt();
- continue;
- }
- b'C' => {
- se.move_right_word();
- }
- b'D' => {
- se.move_left_word();
- }
- _ => todo!("unhandled {}", seq.escape_ascii()),
- }
- continue;
- }
- todo!("unhandled {}", seq[1..].escape_ascii())
- }
-
- _ => todo!("escape characters {}", seq[1..].escape_ascii()),
+ }
+ Direction::Right => {
+ if se.line.right() {
+ move_cursor(Direction::Right, 1);
+ io::stdout().lock().flush().unwrap();
}
+ }
+ },
+ Kb::CtrlArrow(dir) => match dir {
+ Direction::Left => se.move_left_word(),
+ Direction::Right => se.move_right_word(),
+ _ => {
+ println!("Ctrl+{dir:?} not implemented");
+ se.reprint_prompt();
+ }
+ },
+ Kb::DeleteLeft => {
+ if se.line.is_empty() && !se.line.is_dirty() && !se.history.is_empty() {
+ // take previous command for editing
+ let cmd = se.history[se.history.len() - 1].cmd.clone();
+ se.type_bytes(&cmd);
} else {
- if se.debug_keystrokes {
- println!("escape: {}", seq.escape_ascii());
- }
- if seq[0] == b'd' {
- se.del_right_word();
- }
+ se.del_left();
}
}
-
- b'|' if se.line.is_empty() && !se.history.is_empty() => {
- let mut cmd = se.history[se.history.len() - 1].cmd.clone();
- cmd.extend_from_slice(b" | ");
- io::stdout().write_all(&cmd).unwrap();
- io::stdout().flush().unwrap();
- se.line.set_content(cmd);
- }
-
- // Normal character
- x => {
- se.type_byte(x);
- }
+ Kb::DeleteRight => se.del_right(),
+ Kb::CtrlDeleteRight => se.del_right_word(),
+ Kb::Home => se.move_to_begin(),
+ Kb::End => se.move_to_end(),
+ Kb::Key(x) => se.type_byte(x),
}
}