use super::types::CopyModeState;
impl CopyModeState {
pub fn move_left(&mut self) {
let count = self.effective_count();
self.cursor_col = self.cursor_col.saturating_sub(count);
}
pub fn move_right(&mut self) {
let count = self.effective_count();
self.cursor_col = (self.cursor_col + count).min(self.cols.saturating_sub(1));
}
pub fn move_up(&mut self) {
let count = self.effective_count();
self.cursor_absolute_line = self.cursor_absolute_line.saturating_sub(count);
}
pub fn move_down(&mut self) {
let count = self.effective_count();
self.cursor_absolute_line = (self.cursor_absolute_line + count).min(self.max_line());
}
pub fn move_to_line_start(&mut self) {
self.cursor_col = 0;
}
pub fn move_to_line_end(&mut self) {
self.cursor_col = self.cols.saturating_sub(1);
}
pub fn move_to_first_non_blank(&mut self, line_text: &str) {
let first_non_blank = line_text
.chars()
.position(|c| !c.is_whitespace())
.unwrap_or(0);
self.cursor_col = first_non_blank.min(self.cols.saturating_sub(1));
}
pub fn half_page_up(&mut self) {
let half = self.rows / 2;
let count = self.effective_count();
self.cursor_absolute_line = self.cursor_absolute_line.saturating_sub(half * count);
}
pub fn half_page_down(&mut self) {
let half = self.rows / 2;
let count = self.effective_count();
self.cursor_absolute_line = (self.cursor_absolute_line + half * count).min(self.max_line());
}
pub fn page_up(&mut self) {
let count = self.effective_count();
self.cursor_absolute_line = self.cursor_absolute_line.saturating_sub(self.rows * count);
}
pub fn page_down(&mut self) {
let count = self.effective_count();
self.cursor_absolute_line =
(self.cursor_absolute_line + self.rows * count).min(self.max_line());
}
pub fn goto_top(&mut self) {
self.cursor_absolute_line = 0;
}
pub fn goto_bottom(&mut self) {
self.cursor_absolute_line = self.max_line();
}
pub fn goto_line(&mut self, line: usize) {
self.cursor_absolute_line = line.min(self.max_line());
}
pub fn screen_cursor_pos(&self, scroll_offset: usize) -> Option<(usize, usize)> {
let viewport_top = self.scrollback_len.saturating_sub(scroll_offset);
let viewport_bottom = viewport_top + self.rows;
if self.cursor_absolute_line >= viewport_top && self.cursor_absolute_line < viewport_bottom
{
let screen_row = self.cursor_absolute_line - viewport_top;
Some((self.cursor_col, screen_row))
} else {
None
}
}
pub fn required_scroll_offset(&self, current_offset: usize) -> Option<usize> {
let viewport_top = self.scrollback_len.saturating_sub(current_offset);
let viewport_bottom = viewport_top + self.rows;
if self.cursor_absolute_line < viewport_top {
let new_offset = self
.scrollback_len
.saturating_sub(self.cursor_absolute_line);
Some(new_offset)
} else if self.cursor_absolute_line >= viewport_bottom {
let lines_below = self.cursor_absolute_line - viewport_top;
let needed_offset = current_offset
.saturating_sub(lines_below.saturating_sub(self.rows.saturating_sub(1)));
let target_viewport_top = self
.cursor_absolute_line
.saturating_sub(self.rows.saturating_sub(1));
let new_offset = self.scrollback_len.saturating_sub(target_viewport_top);
let _ = needed_offset; Some(new_offset.min(self.scrollback_len))
} else {
None
}
}
}