From 54ccd81c0d489c574b1bf827f502b6850ae990d5 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 7 Nov 2025 16:25:28 +0200 Subject: [PATCH] Properly invalidate the brackets --- crates/editor/src/bracket_colorization.rs | 8 ++-- crates/editor/src/editor.rs | 57 ++++++++++++++++++----- crates/editor/src/scroll.rs | 2 +- crates/language/src/language_settings.rs | 10 ++-- 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/crates/editor/src/bracket_colorization.rs b/crates/editor/src/bracket_colorization.rs index cee4f62d9ad47c75875cb264c0db62c711e382e1..6077b2f159cd4d3eba8dce835adcd4450b3c1c67 100644 --- a/crates/editor/src/bracket_colorization.rs +++ b/crates/editor/src/bracket_colorization.rs @@ -7,7 +7,7 @@ use ui::{ActiveTheme, utils::ensure_minimum_contrast}; struct RainbowBracketHighlight; impl Editor { - pub(crate) fn colorize_brackets(&mut self, cx: &mut Context) { + pub(crate) fn colorize_brackets(&mut self, invalidate: bool, cx: &mut Context) { if !self.mode.is_full() { return; } @@ -59,8 +59,10 @@ impl Editor { .flatten() .into_group_map_by(|&(depth, ..)| depth); - // todo! this is not necessary needed, e.g. after scrolling - self.clear_highlights::(cx); + if invalidate { + self.clear_highlights::(cx); + } + let editor_background = cx.theme().colors().editor_background; for (depth, bracket_highlights) in bracket_matches { let bracket_color = cx.theme().accents().color_for_index(depth as u32); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 3cfe9f7744f4a5938fb5fe56e978e4a8813f7af2..337b71297f47c715726ed7aa32dd267aafd0f0a9 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -118,11 +118,11 @@ use language::{ AutoindentMode, BlockCommentConfig, BracketMatch, BracketPair, Buffer, BufferRow, BufferSnapshot, Capability, CharClassifier, CharKind, CharScopeContext, CodeLabel, CursorShape, DiagnosticEntryRef, DiffOptions, EditPredictionsMode, EditPreview, HighlightedText, IndentKind, - IndentSize, Language, OffsetRangeExt, Point, Runnable, RunnableRange, Selection, SelectionGoal, - TextObject, TransactionId, TreeSitterOptions, WordsQuery, + IndentSize, Language, LanguageName, OffsetRangeExt, Point, Runnable, RunnableRange, Selection, + SelectionGoal, TextObject, TransactionId, TreeSitterOptions, WordsQuery, language_settings::{ - self, LspInsertMode, RewrapBehavior, WordsCompletionMode, all_language_settings, - language_settings, + self, LanguageSettings, LspInsertMode, RewrapBehavior, WordsCompletionMode, + all_language_settings, language_settings, }, point_from_lsp, point_to_lsp, text_diff_with_options, }; @@ -175,6 +175,7 @@ use std::{ borrow::Cow, cell::{OnceCell, RefCell}, cmp::{self, Ordering, Reverse}, + collections::hash_map, iter::{self, Peekable}, mem, num::NonZeroU32, @@ -1197,6 +1198,7 @@ pub struct Editor { inlay_hints: Option, folding_newlines: Task<()>, pub lookup_key: Option>, + applicable_language_settings: HashMap, LanguageSettings>, } fn debounce_value(debounce_ms: u64) -> Option { @@ -2294,12 +2296,15 @@ impl Editor { selection_drag_state: SelectionDragState::None, folding_newlines: Task::ready(()), lookup_key: None, + applicable_language_settings: HashMap::default(), }; if is_minimap { return editor; } + editor.applicable_language_settings = editor.fetch_applicable_language_settings(cx); + if let Some(breakpoints) = editor.breakpoint_store.as_ref() { editor ._subscriptions @@ -2353,7 +2358,7 @@ impl Editor { editor.refresh_colors_for_visible_range(None, window, cx); editor .refresh_inlay_hints(InlayHintRefreshReason::NewLinesShown, cx); - editor.colorize_brackets(cx); + editor.colorize_brackets(false, cx); }) .ok(); }); @@ -3243,7 +3248,7 @@ impl Editor { refresh_linked_ranges(self, window, cx); self.refresh_selected_text_highlights(false, window, cx); - self.colorize_brackets(cx); + self.colorize_brackets(false, cx); self.refresh_matching_bracket_highlights(window, cx); self.update_visible_edit_prediction(window, cx); self.edit_prediction_requires_modifier_in_indent_conflict = true; @@ -21030,7 +21035,7 @@ impl Editor { self.refresh_code_actions(window, cx); self.refresh_selected_text_highlights(true, window, cx); self.refresh_single_line_folds(window, cx); - self.colorize_brackets(cx); + self.colorize_brackets(true, cx); self.refresh_matching_bracket_highlights(window, cx); if self.has_active_edit_prediction() { self.update_visible_edit_prediction(window, cx); @@ -21085,7 +21090,7 @@ impl Editor { } self.update_lsp_data(Some(buffer_id), window, cx); self.refresh_inlay_hints(InlayHintRefreshReason::NewLinesShown, cx); - self.colorize_brackets(cx); + self.colorize_brackets(false, cx); cx.emit(EditorEvent::ExcerptsAdded { buffer: buffer.clone(), predecessor: *predecessor, @@ -21123,12 +21128,12 @@ impl Editor { multi_buffer::Event::ExcerptsExpanded { ids } => { self.refresh_inlay_hints(InlayHintRefreshReason::NewLinesShown, cx); self.refresh_document_highlights(cx); - self.colorize_brackets(cx); + self.colorize_brackets(false, cx); cx.emit(EditorEvent::ExcerptsExpanded { ids: ids.clone() }) } multi_buffer::Event::Reparsed(buffer_id) => { self.tasks_update_task = Some(self.refresh_runnables(window, cx)); - self.colorize_brackets(cx); + self.colorize_brackets(true, cx); jsx_tag_auto_close::refresh_enabled_in_any_buffer(self, multibuffer, cx); cx.emit(EditorEvent::Reparsed(*buffer_id)); @@ -21199,7 +21204,35 @@ impl Editor { cx.notify(); } + fn fetch_applicable_language_settings( + &self, + cx: &App, + ) -> HashMap, LanguageSettings> { + if !self.mode.is_full() { + return HashMap::default(); + } + + self.buffer().read(cx).all_buffers().into_iter().fold( + HashMap::default(), + |mut acc, buffer| { + let buffer = buffer.read(cx); + let language = buffer.language().map(|language| language.name()); + if let hash_map::Entry::Vacant(v) = acc.entry(language.clone()) { + let file = buffer.file(); + v.insert(language_settings(language, file, cx).into_owned()); + } + acc + }, + ) + } + fn settings_changed(&mut self, window: &mut Window, cx: &mut Context) { + let new_language_settings = self.fetch_applicable_language_settings(cx); + let language_settings_changed = new_language_settings != self.applicable_language_settings; + if language_settings_changed { + self.applicable_language_settings = new_language_settings; + } + if self.diagnostics_enabled() { let new_severity = EditorSettings::get_global(cx) .diagnostics_max_severity @@ -21272,7 +21305,9 @@ impl Editor { } } - self.colorize_brackets(cx); + if language_settings_changed { + self.colorize_brackets(true, cx); + } if let Some(inlay_splice) = self.colors.as_mut().and_then(|colors| { colors.render_mode_updated(EditorSettings::get_global(cx).lsp_document_colors) diff --git a/crates/editor/src/scroll.rs b/crates/editor/src/scroll.rs index 1f443d9909a9b410047ab71b8ee9798c0f9aa22c..a92735d18617057ddd10f049e5a22525827e1874 100644 --- a/crates/editor/src/scroll.rs +++ b/crates/editor/src/scroll.rs @@ -500,7 +500,7 @@ impl Editor { editor.register_visible_buffers(cx); editor.refresh_inlay_hints(InlayHintRefreshReason::NewLinesShown, cx); editor.update_lsp_data(None, window, cx); - editor.colorize_brackets(cx); + editor.colorize_brackets(false, cx); }) .ok(); }); diff --git a/crates/language/src/language_settings.rs b/crates/language/src/language_settings.rs index b95488b357898f27d28dc2e3fbaf5e9131ab67d9..6b7575b513afcf75f0d9932d28e65fc495eb69e7 100644 --- a/crates/language/src/language_settings.rs +++ b/crates/language/src/language_settings.rs @@ -59,14 +59,14 @@ pub struct AllLanguageSettings { pub(crate) file_types: FxHashMap, GlobSet>, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct WhitespaceMap { pub space: SharedString, pub tab: SharedString, } /// The settings for a particular language. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct LanguageSettings { /// How many columns a tab should occupy. pub tab_size: NonZeroU32, @@ -162,7 +162,7 @@ pub struct LanguageSettings { pub colorize_brackets: bool, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct CompletionSettings { /// Controls how words are completed. /// For large documents, not all words may be fetched for completion. @@ -214,7 +214,7 @@ pub struct IndentGuideSettings { pub background_coloring: settings::IndentGuideBackgroundColoring, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct LanguageTaskSettings { /// Extra task variables to set for a particular language. pub variables: HashMap, @@ -232,7 +232,7 @@ pub struct LanguageTaskSettings { /// Allows to enable/disable formatting with Prettier /// and configure default Prettier, used when no project-level Prettier installation is found. /// Prettier formatting is disabled by default. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct PrettierSettings { /// Enables or disables formatting with Prettier for a given language. pub allowed: bool,