diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cursor.rs | 29 | ||||
| -rw-r--r-- | src/linebuf.rs | 64 | ||||
| -rw-r--r-- | src/main.rs | 112 |
3 files changed, 109 insertions, 96 deletions
diff --git a/src/cursor.rs b/src/cursor.rs new file mode 100644 index 0000000..7913d3c --- /dev/null +++ b/src/cursor.rs @@ -0,0 +1,29 @@ +#[derive(Debug, Clone, Copy)] +pub enum Direction { + Up, + Down, + Left, + Right, +} + +pub fn move_cursor(direction: Direction, n: usize) { + if n == 0 { + return; + } + + let code = match direction { + Direction::Up => 'A', + Direction::Down => 'B', + Direction::Right => 'C', + Direction::Left => 'D', + }; + + print!("\x1b[{n}{code}"); +} + +/// Represents a cursor position +#[derive(Debug, Clone, Copy)] +pub struct CursorPos { + pub row: usize, + pub col: usize, +} diff --git a/src/linebuf.rs b/src/linebuf.rs new file mode 100644 index 0000000..91d0306 --- /dev/null +++ b/src/linebuf.rs @@ -0,0 +1,64 @@ +use std::io::Write; +use crate::cursor::*; + +pub struct LineBuf { + pre: Vec<u8>, + post: Vec<u8>, +} + +#[allow(unused)] +impl LineBuf { + pub fn new() -> Self { + Self { + pre: Vec::new(), + post: Vec::new(), + } + } + + pub fn del_left(&mut self) -> Option<u8> { + self.pre.pop() + } + + pub fn del_right(&mut self) -> Option<u8> { + self.post.pop() + } + + pub fn left(&mut self) -> bool { + if let Some(byte) = self.del_left() { + self.post.push(byte); + true + } else { + false + } + } + + pub fn right(&mut self) -> bool { + if let Some(byte) = self.del_right() { + self.pre.push(byte); + true + } else { + false + } + } + + pub fn add(&mut self, chr: u8) { + self.pre.push(chr); + } + + /// returns the whole contents of the buffer, and empties it in the process + pub fn dump(&mut self) -> Vec<u8> { + while self.right() {} + let mut buf = Vec::new(); + core::mem::swap(&mut self.pre, &mut buf); + buf + } + + /// TODO: kinda ugly that this is here + pub fn display_post(&self) { + for &x in self.post.iter().rev() { + std::io::stdout().write_all(&[x]).unwrap(); + } + move_cursor(Direction::Left, self.post.len()); + std::io::stdout().flush().unwrap(); + } +} diff --git a/src/main.rs b/src/main.rs index 2836b2c..9b10890 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,20 @@ -use std::io::{self, Read, Write, IsTerminal}; -use std::os::unix::io::AsRawFd; -use std::process::Command; use std::ffi::OsStr; +use std::io::{self, IsTerminal, Read, Write}; use std::os::unix::ffi::OsStrExt; +use std::os::unix::io::AsRawFd; use std::path::Path; +use std::process::Command; -mod raw; +mod cursor; +mod linebuf; mod parse; +mod raw; + +use linebuf::LineBuf; use raw::*; +use crate::cursor::{Direction, move_cursor}; + macro_rules! print { ($($x:tt)*) => {{ write!(io::stdout(), $($x)*).unwrap(); @@ -27,92 +33,6 @@ macro_rules! println { }}; } -struct LineBuffer { - pre: Vec<u8>, - post: Vec<u8>, -} - -#[allow(unused)] -impl LineBuffer { - pub fn new() -> Self { - Self { - pre: Vec::new(), - post: Vec::new(), - } - } - pub fn del_left(&mut self) -> Option<u8> { - self.pre.pop() - } - pub fn del_right(&mut self) -> Option<u8> { - self.post.pop() - } - pub fn left(&mut self) -> bool { - if let Some(byte) = self.del_left() { - self.post.push(byte); - true - } else { - false - } - } - pub fn right(&mut self) -> bool { - if let Some(byte) = self.del_right() { - self.pre.push(byte); - true - } else { - false - } - } - pub fn add(&mut self, chr: u8) { - self.pre.push(chr); - } - - /// returns the whole contents of the buffer, and empties it in the process - pub fn dump(&mut self) -> Vec<u8> { - while self.right() {} - let mut buf = Vec::new(); - core::mem::swap(&mut self.pre, &mut buf); - buf - } - - pub fn display_post(&self) { - for &x in self.post.iter().rev() { - io::stdout().write_all(&[x]).unwrap(); - } - move_cursor(Direction::Left, self.post.len()); - io::stdout().flush().unwrap(); - } -} - -#[derive(Debug, Clone, Copy)] -pub enum Direction { - Up, - Down, - Left, - Right, -} - -pub fn move_cursor(direction: Direction, n: usize) { - if n == 0 { - return; - } - - let code = match direction { - Direction::Up => 'A', // CUU - Direction::Down => 'B', // CUD - Direction::Right => 'C', // CUF - Direction::Left => 'D', // CUB - }; - - print!("\x1b[{n}{code}"); -} - -/// Represents a cursor position -#[derive(Debug, Clone, Copy)] -pub struct CursorPos { - pub row: usize, - pub col: usize, -} - const PROMPT: &str = "> "; fn run_command(raw: &ScopedRawMode, line: Vec<u8>) { @@ -141,7 +61,7 @@ fn run_command(raw: &ScopedRawMode, line: Vec<u8>) { } return; - }, + } _ => (), } @@ -180,7 +100,7 @@ fn main() { let mut stdout = stdout.lock(); let mut buffer = [0u8; 1]; - let mut line = LineBuffer::new(); + let mut line = LineBuf::new(); print!("{PROMPT}"); @@ -220,10 +140,10 @@ fn main() { match seq[1] { b'A' => { // up - }, + } b'B' => { // down - }, + } b'C' => { move_cursor(Direction::Right, 1); line.right(); @@ -232,7 +152,7 @@ fn main() { move_cursor(Direction::Left, 1); line.left(); } - x => todo!("escape character {x}") + x => todo!("escape character {x}"), } } } @@ -247,5 +167,5 @@ fn main() { } raw.disable(); - println!(); + println!("bye"); } |
