aboutsummaryrefslogtreecommitdiffstats
path: root/src/term.rs
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2024-01-11 16:38:04 -0800
committerRose Hogenson <rosehogenson@posteo.net>2024-01-11 21:31:39 -0800
commite23b1c7254aa21c0eb2fd18f720df262725c6d81 (patch)
treebec06482f9e461f25aced992277718af9a83ac72 /src/term.rs
parente8685c54228ca3337060520f7fbeb5629281764c (diff)
downloadeditor-e23b1c7254aa21c0eb2fd18f720df262725c6d81.tar.zst
Implement Home, End, PgUp, and PgDn.
Diffstat (limited to 'src/term.rs')
-rw-r--r--src/term.rs51
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;
}