highlighter: Fix highlight offset and reset highlight when replace all text. (#950)

- Improve JSON highlights.

<img width="839" alt="image"
src="https://github.com/user-attachments/assets/3f28ae1c-9f07-4df4-a477-f875a26d4c7d"
/>
This commit is contained in:
Jason Lee 2025-06-12 14:11:01 +08:00 committed by GitHub
parent 2febe2611b
commit d61b0d2510
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 73 additions and 8 deletions

View file

@ -47,7 +47,7 @@ impl Lang {
} }
} }
const LANGUAGES: [(Lang, &'static str); 9] = [ const LANGUAGES: [(Lang, &'static str); 10] = [
( (
Lang::BuiltIn(Language::Rust), Lang::BuiltIn(Language::Rust),
include_str!("./fixtures/test.rs"), include_str!("./fixtures/test.rs"),
@ -80,6 +80,10 @@ const LANGUAGES: [(Lang, &'static str); 9] = [
Lang::BuiltIn(Language::Sql), Lang::BuiltIn(Language::Sql),
include_str!("./fixtures/test.sql"), include_str!("./fixtures/test.sql"),
), ),
(
Lang::BuiltIn(Language::Json),
include_str!("./fixtures/test.json"),
),
(Lang::External("navi"), include_str!("./fixtures/test.nv")), (Lang::External("navi"), include_str!("./fixtures/test.nv")),
]; ];

View file

@ -0,0 +1,11 @@
[
{
"name": "GPUI Component",
"description": "UI components for building fantastic desktop application by using GPUI.",
"license": "Apache-2.0",
"keywords": ["UI", "desktop", "application"],
"stars": 3000,
"public": true,
"repository": "https://github.com/longbridge/gpui-component"
}
]

View file

@ -308,12 +308,14 @@ impl SyntaxHighlighter {
for (start, (old_range, highlight_name)) in old_cache.into_iter() { for (start, (old_range, highlight_name)) in old_cache.into_iter() {
if old_range.end >= byte_range.start { if old_range.end >= byte_range.start {
let new_range = Range { let new_range = Range {
start: (old_range.start as isize + changed_len) as usize, start: (old_range.start as isize + changed_len).max(0) as usize,
end: (old_range.end as isize + changed_len) as usize, end: (old_range.end as isize + changed_len).max(0) as usize,
}; };
self.cache if new_range.len() > 0 {
.insert(new_range.start, (new_range, highlight_name)); self.cache
.insert(new_range.start, (new_range, highlight_name));
}
} else { } else {
self.cache.insert(start, (old_range, highlight_name)); self.cache.insert(start, (old_range, highlight_name));
} }
@ -365,6 +367,14 @@ impl SyntaxHighlighter {
last_range.start, last_range.start,
(last_range.start..node_range.end, highlight_name.clone()), (last_range.start..node_range.end, highlight_name.clone()),
); );
} else if last_range == &node_range {
// case:
// last_range: 213..220, last_highlight_name: Some("property")
// last_range: 213..220, last_highlight_name: Some("string")
self.cache.insert(
node_range.start,
(node_range, last_highlight_name.unwrap_or(highlight_name)),
);
} else { } else {
self.cache self.cache
.insert(node_range.start, (node_range, highlight_name.clone())); .insert(node_range.start, (node_range, highlight_name.clone()));
@ -581,7 +591,7 @@ impl SyntaxHighlighter {
let styles = unique_styles(styles); let styles = unique_styles(styles);
// NOTE: DO NOT remove this comment, it is used for debugging. // NOTE: DO NOT remove this comment, it is used for debugging.
// for style in &result { // for style in &styles {
// println!("---- style: {:?} - {:?}", style.0, style.1.color); // println!("---- style: {:?} - {:?}", style.0, style.1.color);
// } // }
// println!("--------------------------------"); // println!("--------------------------------");

View file

@ -184,7 +184,7 @@ impl Language {
let (language, query, injection, locals) = match self { let (language, query, injection, locals) = match self {
Self::Json => ( Self::Json => (
tree_sitter_json::LANGUAGE, tree_sitter_json::LANGUAGE,
tree_sitter_json::HIGHLIGHTS_QUERY, include_str!("languages/json/highlights.scm"),
"", "",
"", "",
), ),

View file

@ -0,0 +1,24 @@
(comment) @comment
(string) @string
(escape_sequence) @string.escape
(number) @number
(pair key: (string) @property)
[
(true)
(false)
] @boolean
(null) @constant.builtin
[
","
":"
"{"
"}"
"["
"]"
] @punctuation

View file

@ -155,6 +155,11 @@
"font_style": null, "font_style": null,
"font_weight": null "font_weight": null
}, },
"property": {
"color": "#CACCCA",
"font_style": null,
"font_weight": null
},
"variable.special": { "variable.special": {
"color": "#E19773", "color": "#E19773",
"font_style": null, "font_style": null,
@ -162,4 +167,4 @@
} }
} }
} }
} }

View file

@ -477,6 +477,16 @@ impl InputState {
cx.notify(); cx.notify();
} }
fn reset_highlighter(&mut self, cx: &mut Context<Self>) {
match &mut self.mode {
InputMode::CodeEditor { highlighter, .. } => {
*highlighter.borrow_mut() = None;
}
_ => {}
}
cx.notify();
}
/// Set markers, only for [`InputMode::CodeEditor`] mode. /// Set markers, only for [`InputMode::CodeEditor`] mode.
/// ///
/// For example to set the diagnostic markers in the code editor. /// For example to set the diagnostic markers in the code editor.
@ -715,6 +725,7 @@ impl InputState {
let text: SharedString = text.into(); let text: SharedString = text.into();
let range = 0..self.text.chars().map(|c| c.len_utf16()).sum(); let range = 0..self.text.chars().map(|c| c.len_utf16()).sum();
self.replace_text_in_range(Some(range), &text, window, cx); self.replace_text_in_range(Some(range), &text, window, cx);
self.reset_highlighter(cx);
} }
/// Set with disabled mode. /// Set with disabled mode.