par_term/copy_mode/
visual.rs1use super::types::{CopyModeState, VisualMode};
4use crate::selection::{Selection, SelectionMode};
5
6impl CopyModeState {
7 pub fn toggle_visual_char(&mut self) {
13 if self.visual_mode == VisualMode::Char {
14 self.visual_mode = VisualMode::None;
15 self.selection_anchor = None;
16 } else {
17 self.visual_mode = VisualMode::Char;
18 self.selection_anchor = Some((self.cursor_absolute_line, self.cursor_col));
19 }
20 }
21
22 pub fn toggle_visual_line(&mut self) {
24 if self.visual_mode == VisualMode::Line {
25 self.visual_mode = VisualMode::None;
26 self.selection_anchor = None;
27 } else {
28 self.visual_mode = VisualMode::Line;
29 self.selection_anchor = Some((self.cursor_absolute_line, self.cursor_col));
30 }
31 }
32
33 pub fn toggle_visual_block(&mut self) {
35 if self.visual_mode == VisualMode::Block {
36 self.visual_mode = VisualMode::None;
37 self.selection_anchor = None;
38 } else {
39 self.visual_mode = VisualMode::Block;
40 self.selection_anchor = Some((self.cursor_absolute_line, self.cursor_col));
41 }
42 }
43
44 pub fn compute_selection(&self, scroll_offset: usize) -> Option<Selection> {
50 if self.visual_mode == VisualMode::None {
51 return None;
52 }
53
54 let (anchor_line, anchor_col) = self.selection_anchor?;
55
56 let viewport_top = self.scrollback_len.saturating_sub(scroll_offset);
59
60 let anchor_row = anchor_line.saturating_sub(viewport_top);
64 let cursor_row = self.cursor_absolute_line.saturating_sub(viewport_top);
65
66 let mode = match self.visual_mode {
67 VisualMode::None => return None,
68 VisualMode::Char => SelectionMode::Normal,
69 VisualMode::Line => SelectionMode::Line,
70 VisualMode::Block => SelectionMode::Rectangular,
71 };
72
73 let start = (anchor_col, anchor_row);
74 let end = (self.cursor_col, cursor_row);
75
76 Some(Selection::new(start, end, mode, scroll_offset))
77 }
78}