Support invisibles in the selection

This commit is contained in:
Kirill Bulatov 2023-05-05 00:36:31 +03:00
parent 1eeeec157e
commit 4aaf44df94
3 changed files with 38 additions and 22 deletions

View file

@ -36,11 +36,13 @@
// Whether to show tabs and spaces in the editor. // Whether to show tabs and spaces in the editor.
// This setting can take two values: // This setting can take two values:
// //
// 1. Do not draw any tabs or spaces (default): // 1. Draw tabs and spaces only for the selected text (default):
// "selection"
// 2. Do not draw any tabs or spaces:
// "none" // "none"
// 2. Draw all invisible symbols: // 3. Draw all invisible symbols:
// "all" // "all"
"show_invisibles": "none", "show_invisibles": "selection",
// Whether the screen sharing icon is shown in the os status bar. // Whether the screen sharing icon is shown in the os status bar.
"show_call_status_icon": true, "show_call_status_icon": true,
// Whether to use language servers to provide code intelligence. // Whether to use language servers to provide code intelligence.

View file

@ -784,11 +784,15 @@ impl EditorElement {
let mut cursors = SmallVec::<[Cursor; 32]>::new(); let mut cursors = SmallVec::<[Cursor; 32]>::new();
let corner_radius = 0.15 * layout.position_map.line_height; let corner_radius = 0.15 * layout.position_map.line_height;
let mut selection_ranges = SmallVec::<[Range<DisplayPoint>; 32]>::new();
for (replica_id, selections) in &layout.selections { for (replica_id, selections) in &layout.selections {
let selection_style = style.replica_selection_style(*replica_id); let selection_style = style.replica_selection_style(*replica_id);
for selection in selections { for selection in selections {
if !selection.range.is_empty() {
selection_ranges.push(selection.range.clone());
}
self.paint_highlighted_range( self.paint_highlighted_range(
scene, scene,
selection.range.clone(), selection.range.clone(),
@ -880,36 +884,45 @@ impl EditorElement {
); );
let settings = cx.global::<Settings>(); let settings = cx.global::<Settings>();
match settings let regions_to_hit = match settings
.editor_overrides .editor_overrides
.show_invisibles .show_invisibles
.or(settings.editor_defaults.show_invisibles) .or(settings.editor_defaults.show_invisibles)
.unwrap_or_default() .unwrap_or_default()
{ {
ShowInvisibles::None => {} ShowInvisibles::None => continue,
ShowInvisibles::All => { ShowInvisibles::Selection => Some(&selection_ranges),
ShowInvisibles::All => None,
};
for invisible in &line_with_invisibles.invisibles { for invisible in &line_with_invisibles.invisibles {
let (token_offset, invisible_symbol) = match invisible { let (&token_offset, invisible_symbol) = match invisible {
Invisible::Tab { line_start_offset } => { Invisible::Tab { line_start_offset } => {
(*line_start_offset, &layout.tab_invisible) (line_start_offset, &layout.tab_invisible)
} }
Invisible::Whitespace { line_offset } => { Invisible::Whitespace { line_offset } => {
(*line_offset, &layout.space_invisible) (line_offset, &layout.space_invisible)
} }
}; };
let x_offset = line_with_invisibles.line.x_for_index(token_offset); let x_offset = line_with_invisibles.line.x_for_index(token_offset);
let invisible_offset = let invisible_offset =
(layout.position_map.em_width - invisible_symbol.width()).max(0.0) (layout.position_map.em_width - invisible_symbol.width()).max(0.0) / 2.0;
/ 2.0; let origin =
let origin = content_origin content_origin + vec2f(-scroll_left + x_offset + invisible_offset, line_y);
+ vec2f(-scroll_left + x_offset + invisible_offset, line_y);
if let Some(regions_to_hit) = regions_to_hit {
let invisible_point = DisplayPoint::new(row, token_offset as u32);
if !regions_to_hit.iter().any(|region| {
region.start <= invisible_point && invisible_point < region.end
}) {
continue;
}
}
invisible_symbol.paint(scene, origin, visible_bounds, line_height, cx); invisible_symbol.paint(scene, origin, visible_bounds, line_height, cx);
} }
} }
} }
}
}
scene.paint_layer(Some(bounds), |scene| { scene.paint_layer(Some(bounds), |scene| {
for cursor in cursors { for cursor in cursors {

View file

@ -451,6 +451,7 @@ pub struct FeaturesContent {
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum ShowInvisibles { pub enum ShowInvisibles {
#[default] #[default]
Selection,
None, None,
All, All,
} }