diff options
| author | Jonas Maier <> | 2026-03-07 18:47:22 +0100 |
|---|---|---|
| committer | Jonas Maier <> | 2026-03-07 18:47:22 +0100 |
| commit | 86cdb8c21dec737a3f0a40311782de851c1203d1 (patch) | |
| tree | e8aeac2d0d5dd81b39bf37016782afb3f087b69a | |
| parent | 8fcde466805466c7ecebfc3cd7d4340117a29576 (diff) | |
| download | pish-86cdb8c21dec737a3f0a40311782de851c1203d1.tar.gz | |
Ctrl+Left and Ctrl+Right
| -rw-r--r-- | src/linebuf.rs | 12 | ||||
| -rw-r--r-- | src/main.rs | 89 |
2 files changed, 99 insertions, 2 deletions
diff --git a/src/linebuf.rs b/src/linebuf.rs index 86c4f95..f5bd95f 100644 --- a/src/linebuf.rs +++ b/src/linebuf.rs @@ -61,6 +61,14 @@ impl LineBuf { n } + pub fn get_left(&self) -> Option<u8>{ + self.pre.last().cloned() + } + + pub fn get_right(&self) -> Option<u8>{ + self.post.last().cloned() + } + pub fn add(&mut self, chr: u8) { self.dirty = true; self.pre.push(chr); @@ -108,6 +116,10 @@ impl LineBuf { self.dirty = false; } + pub fn display_pre(&self) { + std::io::stdout().write_all(&self.pre).unwrap(); + } + /// TODO: kinda ugly that this is here pub fn display_post(&self, post: &[u8]) { for &x in self.post.iter().rev() { diff --git a/src/main.rs b/src/main.rs index cd7b244..5e29a6e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -120,6 +120,12 @@ impl Session { self.line.clear(); } + fn reprint_prompt(&self) { + print!("{}", self.prompt()); + self.line.display_pre(); + self.line.display_post(b""); + } + fn display_historic_entry(&mut self) { self.clear_prompt(); let new = if self.history_visit == 0 { @@ -146,6 +152,47 @@ impl Session { } } + // move to next + fn move_left_word(&mut self) { + let mut i = 0; + + // find word + while let Some(b' ') = self.line.get_left() { + self.line.left(); + i += 1; + } + + // skip it + while let Some(x) = self.line.get_left() && !x.is_ascii_whitespace() { + self.line.left(); + i += 1; + } + + cursor::move_cursor(Direction::Left, i); + io::stdout().flush().unwrap(); + } + + fn move_right_word(&mut self) { + let mut i = 0; + + // find word + while let Some(b' ') = self.line.get_right() { + self.line.right(); + i += 1; + } + + // skip it + while let Some(x) = self.line.get_right() + && !x.is_ascii_whitespace() + { + self.line.right(); + i += 1; + } + + cursor::move_cursor(Direction::Right, i); + io::stdout().flush().unwrap(); + } + fn type_byte(&mut self, b: u8) { self.line.add(b); io::stdout().lock().write_all(&[b]).unwrap(); @@ -244,6 +291,9 @@ fn event_loop() { break; } + // apparently another backspace, don't do anything. + 8 => {} + // Ctrl+L 12 => { clear_screen(); @@ -355,16 +405,51 @@ fn event_loop() { if seq.len() > 2 && seq[2] == b'~' { se.del_right(); } else { - todo!("unhandled: {seq:?}"); + todo!("unhandled: {}", seq.escape_ascii()); } } + // HOME button + b'H' => { + se.move_to_begin(); + } + // END button b'F' => { se.move_to_end(); } - x => todo!("escape character {x}"), + // 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()), } } } |
