Further improve color inlay hints in multi buffers (#33642)
Follow-up of https://github.com/zed-industries/zed/pull/33605 Release Notes: - N/A
This commit is contained in:
parent
ac3328adb6
commit
ae6237178c
7 changed files with 230 additions and 128 deletions
|
@ -37,7 +37,9 @@ pub use block_map::{
|
|||
use block_map::{BlockRow, BlockSnapshot};
|
||||
use collections::{HashMap, HashSet};
|
||||
pub use crease_map::*;
|
||||
pub use fold_map::{ChunkRenderer, ChunkRendererContext, Fold, FoldId, FoldPlaceholder, FoldPoint};
|
||||
pub use fold_map::{
|
||||
ChunkRenderer, ChunkRendererContext, ChunkRendererId, Fold, FoldId, FoldPlaceholder, FoldPoint,
|
||||
};
|
||||
use fold_map::{FoldMap, FoldSnapshot};
|
||||
use gpui::{App, Context, Entity, Font, HighlightStyle, LineLayout, Pixels, UnderlineStyle};
|
||||
pub use inlay_map::Inlay;
|
||||
|
@ -538,7 +540,7 @@ impl DisplayMap {
|
|||
|
||||
pub fn update_fold_widths(
|
||||
&mut self,
|
||||
widths: impl IntoIterator<Item = (FoldId, Pixels)>,
|
||||
widths: impl IntoIterator<Item = (ChunkRendererId, Pixels)>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> bool {
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::display_map::inlay_map::InlayChunk;
|
||||
use crate::{InlayId, display_map::inlay_map::InlayChunk};
|
||||
|
||||
use super::{
|
||||
Highlights,
|
||||
|
@ -277,13 +277,16 @@ impl FoldMapWriter<'_> {
|
|||
|
||||
pub(crate) fn update_fold_widths(
|
||||
&mut self,
|
||||
new_widths: impl IntoIterator<Item = (FoldId, Pixels)>,
|
||||
new_widths: impl IntoIterator<Item = (ChunkRendererId, Pixels)>,
|
||||
) -> (FoldSnapshot, Vec<FoldEdit>) {
|
||||
let mut edits = Vec::new();
|
||||
let inlay_snapshot = self.0.snapshot.inlay_snapshot.clone();
|
||||
let buffer = &inlay_snapshot.buffer;
|
||||
|
||||
for (id, new_width) in new_widths {
|
||||
let ChunkRendererId::Fold(id) = id else {
|
||||
continue;
|
||||
};
|
||||
if let Some(metadata) = self.0.snapshot.fold_metadata_by_id.get(&id).cloned() {
|
||||
if Some(new_width) != metadata.width {
|
||||
let buffer_start = metadata.range.start.to_offset(buffer);
|
||||
|
@ -529,7 +532,7 @@ impl FoldMap {
|
|||
placeholder: Some(TransformPlaceholder {
|
||||
text: ELLIPSIS,
|
||||
renderer: ChunkRenderer {
|
||||
id: fold.id,
|
||||
id: ChunkRendererId::Fold(fold.id),
|
||||
render: Arc::new(move |cx| {
|
||||
(fold.placeholder.render)(
|
||||
fold_id,
|
||||
|
@ -1267,11 +1270,17 @@ pub struct Chunk<'a> {
|
|||
pub renderer: Option<ChunkRenderer>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum ChunkRendererId {
|
||||
Fold(FoldId),
|
||||
Inlay(InlayId),
|
||||
}
|
||||
|
||||
/// A recipe for how the chunk should be presented.
|
||||
#[derive(Clone)]
|
||||
pub struct ChunkRenderer {
|
||||
/// The id of the fold associated with this chunk.
|
||||
pub id: FoldId,
|
||||
/// The id of the renderer associated with this chunk.
|
||||
pub id: ChunkRendererId,
|
||||
/// Creates a custom element to represent this chunk.
|
||||
pub render: Arc<dyn Send + Sync + Fn(&mut ChunkRendererContext) -> AnyElement>,
|
||||
/// If true, the element is constrained to the shaped width of the text.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{ChunkRenderer, HighlightStyles, InlayId, display_map::FoldId};
|
||||
use crate::{ChunkRenderer, HighlightStyles, InlayId};
|
||||
use collections::BTreeSet;
|
||||
use gpui::{Hsla, Rgba};
|
||||
use language::{Chunk, Edit, Point, TextSummary};
|
||||
|
@ -14,7 +14,7 @@ use sum_tree::{Bias, Cursor, SumTree};
|
|||
use text::{Patch, Rope};
|
||||
use ui::{ActiveTheme, IntoElement as _, ParentElement as _, Styled as _, div};
|
||||
|
||||
use super::{Highlights, custom_highlights::CustomHighlightsChunks};
|
||||
use super::{Highlights, custom_highlights::CustomHighlightsChunks, fold_map::ChunkRendererId};
|
||||
|
||||
/// Decides where the [`Inlay`]s should be displayed.
|
||||
///
|
||||
|
@ -338,10 +338,10 @@ impl<'a> Iterator for InlayChunks<'a> {
|
|||
}
|
||||
InlayId::Hint(_) => self.highlight_styles.inlay_hint,
|
||||
InlayId::DebuggerValue(_) => self.highlight_styles.inlay_hint,
|
||||
InlayId::Color(id) => {
|
||||
InlayId::Color(_) => {
|
||||
if let Some(color) = inlay.color {
|
||||
renderer = Some(ChunkRenderer {
|
||||
id: FoldId(id),
|
||||
id: ChunkRendererId::Inlay(inlay.id),
|
||||
render: Arc::new(move |cx| {
|
||||
div()
|
||||
.w_4()
|
||||
|
|
|
@ -17333,9 +17333,9 @@ impl Editor {
|
|||
self.active_indent_guides_state.dirty = true;
|
||||
}
|
||||
|
||||
pub fn update_fold_widths(
|
||||
pub fn update_renderer_widths(
|
||||
&mut self,
|
||||
widths: impl IntoIterator<Item = (FoldId, Pixels)>,
|
||||
widths: impl IntoIterator<Item = (ChunkRendererId, Pixels)>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> bool {
|
||||
self.display_map
|
||||
|
|
|
@ -12,8 +12,8 @@ use crate::{
|
|||
ToggleFold,
|
||||
code_context_menus::{CodeActionsMenu, MENU_ASIDE_MAX_WIDTH, MENU_ASIDE_MIN_WIDTH, MENU_GAP},
|
||||
display_map::{
|
||||
Block, BlockContext, BlockStyle, DisplaySnapshot, EditorMargins, FoldId, HighlightKey,
|
||||
HighlightedChunk, ToDisplayPoint,
|
||||
Block, BlockContext, BlockStyle, ChunkRendererId, DisplaySnapshot, EditorMargins,
|
||||
HighlightKey, HighlightedChunk, ToDisplayPoint,
|
||||
},
|
||||
editor_settings::{
|
||||
CurrentLineHighlight, DocumentColorsRenderMode, DoubleClickInMultibuffer, Minimap,
|
||||
|
@ -7119,7 +7119,7 @@ pub(crate) struct LineWithInvisibles {
|
|||
enum LineFragment {
|
||||
Text(ShapedLine),
|
||||
Element {
|
||||
id: FoldId,
|
||||
id: ChunkRendererId,
|
||||
element: Option<AnyElement>,
|
||||
size: Size<Pixels>,
|
||||
len: usize,
|
||||
|
@ -8297,7 +8297,7 @@ impl Element for EditorElement {
|
|||
window,
|
||||
cx,
|
||||
);
|
||||
let new_fold_widths = line_layouts
|
||||
let new_renrerer_widths = line_layouts
|
||||
.iter()
|
||||
.flat_map(|layout| &layout.fragments)
|
||||
.filter_map(|fragment| {
|
||||
|
@ -8308,7 +8308,7 @@ impl Element for EditorElement {
|
|||
}
|
||||
});
|
||||
if self.editor.update(cx, |editor, cx| {
|
||||
editor.update_fold_widths(new_fold_widths, cx)
|
||||
editor.update_renderer_widths(new_renrerer_widths, cx)
|
||||
}) {
|
||||
// If the fold widths have changed, we need to prepaint
|
||||
// the element again to account for any changes in
|
||||
|
|
|
@ -19,18 +19,21 @@ use crate::{
|
|||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct LspColorData {
|
||||
cache_version_used: usize,
|
||||
buffer_colors: HashMap<BufferId, BufferColors>,
|
||||
render_mode: DocumentColorsRenderMode,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct BufferColors {
|
||||
colors: Vec<(Range<Anchor>, DocumentColor, InlayId)>,
|
||||
inlay_colors: HashMap<InlayId, usize>,
|
||||
render_mode: DocumentColorsRenderMode,
|
||||
cache_version_used: usize,
|
||||
}
|
||||
|
||||
impl LspColorData {
|
||||
pub fn new(cx: &App) -> Self {
|
||||
Self {
|
||||
cache_version_used: 0,
|
||||
colors: Vec::new(),
|
||||
inlay_colors: HashMap::default(),
|
||||
buffer_colors: HashMap::default(),
|
||||
render_mode: EditorSettings::get_global(cx).lsp_document_colors,
|
||||
}
|
||||
}
|
||||
|
@ -47,8 +50,9 @@ impl LspColorData {
|
|||
DocumentColorsRenderMode::Inlay => Some(InlaySplice {
|
||||
to_remove: Vec::new(),
|
||||
to_insert: self
|
||||
.colors
|
||||
.buffer_colors
|
||||
.iter()
|
||||
.flat_map(|(_, buffer_colors)| buffer_colors.colors.iter())
|
||||
.map(|(range, color, id)| {
|
||||
Inlay::color(
|
||||
id.id(),
|
||||
|
@ -63,33 +67,49 @@ impl LspColorData {
|
|||
})
|
||||
.collect(),
|
||||
}),
|
||||
DocumentColorsRenderMode::None => {
|
||||
self.colors.clear();
|
||||
Some(InlaySplice {
|
||||
to_remove: self.inlay_colors.drain().map(|(id, _)| id).collect(),
|
||||
to_insert: Vec::new(),
|
||||
})
|
||||
}
|
||||
DocumentColorsRenderMode::None => Some(InlaySplice {
|
||||
to_remove: self
|
||||
.buffer_colors
|
||||
.drain()
|
||||
.flat_map(|(_, buffer_colors)| buffer_colors.inlay_colors)
|
||||
.map(|(id, _)| id)
|
||||
.collect(),
|
||||
to_insert: Vec::new(),
|
||||
}),
|
||||
DocumentColorsRenderMode::Border | DocumentColorsRenderMode::Background => {
|
||||
Some(InlaySplice {
|
||||
to_remove: self.inlay_colors.drain().map(|(id, _)| id).collect(),
|
||||
to_remove: self
|
||||
.buffer_colors
|
||||
.iter_mut()
|
||||
.flat_map(|(_, buffer_colors)| buffer_colors.inlay_colors.drain())
|
||||
.map(|(id, _)| id)
|
||||
.collect(),
|
||||
to_insert: Vec::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_colors(&mut self, colors: Vec<(Range<Anchor>, DocumentColor, InlayId)>) -> bool {
|
||||
if self.colors == colors {
|
||||
fn set_colors(
|
||||
&mut self,
|
||||
buffer_id: BufferId,
|
||||
colors: Vec<(Range<Anchor>, DocumentColor, InlayId)>,
|
||||
cache_version: Option<usize>,
|
||||
) -> bool {
|
||||
let buffer_colors = self.buffer_colors.entry(buffer_id).or_default();
|
||||
if let Some(cache_version) = cache_version {
|
||||
buffer_colors.cache_version_used = cache_version;
|
||||
}
|
||||
if buffer_colors.colors == colors {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.inlay_colors = colors
|
||||
buffer_colors.inlay_colors = colors
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, (_, _, id))| (*id, i))
|
||||
.collect();
|
||||
self.colors = colors;
|
||||
buffer_colors.colors = colors;
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -103,8 +123,9 @@ impl LspColorData {
|
|||
{
|
||||
Vec::new()
|
||||
} else {
|
||||
self.colors
|
||||
self.buffer_colors
|
||||
.iter()
|
||||
.flat_map(|(_, buffer_colors)| &buffer_colors.colors)
|
||||
.map(|(range, color, _)| {
|
||||
let display_range = range.clone().to_display_points(snapshot);
|
||||
let color = Hsla::from(Rgba {
|
||||
|
@ -162,10 +183,9 @@ impl Editor {
|
|||
ColorFetchStrategy::IgnoreCache
|
||||
} else {
|
||||
ColorFetchStrategy::UseCache {
|
||||
known_cache_version: self
|
||||
.colors
|
||||
.as_ref()
|
||||
.map(|colors| colors.cache_version_used),
|
||||
known_cache_version: self.colors.as_ref().and_then(|colors| {
|
||||
Some(colors.buffer_colors.get(&buffer_id)?.cache_version_used)
|
||||
}),
|
||||
}
|
||||
};
|
||||
let colors_task = lsp_store.document_colors(fetch_strategy, buffer, cx)?;
|
||||
|
@ -201,15 +221,13 @@ impl Editor {
|
|||
return;
|
||||
};
|
||||
|
||||
let mut cache_version = None;
|
||||
let mut new_editor_colors = Vec::<(Range<Anchor>, DocumentColor)>::new();
|
||||
let mut new_editor_colors = HashMap::default();
|
||||
for (buffer_id, colors) in all_colors {
|
||||
let Some(excerpts) = editor_excerpts.get(&buffer_id) else {
|
||||
continue;
|
||||
};
|
||||
match colors {
|
||||
Ok(colors) => {
|
||||
cache_version = colors.cache_version;
|
||||
for color in colors.colors {
|
||||
let color_start = point_from_lsp(color.lsp_range.start);
|
||||
let color_end = point_from_lsp(color.lsp_range.end);
|
||||
|
@ -243,8 +261,15 @@ impl Editor {
|
|||
continue;
|
||||
};
|
||||
|
||||
let new_entry =
|
||||
new_editor_colors.entry(buffer_id).or_insert_with(|| {
|
||||
(Vec::<(Range<Anchor>, DocumentColor)>::new(), None)
|
||||
});
|
||||
new_entry.1 = colors.cache_version;
|
||||
let new_buffer_colors = &mut new_entry.0;
|
||||
|
||||
let (Ok(i) | Err(i)) =
|
||||
new_editor_colors.binary_search_by(|(probe, _)| {
|
||||
new_buffer_colors.binary_search_by(|(probe, _)| {
|
||||
probe
|
||||
.start
|
||||
.cmp(&color_start_anchor, &multi_buffer_snapshot)
|
||||
|
@ -254,7 +279,7 @@ impl Editor {
|
|||
.cmp(&color_end_anchor, &multi_buffer_snapshot)
|
||||
})
|
||||
});
|
||||
new_editor_colors
|
||||
new_buffer_colors
|
||||
.insert(i, (color_start_anchor..color_end_anchor, color));
|
||||
break;
|
||||
}
|
||||
|
@ -267,45 +292,70 @@ impl Editor {
|
|||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
let mut colors_splice = InlaySplice::default();
|
||||
let mut new_color_inlays = Vec::with_capacity(new_editor_colors.len());
|
||||
let Some(colors) = &mut editor.colors else {
|
||||
return;
|
||||
};
|
||||
let mut existing_colors = colors.colors.iter().peekable();
|
||||
for (new_range, new_color) in new_editor_colors {
|
||||
let rgba_color = Rgba {
|
||||
r: new_color.color.red,
|
||||
g: new_color.color.green,
|
||||
b: new_color.color.blue,
|
||||
a: new_color.color.alpha,
|
||||
};
|
||||
let mut updated = false;
|
||||
for (buffer_id, (new_buffer_colors, new_cache_version)) in new_editor_colors {
|
||||
let mut new_buffer_color_inlays =
|
||||
Vec::with_capacity(new_buffer_colors.len());
|
||||
let mut existing_buffer_colors = colors
|
||||
.buffer_colors
|
||||
.entry(buffer_id)
|
||||
.or_default()
|
||||
.colors
|
||||
.iter()
|
||||
.peekable();
|
||||
for (new_range, new_color) in new_buffer_colors {
|
||||
let rgba_color = Rgba {
|
||||
r: new_color.color.red,
|
||||
g: new_color.color.green,
|
||||
b: new_color.color.blue,
|
||||
a: new_color.color.alpha,
|
||||
};
|
||||
|
||||
loop {
|
||||
match existing_colors.peek() {
|
||||
Some((existing_range, existing_color, existing_inlay_id)) => {
|
||||
match existing_range
|
||||
.start
|
||||
.cmp(&new_range.start, &multi_buffer_snapshot)
|
||||
.then_with(|| {
|
||||
existing_range
|
||||
.end
|
||||
.cmp(&new_range.end, &multi_buffer_snapshot)
|
||||
}) {
|
||||
cmp::Ordering::Less => {
|
||||
colors_splice.to_remove.push(*existing_inlay_id);
|
||||
existing_colors.next();
|
||||
continue;
|
||||
}
|
||||
cmp::Ordering::Equal => {
|
||||
if existing_color == &new_color {
|
||||
new_color_inlays.push((
|
||||
new_range,
|
||||
new_color,
|
||||
*existing_inlay_id,
|
||||
));
|
||||
} else {
|
||||
loop {
|
||||
match existing_buffer_colors.peek() {
|
||||
Some((existing_range, existing_color, existing_inlay_id)) => {
|
||||
match existing_range
|
||||
.start
|
||||
.cmp(&new_range.start, &multi_buffer_snapshot)
|
||||
.then_with(|| {
|
||||
existing_range
|
||||
.end
|
||||
.cmp(&new_range.end, &multi_buffer_snapshot)
|
||||
}) {
|
||||
cmp::Ordering::Less => {
|
||||
colors_splice.to_remove.push(*existing_inlay_id);
|
||||
existing_buffer_colors.next();
|
||||
continue;
|
||||
}
|
||||
cmp::Ordering::Equal => {
|
||||
if existing_color == &new_color {
|
||||
new_buffer_color_inlays.push((
|
||||
new_range,
|
||||
new_color,
|
||||
*existing_inlay_id,
|
||||
));
|
||||
} else {
|
||||
colors_splice
|
||||
.to_remove
|
||||
.push(*existing_inlay_id);
|
||||
|
||||
let inlay = Inlay::color(
|
||||
post_inc(&mut editor.next_color_inlay_id),
|
||||
new_range.start,
|
||||
rgba_color,
|
||||
);
|
||||
let inlay_id = inlay.id;
|
||||
colors_splice.to_insert.push(inlay);
|
||||
new_buffer_color_inlays
|
||||
.push((new_range, new_color, inlay_id));
|
||||
}
|
||||
existing_buffer_colors.next();
|
||||
break;
|
||||
}
|
||||
cmp::Ordering::Greater => {
|
||||
let inlay = Inlay::color(
|
||||
post_inc(&mut editor.next_color_inlay_id),
|
||||
new_range.start,
|
||||
|
@ -313,49 +363,40 @@ impl Editor {
|
|||
);
|
||||
let inlay_id = inlay.id;
|
||||
colors_splice.to_insert.push(inlay);
|
||||
new_color_inlays
|
||||
new_buffer_color_inlays
|
||||
.push((new_range, new_color, inlay_id));
|
||||
break;
|
||||
}
|
||||
existing_colors.next();
|
||||
break;
|
||||
}
|
||||
cmp::Ordering::Greater => {
|
||||
let inlay = Inlay::color(
|
||||
post_inc(&mut editor.next_color_inlay_id),
|
||||
new_range.start,
|
||||
rgba_color,
|
||||
);
|
||||
let inlay_id = inlay.id;
|
||||
colors_splice.to_insert.push(inlay);
|
||||
new_color_inlays.push((new_range, new_color, inlay_id));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let inlay = Inlay::color(
|
||||
post_inc(&mut editor.next_color_inlay_id),
|
||||
new_range.start,
|
||||
rgba_color,
|
||||
);
|
||||
let inlay_id = inlay.id;
|
||||
colors_splice.to_insert.push(inlay);
|
||||
new_color_inlays.push((new_range, new_color, inlay_id));
|
||||
break;
|
||||
None => {
|
||||
let inlay = Inlay::color(
|
||||
post_inc(&mut editor.next_color_inlay_id),
|
||||
new_range.start,
|
||||
rgba_color,
|
||||
);
|
||||
let inlay_id = inlay.id;
|
||||
colors_splice.to_insert.push(inlay);
|
||||
new_buffer_color_inlays
|
||||
.push((new_range, new_color, inlay_id));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if existing_colors.peek().is_some() {
|
||||
colors_splice
|
||||
.to_remove
|
||||
.extend(existing_colors.map(|(_, _, id)| *id));
|
||||
|
||||
if existing_buffer_colors.peek().is_some() {
|
||||
colors_splice
|
||||
.to_remove
|
||||
.extend(existing_buffer_colors.map(|(_, _, id)| *id));
|
||||
}
|
||||
updated |= colors.set_colors(
|
||||
buffer_id,
|
||||
new_buffer_color_inlays,
|
||||
new_cache_version,
|
||||
);
|
||||
}
|
||||
|
||||
let mut updated = colors.set_colors(new_color_inlays);
|
||||
if let Some(cache_version) = cache_version {
|
||||
colors.cache_version_used = cache_version;
|
||||
}
|
||||
if colors.render_mode == DocumentColorsRenderMode::Inlay
|
||||
&& (!colors_splice.to_insert.is_empty()
|
||||
|| !colors_splice.to_remove.is_empty())
|
||||
|
|
|
@ -170,6 +170,7 @@ pub struct LocalLspStore {
|
|||
_subscription: gpui::Subscription,
|
||||
lsp_tree: Entity<LanguageServerTree>,
|
||||
registered_buffers: HashMap<BufferId, usize>,
|
||||
buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
|
||||
buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
|
||||
}
|
||||
|
||||
|
@ -2546,6 +2547,10 @@ impl LocalLspStore {
|
|||
vec![snapshot]
|
||||
});
|
||||
|
||||
self.buffers_opened_in_servers
|
||||
.entry(buffer_id)
|
||||
.or_default()
|
||||
.insert(server.server_id());
|
||||
cx.emit(LspStoreEvent::LanguageServerUpdate {
|
||||
language_server_id: server.server_id(),
|
||||
name: None,
|
||||
|
@ -3208,6 +3213,9 @@ impl LocalLspStore {
|
|||
self.language_servers.remove(server_id_to_remove);
|
||||
self.buffer_pull_diagnostics_result_ids
|
||||
.remove(server_id_to_remove);
|
||||
for buffer_servers in self.buffers_opened_in_servers.values_mut() {
|
||||
buffer_servers.remove(server_id_to_remove);
|
||||
}
|
||||
cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
|
||||
}
|
||||
servers_to_remove.into_keys().collect()
|
||||
|
@ -3787,6 +3795,7 @@ impl LspStore {
|
|||
}),
|
||||
lsp_tree: LanguageServerTree::new(manifest_tree, languages.clone(), cx),
|
||||
registered_buffers: HashMap::default(),
|
||||
buffers_opened_in_servers: HashMap::default(),
|
||||
buffer_pull_diagnostics_result_ids: HashMap::default(),
|
||||
}),
|
||||
last_formatting_failure: None,
|
||||
|
@ -4159,6 +4168,7 @@ impl LspStore {
|
|||
lsp_store.lsp_data.remove(&buffer_id);
|
||||
let local = lsp_store.as_local_mut().unwrap();
|
||||
local.registered_buffers.remove(&buffer_id);
|
||||
local.buffers_opened_in_servers.remove(&buffer_id);
|
||||
if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
|
||||
local.unregister_old_buffer_from_language_servers(&buffer, &file, cx);
|
||||
}
|
||||
|
@ -6235,21 +6245,31 @@ impl LspStore {
|
|||
} => {
|
||||
if let Some(cached_data) = self.lsp_data.get(&buffer_id) {
|
||||
if !version_queried_for.changed_since(&cached_data.colors_for_version) {
|
||||
if Some(cached_data.cache_version) == known_cache_version {
|
||||
return None;
|
||||
} else {
|
||||
return Some(
|
||||
Task::ready(Ok(DocumentColors {
|
||||
colors: cached_data
|
||||
.colors
|
||||
.values()
|
||||
.flatten()
|
||||
.cloned()
|
||||
.collect(),
|
||||
cache_version: Some(cached_data.cache_version),
|
||||
}))
|
||||
.shared(),
|
||||
);
|
||||
let has_different_servers = self.as_local().is_some_and(|local| {
|
||||
local
|
||||
.buffers_opened_in_servers
|
||||
.get(&buffer_id)
|
||||
.cloned()
|
||||
.unwrap_or_default()
|
||||
!= cached_data.colors.keys().copied().collect()
|
||||
});
|
||||
if !has_different_servers {
|
||||
if Some(cached_data.cache_version) == known_cache_version {
|
||||
return None;
|
||||
} else {
|
||||
return Some(
|
||||
Task::ready(Ok(DocumentColors {
|
||||
colors: cached_data
|
||||
.colors
|
||||
.values()
|
||||
.flatten()
|
||||
.cloned()
|
||||
.collect(),
|
||||
cache_version: Some(cached_data.cache_version),
|
||||
}))
|
||||
.shared(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7522,6 +7542,14 @@ impl LspStore {
|
|||
.unwrap_or(true)
|
||||
})
|
||||
.map(|(_, server)| server.server_id())
|
||||
.filter(|server_id| {
|
||||
self.as_local().is_none_or(|local| {
|
||||
local
|
||||
.buffers_opened_in_servers
|
||||
.get(&snapshot.remote_id())
|
||||
.is_some_and(|servers| servers.contains(server_id))
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
|
||||
|
@ -10084,6 +10112,7 @@ impl LspStore {
|
|||
}
|
||||
|
||||
// Tell the language server about every open buffer in the worktree that matches the language.
|
||||
let mut buffer_paths_registered = Vec::new();
|
||||
self.buffer_store.clone().update(cx, |buffer_store, cx| {
|
||||
for buffer_handle in buffer_store.buffers() {
|
||||
let buffer = buffer_handle.read(cx);
|
||||
|
@ -10142,6 +10171,12 @@ impl LspStore {
|
|||
version,
|
||||
initial_snapshot.text(),
|
||||
);
|
||||
buffer_paths_registered.push(file.abs_path(cx));
|
||||
local
|
||||
.buffers_opened_in_servers
|
||||
.entry(buffer.remote_id())
|
||||
.or_default()
|
||||
.insert(server_id);
|
||||
}
|
||||
buffer_handle.update(cx, |buffer, cx| {
|
||||
buffer.set_completion_triggers(
|
||||
|
@ -10163,6 +10198,18 @@ impl LspStore {
|
|||
}
|
||||
});
|
||||
|
||||
for abs_path in buffer_paths_registered {
|
||||
cx.emit(LspStoreEvent::LanguageServerUpdate {
|
||||
language_server_id: server_id,
|
||||
name: Some(adapter.name()),
|
||||
message: proto::update_language_server::Variant::RegisteredForBuffer(
|
||||
proto::RegisteredForBuffer {
|
||||
buffer_abs_path: abs_path.to_string_lossy().to_string(),
|
||||
},
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
|
@ -10612,6 +10659,9 @@ impl LspStore {
|
|||
}
|
||||
if let Some(local) = self.as_local_mut() {
|
||||
local.buffer_pull_diagnostics_result_ids.remove(&for_server);
|
||||
for buffer_servers in local.buffers_opened_in_servers.values_mut() {
|
||||
buffer_servers.remove(&for_server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue