Compare commits
5 commits
main
...
kb/shared-
Author | SHA1 | Date | |
---|---|---|---|
![]() |
44b1d5db2d | ||
![]() |
5cf3dcfdfd | ||
![]() |
0afe7c3210 | ||
![]() |
c06534b079 | ||
![]() |
ee3245c9a5 |
6 changed files with 480 additions and 49 deletions
|
@ -126,7 +126,7 @@ use language::{
|
||||||
Language, OffsetRangeExt, Point, Runnable, RunnableRange, Selection, SelectionGoal, TextObject,
|
Language, OffsetRangeExt, Point, Runnable, RunnableRange, Selection, SelectionGoal, TextObject,
|
||||||
TransactionId, TreeSitterOptions, WordsQuery,
|
TransactionId, TreeSitterOptions, WordsQuery,
|
||||||
language_settings::{
|
language_settings::{
|
||||||
self, InlayHintSettings, LspInsertMode, RewrapBehavior, WordsCompletionMode,
|
self, InlayHintKind, InlayHintSettings, LspInsertMode, RewrapBehavior, WordsCompletionMode,
|
||||||
all_language_settings, language_settings,
|
all_language_settings, language_settings,
|
||||||
},
|
},
|
||||||
point_from_lsp, point_to_lsp, text_diff_with_options,
|
point_from_lsp, point_to_lsp, text_diff_with_options,
|
||||||
|
@ -150,18 +150,18 @@ use project::{
|
||||||
BreakpointWithPosition, CodeAction, Completion, CompletionIntent, CompletionResponse,
|
BreakpointWithPosition, CodeAction, Completion, CompletionIntent, CompletionResponse,
|
||||||
CompletionSource, DisableAiSettings, DocumentHighlight, InlayHint, Location, LocationLink,
|
CompletionSource, DisableAiSettings, DocumentHighlight, InlayHint, Location, LocationLink,
|
||||||
PrepareRenameResponse, Project, ProjectItem, ProjectPath, ProjectTransaction, TaskSourceKind,
|
PrepareRenameResponse, Project, ProjectItem, ProjectPath, ProjectTransaction, TaskSourceKind,
|
||||||
debugger::breakpoint_store::Breakpoint,
|
|
||||||
debugger::{
|
debugger::{
|
||||||
breakpoint_store::{
|
breakpoint_store::{
|
||||||
BreakpointEditAction, BreakpointSessionState, BreakpointState, BreakpointStore,
|
Breakpoint, BreakpointEditAction, BreakpointSessionState, BreakpointState,
|
||||||
BreakpointStoreEvent,
|
BreakpointStore, BreakpointStoreEvent,
|
||||||
},
|
},
|
||||||
session::{Session, SessionEvent},
|
session::{Session, SessionEvent},
|
||||||
},
|
},
|
||||||
git_store::{GitStoreEvent, RepositoryEvent},
|
git_store::{GitStoreEvent, RepositoryEvent},
|
||||||
lsp_store::{CompletionDocumentation, FormatTrigger, LspFormatTarget, OpenLspBufferHandle},
|
lsp_store::{CompletionDocumentation, FormatTrigger, LspFormatTarget, OpenLspBufferHandle},
|
||||||
project_settings::{DiagnosticSeverity, GoToDiagnosticSeverityFilter},
|
project_settings::{
|
||||||
project_settings::{GitGutterSetting, ProjectSettings},
|
DiagnosticSeverity, GitGutterSetting, GoToDiagnosticSeverityFilter, ProjectSettings,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use rand::{seq::SliceRandom, thread_rng};
|
use rand::{seq::SliceRandom, thread_rng};
|
||||||
use rpc::{ErrorCode, ErrorExt, proto::PeerId};
|
use rpc::{ErrorCode, ErrorExt, proto::PeerId};
|
||||||
|
@ -1177,9 +1177,137 @@ pub struct Editor {
|
||||||
selection_drag_state: SelectionDragState,
|
selection_drag_state: SelectionDragState,
|
||||||
next_color_inlay_id: usize,
|
next_color_inlay_id: usize,
|
||||||
colors: Option<LspColorData>,
|
colors: Option<LspColorData>,
|
||||||
|
inlay_hints: Option<LspInlayHintData>,
|
||||||
folding_newlines: Task<()>,
|
folding_newlines: Task<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct LspInlayHintData {
|
||||||
|
enabled: bool,
|
||||||
|
modifiers_override: bool,
|
||||||
|
enabled_in_settings: bool,
|
||||||
|
allowed_hint_kinds: HashSet<Option<InlayHintKind>>,
|
||||||
|
invalidate_debounce: Option<Duration>,
|
||||||
|
append_debounce: Option<Duration>,
|
||||||
|
inlays_for_version: Option<clock::Global>,
|
||||||
|
inlays: HashMap<BufferId, Vec<InlayId>>,
|
||||||
|
inlay_tasks: HashMap<BufferId, HashMap<Range<BufferRow>, Task<()>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LspInlayHintData {
|
||||||
|
fn new(settings: InlayHintSettings) -> Self {
|
||||||
|
Self {
|
||||||
|
modifiers_override: false,
|
||||||
|
enabled: settings.enabled,
|
||||||
|
enabled_in_settings: settings.enabled,
|
||||||
|
inlays: HashMap::default(),
|
||||||
|
inlays_for_version: None,
|
||||||
|
inlay_tasks: HashMap::default(),
|
||||||
|
invalidate_debounce: debounce_value(settings.edit_debounce_ms),
|
||||||
|
append_debounce: debounce_value(settings.scroll_debounce_ms),
|
||||||
|
allowed_hint_kinds: settings.enabled_inlay_hint_kinds(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn modifiers_override(&mut self, new_override: bool) -> Option<bool> {
|
||||||
|
if self.modifiers_override == new_override {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
self.modifiers_override = new_override;
|
||||||
|
if (self.enabled && self.modifiers_override) || (!self.enabled && !self.modifiers_override)
|
||||||
|
{
|
||||||
|
self.clear();
|
||||||
|
Some(false)
|
||||||
|
} else {
|
||||||
|
Some(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toggle(&mut self, enabled: bool) -> bool {
|
||||||
|
if self.enabled == enabled {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self.enabled = enabled;
|
||||||
|
self.modifiers_override = false;
|
||||||
|
if !enabled {
|
||||||
|
self.clear();
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear(&mut self) {
|
||||||
|
self.inlay_tasks.clear();
|
||||||
|
// TODO kb splice!?
|
||||||
|
self.inlays.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks inlay hint settings for enabled hint kinds and general enabled state.
|
||||||
|
/// Generates corresponding inlay_map splice updates on settings changes.
|
||||||
|
/// Does not update inlay hint cache state on disabling or inlay hint kinds change: only reenabling forces new LSP queries.
|
||||||
|
fn update_settings(
|
||||||
|
&mut self,
|
||||||
|
multi_buffer: &Entity<MultiBuffer>,
|
||||||
|
new_hint_settings: InlayHintSettings,
|
||||||
|
visible_hints: Vec<Inlay>,
|
||||||
|
cx: &mut App,
|
||||||
|
) -> ControlFlow<Option<InlaySplice>> {
|
||||||
|
let old_enabled = self.enabled;
|
||||||
|
// If the setting for inlay hints has changed, update `enabled`. This condition avoids inlay
|
||||||
|
// hint visibility changes when other settings change (such as theme).
|
||||||
|
//
|
||||||
|
// Another option might be to store whether the user has manually toggled inlay hint
|
||||||
|
// visibility, and prefer this. This could lead to confusion as it means inlay hint
|
||||||
|
// visibility would not change when updating the setting if they were ever toggled.
|
||||||
|
if new_hint_settings.enabled != self.enabled_in_settings {
|
||||||
|
self.enabled = new_hint_settings.enabled;
|
||||||
|
self.enabled_in_settings = new_hint_settings.enabled;
|
||||||
|
self.modifiers_override = false;
|
||||||
|
};
|
||||||
|
self.invalidate_debounce = debounce_value(new_hint_settings.edit_debounce_ms);
|
||||||
|
self.append_debounce = debounce_value(new_hint_settings.scroll_debounce_ms);
|
||||||
|
let new_allowed_hint_kinds = new_hint_settings.enabled_inlay_hint_kinds();
|
||||||
|
match (old_enabled, self.enabled) {
|
||||||
|
(false, false) => {
|
||||||
|
self.allowed_hint_kinds = new_allowed_hint_kinds;
|
||||||
|
ControlFlow::Break(None)
|
||||||
|
}
|
||||||
|
(true, true) => {
|
||||||
|
if new_allowed_hint_kinds == self.allowed_hint_kinds {
|
||||||
|
ControlFlow::Break(None)
|
||||||
|
} else {
|
||||||
|
todo!("TODO kb")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(true, false) => {
|
||||||
|
self.modifiers_override = false;
|
||||||
|
self.allowed_hint_kinds = new_allowed_hint_kinds;
|
||||||
|
if self.inlays.is_empty() {
|
||||||
|
ControlFlow::Break(None)
|
||||||
|
} else {
|
||||||
|
self.clear();
|
||||||
|
ControlFlow::Break(Some(InlaySplice {
|
||||||
|
to_remove: visible_hints.iter().map(|inlay| inlay.id).collect(),
|
||||||
|
to_insert: Vec::new(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(false, true) => {
|
||||||
|
self.modifiers_override = false;
|
||||||
|
self.allowed_hint_kinds = new_allowed_hint_kinds;
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn debounce_value(debounce_ms: u64) -> Option<Duration> {
|
||||||
|
if debounce_ms > 0 {
|
||||||
|
Some(Duration::from_millis(debounce_ms))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
|
||||||
enum NextScrollCursorCenterTopBottom {
|
enum NextScrollCursorCenterTopBottom {
|
||||||
#[default]
|
#[default]
|
||||||
|
@ -1611,7 +1739,7 @@ enum InlayHintRefreshReason {
|
||||||
SettingsChange(InlayHintSettings),
|
SettingsChange(InlayHintSettings),
|
||||||
NewLinesShown,
|
NewLinesShown,
|
||||||
BufferEdited(HashSet<Arc<Language>>),
|
BufferEdited(HashSet<Arc<Language>>),
|
||||||
RefreshRequested,
|
RefreshRequested(LanguageServerId),
|
||||||
ExcerptsRemoved(Vec<ExcerptId>),
|
ExcerptsRemoved(Vec<ExcerptId>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1623,7 +1751,7 @@ impl InlayHintRefreshReason {
|
||||||
Self::SettingsChange(_) => "settings change",
|
Self::SettingsChange(_) => "settings change",
|
||||||
Self::NewLinesShown => "new lines shown",
|
Self::NewLinesShown => "new lines shown",
|
||||||
Self::BufferEdited(_) => "buffer edited",
|
Self::BufferEdited(_) => "buffer edited",
|
||||||
Self::RefreshRequested => "refresh requested",
|
Self::RefreshRequested(_) => "refresh requested",
|
||||||
Self::ExcerptsRemoved(_) => "excerpts removed",
|
Self::ExcerptsRemoved(_) => "excerpts removed",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1864,8 +1992,11 @@ impl Editor {
|
||||||
project::Event::RefreshCodeLens => {
|
project::Event::RefreshCodeLens => {
|
||||||
// we always query lens with actions, without storing them, always refreshing them
|
// we always query lens with actions, without storing them, always refreshing them
|
||||||
}
|
}
|
||||||
project::Event::RefreshInlayHints => {
|
project::Event::RefreshInlayHints(server_id) => {
|
||||||
editor.refresh_inlay_hints(InlayHintRefreshReason::RefreshRequested, cx);
|
editor.refresh_inlay_hints(
|
||||||
|
InlayHintRefreshReason::RefreshRequested(*server_id),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
project::Event::LanguageServerAdded(..)
|
project::Event::LanguageServerAdded(..)
|
||||||
| project::Event::LanguageServerRemoved(..) => {
|
| project::Event::LanguageServerRemoved(..) => {
|
||||||
|
@ -2230,6 +2361,7 @@ impl Editor {
|
||||||
tasks_update_task: None,
|
tasks_update_task: None,
|
||||||
pull_diagnostics_task: Task::ready(()),
|
pull_diagnostics_task: Task::ready(()),
|
||||||
colors: None,
|
colors: None,
|
||||||
|
inlay_hints: None,
|
||||||
next_color_inlay_id: 0,
|
next_color_inlay_id: 0,
|
||||||
linked_edit_ranges: Default::default(),
|
linked_edit_ranges: Default::default(),
|
||||||
in_project_search: false,
|
in_project_search: false,
|
||||||
|
@ -2378,6 +2510,7 @@ impl Editor {
|
||||||
editor.minimap =
|
editor.minimap =
|
||||||
editor.create_minimap(EditorSettings::get_global(cx).minimap, window, cx);
|
editor.create_minimap(EditorSettings::get_global(cx).minimap, window, cx);
|
||||||
editor.colors = Some(LspColorData::new(cx));
|
editor.colors = Some(LspColorData::new(cx));
|
||||||
|
editor.inlay_hints = Some(LspInlayHintData::new(inlay_hint_settings));
|
||||||
editor.update_lsp_data(false, None, window, cx);
|
editor.update_lsp_data(false, None, window, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5229,7 +5362,7 @@ impl Editor {
|
||||||
InlayHintRefreshReason::BufferEdited(buffer_languages) => {
|
InlayHintRefreshReason::BufferEdited(buffer_languages) => {
|
||||||
(InvalidationStrategy::BufferEdited, Some(buffer_languages))
|
(InvalidationStrategy::BufferEdited, Some(buffer_languages))
|
||||||
}
|
}
|
||||||
InlayHintRefreshReason::RefreshRequested => {
|
InlayHintRefreshReason::RefreshRequested(_) => {
|
||||||
(InvalidationStrategy::RefreshRequested, None)
|
(InvalidationStrategy::RefreshRequested, None)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -5248,6 +5381,209 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn refresh_inlay_hints_2(&mut self, reason: InlayHintRefreshReason, cx: &mut Context<Self>) {
|
||||||
|
if !self.mode.is_full() || self.semantics_provider.is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let Some(inlay_hints) = self.inlay_hints.as_mut() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let reason_description = reason.description();
|
||||||
|
let ignore_debounce = matches!(
|
||||||
|
reason,
|
||||||
|
InlayHintRefreshReason::SettingsChange(_)
|
||||||
|
| InlayHintRefreshReason::Toggle(_)
|
||||||
|
| InlayHintRefreshReason::ExcerptsRemoved(_)
|
||||||
|
| InlayHintRefreshReason::ModifiersChanged(_)
|
||||||
|
);
|
||||||
|
let (invalidate_cache, required_languages) = match reason {
|
||||||
|
InlayHintRefreshReason::ModifiersChanged(enabled) => {
|
||||||
|
match inlay_hints.modifiers_override(enabled) {
|
||||||
|
Some(enabled) => {
|
||||||
|
if enabled {
|
||||||
|
(InvalidationStrategy::RefreshRequested, None)
|
||||||
|
} else {
|
||||||
|
self.splice_inlays(
|
||||||
|
&self
|
||||||
|
.visible_inlay_hints(cx)
|
||||||
|
.iter()
|
||||||
|
.map(|inlay| inlay.id)
|
||||||
|
.collect::<Vec<InlayId>>(),
|
||||||
|
Vec::new(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => return,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InlayHintRefreshReason::Toggle(enabled) => {
|
||||||
|
if inlay_hints.toggle(enabled) {
|
||||||
|
if enabled {
|
||||||
|
(InvalidationStrategy::RefreshRequested, None)
|
||||||
|
} else {
|
||||||
|
self.splice_inlays(
|
||||||
|
&self
|
||||||
|
.visible_inlay_hints(cx)
|
||||||
|
.iter()
|
||||||
|
.map(|inlay| inlay.id)
|
||||||
|
.collect::<Vec<InlayId>>(),
|
||||||
|
Vec::new(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InlayHintRefreshReason::SettingsChange(new_settings) => {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
InlayHintRefreshReason::ExcerptsRemoved(excerpts_removed) => {
|
||||||
|
if let Some(InlaySplice {
|
||||||
|
to_remove,
|
||||||
|
to_insert,
|
||||||
|
}) = self.inlay_hint_cache.remove_excerpts(&excerpts_removed)
|
||||||
|
{
|
||||||
|
self.splice_inlays(&to_remove, to_insert, cx);
|
||||||
|
}
|
||||||
|
self.display_map.update(cx, |display_map, _| {
|
||||||
|
display_map.remove_inlays_for_excerpts(&excerpts_removed)
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
InlayHintRefreshReason::NewLinesShown => (InvalidationStrategy::None, None),
|
||||||
|
InlayHintRefreshReason::BufferEdited(buffer_languages) => {
|
||||||
|
(InvalidationStrategy::BufferEdited, Some(buffer_languages))
|
||||||
|
}
|
||||||
|
InlayHintRefreshReason::RefreshRequested(_) => {
|
||||||
|
(InvalidationStrategy::RefreshRequested, None)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let multi_buffer_snapshot = self.buffer().read(cx).snapshot(cx);
|
||||||
|
let Some(semantics_provider) = self.semantics_provider.clone() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
for (excerpt_id, (buffer, buffer_version, range)) in self.visible_excerpts(None, cx) {
|
||||||
|
let Some(excerpt_text_anchor_range) =
|
||||||
|
multi_buffer_snapshot.context_range_for_excerpt(excerpt_id)
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let buffer_id = buffer.read(cx).remote_id();
|
||||||
|
let buffer_snapshot = buffer.read(cx).snapshot();
|
||||||
|
let buffer_anchor_range =
|
||||||
|
buffer_snapshot.anchor_before(range.start)..buffer_snapshot.anchor_after(range.end);
|
||||||
|
|
||||||
|
let new_hints =
|
||||||
|
semantics_provider.inlay_hints_2(buffer, buffer_anchor_range.clone(), cx);
|
||||||
|
let Some(inlay_hints) = self.inlay_hints.as_mut() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if let Some((hints_range, new_hints)) = new_hints {
|
||||||
|
let buffer_hints = inlay_hints.inlay_tasks.entry(buffer_id).or_default();
|
||||||
|
buffer_hints.insert(
|
||||||
|
hints_range.clone(),
|
||||||
|
cx.spawn(async move |editor, cx| {
|
||||||
|
let new_hints = new_hints.await;
|
||||||
|
editor
|
||||||
|
.update(cx, |editor, cx| {
|
||||||
|
let multi_buffer_snapshot = editor.buffer.read(cx).snapshot(cx);
|
||||||
|
let Some(buffer_snapshot) =
|
||||||
|
multi_buffer_snapshot.buffer_for_excerpt(excerpt_id)
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut update_data = None;
|
||||||
|
if let Some(inlay_hints) = editor.inlay_hints.as_mut() {
|
||||||
|
let inlay_tasks =
|
||||||
|
inlay_hints.inlay_tasks.entry(buffer_id).or_default();
|
||||||
|
match new_hints {
|
||||||
|
Ok(new_hints) => {
|
||||||
|
if inlay_hints.inlays_for_version.as_ref().is_some_and(
|
||||||
|
|inlays_for_version| {
|
||||||
|
!inlays_for_version
|
||||||
|
.changed_since(&buffer_version)
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
let hints_to_remove = if inlay_hints
|
||||||
|
.inlays_for_version
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|inlays_for_version| {
|
||||||
|
buffer_version
|
||||||
|
.changed_since(&inlays_for_version)
|
||||||
|
}) {
|
||||||
|
inlay_hints
|
||||||
|
.inlays
|
||||||
|
.remove(&buffer_id)
|
||||||
|
.unwrap_or_default()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
let hints_to_insert = new_hints
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|lsp_hint| {
|
||||||
|
if buffer_anchor_range
|
||||||
|
.start
|
||||||
|
.cmp(
|
||||||
|
&lsp_hint.position,
|
||||||
|
buffer_snapshot,
|
||||||
|
)
|
||||||
|
.is_ge()
|
||||||
|
&& buffer_anchor_range
|
||||||
|
.end
|
||||||
|
.cmp(
|
||||||
|
&lsp_hint.position,
|
||||||
|
buffer_snapshot,
|
||||||
|
)
|
||||||
|
.is_le()
|
||||||
|
{
|
||||||
|
let position = multi_buffer_snapshot
|
||||||
|
.anchor_in_excerpt(
|
||||||
|
excerpt_id,
|
||||||
|
lsp_hint.position,
|
||||||
|
)?;
|
||||||
|
return Some(Inlay::hint(
|
||||||
|
post_inc(&mut editor.next_inlay_id),
|
||||||
|
position,
|
||||||
|
&lsp_hint,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
update_data =
|
||||||
|
Some((hints_to_remove, hints_to_insert));
|
||||||
|
inlay_hints.inlays_for_version =
|
||||||
|
Some(buffer_version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO kb who should log and clean up the errored state? Could we do that with `lsp_store_cx.spawn`?
|
||||||
|
Err(_) => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
inlay_tasks.remove(&hints_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some((hints_to_remove, hints_to_insert)) = update_data {
|
||||||
|
editor.splice_inlays(&hints_to_remove, hints_to_insert, cx);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visible_inlay_hints(&self, cx: &Context<Editor>) -> Vec<Inlay> {
|
fn visible_inlay_hints(&self, cx: &Context<Editor>) -> Vec<Inlay> {
|
||||||
self.display_map
|
self.display_map
|
||||||
.read(cx)
|
.read(cx)
|
||||||
|
@ -16751,9 +17087,9 @@ impl Editor {
|
||||||
HashSet::default(),
|
HashSet::default(),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
cx.emit(project::Event::RefreshInlayHints);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
self.refresh_inlay_hints(InlayHintRefreshReason::NewLinesShown, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21874,6 +22210,18 @@ pub trait SemanticsProvider {
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Option<Task<anyhow::Result<Vec<InlayHint>>>>;
|
) -> Option<Task<anyhow::Result<Vec<InlayHint>>>>;
|
||||||
|
|
||||||
|
fn inlay_hints_2(
|
||||||
|
&self,
|
||||||
|
buffer: Entity<Buffer>,
|
||||||
|
range: Range<text::Anchor>,
|
||||||
|
cx: &mut App,
|
||||||
|
) -> Option<(
|
||||||
|
Range<BufferRow>,
|
||||||
|
Shared<Task<Result<Vec<InlayHint>, Arc<anyhow::Error>>>>,
|
||||||
|
)> {
|
||||||
|
todo!("TODO kb")
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_inlay_hint(
|
fn resolve_inlay_hint(
|
||||||
&self,
|
&self,
|
||||||
hint: InlayHint,
|
hint: InlayHint,
|
||||||
|
|
|
@ -14,6 +14,9 @@ pub mod json_language_server_ext;
|
||||||
pub mod lsp_ext_command;
|
pub mod lsp_ext_command;
|
||||||
pub mod rust_analyzer_ext;
|
pub mod rust_analyzer_ext;
|
||||||
|
|
||||||
|
mod inlay_hint_cache;
|
||||||
|
|
||||||
|
use self::inlay_hint_cache::BufferInlayHints;
|
||||||
use crate::{
|
use crate::{
|
||||||
CodeAction, ColorPresentation, Completion, CompletionResponse, CompletionSource,
|
CodeAction, ColorPresentation, Completion, CompletionResponse, CompletionSource,
|
||||||
CoreCompletion, DocumentColor, Hover, InlayHint, LocationLink, LspAction, LspPullDiagnostics,
|
CoreCompletion, DocumentColor, Hover, InlayHint, LocationLink, LspAction, LspPullDiagnostics,
|
||||||
|
@ -564,7 +567,7 @@ impl LocalLspStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_lsp_messages(
|
fn setup_lsp_messages(
|
||||||
this: WeakEntity<LspStore>,
|
lsp_store: WeakEntity<LspStore>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
language_server: &LanguageServer,
|
language_server: &LanguageServer,
|
||||||
delegate: Arc<dyn LspAdapterDelegate>,
|
delegate: Arc<dyn LspAdapterDelegate>,
|
||||||
|
@ -575,7 +578,7 @@ impl LocalLspStore {
|
||||||
language_server
|
language_server
|
||||||
.on_notification::<lsp::notification::PublishDiagnostics, _>({
|
.on_notification::<lsp::notification::PublishDiagnostics, _>({
|
||||||
let adapter = adapter.clone();
|
let adapter = adapter.clone();
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
move |mut params, cx| {
|
move |mut params, cx| {
|
||||||
let adapter = adapter.clone();
|
let adapter = adapter.clone();
|
||||||
if let Some(this) = this.upgrade() {
|
if let Some(this) = this.upgrade() {
|
||||||
|
@ -619,7 +622,7 @@ impl LocalLspStore {
|
||||||
.on_request::<lsp::request::WorkspaceConfiguration, _, _>({
|
.on_request::<lsp::request::WorkspaceConfiguration, _, _>({
|
||||||
let adapter = adapter.adapter.clone();
|
let adapter = adapter.adapter.clone();
|
||||||
let delegate = delegate.clone();
|
let delegate = delegate.clone();
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
let fs = fs.clone();
|
let fs = fs.clone();
|
||||||
move |params, cx| {
|
move |params, cx| {
|
||||||
let adapter = adapter.clone();
|
let adapter = adapter.clone();
|
||||||
|
@ -667,7 +670,7 @@ impl LocalLspStore {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
|
.on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
move |_, cx| {
|
move |_, cx| {
|
||||||
let this = this.clone();
|
let this = this.clone();
|
||||||
let cx = cx.clone();
|
let cx = cx.clone();
|
||||||
|
@ -695,7 +698,7 @@ impl LocalLspStore {
|
||||||
// to these requests when initializing.
|
// to these requests when initializing.
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
|
.on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
move |params, cx| {
|
move |params, cx| {
|
||||||
let this = this.clone();
|
let this = this.clone();
|
||||||
let mut cx = cx.clone();
|
let mut cx = cx.clone();
|
||||||
|
@ -716,7 +719,7 @@ impl LocalLspStore {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp::request::RegisterCapability, _, _>({
|
.on_request::<lsp::request::RegisterCapability, _, _>({
|
||||||
let lsp_store = this.clone();
|
let lsp_store = lsp_store.clone();
|
||||||
move |params, cx| {
|
move |params, cx| {
|
||||||
let lsp_store = lsp_store.clone();
|
let lsp_store = lsp_store.clone();
|
||||||
let mut cx = cx.clone();
|
let mut cx = cx.clone();
|
||||||
|
@ -745,7 +748,7 @@ impl LocalLspStore {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp::request::UnregisterCapability, _, _>({
|
.on_request::<lsp::request::UnregisterCapability, _, _>({
|
||||||
let lsp_store = this.clone();
|
let lsp_store = lsp_store.clone();
|
||||||
move |params, cx| {
|
move |params, cx| {
|
||||||
let lsp_store = lsp_store.clone();
|
let lsp_store = lsp_store.clone();
|
||||||
let mut cx = cx.clone();
|
let mut cx = cx.clone();
|
||||||
|
@ -774,7 +777,7 @@ impl LocalLspStore {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
|
.on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
move |params, cx| {
|
move |params, cx| {
|
||||||
let mut cx = cx.clone();
|
let mut cx = cx.clone();
|
||||||
let this = this.clone();
|
let this = this.clone();
|
||||||
|
@ -793,18 +796,22 @@ impl LocalLspStore {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
|
.on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
|
||||||
let this = this.clone();
|
let lsp_store = lsp_store.clone();
|
||||||
move |(), cx| {
|
move |(), cx| {
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
let mut cx = cx.clone();
|
let mut cx = cx.clone();
|
||||||
async move {
|
async move {
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |lsp_store, cx| {
|
||||||
cx.emit(LspStoreEvent::RefreshInlayHints);
|
cx.emit(LspStoreEvent::RefreshInlayHints(server_id));
|
||||||
this.downstream_client.as_ref().map(|(client, project_id)| {
|
lsp_store
|
||||||
client.send(proto::RefreshInlayHints {
|
.downstream_client
|
||||||
project_id: *project_id,
|
.as_ref()
|
||||||
|
.map(|(client, project_id)| {
|
||||||
|
client.send(proto::RefreshInlayHints {
|
||||||
|
project_id: *project_id,
|
||||||
|
server_id: server_id.to_proto(),
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
|
||||||
})?
|
})?
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -815,7 +822,7 @@ impl LocalLspStore {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp::request::CodeLensRefresh, _, _>({
|
.on_request::<lsp::request::CodeLensRefresh, _, _>({
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
move |(), cx| {
|
move |(), cx| {
|
||||||
let this = this.clone();
|
let this = this.clone();
|
||||||
let mut cx = cx.clone();
|
let mut cx = cx.clone();
|
||||||
|
@ -837,7 +844,7 @@ impl LocalLspStore {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
|
.on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
move |(), cx| {
|
move |(), cx| {
|
||||||
let this = this.clone();
|
let this = this.clone();
|
||||||
let mut cx = cx.clone();
|
let mut cx = cx.clone();
|
||||||
|
@ -863,7 +870,7 @@ impl LocalLspStore {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp::request::ShowMessageRequest, _, _>({
|
.on_request::<lsp::request::ShowMessageRequest, _, _>({
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
let name = name.to_string();
|
let name = name.to_string();
|
||||||
move |params, cx| {
|
move |params, cx| {
|
||||||
let this = this.clone();
|
let this = this.clone();
|
||||||
|
@ -901,7 +908,7 @@ impl LocalLspStore {
|
||||||
.detach();
|
.detach();
|
||||||
language_server
|
language_server
|
||||||
.on_notification::<lsp::notification::ShowMessage, _>({
|
.on_notification::<lsp::notification::ShowMessage, _>({
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
let name = name.to_string();
|
let name = name.to_string();
|
||||||
move |params, cx| {
|
move |params, cx| {
|
||||||
let this = this.clone();
|
let this = this.clone();
|
||||||
|
@ -933,7 +940,7 @@ impl LocalLspStore {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_notification::<lsp::notification::Progress, _>({
|
.on_notification::<lsp::notification::Progress, _>({
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
move |params, cx| {
|
move |params, cx| {
|
||||||
if let Some(this) = this.upgrade() {
|
if let Some(this) = this.upgrade() {
|
||||||
this.update(cx, |this, cx| {
|
this.update(cx, |this, cx| {
|
||||||
|
@ -952,7 +959,7 @@ impl LocalLspStore {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_notification::<lsp::notification::LogMessage, _>({
|
.on_notification::<lsp::notification::LogMessage, _>({
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
move |params, cx| {
|
move |params, cx| {
|
||||||
if let Some(this) = this.upgrade() {
|
if let Some(this) = this.upgrade() {
|
||||||
this.update(cx, |_, cx| {
|
this.update(cx, |_, cx| {
|
||||||
|
@ -970,7 +977,7 @@ impl LocalLspStore {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_notification::<lsp::notification::LogTrace, _>({
|
.on_notification::<lsp::notification::LogTrace, _>({
|
||||||
let this = this.clone();
|
let this = lsp_store.clone();
|
||||||
move |params, cx| {
|
move |params, cx| {
|
||||||
let mut cx = cx.clone();
|
let mut cx = cx.clone();
|
||||||
if let Some(this) = this.upgrade() {
|
if let Some(this) = this.upgrade() {
|
||||||
|
@ -987,9 +994,9 @@ impl LocalLspStore {
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
json_language_server_ext::register_requests(this.clone(), language_server);
|
json_language_server_ext::register_requests(lsp_store.clone(), language_server);
|
||||||
rust_analyzer_ext::register_notifications(this.clone(), language_server);
|
rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
|
||||||
clangd_ext::register_notifications(this, language_server, adapter);
|
clangd_ext::register_notifications(lsp_store, language_server, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shutdown_language_servers_on_quit(
|
fn shutdown_language_servers_on_quit(
|
||||||
|
@ -3491,6 +3498,7 @@ pub struct LspStore {
|
||||||
pub(super) lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
|
pub(super) lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
|
||||||
lsp_document_colors: HashMap<BufferId, DocumentColorData>,
|
lsp_document_colors: HashMap<BufferId, DocumentColorData>,
|
||||||
lsp_code_lens: HashMap<BufferId, CodeLensData>,
|
lsp_code_lens: HashMap<BufferId, CodeLensData>,
|
||||||
|
inlay_hint_data: HashMap<BufferId, BufferInlayHints>,
|
||||||
running_lsp_requests: HashMap<TypeId, (Global, HashMap<LspRequestId, Task<()>>)>,
|
running_lsp_requests: HashMap<TypeId, (Global, HashMap<LspRequestId, Task<()>>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3540,7 +3548,7 @@ pub enum LspStoreEvent {
|
||||||
new_language: Option<Arc<Language>>,
|
new_language: Option<Arc<Language>>,
|
||||||
},
|
},
|
||||||
Notification(String),
|
Notification(String),
|
||||||
RefreshInlayHints,
|
RefreshInlayHints(LanguageServerId),
|
||||||
RefreshCodeLens,
|
RefreshCodeLens,
|
||||||
DiagnosticsUpdated {
|
DiagnosticsUpdated {
|
||||||
server_id: LanguageServerId,
|
server_id: LanguageServerId,
|
||||||
|
@ -3762,6 +3770,7 @@ impl LspStore {
|
||||||
lsp_server_capabilities: HashMap::default(),
|
lsp_server_capabilities: HashMap::default(),
|
||||||
lsp_document_colors: HashMap::default(),
|
lsp_document_colors: HashMap::default(),
|
||||||
lsp_code_lens: HashMap::default(),
|
lsp_code_lens: HashMap::default(),
|
||||||
|
inlay_hint_data: HashMap::default(),
|
||||||
running_lsp_requests: HashMap::default(),
|
running_lsp_requests: HashMap::default(),
|
||||||
active_entry: None,
|
active_entry: None,
|
||||||
_maintain_workspace_config,
|
_maintain_workspace_config,
|
||||||
|
@ -3824,6 +3833,7 @@ impl LspStore {
|
||||||
lsp_server_capabilities: HashMap::default(),
|
lsp_server_capabilities: HashMap::default(),
|
||||||
lsp_document_colors: HashMap::default(),
|
lsp_document_colors: HashMap::default(),
|
||||||
lsp_code_lens: HashMap::default(),
|
lsp_code_lens: HashMap::default(),
|
||||||
|
inlay_hint_data: HashMap::default(),
|
||||||
running_lsp_requests: HashMap::default(),
|
running_lsp_requests: HashMap::default(),
|
||||||
active_entry: None,
|
active_entry: None,
|
||||||
|
|
||||||
|
@ -4125,6 +4135,7 @@ impl LspStore {
|
||||||
if refcount == 0 {
|
if refcount == 0 {
|
||||||
lsp_store.lsp_document_colors.remove(&buffer_id);
|
lsp_store.lsp_document_colors.remove(&buffer_id);
|
||||||
lsp_store.lsp_code_lens.remove(&buffer_id);
|
lsp_store.lsp_code_lens.remove(&buffer_id);
|
||||||
|
lsp_store.inlay_hint_data.remove(&buffer_id);
|
||||||
let local = lsp_store.as_local_mut().unwrap();
|
let local = lsp_store.as_local_mut().unwrap();
|
||||||
local.registered_buffers.remove(&buffer_id);
|
local.registered_buffers.remove(&buffer_id);
|
||||||
local.buffers_opened_in_servers.remove(&buffer_id);
|
local.buffers_opened_in_servers.remove(&buffer_id);
|
||||||
|
@ -9524,7 +9535,7 @@ impl LspStore {
|
||||||
if let Some(work) = status.pending_work.remove(&token)
|
if let Some(work) = status.pending_work.remove(&token)
|
||||||
&& !work.is_disk_based_diagnostics_progress
|
&& !work.is_disk_based_diagnostics_progress
|
||||||
{
|
{
|
||||||
cx.emit(LspStoreEvent::RefreshInlayHints);
|
cx.emit(LspStoreEvent::RefreshInlayHints(language_server_id));
|
||||||
}
|
}
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
@ -9656,12 +9667,14 @@ impl LspStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_refresh_inlay_hints(
|
async fn handle_refresh_inlay_hints(
|
||||||
this: Entity<Self>,
|
lsp_store: Entity<Self>,
|
||||||
_: TypedEnvelope<proto::RefreshInlayHints>,
|
envelope: TypedEnvelope<proto::RefreshInlayHints>,
|
||||||
mut cx: AsyncApp,
|
mut cx: AsyncApp,
|
||||||
) -> Result<proto::Ack> {
|
) -> Result<proto::Ack> {
|
||||||
this.update(&mut cx, |_, cx| {
|
lsp_store.update(&mut cx, |_, cx| {
|
||||||
cx.emit(LspStoreEvent::RefreshInlayHints);
|
cx.emit(LspStoreEvent::RefreshInlayHints(
|
||||||
|
LanguageServerId::from_proto(envelope.payload.server_id),
|
||||||
|
));
|
||||||
})?;
|
})?;
|
||||||
Ok(proto::Ack {})
|
Ok(proto::Ack {})
|
||||||
}
|
}
|
||||||
|
@ -10913,7 +10926,7 @@ impl LspStore {
|
||||||
language_server.name(),
|
language_server.name(),
|
||||||
Some(key.worktree_id),
|
Some(key.worktree_id),
|
||||||
));
|
));
|
||||||
cx.emit(LspStoreEvent::RefreshInlayHints);
|
cx.emit(LspStoreEvent::RefreshInlayHints(server_id));
|
||||||
|
|
||||||
let server_capabilities = language_server.capabilities();
|
let server_capabilities = language_server.capabilities();
|
||||||
if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
|
if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
|
||||||
|
@ -11517,6 +11530,10 @@ impl LspStore {
|
||||||
buffer_servers.remove(&for_server);
|
buffer_servers.remove(&for_server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for inlay_hint_cache in self.inlay_hint_data.values_mut() {
|
||||||
|
inlay_hint_cache.remove_server_data(for_server);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn result_id(
|
pub fn result_id(
|
||||||
|
|
57
crates/project/src/lsp_store/inlay_hint_cache.rs
Normal file
57
crates/project/src/lsp_store/inlay_hint_cache.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use std::{collections::BTreeMap, ops::Range};
|
||||||
|
|
||||||
|
use clock::Global;
|
||||||
|
use collections::HashMap;
|
||||||
|
use futures::future::Shared;
|
||||||
|
use gpui::{Context, Entity, Task};
|
||||||
|
use language::BufferRow;
|
||||||
|
use lsp::LanguageServerId;
|
||||||
|
use text::BufferId;
|
||||||
|
|
||||||
|
use crate::{InlayHint, buffer_store::BufferStore};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct InlayHintId(usize);
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct BufferInlayHints {
|
||||||
|
all_hints: HashMap<InlayHintId, InlayHint>,
|
||||||
|
hints: HashMap<LanguageServerId, HintChunks>,
|
||||||
|
chunks_for_version: Global,
|
||||||
|
cache_version: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct HintChunks {
|
||||||
|
hints_by_chunks: BTreeMap<Range<BufferRow>, Option<Vec<InlayHintId>>>,
|
||||||
|
chunk_updates: HashMap<Range<BufferRow>, Shared<Task<Vec<InlayHint>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
|
pub enum HintFetchStrategy {
|
||||||
|
IgnoreCache,
|
||||||
|
UseCache { known_cache_version: Option<usize> },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BufferInlayHints {
|
||||||
|
pub fn remove_server_data(&mut self, for_server: LanguageServerId) -> bool {
|
||||||
|
let removed = self.hints.remove(&for_server).is_some();
|
||||||
|
if removed {
|
||||||
|
self.cache_version += 1;
|
||||||
|
}
|
||||||
|
removed
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hints(
|
||||||
|
&self,
|
||||||
|
buffer_store: Entity<BufferStore>,
|
||||||
|
buffer: BufferId,
|
||||||
|
strategy: HintFetchStrategy,
|
||||||
|
range: impl text::ToOffset,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) -> Option<(Range<BufferRow>, Shared<Task<Vec<InlayHint>>>)> {
|
||||||
|
todo!("TODO kb")
|
||||||
|
}
|
||||||
|
// we want to store the cache version outbound, so they can query with it: we can return nothing (`Option`) if the version matches
|
||||||
|
// we can get a new server up/down, so we want to re-query for them things, ignoring the cache version
|
||||||
|
}
|
|
@ -322,7 +322,7 @@ pub enum Event {
|
||||||
HostReshared,
|
HostReshared,
|
||||||
Reshared,
|
Reshared,
|
||||||
Rejoined,
|
Rejoined,
|
||||||
RefreshInlayHints,
|
RefreshInlayHints(LanguageServerId),
|
||||||
RefreshCodeLens,
|
RefreshCodeLens,
|
||||||
RevealInProjectPanel(ProjectEntryId),
|
RevealInProjectPanel(ProjectEntryId),
|
||||||
SnippetEdit(BufferId, Vec<(lsp::Range, Snippet)>),
|
SnippetEdit(BufferId, Vec<(lsp::Range, Snippet)>),
|
||||||
|
@ -2922,7 +2922,9 @@ impl Project {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
LspStoreEvent::RefreshInlayHints => cx.emit(Event::RefreshInlayHints),
|
LspStoreEvent::RefreshInlayHints(server_id) => {
|
||||||
|
cx.emit(Event::RefreshInlayHints(*server_id))
|
||||||
|
}
|
||||||
LspStoreEvent::RefreshCodeLens => cx.emit(Event::RefreshCodeLens),
|
LspStoreEvent::RefreshCodeLens => cx.emit(Event::RefreshCodeLens),
|
||||||
LspStoreEvent::LanguageServerPrompt(prompt) => {
|
LspStoreEvent::LanguageServerPrompt(prompt) => {
|
||||||
cx.emit(Event::LanguageServerPrompt(prompt.clone()))
|
cx.emit(Event::LanguageServerPrompt(prompt.clone()))
|
||||||
|
|
|
@ -1804,7 +1804,10 @@ async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) {
|
||||||
fake_server
|
fake_server
|
||||||
.start_progress(format!("{}/0", progress_token))
|
.start_progress(format!("{}/0", progress_token))
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(events.next().await.unwrap(), Event::RefreshInlayHints);
|
assert_eq!(
|
||||||
|
events.next().await.unwrap(),
|
||||||
|
Event::RefreshInlayHints(fake_server.server.server_id())
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
events.next().await.unwrap(),
|
events.next().await.unwrap(),
|
||||||
Event::DiskBasedDiagnosticsStarted {
|
Event::DiskBasedDiagnosticsStarted {
|
||||||
|
@ -1943,7 +1946,10 @@ async fn test_restarting_server_with_diagnostics_running(cx: &mut gpui::TestAppC
|
||||||
Some(worktree_id)
|
Some(worktree_id)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(events.next().await.unwrap(), Event::RefreshInlayHints);
|
assert_eq!(
|
||||||
|
events.next().await.unwrap(),
|
||||||
|
Event::RefreshInlayHints(fake_server.server.server_id())
|
||||||
|
);
|
||||||
fake_server.start_progress(progress_token).await;
|
fake_server.start_progress(progress_token).await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
events.next().await.unwrap(),
|
events.next().await.unwrap(),
|
||||||
|
|
|
@ -465,6 +465,7 @@ message ResolveInlayHintResponse {
|
||||||
|
|
||||||
message RefreshInlayHints {
|
message RefreshInlayHints {
|
||||||
uint64 project_id = 1;
|
uint64 project_id = 1;
|
||||||
|
uint64 server_id = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CodeLens {
|
message CodeLens {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue