diff options
Diffstat (limited to 'src/buffer.rs')
-rw-r--r-- | src/buffer.rs | 89 |
1 files changed, 57 insertions, 32 deletions
diff --git a/src/buffer.rs b/src/buffer.rs index 4d00d34..7ece258 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -10,6 +10,7 @@ use std::sync::{Arc, Mutex}; pub const STDIN: i32 = 0; // Key input types from the user +#[derive(PartialEq)] enum Key { Up, Down, @@ -79,9 +80,6 @@ fn autocomplete( index: usize, pwd: &PathBuf, ) -> Result<(String, usize), Box<dyn std::error::Error>> { - // Get the present working directory - // let pwd = current_dir()?; - let buffer = buffer.lock().unwrap(); let word = match buffer.last() { Some(c) if *c == b' ' => "".to_string(), @@ -185,14 +183,21 @@ fn autocomplete( /// that (ICANON and ECHO) are off. See the beginning of [crate::repl] /// for more details. pub fn getline(buffer: &mut Arc<Mutex<Vec<u8>>>, pos: &mut Arc<Mutex<usize>>) -> usize { + // Keep track of the last key + let mut last: Option<Key> = None; + // Keep track of index for autocomplete let mut pwd = current_dir().unwrap_or(PathBuf::from(env!("HOME"))); let mut auindex = 0; let mut aulen = 0; + // Keep track of the length of the last buffer from autcomplete() + let mut length = 0; + // Loop over characters until there is a newline loop { - match getchar() { + let c = getchar(); + match c { Key::Up => { continue; } @@ -214,6 +219,12 @@ pub fn getline(buffer: &mut Arc<Mutex<Vec<u8>>>, pos: &mut Arc<Mutex<usize>>) -> *pos.lock().unwrap() -= 1; } Key::Tab => { + if last == Some(Key::ShiftTab) { + auindex += 2; + if auindex >= length { + auindex = 0; + } + } while aulen > 0 { buffer.lock().unwrap().pop(); print!("\u{8} \u{8}"); @@ -222,6 +233,7 @@ pub fn getline(buffer: &mut Arc<Mutex<Vec<u8>>>, pos: &mut Arc<Mutex<usize>>) -> } let (path, len) = autocomplete(buffer, auindex, &pwd).unwrap_or(("".to_string(), 0)); + length = len; for c in path.into_bytes().iter() { buffer.lock().unwrap().insert(*pos.lock().unwrap(), *c); *pos.lock().unwrap() += 1; @@ -233,6 +245,13 @@ pub fn getline(buffer: &mut Arc<Mutex<Vec<u8>>>, pos: &mut Arc<Mutex<usize>>) -> } } Key::ShiftTab => { + if last == Some(Key::Tab) { + if auindex.checked_sub(2) == None { + auindex = length - 1; + } else { + auindex -= 2; + } + } while aulen > 0 { buffer.lock().unwrap().pop(); print!("\u{8} \u{8}"); @@ -241,6 +260,7 @@ pub fn getline(buffer: &mut Arc<Mutex<Vec<u8>>>, pos: &mut Arc<Mutex<usize>>) -> } let (path, len) = autocomplete(buffer, auindex, &pwd).unwrap_or(("".to_string(), 0)); + length = len; for c in path.into_bytes().iter() { buffer.lock().unwrap().insert(*pos.lock().unwrap(), *c); *pos.lock().unwrap() += 1; @@ -300,6 +320,35 @@ pub fn getline(buffer: &mut Arc<Mutex<Vec<u8>>>, pos: &mut Arc<Mutex<usize>>) -> _ => { let mut buffer = buffer.lock().unwrap(); + // Print out the character as the user is typing + match buffer.last() { + Some(last) if *last == b'/' && c == b'/' => { + buffer.pop(); + *pos.lock().unwrap() -= 1; + } + Some(_) => print!("{}", c as char), + None => print!("{}", c as char), + } + + // Insert the character onto the buffer at whatever *pos.lock().unwrap()ition + // the cursor is at + buffer.insert(*pos.lock().unwrap(), c); + + // Increment our *pos.lock().unwrap()ition + *pos.lock().unwrap() += 1; + + // Reprint the end of the buffer if inserting at the front or middle + if *pos.lock().unwrap() != buffer.len() { + print!( + "{}", + String::from_utf8_lossy(&buffer[*pos.lock().unwrap()..]) + ); + for _ in *pos.lock().unwrap()..buffer.len() { + print!("\u{8}"); + } + } + + // Update directory for autocomplete let word = match buffer.last() { Some(c) if *c == b' ' => "".to_string(), None => "".to_string(), @@ -319,7 +368,7 @@ pub fn getline(buffer: &mut Arc<Mutex<Vec<u8>>>, pos: &mut Arc<Mutex<usize>>) -> } loop { match word.last() { - Some(c) if *c == b'/' || *c == b'.' => { + Some(c) if *c == b'/' || *c == b'.' || *c == b'~' => { break; } Some(_) => { @@ -351,36 +400,12 @@ pub fn getline(buffer: &mut Arc<Mutex<Vec<u8>>>, pos: &mut Arc<Mutex<usize>>) -> pwd = PathBuf::from(word); auindex = 0; aulen = 0; - - // Print out the character as the user is typing - match buffer.last() { - Some(last) if *last == b'/' && c == b'/' => { - buffer.pop(); - *pos.lock().unwrap() -= 1; - } - Some(_) => print!("{}", c as char), - None => print!("{}", c as char), - } - - // Insert the character onto the buffer at whatever *pos.lock().unwrap()ition the cursor is at - buffer.insert(*pos.lock().unwrap(), c); - - // Increment our *pos.lock().unwrap()ition - *pos.lock().unwrap() += 1; - - // Reprint the end of the buffer if inserting at the front or middle - if *pos.lock().unwrap() != buffer.len() { - print!( - "{}", - String::from_utf8_lossy(&buffer[*pos.lock().unwrap()..]) - ); - for _ in *pos.lock().unwrap()..buffer.len() { - print!("\u{8}"); - } - } } }, } + + // Update the last key + last = Some(c); } *pos.lock().unwrap() = 0; |