aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2024-01-06 12:11:43 -0800
committerRose Hogenson <rosehogenson@posteo.net>2024-01-06 12:11:43 -0800
commitbefdde33f29ab435b328c3bc501562e2e9386a8e (patch)
treef3e038d65d095d37350ca877c21292e5388cb8c5 /src
parent73c2fbc538a34f89391ac5174357aac9af253672 (diff)
downloadeditor-befdde33f29ab435b328c3bc501562e2e9386a8e.tar.zst
Truncate long lines.
Diffstat (limited to 'src')
-rw-r--r--src/main.rs63
-rw-r--r--src/rope.rs17
2 files changed, 58 insertions, 22 deletions
diff --git a/src/main.rs b/src/main.rs
index 7f2beaa..c9e8928 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -46,19 +46,51 @@ impl State {
return Ok(pos);
}
+ fn repaint_full(&mut self) -> Result<(), Box<dyn Error>> {
+ let size = term::size()?;
+
+ write!(stdout(), "\x1b[H\x1b[J")?;
+ for i in 0..usize::from(size.ws_row) {
+ if i > 0 {
+ write!(stdout(), "\r\n")?;
+ }
+ if i > self.buf.lines() {
+ break;
+ }
+ let line = self.buf.line(i);
+ let max_len = line.char(usize::from(size.ws_col-1));
+ line.slice(0, max_len).print(&mut stdout())?;
+ if max_len < line.len() {
+ write!(stdout(), "\x1b[30m\x1b[47m>\x1b[m")?;
+ }
+ }
+ return Ok(());
+ }
+
fn repaint_line_full(&mut self) -> Result<(), Box<dyn Error>> {
- write!(stdout(), "\x1b[{}H", self.cursor_row+1)?;
- let line = self.buf.line(self.cursor_row);
+ let term_size = term::size()?;
+
+ write!(stdout(), "\x1b[{}H\x1b[K", self.cursor_row+1)?;
+ let mut line = self.buf.line(self.cursor_row);
+ let max_len = line.char(usize::from(term_size.ws_col-1));
+ let mut truncated = false;
+ if max_len < line.len() {
+ line = line.slice(0, max_len);
+ truncated = true;
+ }
line.print(&mut stdout())?;
let (_, col) = self.cursor_pos()?;
self.line_cols = col;
if self.cursor_col >= self.line_cols {
self.line_offset = line.len();
+ if truncated {
+ write!(stdout(), "\x1b[30m\x1b[47m>\x1b[m\x1b[{}G", self.cursor_col+1)?;
+ }
return Ok(());
}
- let mut lo = line.ceil_char_boundary(self.cursor_col);
+ let mut lo = line.char(self.cursor_col);
let mut hi = line.len();
// Binary search :D
while hi > lo {
@@ -73,8 +105,11 @@ impl State {
}
}
self.line_offset = line.floor_char_boundary(lo-1);
- write!(stdout(), "\x1b[G\x1b[K")?;
+ write!(stdout(), "\x1b[G")?;
line.print(&mut stdout())?;
+ if truncated {
+ write!(stdout(), "\x1b[30m\x1b[47m>\x1b[m")?;
+ }
write!(stdout(), "\x1b[{}G", self.cursor_col+1)?;
return Ok(());
}
@@ -92,22 +127,7 @@ fn edit(file: &OsStr) -> Result<(), Box<dyn Error>> {
line_offset: 0,
line_cols: 0,
};
- let _ = write!(stdout(), "\x1b[J");
- for i in 0..usize::from(size.ws_row) {
- if i > 0 {
- let _ = write!(stdout(), "\r\n");
- }
- if i > state.buf.lines() {
- break;
- }
- let line = state.buf.line(i);
- // TODO: handle line-wrapping.
- let _ = line.print(&mut stdout());
- if i == 0 {
- let (_, col) = state.cursor_pos()?;
- state.line_cols = col;
- }
- }
+ let _ = state.repaint_full();
let _ = write!(stdout(), "\x1b[H");
let _ = stdout().flush();
@@ -144,8 +164,7 @@ fn edit(file: &OsStr) -> Result<(), Box<dyn Error>> {
state.cursor_row -= 1;
let _ = state.repaint_line_full();
state.cursor_col = state.line_cols;
- state.line_offset = state.buf.line(state.cursor_row).len();
- let _ = write!(stdout(), "\x1b[{}G", state.cursor_col+1);
+ let _ = state.repaint_line_full();
} else {
state.cursor_col -= 1;
let _ = state.repaint_line_full();
diff --git a/src/rope.rs b/src/rope.rs
index c5e9aa1..5f4fca8 100644
--- a/src/rope.rs
+++ b/src/rope.rs
@@ -278,4 +278,21 @@ impl Rope {
}
return self.len();
}
+
+ pub fn char(&self, index: usize) -> usize {
+ if index == 0 {
+ return 0;
+ }
+ let mut count = 1;
+ for i in 1..self.len() {
+ if !self.is_char_boundary(i) {
+ continue;
+ }
+ if count == index {
+ return i;
+ }
+ count += 1;
+ }
+ return self.len();
+ }
}