From f898a97005844d5c451842eca63871ba382f5d96 Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Fri, 29 Dec 2023 11:20:05 -0800 Subject: Allow moving the cursor with the arrow keys. --- src/term.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src/term.rs') diff --git a/src/term.rs b/src/term.rs index 149f00f..20098a0 100644 --- a/src/term.rs +++ b/src/term.rs @@ -1,4 +1,5 @@ use libc::{termios, winsize}; +use std::io::{Read, Stdin}; pub fn size() -> Option { unsafe { @@ -59,3 +60,57 @@ pub fn raw() -> Option { } return Some(RawHandle { old: old }); } + +pub enum Key { + CtrlQ, + Up, + Down, + Left, + Right, + Char(char), +} + +pub fn read_key(stdin: &mut Stdin) -> Result { + const CTRL_Q: u8 = 17; + const ESC: u8 = 27; + + loop { + let mut buf = vec![0; 1]; + if let Err(err) = stdin.read_exact(&mut buf) { + return Err(format!("read input: {}", err)); + } + if buf[0] == CTRL_Q { + return Ok(Key::CtrlQ); + } + if buf[0] != ESC { + return Ok(Key::Char(char::from(buf[0]))); + } + // Try to handle an escape sequence. + let mut buf = vec![0; 2]; + if let Err(err) = stdin.read_exact(&mut buf) { + return Err(format!("read input: {}", err)); + } + if buf[0] != b'[' { + // Unknown escape sequence, just read another key. + continue; + } + match buf[1] { + b'A' => { + return Ok(Key::Up); + } + b'B' => { + return Ok(Key::Down); + } + b'C' => { + return Ok(Key::Right); + } + b'D' => { + return Ok(Key::Left); + } + _ => { + // Unknown key, just ignore it. + continue; + } + } + } +} -- cgit v1.3.1