diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2023-12-29 11:20:05 -0800 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2023-12-29 11:20:05 -0800 |
| commit | f898a97005844d5c451842eca63871ba382f5d96 (patch) | |
| tree | 6bad85df432f89888df52e8db414d963a164de37 /src/term.rs | |
| parent | 2a2181daaf96d2646a8001b9f138099510d0b34e (diff) | |
| download | editor-f898a97005844d5c451842eca63871ba382f5d96.tar.zst | |
Allow moving the cursor with the arrow keys.
Diffstat (limited to 'src/term.rs')
| -rw-r--r-- | src/term.rs | 55 |
1 files changed, 55 insertions, 0 deletions
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<winsize> { unsafe { @@ -59,3 +60,57 @@ pub fn raw() -> Option<RawHandle> { } return Some(RawHandle { old: old }); } + +pub enum Key { + CtrlQ, + Up, + Down, + Left, + Right, + Char(char), +} + +pub fn read_key(stdin: &mut Stdin) -> Result<Key, String> { + 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; + } + } + } +} |
