diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2023-12-29 15:31:07 -0800 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2023-12-29 15:31:07 -0800 |
| commit | 52591143ae4211555c955a7f9304684f75a59660 (patch) | |
| tree | 115075713e931d2243d3a4201dea319184cf2702 /src/main.rs | |
| parent | f898a97005844d5c451842eca63871ba382f5d96 (diff) | |
| download | editor-52591143ae4211555c955a7f9304684f75a59660.tar.zst | |
Keep track of cursor position.
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 75 |
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); |
