diff options
Diffstat (limited to 'alacritty/src/display')
-rw-r--r-- | alacritty/src/display/content.rs | 63 | ||||
-rw-r--r-- | alacritty/src/display/cursor.rs | 2 | ||||
-rw-r--r-- | alacritty/src/display/hint.rs | 4 | ||||
-rw-r--r-- | alacritty/src/display/mod.rs | 58 |
4 files changed, 58 insertions, 69 deletions
diff --git a/alacritty/src/display/content.rs b/alacritty/src/display/content.rs index a25ddce8..a793f443 100644 --- a/alacritty/src/display/content.rs +++ b/alacritty/src/display/content.rs @@ -1,5 +1,5 @@ use std::borrow::Cow; -use std::cmp::max; +use std::cmp::{max, min}; use std::mem; use std::ops::{Deref, DerefMut, RangeInclusive}; @@ -126,12 +126,17 @@ impl<'a> RenderableContent<'a> { let text_color = text_color.color(cell.fg, cell.bg); let cursor_color = cursor_color.color(cell.fg, cell.bg); + // Convert cursor point to viewport position. + let cursor_point = self.terminal_cursor.point; + let line = (cursor_point.line + self.terminal_content.display_offset as i32).0 as usize; + let point = Point::new(line, cursor_point.column); + Some(RenderableCursor { - point: self.terminal_cursor.point, shape: self.terminal_cursor.shape, cursor_color, text_color, is_wide, + point, }) } } @@ -147,9 +152,10 @@ impl<'a> Iterator for RenderableContent<'a> { fn next(&mut self) -> Option<Self::Item> { loop { let cell = self.terminal_content.display_iter.next()?; + let cell_point = cell.point; let mut cell = RenderableCell::new(self, cell); - if self.terminal_cursor.point == cell.point { + if self.terminal_cursor.point == cell_point { // Store the cursor which should be rendered. self.cursor = self.renderable_cursor(&cell).map(|cursor| { if cursor.shape == CursorShape::Block { @@ -178,16 +184,15 @@ impl<'a> Iterator for RenderableContent<'a> { pub struct RenderableCell { pub character: char, pub zerowidth: Option<Vec<char>>, - pub point: Point, + pub point: Point<usize>, pub fg: Rgb, pub bg: Rgb, pub bg_alpha: f32, pub flags: Flags, - pub is_match: bool, } impl RenderableCell { - fn new<'a>(content: &mut RenderableContent<'a>, cell: Indexed<&Cell, Line>) -> Self { + fn new<'a>(content: &mut RenderableContent<'a>, cell: Indexed<&Cell>) -> Self { // Lookup RGB values. let mut fg_rgb = Self::compute_fg_rgb(content, cell.fg, cell.flags); let mut bg_rgb = Self::compute_bg_rgb(content, cell.bg); @@ -203,7 +208,6 @@ impl RenderableCell { .terminal_content .selection .map_or(false, |selection| selection.contains_cell(&cell, content.terminal_cursor)); - let mut is_match = false; let mut character = cell.c; @@ -233,19 +237,21 @@ impl RenderableCell { let config_fg = colors.search.matches.foreground; let config_bg = colors.search.matches.background; Self::compute_cell_rgb(&mut fg_rgb, &mut bg_rgb, &mut bg_alpha, config_fg, config_bg); - - is_match = true; } + // Convert cell point to viewport position. + let cell_point = cell.point; + let line = (cell_point.line + content.terminal_content.display_offset as i32).0 as usize; + let point = Point::new(line, cell_point.column); + RenderableCell { - character, zerowidth: cell.zerowidth().map(|zerowidth| zerowidth.to_vec()), - point: cell.point, + flags: cell.flags, fg: fg_rgb, bg: bg_rgb, + character, bg_alpha, - flags: cell.flags, - is_match, + point, } } @@ -349,7 +355,7 @@ pub struct RenderableCursor { cursor_color: Rgb, text_color: Rgb, is_wide: bool, - point: Point, + point: Point<usize>, } impl RenderableCursor { @@ -365,7 +371,7 @@ impl RenderableCursor { self.is_wide } - pub fn point(&self) -> Point { + pub fn point(&self) -> Point<usize> { self.point } } @@ -423,36 +429,23 @@ pub struct RegexMatches(Vec<RangeInclusive<Point>>); impl RegexMatches { /// Find all visible matches. pub fn new<T>(term: &Term<T>, dfas: &RegexSearch) -> Self { - let viewport_end = term.grid().display_offset(); - let viewport_start = viewport_end + term.screen_lines().0 - 1; + let viewport_start = Line(-(term.grid().display_offset() as i32)); + let viewport_end = viewport_start + term.bottommost_line(); // Compute start of the first and end of the last line. let start_point = Point::new(viewport_start, Column(0)); let mut start = term.line_search_left(start_point); - let end_point = Point::new(viewport_end, term.cols() - 1); + let end_point = Point::new(viewport_end, term.last_column()); let mut end = term.line_search_right(end_point); // Set upper bound on search before/after the viewport to prevent excessive blocking. - if start.line > viewport_start + MAX_SEARCH_LINES { - if start.line == 0 { - // Do not highlight anything if this line is the last. - return Self::default(); - } else { - // Start at next line if this one is too long. - start.line -= 1; - } - } - end.line = max(end.line, viewport_end.saturating_sub(MAX_SEARCH_LINES)); + start.line = max(start.line, viewport_start - MAX_SEARCH_LINES); + end.line = min(end.line, viewport_end + MAX_SEARCH_LINES); // Create an iterater for the current regex search for all visible matches. let iter = RegexIter::new(start, end, Direction::Right, term, dfas) - .skip_while(move |rm| rm.end().line > viewport_start) - .take_while(move |rm| rm.start().line >= viewport_end) - .map(|rm| { - let viewport_start = term.grid().clamp_buffer_to_visible(*rm.start()); - let viewport_end = term.grid().clamp_buffer_to_visible(*rm.end()); - viewport_start..=viewport_end - }); + .skip_while(move |rm| rm.end().line < viewport_start) + .take_while(move |rm| rm.start().line <= viewport_end); Self(iter.collect()) } diff --git a/alacritty/src/display/cursor.rs b/alacritty/src/display/cursor.rs index 7cd631e3..f3a782cc 100644 --- a/alacritty/src/display/cursor.rs +++ b/alacritty/src/display/cursor.rs @@ -17,7 +17,7 @@ impl IntoRects for RenderableCursor { fn rects(self, size_info: &SizeInfo, thickness: f32) -> CursorRects { let point = self.point(); let x = point.column.0 as f32 * size_info.cell_width() + size_info.padding_x(); - let y = point.line.0 as f32 * size_info.cell_height() + size_info.padding_y(); + let y = point.line as f32 * size_info.cell_height() + size_info.padding_y(); let mut width = size_info.cell_width(); let height = size_info.cell_height(); diff --git a/alacritty/src/display/hint.rs b/alacritty/src/display/hint.rs index 6499a959..fe107139 100644 --- a/alacritty/src/display/hint.rs +++ b/alacritty/src/display/hint.rs @@ -118,9 +118,7 @@ impl HintState { if label.len() == 1 { // Get text for the hint's regex match. let hint_match = &self.matches[index]; - let start = term.visible_to_buffer(*hint_match.start()); - let end = term.visible_to_buffer(*hint_match.end()); - let text = term.bounds_to_string(start, end); + let text = term.bounds_to_string(*hint_match.start(), *hint_match.end()); // Append text as last argument and launch command. let program = hint.command.program(); diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index cbf2930a..0f20e45f 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -27,7 +27,7 @@ use alacritty_terminal::event::{EventListener, OnResize}; use alacritty_terminal::grid::Dimensions as _; use alacritty_terminal::index::{Column, Direction, Line, Point}; use alacritty_terminal::selection::Selection; -use alacritty_terminal::term::{SizeInfo, Term, TermMode, MIN_COLS, MIN_SCREEN_LINES}; +use alacritty_terminal::term::{SizeInfo, Term, TermMode, MIN_COLUMNS, MIN_SCREEN_LINES}; use crate::config::font::Font; use crate::config::window::Dimensions; @@ -477,12 +477,6 @@ impl Display { mods: ModifiersState, search_state: &SearchState, ) { - // Convert search match from viewport to absolute indexing. - let search_active = search_state.regex().is_some(); - let viewport_match = search_state - .focused_match() - .and_then(|focused_match| terminal.grid().clamp_buffer_range_to_visible(focused_match)); - // Collect renderable content before the terminal is dropped. let mut content = RenderableContent::new(config, self, &terminal, search_state); let mut grid_cells = Vec::new(); @@ -522,13 +516,15 @@ impl Display { let glyph_cache = &mut self.glyph_cache; self.renderer.with_api(&config.ui_config, &size_info, |mut api| { // Iterate over all non-empty cells in the grid. + let focused_match = search_state.focused_match(); for mut cell in grid_cells { - // Invert the active match during search. - if cell.is_match - && viewport_match - .as_ref() - .map_or(false, |viewport_match| viewport_match.contains(&cell.point)) - { + let focused = focused_match.as_ref().map_or(false, |focused_match| { + let line = Line(cell.point.line as i32) - display_offset; + focused_match.contains(&Point::new(line, cell.point.column)) + }); + + // Invert the focused match during search. + if focused { let colors = config.ui_config.colors.search.focused_match; let match_fg = colors.foreground.color(cell.fg, cell.bg); cell.bg = colors.background.color(cell.fg, cell.bg); @@ -537,7 +533,7 @@ impl Display { } // Update URL underlines. - urls.update(size_info.cols(), &cell); + urls.update(&size_info, &cell); // Update underline/strikeout. lines.update(&cell); @@ -570,15 +566,16 @@ impl Display { if let Some(vi_mode_cursor) = vi_mode_cursor { // Highlight URLs at the vi mode cursor position. - let vi_mode_point = vi_mode_cursor.point; - if let Some(url) = self.urls.find_at(vi_mode_point) { + let vi_point = vi_mode_cursor.point; + let line = (vi_point.line + display_offset).0 as usize; + if let Some(url) = self.urls.find_at(Point::new(line, vi_point.column)) { rects.append(&mut url.rects(&metrics, &size_info)); } // Indicate vi mode by showing the cursor's position in the top right corner. - let line = size_info.screen_lines() + display_offset - vi_mode_point.line - 1; - self.draw_line_indicator(config, &size_info, total_lines, Some(vi_mode_point), line.0); - } else if search_active { + let line = (-vi_point.line.0 + size_info.bottommost_line().0) as usize; + self.draw_line_indicator(config, &size_info, total_lines, Some(vi_point), line); + } else if search_state.regex().is_some() { // Show current display offset in vi-less search to indicate match position. self.draw_line_indicator(config, &size_info, total_lines, None, display_offset); } @@ -605,12 +602,12 @@ impl Display { } if let Some(message) = message_buffer.message() { - let search_offset = if search_active { 1 } else { 0 }; + let search_offset = if search_state.regex().is_some() { 1 } else { 0 }; let text = message.text(&size_info); // Create a new rectangle for the background. let start_line = size_info.screen_lines() + search_offset; - let y = size_info.cell_height().mul_add(start_line.0 as f32, size_info.padding_y()); + let y = size_info.cell_height().mul_add(start_line as f32, size_info.padding_y()); let bg = match message.ty() { MessageType::Error => config.ui_config.colors.normal.red, @@ -656,7 +653,8 @@ impl Display { self.draw_search(config, &size_info, &search_text); // Compute IME position. - Point::new(size_info.screen_lines() + 1, Column(search_text.chars().count() - 1)) + let line = Line(size_info.screen_lines() as i32 + 1); + Point::new(line, Column(search_text.chars().count() - 1)) }, None => cursor_point, }; @@ -703,7 +701,7 @@ impl Display { formatted_regex.push('_'); // Truncate beginning of the search regex if it exceeds the viewport width. - let num_cols = size_info.cols().0; + let num_cols = size_info.columns(); let label_len = search_label.chars().count(); let regex_len = formatted_regex.chars().count(); let truncate_len = min((regex_len + label_len).saturating_sub(num_cols), regex_len); @@ -722,7 +720,7 @@ impl Display { /// Draw current search regex. fn draw_search(&mut self, config: &Config, size_info: &SizeInfo, text: &str) { let glyph_cache = &mut self.glyph_cache; - let num_cols = size_info.cols().0; + let num_cols = size_info.columns(); // Assure text length is at least num_cols. let text = format!("{:<1$}", text, num_cols); @@ -745,7 +743,7 @@ impl Display { let glyph_cache = &mut self.glyph_cache; let timing = format!("{:.3} usec", self.meter.average()); - let point = Point::new(size_info.screen_lines() - 2, Column(0)); + let point = Point::new(size_info.screen_lines().saturating_sub(2), Column(0)); let fg = config.ui_config.colors.primary.background; let bg = config.ui_config.colors.normal.red; @@ -764,16 +762,16 @@ impl Display { line: usize, ) { let text = format!("[{}/{}]", line, total_lines - 1); - let column = Column(size_info.cols().0.saturating_sub(text.len())); + let column = Column(size_info.columns().saturating_sub(text.len())); let colors = &config.ui_config.colors; let fg = colors.line_indicator.foreground.unwrap_or(colors.primary.background); let bg = colors.line_indicator.background.unwrap_or(colors.primary.foreground); // Do not render anything if it would obscure the vi mode cursor. - if vi_mode_point.map_or(true, |point| point.line.0 != 0 || point.column < column) { + if vi_mode_point.map_or(true, |point| point.line != 0 || point.column < column) { let glyph_cache = &mut self.glyph_cache; self.renderer.with_api(&config.ui_config, &size_info, |mut api| { - api.render_string(glyph_cache, Point::new(Line(0), column), fg, bg, &text); + api.render_string(glyph_cache, Point::new(0, column), fg, bg, &text); }); } } @@ -822,8 +820,8 @@ fn window_size( ) -> PhysicalSize<u32> { let padding = config.ui_config.window.padding(dpr); - let grid_width = cell_width * dimensions.columns.0.max(MIN_COLS) as f32; - let grid_height = cell_height * dimensions.lines.0.max(MIN_SCREEN_LINES) as f32; + let grid_width = cell_width * dimensions.columns.0.max(MIN_COLUMNS) as f32; + let grid_height = cell_height * dimensions.lines.max(MIN_SCREEN_LINES) as f32; let width = (padding.0).mul_add(2., grid_width).floor(); let height = (padding.1).mul_add(2., grid_height).floor(); |