mirror of
https://github.com/wez/wezterm.git
synced 2024-11-24 07:46:59 +03:00
Add StableRowIndex concept
This will make it easier to manage both the viewport and the selection in the gui layer. refs: https://github.com/wez/wezterm/issues/106
This commit is contained in:
parent
a0ad0d0c34
commit
1b3ced2ab3
@ -53,6 +53,20 @@ pub type VisibleRowIndex = i64;
|
||||
/// to want to scroll back or select more than ~2billion lines of scrollback.
|
||||
pub type ScrollbackOrVisibleRowIndex = i32;
|
||||
|
||||
/// Allows referencing a logical line in the scrollback, allowing for scrolling.
|
||||
/// The StableRowIndex counts from the top of the scrollback, growing larger
|
||||
/// as you move down through the display rows.
|
||||
/// Initially the very first line as StableRowIndex==0. If the scrollback
|
||||
/// is filled and lines are purged (say we need to purge 5 lines), then whichever
|
||||
/// line is first in the scrollback (PhysRowIndex==0) will now have StableRowIndex==5
|
||||
/// which is the same value that that logical line had prior to data being purged
|
||||
/// out of the scrollback.
|
||||
///
|
||||
/// As per ScrollbackOrVisibleRowIndex above, a StableRowIndex can never
|
||||
/// legally be a negative number. We're just using a differently sized type
|
||||
/// to have the compiler assist us in detecting improper usage.
|
||||
pub type StableRowIndex = isize;
|
||||
|
||||
/// Returns true if r1 intersects r2
|
||||
pub fn intersects_range<T: Ord + Copy>(r1: Range<T>, r2: Range<T>) -> bool {
|
||||
use std::cmp::{max, min};
|
||||
|
@ -19,6 +19,11 @@ pub struct Screen {
|
||||
/// would otherwise have exceeded the line capacity
|
||||
pub lines: VecDeque<Line>,
|
||||
|
||||
/// Whenever we scroll a line off the top of the scrollback, we
|
||||
/// increment this. We use this offset to translate between
|
||||
/// PhysRowIndex and StableRowIndex.
|
||||
stable_row_index_offset: usize,
|
||||
|
||||
/// config so we can access Maximum number of lines of scrollback
|
||||
config: Arc<dyn TerminalConfiguration>,
|
||||
allow_scrollback: bool,
|
||||
@ -62,6 +67,7 @@ impl Screen {
|
||||
allow_scrollback,
|
||||
physical_rows,
|
||||
physical_cols,
|
||||
stable_row_index_offset: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,6 +203,27 @@ impl Screen {
|
||||
self.phys_row(range.start)..self.phys_row(range.end)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn phys_to_stable_row_index(&self, phys: PhysRowIndex) -> StableRowIndex {
|
||||
(phys + self.stable_row_index_offset) as StableRowIndex
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn stable_row_to_phys(&self, stable: StableRowIndex) -> Option<PhysRowIndex> {
|
||||
let idx = stable - self.stable_row_index_offset as isize;
|
||||
if idx < 0 || idx >= self.lines.len() as isize {
|
||||
// Index is no longer valid
|
||||
None
|
||||
} else {
|
||||
Some(idx as PhysRowIndex)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn visible_row_to_stable_row(&self, vis: VisibleRowIndex) -> StableRowIndex {
|
||||
self.phys_to_stable_row_index(self.phys_row(vis))
|
||||
}
|
||||
|
||||
/// ---------
|
||||
/// |
|
||||
/// |--- top
|
||||
@ -268,6 +295,10 @@ impl Screen {
|
||||
self.lines.remove(remove_idx);
|
||||
}
|
||||
|
||||
if remove_idx == 0 {
|
||||
self.stable_row_index_offset += lines_removed;
|
||||
}
|
||||
|
||||
if scroll_region.end as usize == self.physical_rows {
|
||||
// It's cheaper to push() than it is insert() at the end
|
||||
for _ in 0..to_add {
|
||||
|
@ -529,20 +529,35 @@ fn test_scrollup() {
|
||||
let mut term = TestTerm::new(2, 1, 4);
|
||||
term.print("1\n");
|
||||
assert_all_contents(&term, &["1", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 0);
|
||||
|
||||
term.print("2\n");
|
||||
assert_all_contents(&term, &["1", "2", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 1);
|
||||
|
||||
term.print("3\n");
|
||||
assert_all_contents(&term, &["1", "2", "3", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 2);
|
||||
|
||||
term.print("4\n");
|
||||
assert_all_contents(&term, &["1", "2", "3", "4", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 3);
|
||||
|
||||
term.print("5\n");
|
||||
assert_all_contents(&term, &["1", "2", "3", "4", "5", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 4);
|
||||
|
||||
term.print("6\n");
|
||||
assert_all_contents(&term, &["2", "3", "4", "5", "6", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 5);
|
||||
|
||||
term.print("7\n");
|
||||
assert_all_contents(&term, &["3", "4", "5", "6", "7", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 6);
|
||||
|
||||
term.print("8\n");
|
||||
assert_all_contents(&term, &["4", "5", "6", "7", "8", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
Reference in New Issue
Block a user