aboutsummaryrefslogtreecommitdiffstats
path: root/src/line/buf.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/line/buf.rs')
-rw-r--r--src/line/buf.rs150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/line/buf.rs b/src/line/buf.rs
new file mode 100644
index 0000000..420546a
--- /dev/null
+++ b/src/line/buf.rs
@@ -0,0 +1,150 @@
+use crate::cursor::*;
+use std::io::Write;
+
+pub struct LineBuf {
+ pre: Vec<u8>,
+ post: Vec<u8>,
+ dirty: bool,
+}
+
+impl Default for LineBuf {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+#[allow(unused)]
+impl LineBuf {
+ pub fn new() -> Self {
+ Self {
+ pre: Vec::new(),
+ post: Vec::new(),
+ dirty: false,
+ }
+ }
+
+ pub fn del_left(&mut self) -> Option<u8> {
+ self.dirty = true;
+ self.pre.pop()
+ }
+
+ pub fn del_right(&mut self) -> Option<u8> {
+ self.dirty = true;
+ self.post.pop()
+ }
+
+ pub fn len(&self) -> usize {
+ self.pre.len() + self.post.len()
+ }
+
+ 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 all_left(&mut self) -> usize {
+ let n = self.pre.len();
+ while self.left() {}
+ n
+ }
+
+ pub fn all_right(&mut self) -> usize {
+ let n = self.post.len();
+ while self.right() {}
+ n
+ }
+
+ pub fn get_left(&self) -> Option<u8> {
+ self.pre.last().cloned()
+ }
+
+ pub fn get_right(&self) -> Option<u8> {
+ self.post.last().cloned()
+ }
+
+ pub fn add(&mut self, chr: u8) {
+ self.dirty = true;
+ self.pre.push(chr);
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.pre.is_empty() && self.post.is_empty()
+ }
+
+ pub fn is_dirty(&self) -> bool {
+ self.dirty
+ }
+
+ /// sets content all to the left
+ pub fn set_content(&mut self, buf: Vec<u8>) {
+ self.pre = buf;
+ self.post = Vec::new();
+ }
+
+ pub fn pre(&self) -> &[u8] {
+ &self.pre
+ }
+
+ pub fn into_bytes(&self) -> Vec<u8> {
+ let mut buf = Vec::with_capacity(self.pre.len() + self.post.len());
+ buf.extend_from_slice(&self.pre);
+ for b in self.post.iter().rev() {
+ buf.push(*b);
+ }
+ buf
+ }
+
+ pub fn distance_from_right_end(&self) -> usize {
+ self.post.len()
+ }
+
+ /// 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);
+ self.dirty = false;
+ buf
+ }
+
+ pub fn clear(&mut self) {
+ self.pre.clear();
+ self.post.clear();
+ self.dirty = false;
+ }
+
+ pub fn display_pre(&self) {
+ std::io::stdout().write_all(&self.pre).unwrap();
+ }
+
+ /// TODO: kinda ugly that this is here
+ pub fn display_post(&self, post: &[u8]) {
+ for &x in self.post.iter().rev() {
+ std::io::stdout().write_all(&[x]).unwrap();
+ }
+ std::io::stdout().write_all(post).unwrap();
+ move_cursor(Direction::Left, self.post.len() + post.len());
+ std::io::stdout().flush().unwrap();
+ }
+
+ pub fn left_len(&self) -> usize {
+ self.pre.len()
+ }
+
+ pub fn right_len(&self) -> usize {
+ self.post.len()
+ }
+}