diff options
| author | Jonas Maier <> | 2026-03-05 16:47:13 +0100 |
|---|---|---|
| committer | Jonas Maier <> | 2026-03-05 16:47:13 +0100 |
| commit | 076993268da470bbc28129170a9e5c9dad1b80b8 (patch) | |
| tree | 38d2ca17ec74ad0736f66d8599ecdc5d9dafe51a /src | |
| parent | a6f60f36720e16f56913dd3b12560958b6059e68 (diff) | |
| download | pish-076993268da470bbc28129170a9e5c9dad1b80b8.tar.gz | |
delete button, and various fixes
Diffstat (limited to 'src')
| -rw-r--r-- | src/linebuf.rs | 28 | ||||
| -rw-r--r-- | src/main.rs | 56 |
2 files changed, 74 insertions, 10 deletions
diff --git a/src/linebuf.rs b/src/linebuf.rs index 1d28549..836cfee 100644 --- a/src/linebuf.rs +++ b/src/linebuf.rs @@ -27,6 +27,10 @@ impl LineBuf { self.post.pop() } + pub fn len(&self) -> usize { + self.pre.len() + self.post.len() + } + pub fn left(&mut self) -> bool { if let Some(byte) = self.del_left() { self.post.push(byte); @@ -64,6 +68,19 @@ impl LineBuf { self.post = Vec::new(); } + pub fn into_bytes(&self) -> Vec<u8> { + let mut buf = Vec::with_capacity(self.pre.len() + self.post.len()); + buf.extend_from_slice(&self.pre); + for b in self.post.iter().rev() { + buf.push(*b); + } + buf + } + + pub fn distance_from_right_end(&self) -> usize { + self.post.len() + } + /// returns the whole contents of the buffer, and empties it in the process pub fn dump(&mut self) -> Vec<u8> { while self.right() {} @@ -73,12 +90,19 @@ impl LineBuf { buf } + pub fn clear(&mut self) { + self.pre.clear(); + self.post.clear(); + self.dirty = false; + } + /// TODO: kinda ugly that this is here - pub fn display_post(&self) { + pub fn display_post(&self, post: &[u8]) { for &x in self.post.iter().rev() { std::io::stdout().write_all(&[x]).unwrap(); } - move_cursor(Direction::Left, self.post.len()); + std::io::stdout().write_all(post).unwrap(); + move_cursor(Direction::Left, self.post.len() + post.len()); std::io::stdout().flush().unwrap(); } } diff --git a/src/main.rs b/src/main.rs index 19b98c2..81cc5d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -96,6 +96,12 @@ impl Session { } } +fn read1() -> u8 { + let mut buf = [0]; + io::stdin().lock().read_exact(&mut buf).unwrap(); + buf[0] +} + fn event_loop() { let stdin = io::stdin(); let stdout = io::stdout(); @@ -121,6 +127,17 @@ fn event_loop() { }; match buf[0] { + // Ctrl+C + 3 => { + // clear line + cursor::move_cursor(Direction::Right, se.line.distance_from_right_end()); + for _ in 0..se.line.len() { + write!(io::stdout(), "\x08 \x08").unwrap(); + } + io::stdout().lock().flush().unwrap(); + se.line.clear(); + } + // EOF 4 => { break; @@ -129,7 +146,10 @@ fn event_loop() { // Ctrl+L 12 => { clear_screen(); - print!("{}", se.prompt()); + write!(io::stdout(), "{}", se.prompt()).unwrap(); + 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 @@ -164,10 +184,17 @@ fn event_loop() { // Escape sequence 27 => { - let mut seq = [0u8; 2]; - stdin.lock().read_exact(&mut seq).unwrap(); + let mut seq = vec![read1()]; if seq[0] == b'[' { + // still more + while { + let last = seq[seq.len() - 1]; + last < 0x40 || last > 0x7E || seq.len() == 1 + } { + seq.push(read1()); + } + match seq[1] { b'A' => { // up @@ -176,12 +203,25 @@ fn event_loop() { // down } b'C' => { - move_cursor(Direction::Right, 1); - se.line.right(); + if se.line.right() { + move_cursor(Direction::Right, 1); + io::stdout().lock().flush().unwrap(); + } } b'D' => { - move_cursor(Direction::Left, 1); - se.line.left(); + if se.line.left() { + move_cursor(Direction::Left, 1); + io::stdout().lock().flush().unwrap(); + } + } + b'3' => { + if seq.len() > 2 && seq[2] == b'~' { + // delete + se.line.del_right(); + se.line.display_post(b" "); + } else { + todo!("unhandled: {seq:?}"); + } } x => todo!("escape character {x}"), } @@ -200,7 +240,7 @@ fn event_loop() { x => { se.line.add(x); stdout.lock().write_all(&[x]).unwrap(); - se.line.display_post(); + se.line.display_post(b""); } } } |
