aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2023-12-29 15:31:07 -0800
committerRose Hogenson <rosehogenson@posteo.net>2023-12-29 15:31:07 -0800
commit52591143ae4211555c955a7f9304684f75a59660 (patch)
tree115075713e931d2243d3a4201dea319184cf2702 /src/main.rs
parentf898a97005844d5c451842eca63871ba382f5d96 (diff)
downloadeditor-52591143ae4211555c955a7f9304684f75a59660.tar.zst
Keep track of cursor position.
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs75
1 files changed, 65 insertions, 10 deletions
diff --git a/src/main.rs b/src/main.rs
index 592f89c..de25e9c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,10 +3,15 @@ mod term;
use rope::Rope;
use std::ffi::{OsStr, OsString};
-use std::io::Write;
+use std::io::{Stdout, Write};
use std::path::Path;
use term::Key;
+fn move_cursor(stdout: &mut Stdout, row: usize, col: usize) {
+ let _ = write!(stdout, "\x1b[{};{}H", row + 1, col + 1);
+ let _ = stdout.flush();
+}
+
fn edit(file: &OsStr) -> Result<(), String> {
let _raw_handle = match term::raw() {
Some(h) => h,
@@ -28,14 +33,25 @@ fn edit(file: &OsStr) -> Result<(), String> {
}
};
let mut stdout = std::io::stdout();
+ let _ = stdout.write(b"\x1b[J");
for i in 0..usize::from(size.ws_row) {
if i > 0 {
let _ = stdout.write(b"\r\n");
}
- let _ = r.print_line(&mut stdout, i);
+ let line = match r.line(i) {
+ Some(line) => line,
+ None => {
+ break;
+ }
+ };
+ let _ = line.print(&mut stdout);
}
+ let _ = stdout.write(b"\x1b[H");
let _ = stdout.flush();
+ let mut cursor_row = 0;
+ let mut cursor_col = 0;
+
let mut stdin = std::io::stdin();
loop {
let c = match term::read_key(&mut stdin) {
@@ -49,20 +65,59 @@ fn edit(file: &OsStr) -> Result<(), String> {
break;
}
Key::Up => {
- let _ = stdout.write(b"\x1b[A");
- let _ = stdout.flush();
+ if cursor_row == 0 {
+ continue;
+ }
+ cursor_row -= 1;
+
+ let len = r
+ .line(cursor_row)
+ .expect("cursor_row should always be valid")
+ .len();
+ if cursor_col > len {
+ move_cursor(&mut stdout, cursor_row, len);
+ } else {
+ move_cursor(&mut stdout, cursor_row, cursor_col);
+ }
}
Key::Down => {
- let _ = stdout.write(b"\x1b[B");
- let _ = stdout.flush();
+ if cursor_row == usize::from(size.ws_row - 1) || cursor_row == r.lines() {
+ continue;
+ }
+ cursor_row += 1;
+
+ let len = r
+ .line(cursor_row)
+ .expect("cursor_row should always be valid")
+ .len();
+ if cursor_col > len {
+ move_cursor(&mut stdout, cursor_row, len);
+ } else {
+ move_cursor(&mut stdout, cursor_row, cursor_col);
+ }
}
Key::Left => {
- let _ = stdout.write(b"\x1b[D");
- let _ = stdout.flush();
+ let len = r
+ .line(cursor_row)
+ .expect("cursor_row should always be valid")
+ .len();
+ cursor_col = std::cmp::min(cursor_col, len);
+ if cursor_col == 0 {
+ continue;
+ }
+ cursor_col -= 1;
+ move_cursor(&mut stdout, cursor_row, cursor_col);
}
Key::Right => {
- let _ = stdout.write(b"\x1b[C");
- let _ = stdout.flush();
+ let len = r
+ .line(cursor_row)
+ .expect("cursor_row should always be valid")
+ .len();
+ if cursor_col == usize::from(size.ws_col - 1) || cursor_col >= len {
+ continue;
+ }
+ cursor_col += 1;
+ move_cursor(&mut stdout, cursor_row, cursor_col);
}
Key::Char(c) => {
print!("{} ", c);