diff --git a/assets/settings/default.json b/assets/settings/default.json index c69d8089bc..c413db5788 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -73,6 +73,16 @@ // Whether to show git diff indicators in the scrollbar. "git_diff": true }, + // Inlay hint related settings + "inlay_hints": { + // Global switch to toggle hints on and off, switched off by default. + "enabled": false, + // Toggle certain types of hints on and off, all switched on by default. + "show_type_hints": true, + "show_parameter_hints": true, + // Corresponds to null/None LSP hint type value. + "show_other_hints": true + }, "project_panel": { // Whether to show the git status in the project panel. "git_status": true, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 93535c9480..afe82bddc5 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -74,7 +74,8 @@ pub use multi_buffer::{ use multi_buffer::{MultiBufferChunks, ToOffsetUtf16}; use ordered_float::OrderedFloat; use project::{ - FormatTrigger, InlayHint, Location, LocationLink, Project, ProjectPath, ProjectTransaction, + FormatTrigger, InlayHint, InlayHintKind, Location, LocationLink, Project, ProjectPath, + ProjectTransaction, }; use scroll::{ autoscroll::Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide, @@ -2590,11 +2591,20 @@ impl Editor { } } - fn refresh_inlays(&self, cx: &mut ViewContext) { + fn refresh_inlays(&mut self, cx: &mut ViewContext) { if self.mode != EditorMode::Full { return; } + let inlay_hint_settings = settings::get::(cx).inlay_hints; + if !inlay_hint_settings.enabled { + let to_remove = self.inlay_cache.clear(); + self.display_map.update(cx, |display_map, cx| { + display_map.splice_inlays(to_remove, Vec::new(), cx); + }); + return; + } + struct InlayRequestKey { buffer_path: PathBuf, buffer_version: Global, @@ -2619,6 +2629,9 @@ impl Editor { excerpt_id, }; + // TODO kb split this into 2 different steps: + // 1. cache population + // 2. cache querying + hint filters on top (needs to store previous filter settings) let task = cx.spawn(|editor, mut cx| async move { if inlays_up_to_date { anyhow::Ok((key, None)) @@ -2646,9 +2659,20 @@ impl Editor { Some(task) => { match task.await.context("inlays for buffer task")? { Some(mut new_inlays) => { + let mut allowed_inlay_hint_types = Vec::new(); + if inlay_hint_settings.show_type_hints { + allowed_inlay_hint_types.push(Some(InlayHintKind::Type)); + } + if inlay_hint_settings.show_parameter_hints { + allowed_inlay_hint_types.push(Some(InlayHintKind::Parameter)); + } + if inlay_hint_settings.show_other_hints { + allowed_inlay_hint_types.push(None); + } new_inlays.retain(|inlay| { let inlay_offset = inlay.position.offset; - query_start <= inlay_offset && inlay_offset <= query_end + allowed_inlay_hint_types.contains(&inlay.kind) + && query_start <= inlay_offset && inlay_offset <= query_end }); Some(new_inlays) }, @@ -2713,7 +2737,7 @@ impl Editor { to_remove, to_insert, } = editor.update(&mut cx, |editor, _| { - editor.inlay_cache.update_inlays(inlay_updates) + dbg!(editor.inlay_cache.update_inlays(inlay_updates)) })?; editor.update(&mut cx, |editor, cx| { @@ -7318,6 +7342,7 @@ impl Editor { fn settings_changed(&mut self, cx: &mut ViewContext) { self.refresh_copilot_suggestions(true, cx); + self.refresh_inlays(cx); } pub fn set_searchable(&mut self, searchable: bool) { diff --git a/crates/editor/src/editor_settings.rs b/crates/editor/src/editor_settings.rs index 387d4d2c34..557c3194c0 100644 --- a/crates/editor/src/editor_settings.rs +++ b/crates/editor/src/editor_settings.rs @@ -9,6 +9,7 @@ pub struct EditorSettings { pub show_completions_on_input: bool, pub use_on_type_format: bool, pub scrollbar: Scrollbar, + pub inlay_hints: InlayHints, } #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] @@ -17,6 +18,14 @@ pub struct Scrollbar { pub git_diff: bool, } +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +pub struct InlayHints { + pub enabled: bool, + pub show_type_hints: bool, + pub show_parameter_hints: bool, + pub show_other_hints: bool, +} + #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum ShowScrollbar { @@ -33,6 +42,7 @@ pub struct EditorSettingsContent { pub show_completions_on_input: Option, pub use_on_type_format: Option, pub scrollbar: Option, + pub inlay_hints: Option, } #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] @@ -41,6 +51,14 @@ pub struct ScrollbarContent { pub git_diff: Option, } +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +pub struct InlayHintsContent { + pub enabled: Option, + pub show_type_hints: Option, + pub show_parameter_hints: Option, + pub show_other_hints: Option, +} + impl Setting for EditorSettings { const KEY: Option<&'static str> = None; diff --git a/crates/editor/src/inlay_cache.rs b/crates/editor/src/inlay_cache.rs index 2f5f4204b9..c563102544 100644 --- a/crates/editor/src/inlay_cache.rs +++ b/crates/editor/src/inlay_cache.rs @@ -229,4 +229,22 @@ impl InlayCache { to_insert, } } + + pub fn clear(&mut self) -> Vec { + self.inlays_per_buffer + .drain() + .map(|(_, buffer_inlays)| { + buffer_inlays + .inlays_per_excerpts + .into_iter() + .map(|(_, excerpt_inlays)| { + excerpt_inlays + .into_ordered_elements() + .map(|(_, (id, _))| id) + }) + .flatten() + }) + .flatten() + .collect() + } }