aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs47
-rw-r--r--src/term.rs55
2 files changed, 82 insertions, 20 deletions
diff --git a/src/main.rs b/src/main.rs
index 75a6ebf..592f89c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,24 +3,9 @@ mod term;
use rope::Rope;
use std::ffi::{OsStr, OsString};
-use std::io::{Read, Stdin, Write};
+use std::io::Write;
use std::path::Path;
-
-const CTRL_Q: u8 = 17;
-
-fn read_key(stdin: &mut Stdin) -> Result<u8, String> {
- let mut buf = vec![0; 1];
- match stdin.read(&mut buf) {
- Err(err) => {
- return Err(format!("read input: {}", err));
- }
- Ok(0) => {
- return Err(String::from("no input"));
- }
- _ => (),
- }
- return Ok(buf[0]);
-}
+use term::Key;
fn edit(file: &OsStr) -> Result<(), String> {
let _raw_handle = match term::raw() {
@@ -53,14 +38,36 @@ fn edit(file: &OsStr) -> Result<(), String> {
let mut stdin = std::io::stdin();
loop {
- let c = match read_key(&mut stdin) {
+ let c = match term::read_key(&mut stdin) {
Ok(c) => c,
Err(err) => {
return Err(err);
}
};
- if c == CTRL_Q {
- break;
+ match c {
+ Key::CtrlQ => {
+ break;
+ }
+ Key::Up => {
+ let _ = stdout.write(b"\x1b[A");
+ let _ = stdout.flush();
+ }
+ Key::Down => {
+ let _ = stdout.write(b"\x1b[B");
+ let _ = stdout.flush();
+ }
+ Key::Left => {
+ let _ = stdout.write(b"\x1b[D");
+ let _ = stdout.flush();
+ }
+ Key::Right => {
+ let _ = stdout.write(b"\x1b[C");
+ let _ = stdout.flush();
+ }
+ Key::Char(c) => {
+ print!("{} ", c);
+ let _ = stdout.flush();
+ }
}
}
return Ok(());
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;
+ }
+ }
+ }
+}