aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-11-19 03:40:51 -0500
committerJesse Luehrs <doy@tozt.net>2021-11-19 03:42:50 -0500
commit4227bdedde837347ecd83510b976ab13d474b2b9 (patch)
tree366e5246b9b796c28b26187471214ae18d3fb823 /src
parentb45a23b68ea8eb27f2b616f3f1fc32532cdcf03c (diff)
downloadvt100-rust-4227bdedde837347ecd83510b976ab13d474b2b9.tar.gz
vt100-rust-4227bdedde837347ecd83510b976ab13d474b2b9.zip
fix up some more issues with row_formatted
handle cursor positioning and wrapping a bit better
Diffstat (limited to 'src')
-rw-r--r--src/grid.rs24
-rw-r--r--src/row.rs16
-rw-r--r--src/screen.rs28
3 files changed, 54 insertions, 14 deletions
diff --git a/src/grid.rs b/src/grid.rs
index 021a787..f550f9e 100644
--- a/src/grid.rs
+++ b/src/grid.rs
@@ -214,15 +214,19 @@ impl Grid {
self.size.cols,
i,
wrapping,
- prev_pos,
- prev_attrs,
+ Some(prev_pos),
+ Some(prev_attrs),
);
prev_pos = new_pos;
prev_attrs = new_attrs;
wrapping = row.wrapped();
}
- self.write_cursor_position_formatted(contents, Some(prev_pos));
+ self.write_cursor_position_formatted(
+ contents,
+ Some(prev_pos),
+ Some(prev_attrs),
+ );
prev_attrs
}
@@ -254,7 +258,11 @@ impl Grid {
wrapping = row.wrapped();
}
- self.write_cursor_position_formatted(contents, Some(prev_pos));
+ self.write_cursor_position_formatted(
+ contents,
+ Some(prev_pos),
+ Some(prev_attrs),
+ );
prev_attrs
}
@@ -263,6 +271,7 @@ impl Grid {
&self,
contents: &mut Vec<u8>,
prev_pos: Option<Pos>,
+ prev_attrs: Option<crate::attrs::Attrs>,
) {
// writing a character to the last column of a row doesn't wrap the
// cursor immediately - it waits until the next character is actually
@@ -285,7 +294,14 @@ impl Grid {
} else {
crate::term::MoveTo::new(pos).write_buf(contents);
}
+ cell.attrs().write_escape_code_diff(
+ contents,
+ &prev_attrs.unwrap_or_default(),
+ );
contents.extend(cell.contents().as_bytes());
+ if let Some(prev_attrs) = prev_attrs {
+ prev_attrs.write_escape_code_diff(contents, cell.attrs());
+ }
} else {
// if the cell doesn't have contents, we can't have gotten
// here by drawing a character in the last column. this means
diff --git a/src/row.rs b/src/row.rs
index cbd73ae..6f1cc0b 100644
--- a/src/row.rs
+++ b/src/row.rs
@@ -135,12 +135,24 @@ impl Row {
width: u16,
row: u16,
wrapping: bool,
- mut prev_pos: crate::grid::Pos,
- mut prev_attrs: crate::attrs::Attrs,
+ prev_pos: Option<crate::grid::Pos>,
+ prev_attrs: Option<crate::attrs::Attrs>,
) -> (crate::grid::Pos, crate::attrs::Attrs) {
let mut prev_was_wide = false;
let default_cell = crate::cell::Cell::default();
+ let mut prev_pos = if let Some(prev_pos) = prev_pos {
+ prev_pos
+ } else if wrapping {
+ crate::grid::Pos {
+ row: row - 1,
+ col: self.cols(),
+ }
+ } else {
+ crate::grid::Pos { row, col: start }
+ };
+ let mut prev_attrs = prev_attrs.unwrap_or_default();
+
let first_cell = self.get(start).unwrap();
if wrapping && first_cell == &default_cell {
contents.push(b' ');
diff --git a/src/screen.rs b/src/screen.rs
index 56bd963..57d1d1c 100644
--- a/src/screen.rs
+++ b/src/screen.rs
@@ -294,10 +294,12 @@ impl Screen {
width,
i,
wrapping,
- crate::grid::Pos { row: i, col: start },
- crate::attrs::Attrs::default(),
+ None,
+ None,
);
- wrapping = row.wrapped();
+ if start == 0 && width == self.grid.size().cols {
+ wrapping = row.wrapped();
+ }
contents
})
}
@@ -551,10 +553,12 @@ impl Screen {
/// need to restore the terminal state without the terminal contents
/// necessarily being the same.
///
- /// Note that this is more complicated than it sounds, because the cursor
- /// position's state includes more than just the data returned by
- /// `cursor_position`, since moving the cursor to the next row during text
- /// wrapping is delayed until a character is written.
+ /// Note that the bytes returned by this function may alter the active
+ /// drawing attributes, because it may require redrawing existing cells in
+ /// order to position the cursor correctly (for instance, in the case
+ /// where the cursor is past the end of a row). Therefore, you should
+ /// ensure to reset the active drawing attributes if necessary after
+ /// processing this data, for instance by using `attributes_formatted`.
#[must_use]
pub fn cursor_state_formatted(&self) -> Vec<u8> {
let mut contents = vec![];
@@ -564,7 +568,15 @@ impl Screen {
fn write_cursor_state_formatted(&self, contents: &mut Vec<u8>) {
crate::term::HideCursor::new(self.hide_cursor()).write_buf(contents);
- self.grid().write_cursor_position_formatted(contents, None);
+ self.grid()
+ .write_cursor_position_formatted(contents, None, None);
+
+ // we don't just call write_attributes_formatted here, because that
+ // would still be confusing - consider the case where the user sets
+ // their own unrelated drawing attributes (on a different parser
+ // instance) and then calls cursor_state_formatted. just documenting
+ // it and letting the user handle it on their own is more
+ // straightforward.
}
/// Returns the `Cell` object at the given location in the terminal, if it