diff options
| author | Jonas Maier <> | 2026-03-04 17:14:53 +0100 |
|---|---|---|
| committer | Jonas Maier <> | 2026-03-04 17:14:53 +0100 |
| commit | 3c880475148d770ed39918fb0344faaed43299d0 (patch) | |
| tree | 503d12b806193972fb3d05f8b63832424d5c996c /src/main.rs | |
| parent | 15182b740d9d3d3b7e263b1690051aa06334ab0c (diff) | |
| download | pish-3c880475148d770ed39918fb0344faaed43299d0.tar.gz | |
arrow keys
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 111 |
1 files changed, 102 insertions, 9 deletions
diff --git a/src/main.rs b/src/main.rs index 7f372c1..bb74b2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,6 +34,85 @@ macro_rules! print { }} } +struct LineBuffer { + pre: Vec<u8>, + post: Vec<u8>, +} + +#[allow(unused)] +impl LineBuffer { + pub fn new() -> Self { + Self { + pre: Vec::new(), + post: Vec::new(), + } + } + pub fn del_left(&mut self) -> Option<u8> { + self.pre.pop() + } + pub fn del_right(&mut self) -> Option<u8> { + self.post.pop() + } + pub fn left(&mut self) -> bool { + if let Some(byte) = self.del_left() { + self.post.push(byte); + true + } else { + false + } + } + pub fn right(&mut self) -> bool { + if let Some(byte) = self.del_right() { + self.pre.push(byte); + true + } else { + false + } + } + pub fn add(&mut self, chr: u8) { + self.pre.push(chr); + } + + /// returns the whole contents of the buffer, and empties it in the process + pub fn dump(&mut self) -> Vec<u8> { + while self.right() {} + let mut buf = Vec::new(); + core::mem::swap(&mut self.pre, &mut buf); + buf + } + + pub fn display_post(&self) { + for &x in self.post.iter().rev() { + io::stdout().write_all(&[x]).unwrap(); + } + move_cursor(Direction::Left, self.post.len()); + io::stdout().flush().unwrap(); + } +} + +#[derive(Debug, Clone, Copy)] +pub enum Direction { + Up, + Down, + Left, + Right, +} + +pub fn move_cursor(direction: Direction, n: usize) { + if n == 0 { + return; + } + + let code = match direction { + Direction::Up => 'A', // CUU + Direction::Down => 'B', // CUD + Direction::Right => 'C', // CUF + Direction::Left => 'D', // CUB + }; + + print!("\x1b[{n}{code}"); +} + fn main() { let stdin = io::stdin(); let stdout = io::stdout(); @@ -51,6 +130,7 @@ fn main() { let mut stdout = stdout.lock(); let mut buffer = [0u8; 1]; + let mut line = LineBuffer::new(); loop { let Ok(_) = stdin.read_exact(&mut buffer) else { @@ -65,13 +145,15 @@ fn main() { // Enter b'\r' => { - println!("\r"); + print!("\r\n"); + stdout.write_all(&line.dump()).unwrap(); + print!("\r\n"); } // Backspace (127 on most systems) 127 => { - write!(stdout, "\x08 \x08").unwrap(); - stdout.flush().unwrap(); + line.del_left(); + print!("\x08 \x08"); } // Escape sequence @@ -81,10 +163,20 @@ fn main() { if seq[0] == b'[' { match seq[1] { - b'A' => print!("Up"), - b'B' => print!("Down"), - b'C' => print!("Right"), - b'D' => print!("Left"), + b'A' => { + // up + }, + b'B' => { + // down + }, + b'C' => { + move_cursor(Direction::Right, 1); + line.right(); + } + b'D' => { + move_cursor(Direction::Left, 1); + line.left(); + } _ => {} } } @@ -92,8 +184,9 @@ fn main() { // Normal character x => { - stdout.write(&[x]).unwrap(); - stdout.flush().unwrap(); + line.add(x); + stdout.write_all(&[x]).unwrap(); + line.display_post(); } } } |
