mirror of
https://github.com/wez/wezterm.git
synced 2024-12-24 05:42:03 +03:00
fix an issue with the selection when in scrollback
This commit is contained in:
parent
dd238d5b50
commit
25e2dc2a96
@ -90,7 +90,7 @@ pub struct TerminalState {
|
||||
/// purely for display purposes.
|
||||
/// The offset is measured from the top of the physical viewable
|
||||
/// screen with larger numbers going backwards.
|
||||
viewport_offset: VisibleRowIndex,
|
||||
pub(crate) viewport_offset: VisibleRowIndex,
|
||||
|
||||
/// Remembers the starting coordinate of the selection prior to
|
||||
/// dragging.
|
||||
@ -281,13 +281,15 @@ impl TerminalState {
|
||||
self.selection_range = None;
|
||||
self.selection_start = Some(SelectionCoordinate {
|
||||
x: event.x,
|
||||
y: event.y as ScrollbackOrVisibleRowIndex,
|
||||
y: event.y as ScrollbackOrVisibleRowIndex -
|
||||
self.viewport_offset as ScrollbackOrVisibleRowIndex,
|
||||
});
|
||||
host.set_clipboard(None)?;
|
||||
}
|
||||
// Double click to select a word on the current line
|
||||
Some(&LastMouseClick { streak: 2, .. }) => {
|
||||
let y = event.y as ScrollbackOrVisibleRowIndex;
|
||||
let y = event.y as ScrollbackOrVisibleRowIndex -
|
||||
self.viewport_offset as ScrollbackOrVisibleRowIndex;
|
||||
let idx = self.screen().scrollback_or_visible_row(y);
|
||||
let line = self.screen().lines[idx].as_str();
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
@ -324,18 +326,14 @@ impl TerminalState {
|
||||
}
|
||||
// triple click to select the current line
|
||||
Some(&LastMouseClick { streak: 3, .. }) => {
|
||||
self.selection_start = Some(SelectionCoordinate {
|
||||
x: event.x,
|
||||
y: event.y as ScrollbackOrVisibleRowIndex,
|
||||
});
|
||||
let y = event.y as ScrollbackOrVisibleRowIndex -
|
||||
self.viewport_offset as ScrollbackOrVisibleRowIndex;
|
||||
self.selection_start = Some(SelectionCoordinate { x: event.x, y });
|
||||
self.selection_range = Some(SelectionRange {
|
||||
start: SelectionCoordinate {
|
||||
x: 0,
|
||||
y: event.y as ScrollbackOrVisibleRowIndex,
|
||||
},
|
||||
start: SelectionCoordinate { x: 0, y },
|
||||
end: SelectionCoordinate {
|
||||
x: usize::max_value(),
|
||||
y: event.y as ScrollbackOrVisibleRowIndex,
|
||||
y,
|
||||
},
|
||||
});
|
||||
self.dirty_selection_lines();
|
||||
@ -395,7 +393,8 @@ impl TerminalState {
|
||||
self.dirty_selection_lines();
|
||||
let end = SelectionCoordinate {
|
||||
x: event.x,
|
||||
y: event.y as ScrollbackOrVisibleRowIndex,
|
||||
y: event.y as ScrollbackOrVisibleRowIndex -
|
||||
self.viewport_offset as ScrollbackOrVisibleRowIndex,
|
||||
};
|
||||
let sel = match self.selection_range.take() {
|
||||
None => {
|
||||
|
@ -204,6 +204,34 @@ impl TestTerm {
|
||||
reason
|
||||
);
|
||||
}
|
||||
|
||||
fn viewport_lines(&self) -> Vec<Line> {
|
||||
let screen = self.screen();
|
||||
let line_count = screen.lines.len();
|
||||
let viewport = self.viewport_offset;
|
||||
let phs_rows = screen.physical_rows;
|
||||
screen
|
||||
.all_lines()
|
||||
.iter()
|
||||
.skip((line_count as i64 - phs_rows as i64 - viewport) as usize)
|
||||
.take(phs_rows)
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
fn print_viewport_lines(&self) {
|
||||
println!("viewport contents are:");
|
||||
for line in self.viewport_lines() {
|
||||
println!("[{}]", line.as_str());
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_viewport_contents(&self, expect_lines: &[&str]) {
|
||||
self.print_viewport_lines();
|
||||
|
||||
let expect: Vec<Line> = expect_lines.iter().map(|s| (*s).into()).collect();
|
||||
|
||||
assert_lines_equal(&self.viewport_lines(), &expect, Compare::TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for TestTerm {
|
||||
|
@ -62,3 +62,27 @@ fn triple_click_selection() {
|
||||
|
||||
assert_eq!(term.get_clipboard().unwrap(), "hello worl");
|
||||
}
|
||||
|
||||
/// Make sure that we adjust for the viewport offset when scrolling
|
||||
#[test]
|
||||
fn selection_in_scrollback() {
|
||||
let mut term = TestTerm::new(2, 1, 4);
|
||||
term.print("1234");
|
||||
assert_all_contents(&term, &["1", "2", "3", "4"]);
|
||||
|
||||
// Scroll back one line
|
||||
term.scroll_viewport(-1);
|
||||
term.assert_viewport_contents(&["2", "3"]);
|
||||
|
||||
term.click_n(0, 0, MouseButton::Left, 2);
|
||||
assert_eq!(term.get_clipboard().unwrap(), "2");
|
||||
|
||||
// Clear the click streak
|
||||
term.click_n(0, 1, MouseButton::Right, 1);
|
||||
|
||||
term.click_n(0, 1, MouseButton::Left, 3);
|
||||
assert_eq!(term.get_clipboard().unwrap(), "3");
|
||||
|
||||
term.drag_select(0, 0, 0, 1);
|
||||
assert_eq!(term.get_clipboard().unwrap(), "2\n3");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user