diff options
author | Jesse Luehrs <doy@tozt.net> | 2021-11-16 04:07:38 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2021-11-16 04:26:44 -0500 |
commit | 50960d16b66679b81e4f69b451d834695c86b8c6 (patch) | |
tree | fec8f89f8230dee3c78e06a2021f3c1be6359ab9 /src/screen.rs | |
parent | 1e3ebda4e1d6a2cdfb507cc0ed39aaacf3df0314 (diff) | |
download | vt100-rust-50960d16b66679b81e4f69b451d834695c86b8c6.tar.gz vt100-rust-50960d16b66679b81e4f69b451d834695c86b8c6.zip |
expose some extra internal state to help reproduce line wrapping
adds `row_wrapped` and `cursor_state_formatted` to allow you to better
recreate the internal state of the cursor when using `rows_formatted`.
also make `rows_formatted` keep track of the wrapping state itself,
since there are some edge cases that aren't really able to easily be
tracked externally.
Diffstat (limited to 'src/screen.rs')
-rw-r--r-- | src/screen.rs | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/src/screen.rs b/src/screen.rs index 83677ee..c41184c 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -285,6 +285,7 @@ impl Screen { start: u16, width: u16, ) -> impl Iterator<Item = Vec<u8>> + '_ { + let mut wrapping = false; self.grid().visible_rows().enumerate().map(move |(i, row)| { let i = i.try_into().unwrap(); let mut contents = vec![]; @@ -293,10 +294,11 @@ impl Screen { start, width, i, - false, + wrapping, crate::grid::Pos { row: i, col: start }, crate::attrs::Attrs::default(), ); + wrapping = row.wrapped(); contents }) } @@ -532,6 +534,40 @@ impl Screen { ); } + /// Returns the current cursor position of the terminal. + /// + /// The return value will be (row, col). + #[must_use] + pub fn cursor_position(&self) -> (u16, u16) { + let pos = self.grid().pos(); + (pos.row, pos.col) + } + + /// Returns terminal escape sequences sufficient to set the current + /// cursor state of the terminal. + /// + /// This is not typically necessary, since `contents_formatted` will leave + /// the cursor in the correct state, but this can be useful in the case of + /// drawing additional things on top of a terminal output, since you will + /// 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. + #[must_use] + pub fn cursor_state_formatted(&self) -> Vec<u8> { + let mut contents = vec![]; + self.write_cursor_state_formatted(&mut contents); + contents + } + + 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); + } + /// Returns the `Cell` object at the given location in the terminal, if it /// exists. #[must_use] @@ -539,13 +575,12 @@ impl Screen { self.grid().visible_cell(crate::grid::Pos { row, col }) } - /// Returns the current cursor position of the terminal. - /// - /// The return value will be (row, col). + /// Returns whether the text in row `row` should wrap to the next line. #[must_use] - pub fn cursor_position(&self) -> (u16, u16) { - let pos = self.grid().pos(); - (pos.row, pos.col) + pub fn row_wrapped(&self, row: u16) -> bool { + self.grid() + .visible_row(crate::grid::Pos { row, col: 0 }) + .map_or(false, crate::row::Row::wrapped) } /// Returns the terminal's window title. |