mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-11 13:51:01 -05:00
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.
This commit is contained in:
parent
e35e5ad14f
commit
a58fb39b68
2 changed files with 42 additions and 16 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue