From 3d3eeb142f709ef2c0f1472400e661fa01c4867d Mon Sep 17 00:00:00 2001 From: FantasyPvP <80643031+FantasyPvP@users.noreply.github.com> Date: Sat, 2 Nov 2024 15:20:24 +0000 Subject: [PATCH] added a buffer to make moving around the file smoother --- prototype/src/main.rs | 189 ++++++++++++++++++++++++++++++------------ 1 file changed, 135 insertions(+), 54 deletions(-) diff --git a/prototype/src/main.rs b/prototype/src/main.rs index 986a372..1d1de9b 100644 --- a/prototype/src/main.rs +++ b/prototype/src/main.rs @@ -1,25 +1,100 @@ extern crate ncurses; -use std::{env, fs::{self, File, OpenOptions}, io::Write}; +use std::{ + borrow::BorrowMut, + env, + fs::{self, OpenOptions}, + io::Write, +}; struct EditorData { + buffer: Vec>, // outer vec is the line, inner is col; file_line: i32, file_col: i32, - buff_line: i32, - buff_col: i32, + screen_line: i32, + screen_col: i32, editmode: bool, } impl EditorData { fn new() -> EditorData { EditorData { + buffer: Vec::new(), file_line: 0, file_col: 0, - buff_line: 0, - buff_col: 0, + screen_line: 0, + screen_col: 0, editmode: false, } } + fn from(s: String) -> EditorData { + EditorData { + buffer: s + .lines() + .map(|l| l.chars().collect()) + .collect::>>(), + file_line: 0, + file_col: 0, + screen_line: 0, + screen_col: 0, + editmode: false, + } + } + + fn mv_cursor(&mut self, dy: i32, dx: i32) { + if dy != 0 + && self.screen_line + dy >= 0 + && self.screen_line + dy <= self.buffer.len() as i32 + { + self.screen_line += dy; + let line_width = self.buffer[self.screen_line as usize].len() as i32; + if self.screen_col > line_width { + self.screen_col = line_width; + } + } else if self.screen_col + dx < 0 { + if self.screen_line - 1 >= 0 { + self.screen_line -= 1; + self.screen_col = self.buffer[self.screen_line as usize].len() as i32; + } + } else if self.screen_col + dx > self.buffer[self.screen_line as usize].len() as i32 { + if self.screen_line + 1 <= self.buffer.len() as i32 { + self.screen_col = 0; + self.screen_line += 1; + } + } else if dx != 0 { + self.screen_col += dx; + } + ncurses::mv(self.screen_line, self.screen_col); + } + + fn delchar(&mut self) { + if self.screen_col == self.buffer[self.screen_line as usize].len() as i32 { + let oldline = self.buffer[1 + self.screen_line as usize].clone(); + self.buffer[self.screen_line as usize].extend(&oldline); + self.buffer.remove(1 + self.screen_line as usize); + + ncurses::clear(); + let s = self.to_string(); + ncurses::addstr(&s).unwrap(); + } + + self.buffer[self.file_line as usize].remove(self.file_col as usize); + ncurses::delch(); + } + + fn addchar(&mut self, c: char) { + self.buffer[self.screen_line as usize].insert(self.screen_col as usize, c); + } +} + +impl ToString for EditorData { + fn to_string(&self) -> String { + self.buffer + .iter() + .map(|line| line.iter().collect::()) + .collect::>() + .join("\n") + } } fn main() { @@ -32,36 +107,53 @@ fn main() { // "new" => new(&args[2]), // "mv" => mv(&args[2], &args[3]), // "cp" => cp(&args[2], &args[3]), - // "len" => len(&args[2]), + "lenc" => { + if let Ok(string) = fs::read_to_string(&args[2]) { + println!("{}", string.len()); + } + } + "lenl" => { + if let Ok(string) = fs::read_to_string(&args[2]) { + println!( + "{}", + string + .chars() + .filter(|x| *x == '\n') + .collect::() + .len() + ); + } + } // "log" => log(), _ => help(), } } else { help(); } - } fn help() { - println!("Usage: + println!( + "Usage: cmd open // opens the specified file +Write cmd rm // deletes the specified file cmd new // creates a new empty file at the specified path cmd mv // moves the specified file to the new path cmd cp // copies the specified file to the new path - cmd len // returns the length of the specified file + cmd lenc // returns the length of the specified file in chars + cmd lenl // returns the length of the specified file in lines cmd log // prints a list of all changes made to the file - ") + " + ) } fn open(filename: &str) -> Result<(), &'static str> { - let filestr = match fs::read_to_string(filename) { - Ok(s) => s, - Err(_) => return Err("file not found"), + let mut data = match fs::read_to_string(filename) { + Ok(s) => EditorData::from(s), + Err(_) => EditorData::new(), }; - let mut data = EditorData::new(); - ncurses::initscr(); ncurses::raw(); ncurses::noecho(); @@ -70,14 +162,14 @@ fn open(filename: &str) -> Result<(), &'static str> { let mut max_x = 0; ncurses::getmaxyx(ncurses::stdscr(), &mut max_y, &mut max_x); - if let Err(_) = ncurses::addstr(&filestr) { + let s = data.to_string(); + if let Err(_) = ncurses::addstr(&s) { ncurses::endwin(); return Err("error writing file to buffer"); }; ncurses::mv(0, 0); - loop { ncurses::refresh(); let keystroke = ncurses::getch(); @@ -85,28 +177,37 @@ fn open(filename: &str) -> Result<(), &'static str> { if data.editmode { match keystroke { 27 => data.editmode = false, - ncurses::KEY_BACKSPACE => { - mv_cursor(&mut data, 0, -1); - ncurses::delch(); - }, - ncurses::KEY_DC => { ncurses::delch(); }, - ncurses::KEY_LEFT => mv_cursor(&mut data, 0, -1), - ncurses::KEY_RIGHT => mv_cursor(&mut data, 0, 1), - ncurses::KEY_UP => mv_cursor(&mut data, -1, 0), - ncurses::KEY_DOWN => mv_cursor(&mut data, 1, 0), - _ => { ncurses::insch(keystroke as u32); mv_cursor(&mut data, 0, 1); }, + ncurses::KEY_BACKSPACE => { + data.mv_cursor(0, -1); + data.delchar(); + } + ncurses::KEY_DC => { + data.delchar(); + } + ncurses::KEY_LEFT => data.mv_cursor(0, -1), + ncurses::KEY_RIGHT => data.mv_cursor(0, 1), + ncurses::KEY_UP => data.mv_cursor(-1, 0), + ncurses::KEY_DOWN => data.mv_cursor(1, 0), + _ => { + ncurses::insch(keystroke as u32); + + data.addchar(char::from_u32(keystroke as u32).unwrap()); + data.mv_cursor(0, 1); + } } } else { match keystroke { - 105 => { - data.editmode = true; - }, + 105 => { + data.editmode = true; + } 119 => { let buff_size = max_y * max_x; let mut buff = vec![0; buff_size as usize]; for i in 0..buff_size { - buff[i as usize] = (ncurses::mvwinch(ncurses::stdscr(), i / max_x, i % max_x) & ncurses::A_CHARTEXT) as u8; + buff[i as usize] = + (ncurses::mvwinch(ncurses::stdscr(), i / max_x, i % max_x) + & ncurses::A_CHARTEXT) as u8; } ncurses::endwin(); @@ -121,29 +222,9 @@ fn open(filename: &str) -> Result<(), &'static str> { 113 => { ncurses::endwin(); return Ok(()); - }, - _ => {}, + } + _ => {} } } } -} - -fn mv_cursor(pos: &mut EditorData, dy: i32, dx: i32) { - if pos.file_col + dx >= 0 { - pos.file_col += dx; - } - - if pos.buff_col + dx >= 0 { - pos.buff_col += dx; - } - - if pos.file_line + dy >= 0 { - pos.file_line += dy; - } - - if pos.buff_line + dy >= 0 { - pos.buff_line += dy; - } - - ncurses::mv(pos.buff_line, pos.buff_col); -} \ No newline at end of file +}