diff --git a/crates/editor/src/bracket_colorization.rs b/crates/editor/src/bracket_colorization.rs index cba48402be0c81650a2a1e12af6fbbbbb744f2c4..7c377f5d38e2194e8058280bbaa908ec70d8d03b 100644 --- a/crates/editor/src/bracket_colorization.rs +++ b/crates/editor/src/bracket_colorization.rs @@ -48,7 +48,7 @@ impl Editor { } }) .filter_map(|pair| { - let id = pair.id?; + let id = pair.color_index?; let buffer_open_range = buffer_snapshot .anchor_before(pair.open_range.start) ..buffer_snapshot.anchor_after(pair.open_range.end); diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index b3d8fa4ea541417e8ab4560b721a771cc82f023c..eec7c7af009e3f2ec4bd2e5321d4c5bbd271aba6 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -31,6 +31,7 @@ use gpui::{ Task, TaskLabel, TextStyle, }; +use itertools::Itertools; use lsp::{LanguageServerId, NumberOrString}; use parking_lot::{Mutex, RawMutex, lock_api::MutexGuard}; use serde::{Deserialize, Serialize}; @@ -67,7 +68,7 @@ pub use text::{ use theme::{ActiveTheme as _, SyntaxTheme}; #[cfg(any(test, feature = "test-support"))] use util::RandomCharIter; -use util::{RangeExt, debug_panic, maybe, paths::PathStyle, post_inc, rel_path::RelPath}; +use util::{RangeExt, debug_panic, maybe, paths::PathStyle, rel_path::RelPath}; #[cfg(any(test, feature = "test-support"))] pub use {tree_sitter_python, tree_sitter_rust, tree_sitter_typescript}; @@ -850,7 +851,7 @@ pub struct BracketMatch { pub open_range: Range, pub close_range: Range, pub newline_only: bool, - pub id: Option, + pub color_index: Option, } impl BracketMatch { @@ -4203,23 +4204,7 @@ impl BufferSnapshot { let bracket_matches = match tree_sitter_data.brackets_by_chunks[chunk.id].take() { Some(cached_brackets) => cached_brackets, None => { - // Sequential IDs are needed to determine the color of the bracket pair. - let mut next_id = match tree_sitter_data.chunks.previous_chunk(chunk) { - Some(previous_chunk) => tree_sitter_data.brackets_by_chunks - [previous_chunk.id] - .as_ref() - .and_then(|previous_brackets| previous_brackets.last()) - // Try to continue previous sequence of IDs. - .and_then(|bracket| bracket.id.map(|id| id + 1)) - // If not possible, start another sequence: pick it far enough to avoid overlaps. - // - // This for sure will introduce the gaps between chunks' bracket IDs, - // but this will only potentially skip `mod(accents_number)` colors between chunks. - .unwrap_or_else(|| { - (usize::MAX / tree_sitter_data.chunks.len()) * chunk.id + 1 - }), - None => 0, - }; + let mut bracket_pairs_ends = Vec::new(); let mut matches = self.syntax .matches(chunk_range.clone(), &self.text, |grammar| { @@ -4257,18 +4242,30 @@ impl BufferSnapshot { continue; } - return Some(BracketMatch { - open_range, - close_range, - newline_only: pattern.newline_only, - id: pattern - .rainbow_exclude - .not() - .then(|| post_inc(&mut next_id)), - }); + return Some((open_range, close_range, pattern)); } None }) + .sorted_by_key(|(open_range, _, _)| open_range.start) + .map(|(open_range, close_range, pattern)| { + while let Some(&last_bracket_end) = bracket_pairs_ends.last() { + if last_bracket_end <= open_range.start { + bracket_pairs_ends.pop(); + } else { + break; + } + } + + let depth = bracket_pairs_ends.len(); + bracket_pairs_ends.push(close_range.end); + + BracketMatch { + open_range, + close_range, + newline_only: pattern.newline_only, + color_index: pattern.rainbow_exclude.not().then_some(depth), + } + }) .collect::>(); new_bracket_matches.insert(chunk.id, new_matches.clone()); diff --git a/docs/src/extensions/languages.md b/docs/src/extensions/languages.md index da4ceb345aff7cad26b8367a00845267977b1bde..f3ffcd71ba8122956636cd1d228f885383cb83e6 100644 --- a/docs/src/extensions/languages.md +++ b/docs/src/extensions/languages.md @@ -154,7 +154,7 @@ This query identifies opening and closing brackets, braces, and quotation marks. | @open | Captures opening brackets, braces, and quotes | | @close | Captures closing brackets, braces, and quotes | -Later, Zed will use those to highlight matching brackets: painting each bracket pair with a different color ("rainbow brackets") and highlighting the brackets if the cursor is inside the bracket pair. +Zed uses these to highlight matching brackets: painting each bracket pair with a different color ("rainbow brackets") and highlighting the brackets if the cursor is inside the bracket pair. To opt out of rainbow brackets colorization, add the following to the corresponding `brackets.scm` entry: