diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2024-01-11 16:38:04 -0800 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2024-01-11 21:31:39 -0800 |
| commit | e23b1c7254aa21c0eb2fd18f720df262725c6d81 (patch) | |
| tree | bec06482f9e461f25aced992277718af9a83ac72 /src/term.rs | |
| parent | e8685c54228ca3337060520f7fbeb5629281764c (diff) | |
| download | editor-e23b1c7254aa21c0eb2fd18f720df262725c6d81.tar.zst | |
Implement Home, End, PgUp, and PgDn.
Diffstat (limited to 'src/term.rs')
| -rw-r--r-- | src/term.rs | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/src/term.rs b/src/term.rs index 2e37c65..bf06538 100644 --- a/src/term.rs +++ b/src/term.rs @@ -53,6 +53,10 @@ pub enum Key { Down, Left, Right, + Home, + End, + PgDn, + PgUp, Byte(u8), } @@ -74,31 +78,50 @@ pub fn read_key(stdin: &mut BufReader<Stdin>) -> Result<Key, Box<dyn Error>> { stdin.consume(1); continue; } - let mut n = buf.len(); - for (i, &c) in buf.iter().enumerate() { - match c { - b'A'..=b'Z' | b'a'..=b'z' => { - n = i + 1; - break; - } - _ => (), + // An escape sequence usually starts with [, then has one or two numbers separated by + // semicolon, and ends with some terminating character. To try and munch the whole + // sequence, skip over any numbers and semicolon here. + let mut n = 1; + while let b'0'..=b'9' | b';' = buf[n] { + n += 1; + if n == buf.len() - 1 { + break; } } - let c = buf[1]; + + // Skip the terminating character. + n += 1; + + let seq = buf[1..n].to_vec(); stdin.consume(n); - match c { - b'A' => { + let Ok(s) = String::from_utf8(seq) else { + continue; + }; + match s.as_str() { + "A" => { return Ok(Key::Up); } - b'B' => { + "B" => { return Ok(Key::Down); } - b'C' => { + "C" => { return Ok(Key::Right); } - b'D' => { + "D" => { return Ok(Key::Left); } + "H" | "1~" => { + return Ok(Key::Home); + } + "F" | "8~" => { + return Ok(Key::End); + } + "5~" => { + return Ok(Key::PgUp); + } + "6~" => { + return Ok(Key::PgDn); + } _ => { continue; } |
