basic navigation & character insert
This commit is contained in:
commit
cb4a43d00c
5 changed files with 217 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
err
|
58
Cargo.lock
generated
Normal file
58
Cargo.lock
generated
Normal 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
9
Cargo.toml
Normal 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
142
src/editor.rs
Normal 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
6
src/main.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
mod editor;
|
||||
use editor::Editor;
|
||||
|
||||
fn main() {
|
||||
Editor::new().run();
|
||||
}
|
Loading…
Reference in a new issue