written initial prototype in rust
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
*/target
|
||||||
|
*.out
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#include <ncurses.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int file_line;
|
||||||
|
int file_col;
|
||||||
|
int buff_line;
|
||||||
|
int buff_col;
|
||||||
|
int editmode;
|
||||||
|
} EditorData;
|
||||||
|
|
||||||
|
void help() {
|
||||||
|
printf("Usage:\n");
|
||||||
|
printf(" cmd open <path/to/file> // opens the specified file\n");
|
||||||
|
printf(" cmd rm <path/to/file> // deletes the specified file\n");
|
||||||
|
printf(" cmd new <path/to/file> // creates a new empty file at the specified path\n");
|
||||||
|
printf(" cmd mv <path/to/file> <new/path> // moves the specified file to the new path\n");
|
||||||
|
printf(" cmd cp <path/to/file> <new/path> // copies the specified file to the new path\n");
|
||||||
|
printf(" cmd len <path/to/file> // returns the length of the specified file\n");
|
||||||
|
printf(" cmd log // prints a list of all changes made to the file\n");
|
||||||
|
}
|
||||||
Generated
+48
@@ -0,0 +1,48 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.1.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"
|
||||||
|
dependencies = [
|
||||||
|
"shlex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cs_coursework_editor_draft"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"ncurses",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.161"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ncurses"
|
||||||
|
version = "6.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fbd71afa95710e841d173521e8483e764004eb332bdf47bd01d00f568688027f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "cs_coursework_editor_draft"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ncurses = "6.0.1"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[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.
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
extern crate ncurses;
|
||||||
|
|
||||||
|
use std::{env, fs::{self, File, OpenOptions}, io::Write};
|
||||||
|
|
||||||
|
struct EditorData {
|
||||||
|
file_line: i32,
|
||||||
|
file_col: i32,
|
||||||
|
buff_line: i32,
|
||||||
|
buff_col: i32,
|
||||||
|
editmode: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EditorData {
|
||||||
|
fn new() -> EditorData {
|
||||||
|
EditorData {
|
||||||
|
file_line: 0,
|
||||||
|
file_col: 0,
|
||||||
|
buff_line: 0,
|
||||||
|
buff_col: 0,
|
||||||
|
editmode: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args = env::args().collect::<Vec<String>>();
|
||||||
|
|
||||||
|
if let Some(a) = env::args().nth(1) {
|
||||||
|
match a.as_str() {
|
||||||
|
"open" => open(&args[2]).unwrap(),
|
||||||
|
// "rm" => rm(&args[2]),
|
||||||
|
// "new" => new(&args[2]),
|
||||||
|
// "mv" => mv(&args[2], &args[3]),
|
||||||
|
// "cp" => cp(&args[2], &args[3]),
|
||||||
|
// "len" => len(&args[2]),
|
||||||
|
// "log" => log(),
|
||||||
|
_ => help(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
help();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn help() {
|
||||||
|
println!("Usage:
|
||||||
|
cmd open <path/to/file> // opens the specified file
|
||||||
|
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
|
||||||
|
cmd cp <path/to/file> <new/path> // copies the specified file to the new path
|
||||||
|
cmd len <path/to/file> // returns the length of the specified file
|
||||||
|
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 = EditorData::new();
|
||||||
|
|
||||||
|
ncurses::initscr();
|
||||||
|
ncurses::raw();
|
||||||
|
ncurses::noecho();
|
||||||
|
ncurses::keypad(ncurses::stdscr(), true);
|
||||||
|
let mut max_y = 0;
|
||||||
|
let mut max_x = 0;
|
||||||
|
ncurses::getmaxyx(ncurses::stdscr(), &mut max_y, &mut max_x);
|
||||||
|
|
||||||
|
if let Err(_) = ncurses::addstr(&filestr) {
|
||||||
|
ncurses::endwin();
|
||||||
|
return Err("error writing file to buffer");
|
||||||
|
};
|
||||||
|
|
||||||
|
ncurses::mv(0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
loop {
|
||||||
|
ncurses::refresh();
|
||||||
|
let keystroke = ncurses::getch();
|
||||||
|
|
||||||
|
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); },
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match keystroke {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
ncurses::endwin();
|
||||||
|
|
||||||
|
OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(filename)
|
||||||
|
.unwrap()
|
||||||
|
.write_all(&buff)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user