aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cursor.rs29
-rw-r--r--src/linebuf.rs64
-rw-r--r--src/main.rs112
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");
}