aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2023-09-22 19:49:52 +0200
committerGitHub <noreply@github.com>2023-09-22 21:49:52 +0400
commita58fb39b68caa34b073f66911c0ac6945f56eac2 (patch)
tree4e453bd5da22bcd0cc1a3b8ea6246ff17933e3fa
parente35e5ad14fce8456afdd89f2b392b9924bb27471 (diff)
downloadalacritty-a58fb39b68caa34b073f66911c0ac6945f56eac2.tar.gz
alacritty-a58fb39b68caa34b073f66911c0ac6945f56eac2.zip
Underline hint matches during selection
This patch underlines the full regex hint match while the keyboard hint selection is in process. While it would be possible to color the entire match, this would only introduce unnecessary configuration options and be too noisy. The underline matches the mouse highlighting and has a less drastic visual impact. Closes #6178.
-rw-r--r--CHANGELOG.md1
-rw-r--r--alacritty/src/display/content.rs57
2 files changed, 42 insertions, 16 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 801b059f..40273970 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -39,6 +39,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- The double click threshold was raised to `400ms`
- OSC 52 paste ability is now **disabled by default**; use `terminal.osc52` to adjust it
- Apply `colors.transparent_background_colors` for selections, hints, and search matches
+- Underline full hint during keyboard selection
### Fixed
diff --git a/alacritty/src/display/content.rs b/alacritty/src/display/content.rs
index ec0f4b6a..0849b30a 100644
--- a/alacritty/src/display/content.rs
+++ b/alacritty/src/display/content.rs
@@ -4,7 +4,7 @@ use std::{cmp, mem};
use alacritty_terminal::ansi::{Color, CursorShape, NamedColor};
use alacritty_terminal::event::EventListener;
-use alacritty_terminal::grid::Indexed;
+use alacritty_terminal::grid::{Dimensions, Indexed};
use alacritty_terminal::index::{Column, Line, Point};
use alacritty_terminal::selection::SelectionRange;
use alacritty_terminal::term::cell::{Cell, Flags, Hyperlink};
@@ -15,7 +15,7 @@ use alacritty_terminal::term::{self, RenderableContent as TerminalContent, Term,
use crate::config::UiConfig;
use crate::display::color::{List, DIM_FACTOR};
use crate::display::hint::{self, HintState};
-use crate::display::Display;
+use crate::display::{Display, SizeInfo};
use crate::event::SearchState;
/// Minimum contrast between a fixed cursor color and the cell's background.
@@ -34,6 +34,7 @@ pub struct RenderableContent<'a> {
config: &'a UiConfig,
colors: &'a List,
focused_match: Option<&'a Match>,
+ size: &'a SizeInfo,
}
impl<'a> RenderableContent<'a> {
@@ -74,6 +75,7 @@ impl<'a> RenderableContent<'a> {
Self {
colors: &display.colors,
+ size: &display.size_info,
cursor: RenderableCursor::new_hidden(),
terminal_content,
focused_match,
@@ -223,18 +225,27 @@ impl RenderableCell {
let viewport_start = Point::new(Line(-(display_offset as i32)), Column(0));
let colors = &content.config.colors;
let mut character = cell.c;
+ let mut flags = cell.flags;
- if let Some((c, is_first)) =
- content.hint.as_mut().and_then(|hint| hint.advance(viewport_start, cell.point))
+ let num_cols = content.size.columns();
+ if let Some((c, is_first)) = content
+ .hint
+ .as_mut()
+ .and_then(|hint| hint.advance(viewport_start, num_cols, cell.point))
{
- let (config_fg, config_bg) = if is_first {
- (colors.hints.start.foreground, colors.hints.start.background)
+ if is_first {
+ let (config_fg, config_bg) =
+ (colors.hints.start.foreground, colors.hints.start.background);
+ Self::compute_cell_rgb(&mut fg, &mut bg, &mut bg_alpha, config_fg, config_bg);
+ } else if c.is_some() {
+ let (config_fg, config_bg) =
+ (colors.hints.end.foreground, colors.hints.end.background);
+ Self::compute_cell_rgb(&mut fg, &mut bg, &mut bg_alpha, config_fg, config_bg);
} else {
- (colors.hints.end.foreground, colors.hints.end.background)
- };
- Self::compute_cell_rgb(&mut fg, &mut bg, &mut bg_alpha, config_fg, config_bg);
+ flags.insert(Flags::UNDERLINE);
+ }
- character = c;
+ character = c.unwrap_or(character);
} else if is_selected {
let config_fg = colors.selection.foreground;
let config_bg = colors.selection.background;
@@ -265,7 +276,6 @@ impl RenderableCell {
let cell_point = cell.point;
let point = term::point_to_viewport(display_offset, cell_point).unwrap();
- let flags = cell.flags;
let underline = cell
.underline_color()
.map_or(fg, |underline| Self::compute_fg_rgb(content, underline, flags));
@@ -440,7 +450,15 @@ impl<'a> Hint<'a> {
/// this position will be returned.
///
/// The tuple's [`bool`] will be `true` when the character is the first for this hint.
- fn advance(&mut self, viewport_start: Point, point: Point) -> Option<(char, bool)> {
+ ///
+ /// The tuple's [`Option<char>`] will be [`None`] when the point is part of the match, but not
+ /// part of the hint label.
+ fn advance(
+ &mut self,
+ viewport_start: Point,
+ num_cols: usize,
+ point: Point,
+ ) -> Option<(Option<char>, bool)> {
// Check if we're within a match at all.
if !self.matches.advance(point) {
return None;
@@ -450,15 +468,22 @@ impl<'a> Hint<'a> {
let start = self
.matches
.get(self.matches.index)
- .map(|bounds| cmp::max(*bounds.start(), viewport_start))
- .filter(|start| start.line == point.line)?;
+ .map(|bounds| cmp::max(*bounds.start(), viewport_start))?;
// Position within the hint label.
- let label_position = point.column.0 - start.column.0;
+ let line_delta = point.line.0 - start.line.0;
+ let col_delta = point.column.0 as i32 - start.column.0 as i32;
+ let label_position = usize::try_from(line_delta * num_cols as i32 + col_delta).unwrap_or(0);
let is_first = label_position == 0;
// Hint label character.
- self.labels[self.matches.index].get(label_position).copied().map(|c| (c, is_first))
+ let hint_char = self.labels[self.matches.index]
+ .get(label_position)
+ .copied()
+ .map(|c| (Some(c), is_first))
+ .unwrap_or((None, false));
+
+ Some(hint_char)
}
}