diff options
author | Christian Duerr <contact@christianduerr.com> | 2021-01-01 05:19:03 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-01 05:19:03 +0000 |
commit | a1e2d6a5573d967aaceeadaefa17b6a00a2e4ca4 (patch) | |
tree | 5bdda93b515ad95a57487b266b021507bbc6b049 /alacritty | |
parent | 8ed72cc065255007a7f0687e3b8a540e8c6202c6 (diff) | |
download | r-alacritty-a1e2d6a5573d967aaceeadaefa17b6a00a2e4ca4.tar.gz r-alacritty-a1e2d6a5573d967aaceeadaefa17b6a00a2e4ca4.tar.bz2 r-alacritty-a1e2d6a5573d967aaceeadaefa17b6a00a2e4ca4.zip |
Add vi/search line indicator
This adds a new visual indicator which shows the position in history of
either the display offset during search, or the vi mode cursor.
To make it as unintrusive as possible, the overlay is hidden whenever
the vi mode cursor collides with its position.
Fixes #3984.
Diffstat (limited to 'alacritty')
-rw-r--r-- | alacritty/src/display.rs | 69 | ||||
-rw-r--r-- | alacritty/src/renderer/mod.rs | 18 |
2 files changed, 61 insertions, 26 deletions
diff --git a/alacritty/src/display.rs b/alacritty/src/display.rs index 4084d639..b5c2bfa9 100644 --- a/alacritty/src/display.rs +++ b/alacritty/src/display.rs @@ -23,10 +23,10 @@ use wayland_client::{Display as WaylandDisplay, EventQueue}; use crossfont::{self, Rasterize, Rasterizer}; use alacritty_terminal::event::{EventListener, OnResize}; -use alacritty_terminal::index::{Column, Direction, Point}; +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}; -use alacritty_terminal::term::{MIN_COLS, MIN_SCREEN_LINES}; +use alacritty_terminal::term::{SizeInfo, Term, TermMode, MIN_COLS, MIN_SCREEN_LINES}; use crate::config::font::Font; use crate::config::window::Dimensions; @@ -460,21 +460,19 @@ impl Display { let cursor = content.cursor(); let visual_bell_intensity = terminal.visual_bell.intensity(); + let display_offset = terminal.grid().display_offset(); let background_color = terminal.background_color(); let cursor_point = terminal.grid().cursor.point; + let total_lines = terminal.grid().total_lines(); let metrics = self.glyph_cache.font_metrics(); - let glyph_cache = &mut self.glyph_cache; let size_info = self.size_info; let selection = !terminal.selection.as_ref().map(Selection::is_empty).unwrap_or(true); let mouse_mode = terminal.mode().intersects(TermMode::MOUSE_MODE) && !terminal.mode().contains(TermMode::VI); - let vi_mode_cursor = if terminal.mode().contains(TermMode::VI) { - Some(terminal.vi_mode_cursor) - } else { - None - }; + let vi_mode = terminal.mode().contains(TermMode::VI); + let vi_mode_cursor = if vi_mode { Some(terminal.vi_mode_cursor) } else { None }; // Drop terminal as early as possible to free lock. drop(terminal); @@ -490,6 +488,7 @@ impl Display { { let _sampler = self.meter.sampler(); + 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. for mut cell in grid_cells { @@ -539,11 +538,19 @@ impl Display { } } - // Highlight URLs at the vi mode cursor position. if let Some(vi_mode_cursor) = vi_mode_cursor { - if let Some(url) = self.urls.find_at(vi_mode_cursor.point) { + // 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) { 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 { + // Show current display offset in vi-less search to indicate match position. + self.draw_line_indicator(config, &size_info, total_lines, None, display_offset); } // Push the cursor rects for rendering. @@ -574,13 +581,13 @@ impl Display { 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 color = match message.ty() { + let bg = match message.ty() { MessageType::Error => config.colors.normal.red, MessageType::Warning => config.colors.normal.yellow, }; let message_bar_rect = - RenderRect::new(0., y, size_info.width(), size_info.height() - y, color, 1.); + RenderRect::new(0., y, size_info.width(), size_info.height() - y, bg, 1.); // Push message_bar in the end, so it'll be above all other content. rects.push(message_bar_rect); @@ -589,10 +596,12 @@ impl Display { self.renderer.draw_rects(&size_info, rects); // Relay messages to the user. + let glyph_cache = &mut self.glyph_cache; let fg = config.colors.primary.background; for (i, message_text) in text.iter().enumerate() { + let point = Point::new(start_line + i, Column(0)); self.renderer.with_api(&config.ui_config, &size_info, |mut api| { - api.render_string(glyph_cache, start_line + i, &message_text, fg, None); + api.render_string(glyph_cache, point, fg, bg, &message_text); }); } } else { @@ -681,10 +690,12 @@ impl Display { // Assure text length is at least num_cols. let text = format!("{:<1$}", text, num_cols); + let point = Point::new(size_info.screen_lines(), Column(0)); let fg = config.colors.search_bar_foreground(); let bg = config.colors.search_bar_background(); + self.renderer.with_api(&config.ui_config, &size_info, |mut api| { - api.render_string(glyph_cache, size_info.screen_lines(), &text, fg, Some(bg)); + api.render_string(glyph_cache, point, fg, bg, &text); }); } @@ -693,17 +704,43 @@ impl Display { if !config.ui_config.debug.render_timer { return; } + 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 fg = config.colors.primary.background; let bg = config.colors.normal.red; self.renderer.with_api(&config.ui_config, &size_info, |mut api| { - api.render_string(glyph_cache, size_info.screen_lines() - 2, &timing[..], fg, Some(bg)); + api.render_string(glyph_cache, point, fg, bg, &timing); }); } + /// Draw an indicator for the position of a line in history. + fn draw_line_indicator( + &mut self, + config: &Config, + size_info: &SizeInfo, + total_lines: usize, + vi_mode_point: Option<Point>, + line: usize, + ) { + let text = format!("[{}/{}]", line, total_lines - 1); + let column = Column(size_info.cols().0.saturating_sub(text.len())); + let colors = &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.col < 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); + }); + } + } + /// Requst a new frame for a window on Wayland. #[inline] #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs index 5edcbb4a..39e53b82 100644 --- a/alacritty/src/renderer/mod.rs +++ b/alacritty/src/renderer/mod.rs @@ -14,7 +14,7 @@ use fnv::FnvHasher; use log::{error, info}; use unicode_width::UnicodeWidthChar; -use alacritty_terminal::index::{Column, Line}; +use alacritty_terminal::index::Point; use alacritty_terminal::term::cell::Flags; use alacritty_terminal::term::color::Rgb; use alacritty_terminal::term::render::RenderableCell; @@ -820,25 +820,23 @@ impl<'a> RenderApi<'a> { pub fn render_string( &mut self, glyph_cache: &mut GlyphCache, - line: Line, - string: &str, + point: Point, fg: Rgb, - bg: Option<Rgb>, + bg: Rgb, + string: &str, ) { - let bg_alpha = bg.map(|_| 1.0).unwrap_or(0.0); - let cells = string .chars() .enumerate() .map(|(i, character)| RenderableCell { - line, - column: Column(i), + line: point.line, + column: point.col + i, character, zerowidth: None, flags: Flags::empty(), - bg_alpha, + bg_alpha: 1.0, fg, - bg: bg.unwrap_or(Rgb { r: 0, g: 0, b: 0 }), + bg, is_match: false, }) .collect::<Vec<_>>(); |