basic navigation & character insert

This commit is contained in:
Crispy 2023-02-26 00:29:29 +01:00
commit cb4a43d00c
5 changed files with 217 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/target
err

58
Cargo.lock generated Normal file
View file

@ -0,0 +1,58 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "lili"
version = "0.1.0"
dependencies = [
"termion",
]
[[package]]
name = "numtoa"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_termios"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f"
dependencies = [
"redox_syscall",
]
[[package]]
name = "termion"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "659c1f379f3408c7e5e84c7d0da6d93404e3800b6b9d063ba24436419302ec90"
dependencies = [
"libc",
"numtoa",
"redox_syscall",
"redox_termios",
]

9
Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[package]
name = "lili"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
termion = "2.0.1"

142
src/editor.rs Normal file
View file

@ -0,0 +1,142 @@
use std::{
io::{stdin, stdout, Write},
ops::Range,
};
use termion::{
clear, cursor,
event::{Event, Key},
input::TermRead,
raw::IntoRawMode,
};
pub struct Editor {
text: String,
lines: Vec<Line>,
cursor: Cursor,
quit: bool,
}
struct Cursor {
line: usize,
column: usize,
}
// #[derive(Clone, Copy)]
type Line = Range<usize>;
impl Editor {
pub fn new() -> Self {
Editor {
// text: String::new(),
text: include_str!("editor.rs").into(),
lines: Vec::new(),
cursor: Cursor { line: 0, column: 0 },
quit: false,
}
}
pub fn run(mut self) {
println!("{}", clear::All);
stdout().flush().unwrap();
let _t = stdout().into_raw_mode().unwrap();
while !self.quit {
self.find_lines();
self.draw();
self.input();
}
println!("{}", clear::All);
stdout().flush().unwrap();
// self.term.suspend_raw_mode().unwrap();
}
fn input(&mut self) {
for event in stdin().events().take(1).flatten() {
// dbg!(&event);
if let Event::Key(key) = event {
match key {
Key::Esc => self.quit = true,
Key::Char(char) => self.insert_char(char),
Key::Left => self.move_left(),
Key::Right => self.move_right(),
Key::Up => self.move_up(),
Key::Down => self.move_down(),
_ => (),
}
}
}
}
fn move_left(&mut self) {
if self.cursor.column > 0 {
self.cursor.column -= 1;
} else if self.cursor.line > 0 {
self.cursor.line -= 1;
self.cursor.column = self.current_line().len();
}
}
fn move_right(&mut self) {
if self.cursor.column < self.current_line().len() {
self.cursor.column += 1;
} else if self.cursor.line < self.lines.len() {
self.cursor.line += 1;
self.cursor.column = 0;
}
}
fn move_up(&mut self) {
if self.cursor.line > 0 {
self.cursor.line -= 1;
self.cursor.column = self.cursor.column.min(self.current_line().len());
}
}
fn move_down(&mut self) {
if self.cursor.line < self.lines.len() {
self.cursor.line += 1;
self.cursor.column = self.cursor.column.min(self.current_line().len());
}
}
fn current_line(&self) -> &Line {
self.lines.get(self.cursor.line).unwrap_or(&(0..0))
}
fn find_lines(&mut self) {
self.lines.clear();
let mut this_line = 0..0;
for (index, char) in self.text.chars().enumerate() {
if char == '\n' {
this_line.end = index;
self.lines.push(this_line.clone());
this_line.start = index + 1;
}
}
}
fn draw(&self) {
print!("{}", clear::All);
for (row, line) in self.lines.iter().enumerate() {
let text = &self.text[line.clone()];
print!(
"{}{}",
cursor::Goto(1, row as u16 + 1),
text.replace('\t', " ")
);
}
print!(
"{}",
cursor::Goto(self.cursor.column as u16 + 1, self.cursor.line as u16 + 1)
);
stdout().flush().unwrap();
}
fn insert_char(&mut self, ch: char) {
let index = self.current_line().start + self.cursor.column;
self.text.insert(index, ch);
self.move_right();
self.find_lines();
}
}

6
src/main.rs Normal file
View file

@ -0,0 +1,6 @@
mod editor;
use editor::Editor;
fn main() {
Editor::new().run();
}