aboutsummaryrefslogtreecommitdiffstats
path: root/src/term.rs
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2024-01-13 12:31:42 -0800
committerRose Hogenson <rosehogenson@posteo.net>2024-01-13 12:31:42 -0800
commit1e32f5d480ecefa3a1c8fd1c43ac6b4260459266 (patch)
tree2c268543df0f19fa424a8d01b642e23c3d38771e /src/term.rs
parentd8df9a6e5f09a0f9649ef16d15f86a22c4720ade (diff)
downloadeditor-1e32f5d480ecefa3a1c8fd1c43ac6b4260459266.tar.zst
Reject files with invalid utf-8.
It's easier to only support files with valid utf-8.
Diffstat (limited to 'src/term.rs')
-rw-r--r--src/term.rs24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/term.rs b/src/term.rs
index e390125..831cd43 100644
--- a/src/term.rs
+++ b/src/term.rs
@@ -1,6 +1,6 @@
use libc::{termios, winsize};
use std::error::Error;
-use std::io::{stdout, BufRead, BufReader, Stdin, Write};
+use std::io::{stdout, BufRead, BufReader, Read, Stdin, Write};
const ESC: u8 = 27;
@@ -83,7 +83,7 @@ pub enum Key {
End,
PgDn,
PgUp,
- Byte(u8),
+ Char(char),
}
pub struct Reader {
@@ -110,9 +110,21 @@ impl Reader {
return Ok(Key::Timeout);
}
if buf[0] != ESC {
- let b = buf[0];
- self.stdin.consume(1);
- return Ok(Key::Byte(b));
+ let mut n = usize::try_from(buf[0].leading_ones())
+ .expect("buf[0] is a u8 so it can only have 8 leading ones");
+ if n == 0 {
+ n = 1;
+ }
+ let mut char = [0; 4];
+ self.stdin.read_exact(&mut char[..n])?;
+ let Ok(s) = std::str::from_utf8(&char) else {
+ continue;
+ };
+ return Ok(Key::Char(
+ s.chars()
+ .nth(0)
+ .expect("s should be exactly one codepoint long"),
+ ));
}
if buf.len() < 3 || buf[1] != b'[' {
// Unknown escape sequence, eat the escape and one more byte.
@@ -173,7 +185,7 @@ impl Reader {
}
"3~" => {
// Backspace
- return Ok(Key::Byte(8));
+ return Ok(Key::Char(char::from(b'H' - b'@')));
}
_ => {
continue;