From c22eaa7a26287cf31ade47dc49b534bef195c1c9 Mon Sep 17 00:00:00 2001 From: Xin Zhao Date: Sat, 21 Feb 2026 19:19:56 +0800 Subject: [PATCH] editor: Fix bracket highlight flickering when editing (#49797) Closes #49653 Before you mark this PR as ready for review, make sure that you have: - [x] screen record added - [x] Done a self-review taking into account security and performance aspects - [x] No UI change The original `refresh_matching_bracket_highlights` method always performed a clear --> highlight procedure, even when the bracket positions hadn't changed, causing the highlights to flicker. Normally, for single quotes or brackets, the flickering area is small and hard to notice (though visible if you pay close attention), but for Python docstrings, the three quotes create a larger highlighted area, making this issue much more apparent. After fix: https://github.com/user-attachments/assets/bcd9b464-0def-438d-86b3-7e6b3779b5c6 Release Notes: - Fixed bracket highlights flickering when editing inside brackets --- .../editor/src/highlight_matching_bracket.rs | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/crates/editor/src/highlight_matching_bracket.rs b/crates/editor/src/highlight_matching_bracket.rs index 4401a87195eb13413cfc2fa9c8e7784f737ac3fc..15db878791cc04d430786c2329055fb3e805c4c5 100644 --- a/crates/editor/src/highlight_matching_bracket.rs +++ b/crates/editor/src/highlight_matching_bracket.rs @@ -11,11 +11,10 @@ impl Editor { snapshot: &DisplaySnapshot, cx: &mut Context, ) { - self.clear_highlights(HighlightKey::MatchingBracket, cx); - let newest_selection = self.selections.newest::(&snapshot); // Don't highlight brackets if the selection isn't empty if !newest_selection.is_empty() { + self.clear_highlights(HighlightKey::MatchingBracket, cx); return; } @@ -40,16 +39,32 @@ impl Editor { }); self.refresh_matching_bracket_highlights_task = cx.spawn({ let buffer_snapshot = buffer_snapshot.clone(); - async move |editor, cx| { - if let Some((opening_range, closing_range)) = task.await { - editor - .update(cx, |editor, cx| { + async move |this, cx| { + let bracket_ranges = task.await; + let current_ranges = this + .read_with(cx, |editor, cx| { + editor + .display_map + .read(cx) + .text_highlights(HighlightKey::MatchingBracket) + .map(|(_, ranges)| ranges.to_vec()) + }) + .ok() + .flatten(); + let new_ranges = bracket_ranges.map(|(opening_range, closing_range)| { + vec![ + opening_range.to_anchors(&buffer_snapshot), + closing_range.to_anchors(&buffer_snapshot), + ] + }); + + if current_ranges != new_ranges { + this.update(cx, |editor, cx| { + editor.clear_highlights(HighlightKey::MatchingBracket, cx); + if let Some(new_ranges) = new_ranges { editor.highlight_text( HighlightKey::MatchingBracket, - vec![ - opening_range.to_anchors(&buffer_snapshot), - closing_range.to_anchors(&buffer_snapshot), - ], + new_ranges, HighlightStyle { background_color: Some( cx.theme() @@ -60,8 +75,9 @@ impl Editor { }, cx, ) - }) - .ok(); + } + }) + .ok(); } } });