Fix shared element state across component instances
This commit is contained in:
@@ -13,7 +13,7 @@ use gpui::{
|
||||
use gpui_native_core::scrollbar::{Scrollbar, ScrollbarHandle, ScrollbarVisibility};
|
||||
use gpui_native_theme::{ActiveTheme as _, ColorTokens, Ramps};
|
||||
|
||||
use crate::highlight::{HighlightedCode, Language, Role, highlight_with_tree};
|
||||
use crate::highlight::{HighlightedCode, Language, Role, highlight};
|
||||
use crate::utils::{gutter_cell, run_style};
|
||||
|
||||
actions!(code_view, [Copy]);
|
||||
@@ -53,8 +53,6 @@ pub struct CodeViewState {
|
||||
source: SharedString,
|
||||
language: Language,
|
||||
code: HighlightedCode,
|
||||
/// The parse tree of `source`, so updates reparse incrementally instead of from scratch.
|
||||
tree: Option<tree_sitter::Tree>,
|
||||
handle: UniformListScrollHandle,
|
||||
/// The hovered line, driving the active-line wash and number emphasis.
|
||||
active_line: Option<usize>,
|
||||
@@ -74,14 +72,13 @@ impl CodeViewState {
|
||||
S: Into<SharedString>,
|
||||
{
|
||||
let source = source.into();
|
||||
let (code, tree) = highlight_with_tree(&source, language, None);
|
||||
let code = highlight(&source, language);
|
||||
|
||||
Self {
|
||||
id: id.into(),
|
||||
source,
|
||||
language,
|
||||
code,
|
||||
tree,
|
||||
handle: UniformListScrollHandle::new(),
|
||||
active_line: None,
|
||||
selection: None,
|
||||
@@ -98,18 +95,9 @@ impl CodeViewState {
|
||||
{
|
||||
let source = source.into();
|
||||
|
||||
// The old tree is only reusable when the grammar stays the same.
|
||||
let old_tree = if language == self.language {
|
||||
self.tree.as_ref()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let (code, tree) = highlight_with_tree(&source, language, old_tree);
|
||||
self.code = highlight(&source, language);
|
||||
self.source = source;
|
||||
self.language = language;
|
||||
self.code = code;
|
||||
self.tree = tree;
|
||||
self.selection = None;
|
||||
self.handle.scroll_to_item(0, ScrollStrategy::Top);
|
||||
|
||||
@@ -134,9 +122,7 @@ impl CodeViewState {
|
||||
lines.splice(line_ix..line_ix + 1, replacement);
|
||||
self.source = (lines.join("\n") + if trailing_newline { "\n" } else { "" }).into();
|
||||
|
||||
let (code, tree) = highlight_with_tree(&self.source, self.language, self.tree.as_ref());
|
||||
self.code = code;
|
||||
self.tree = tree;
|
||||
self.code = highlight(&self.source, self.language);
|
||||
self.selection = None;
|
||||
cx.notify();
|
||||
}
|
||||
@@ -348,7 +334,7 @@ impl Render for CodeViewState {
|
||||
code.position_at(
|
||||
*bounds,
|
||||
event.position,
|
||||
Pixels::ZERO,
|
||||
ScrollbarHandle::offset(&code.handle).y,
|
||||
line_height,
|
||||
char_width,
|
||||
text_x,
|
||||
@@ -453,7 +439,8 @@ impl Render for CodeViewState {
|
||||
)
|
||||
.child(rows)
|
||||
.child(
|
||||
Scrollbar::vertical(self.handle.clone()).visibility(ScrollbarVisibility::Platform),
|
||||
Scrollbar::vertical((self.id.clone(), "v-scrollbar"), self.handle.clone())
|
||||
.visibility(ScrollbarVisibility::Platform),
|
||||
)
|
||||
.when_some(self.a11y_label.clone(), |view, label| {
|
||||
view.aria_label(label)
|
||||
|
||||
@@ -363,13 +363,11 @@ impl Render for DiffViewState {
|
||||
})
|
||||
.child(rows)
|
||||
.child(
|
||||
Scrollbar::vertical(self.handle.clone())
|
||||
.key("v-scrollbar")
|
||||
Scrollbar::vertical((self.id.clone(), "v-scrollbar"), self.handle.clone())
|
||||
.visibility(ScrollbarVisibility::Platform),
|
||||
)
|
||||
.child(
|
||||
Scrollbar::horizontal(self.handle.clone())
|
||||
.key("h-scrollbar")
|
||||
Scrollbar::horizontal((self.id.clone(), "h-scrollbar"), self.handle.clone())
|
||||
.visibility(ScrollbarVisibility::Platform),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -67,17 +67,8 @@ pub struct HighlightedCode {
|
||||
|
||||
/// Highlights `source` with `language`'s tree-sitter grammar.
|
||||
pub fn highlight(source: &str, language: Language) -> HighlightedCode {
|
||||
highlight_with_tree(source, language, None).0
|
||||
}
|
||||
|
||||
/// Highlights `source`, reusing `old_tree` so only the changed region is re-lexed.
|
||||
pub fn highlight_with_tree(
|
||||
source: &str,
|
||||
language: Language,
|
||||
old_tree: Option<&tree_sitter::Tree>,
|
||||
) -> (HighlightedCode, Option<tree_sitter::Tree>) {
|
||||
let Some((grammar, query_source)) = grammar_for(language) else {
|
||||
return (plain(source), None);
|
||||
return plain(source);
|
||||
};
|
||||
|
||||
HIGHLIGHTERS.with(|cache| {
|
||||
@@ -104,11 +95,11 @@ pub fn highlight_with_tree(
|
||||
.as_mut();
|
||||
|
||||
let Some(highlighter) = highlighter else {
|
||||
return (plain(source), None);
|
||||
return plain(source);
|
||||
};
|
||||
|
||||
let Some(tree) = highlighter.parser.parse(source, old_tree) else {
|
||||
return (plain(source), None);
|
||||
let Some(tree) = highlighter.parser.parse(source, None) else {
|
||||
return plain(source);
|
||||
};
|
||||
|
||||
// One role per byte; matches arrive in query order
|
||||
@@ -134,7 +125,7 @@ pub fn highlight_with_tree(
|
||||
}
|
||||
}
|
||||
|
||||
(build_lines(source, &role_at), Some(tree))
|
||||
build_lines(source, &role_at)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ use pulldown_cmark::{CodeBlockKind, Event, HeadingLevel, Options, Parser, Tag, T
|
||||
|
||||
use std::ops::Range;
|
||||
|
||||
use crate::highlight::{HighlightedCode, highlight_with_tree, plain};
|
||||
use crate::highlight::{HighlightedCode, highlight, plain};
|
||||
use crate::utils::{code_line, grammar_language};
|
||||
|
||||
/// Heading scale steps relative to the root font size, H1 first.
|
||||
@@ -277,7 +277,8 @@ impl Render for MarkdownViewState {
|
||||
.size_full()
|
||||
.child(blocks)
|
||||
.child(
|
||||
Scrollbar::vertical(self.handle.clone()).visibility(ScrollbarVisibility::Platform),
|
||||
Scrollbar::vertical((self.id.clone(), "v-scrollbar"), self.handle.clone())
|
||||
.visibility(ScrollbarVisibility::Platform),
|
||||
)
|
||||
.when_some(self.a11y_label.clone(), |view, label| {
|
||||
view.aria_label(label)
|
||||
@@ -588,7 +589,7 @@ fn parse(source: &str, highlight_code: bool) -> Vec<MarkdownBlock> {
|
||||
.then(|| language.as_deref().and_then(grammar_language))
|
||||
.flatten()
|
||||
{
|
||||
Some(grammar) => highlight_with_tree(text, grammar, None).0,
|
||||
Some(grammar) => highlight(text, grammar),
|
||||
None => plain(text),
|
||||
};
|
||||
blocks.push(MarkdownBlock::Code {
|
||||
|
||||
Reference in New Issue
Block a user