started C implementation, created custom library for handling strings

This commit is contained in:
FantasyPvP
2024-11-02 22:39:16 +00:00
parent 3d3eeb142f
commit 83a71ae0a1
10 changed files with 488 additions and 30 deletions
+7 -1
View File
@@ -1 +1,7 @@
[package] name = "cs_coursework_editor_draft" version = "0.1.0" edition = "2021" [dependencies] ncurses = "6.0.1" i may have made a very scuffed version of vim.
[package]
name = "cs_coursework_editor_draft"
version = "0.1.0"
edition = "2021"
[dependencies]
ncurses = "6.0.1"
+43 -18
View File
@@ -17,6 +17,7 @@ struct EditorData {
}
impl EditorData {
/// called when the user creates a new file or supplies a valid file path that does not exist/* */.
fn new() -> EditorData {
EditorData {
buffer: Vec::new(),
@@ -27,6 +28,7 @@ impl EditorData {
editmode: false,
}
}
/// called when the user opens an existing file from a valid directory.
fn from(s: String) -> EditorData {
EditorData {
buffer: s
@@ -41,22 +43,23 @@ impl EditorData {
}
}
/// moves the cursor (with bounds checks)
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;
let line_width = self.buffer.get(self.screen_line as usize).unwrap_or(&Vec::<char>::new()).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;
self.screen_col = self.buffer.get(self.screen_line as usize).unwrap_or(&Vec::<char>::new()).len() as i32;
}
} else if self.screen_col + dx > self.buffer[self.screen_line as usize].len() as i32 {
} else if self.screen_col + dx > self.buffer.get(self.screen_line as usize).unwrap_or(&Vec::<char>::new()).len() as i32 {
if self.screen_line + 1 <= self.buffer.len() as i32 {
self.screen_col = 0;
self.screen_line += 1;
@@ -67,6 +70,9 @@ impl EditorData {
ncurses::mv(self.screen_line, self.screen_col);
}
/// Delete the character at the cursor.
/// if the cursor is at the end of the line, the next line is appended to the current line and the next line is removed.
/// Otherwise, the character at the cursor is removed and the rest of the line is shifted left.
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();
@@ -76,18 +82,29 @@ impl EditorData {
ncurses::clear();
let s = self.to_string();
ncurses::addstr(&s).unwrap();
ncurses::mv(self.screen_line, self.screen_col);
} else {
self.buffer[self.screen_line as usize].remove(self.screen_col as usize);
ncurses::delch();
}
self.buffer[self.file_line as usize].remove(self.file_col as usize);
ncurses::delch();
}
/// Insert a character at the cursor,
/// then update the cursor position.
fn addchar(&mut self, c: char) {
self.buffer[self.screen_line as usize].insert(self.screen_col as usize, c);
ncurses::insch(keystroke as u32);
if let Some(line) = self.buffer.get_mut(self.screen_line as usize) {
line.insert(self.screen_col as usize, c);
} else {
self.buffer.push(Vec::new());
self.buffer.get_mut(self.screen_line as usize).unwrap().push(c);
}
data.mv_cursor(0, 1);
}
}
impl ToString for EditorData {
/// converts the buffer to a string so that it can be written back to the text file.
fn to_string(&self) -> String {
self.buffer
.iter()
@@ -97,6 +114,18 @@ impl ToString for EditorData {
}
}
/// commands:
///
/// * `open <path/to/file>`: opens the specified file in the editor.
/// * `rm <path/to/file>`: deletes the specified file.
/// * `new <path/to/file>`: creates a new empty file at the specified path.
/// * `mv <path/to/file> <new/path>`: moves the specified file to the new path.
/// * `cp <path/to/file> <new/path>`: copies the specified file to the new path.
/// * `lenc <path/to/file>`: prints the length of the specified file in characters.
/// * `lenl <path/to/file>`: prints the length of the specified file in lines.
/// * `log`: prints a list of all changes made to the file.
///
/// an invalid command will result in the help message being printed.
fn main() {
let args = env::args().collect::<Vec<String>>();
@@ -136,7 +165,6 @@ fn help() {
println!(
"Usage:
cmd open <path/to/file> // opens the specified file
Write
cmd rm <path/to/file> // deletes the specified file
cmd new <path/to/file> // creates a new empty file at the specified path
cmd mv <path/to/file> <new/path> // moves the specified file to the new path
@@ -188,11 +216,11 @@ fn open(filename: &str) -> Result<(), &'static str> {
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::KEY_ENTER => {
}
_ => {
ncurses::insch(keystroke as u32);
data.addchar(char::from_u32(keystroke as u32).unwrap());
data.mv_cursor(0, 1);
}
}
} else {
@@ -202,13 +230,10 @@ fn open(filename: &str) -> Result<(), &'static str> {
}
119 => {
let buff_size = max_y * max_x;
let mut buff = vec![0; buff_size as usize];
let buff = data.to_string();
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;
}
ncurses::endwin();
OpenOptions::new()
@@ -216,7 +241,7 @@ fn open(filename: &str) -> Result<(), &'static str> {
.truncate(true)
.open(filename)
.unwrap()
.write_all(&buff)
.write_all(buff.as_bytes())
.unwrap();
}
113 => {