aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authorJonas Maier <>2026-03-04 17:14:53 +0100
committerJonas Maier <>2026-03-04 17:14:53 +0100
commit3c880475148d770ed39918fb0344faaed43299d0 (patch)
tree503d12b806193972fb3d05f8b63832424d5c996c /src/main.rs
parent15182b740d9d3d3b7e263b1690051aa06334ab0c (diff)
downloadpish-3c880475148d770ed39918fb0344faaed43299d0.tar.gz
arrow keys
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs111
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();
}
}
}