editor: Do not highlight selected text + Clear highlight preemptively when new selection is detected (#25149)
When selecting text, it highlights all matching occurences along with selected text itself. This causes highlight overlap, which looks bit odd. This PR fixes it. Bonus: Context: We have an edge case (which we already cover) where we don’t want to clear `SelectedTextHighlight` every time the selection changes. This happens when you are dragging the selection across some word, if you clear it directly on selection change, due to debounce wait, the highlight take some time to appear, which causes flickering for the user. We solve this by not clearing it directly but only clearing it when a new selection is found. This avoids the flicker. However, we also need to clear the selection even before the debounce wait if we detect early on that the selection is different from previous ones. Otherwise, the user will have to wait until the debounce time to see it cleared on the screen. The code for this is a little repetitive because we check the buffer state both before and after the debounce. But this is necessary. --- Before: Notice overlapping corners and selected text is bit darker in this case.  After:  Release Notes: - N/A
This commit is contained in:
parent
094430e5a2
commit
fb19db00ca
1 changed files with 26 additions and 11 deletions
|
@ -4782,6 +4782,15 @@ impl Editor {
|
|||
self.clear_background_highlights::<SelectedTextHighlight>(cx);
|
||||
return;
|
||||
}
|
||||
if self.selections.count() != 1 || self.selections.line_mode {
|
||||
self.clear_background_highlights::<SelectedTextHighlight>(cx);
|
||||
return;
|
||||
}
|
||||
let selection = self.selections.newest::<Point>(cx);
|
||||
if selection.is_empty() || selection.start.row != selection.end.row {
|
||||
self.clear_background_highlights::<SelectedTextHighlight>(cx);
|
||||
return;
|
||||
}
|
||||
let debounce = EditorSettings::get_global(cx).selection_highlight_debounce;
|
||||
self.selection_highlight_task = Some(cx.spawn_in(window, |editor, mut cx| async move {
|
||||
cx.background_executor()
|
||||
|
@ -4802,6 +4811,7 @@ impl Editor {
|
|||
Some(cx.background_spawn(async move {
|
||||
let mut ranges = Vec::new();
|
||||
let query = buffer.text_for_range(selection.range()).collect::<String>();
|
||||
let selection_anchors = selection.range().to_anchors(&buffer);
|
||||
for range in [buffer.anchor_before(0)..buffer.anchor_after(buffer.len())] {
|
||||
for (search_buffer, search_range, excerpt_id) in
|
||||
buffer.range_to_buffer_ranges(range)
|
||||
|
@ -4820,17 +4830,22 @@ impl Editor {
|
|||
.search(search_buffer, Some(search_range.clone()))
|
||||
.await
|
||||
.into_iter()
|
||||
.map(|match_range| {
|
||||
let start = search_buffer
|
||||
.anchor_after(search_range.start + match_range.start);
|
||||
let end = search_buffer
|
||||
.anchor_before(search_range.start + match_range.end);
|
||||
Anchor::range_in_buffer(
|
||||
excerpt_id,
|
||||
search_buffer.remote_id(),
|
||||
start..end,
|
||||
)
|
||||
}),
|
||||
.filter_map(
|
||||
|match_range| {
|
||||
let start = search_buffer.anchor_after(
|
||||
search_range.start + match_range.start,
|
||||
);
|
||||
let end = search_buffer.anchor_before(
|
||||
search_range.start + match_range.end,
|
||||
);
|
||||
let range = Anchor::range_in_buffer(
|
||||
excerpt_id,
|
||||
search_buffer.remote_id(),
|
||||
start..end,
|
||||
);
|
||||
(range != selection_anchors).then_some(range)
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue