Move hint settings on the language level
This commit is contained in:
parent
480d8c511b
commit
667b70afde
7 changed files with 196 additions and 145 deletions
|
@ -7,8 +7,8 @@ use client::{User, RECEIVE_TIMEOUT};
|
||||||
use collections::HashSet;
|
use collections::HashSet;
|
||||||
use editor::{
|
use editor::{
|
||||||
test::editor_test_context::EditorTestContext, ConfirmCodeAction, ConfirmCompletion,
|
test::editor_test_context::EditorTestContext, ConfirmCodeAction, ConfirmCompletion,
|
||||||
ConfirmRename, Editor, EditorSettings, ExcerptRange, MultiBuffer, Redo, Rename, ToOffset,
|
ConfirmRename, Editor, ExcerptRange, MultiBuffer, Redo, Rename, ToOffset, ToggleCodeActions,
|
||||||
ToggleCodeActions, Undo,
|
Undo,
|
||||||
};
|
};
|
||||||
use fs::{repository::GitFileStatus, FakeFs, Fs as _, LineEnding, RemoveOptions};
|
use fs::{repository::GitFileStatus, FakeFs, Fs as _, LineEnding, RemoveOptions};
|
||||||
use futures::StreamExt as _;
|
use futures::StreamExt as _;
|
||||||
|
@ -18,15 +18,13 @@ use gpui::{
|
||||||
};
|
};
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::{AllLanguageSettings, Formatter},
|
language_settings::{AllLanguageSettings, Formatter, InlayHintKind, InlayHintSettings},
|
||||||
tree_sitter_rust, Anchor, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language,
|
tree_sitter_rust, Anchor, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language,
|
||||||
LanguageConfig, OffsetRangeExt, Point, Rope,
|
LanguageConfig, OffsetRangeExt, Point, Rope,
|
||||||
};
|
};
|
||||||
use live_kit_client::MacOSDisplay;
|
use live_kit_client::MacOSDisplay;
|
||||||
use lsp::LanguageServerId;
|
use lsp::LanguageServerId;
|
||||||
use project::{
|
use project::{search::SearchQuery, DiagnosticSummary, HoverBlockKind, Project, ProjectPath};
|
||||||
search::SearchQuery, DiagnosticSummary, HoverBlockKind, InlayHintKind, Project, ProjectPath,
|
|
||||||
};
|
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use settings::SettingsStore;
|
use settings::SettingsStore;
|
||||||
|
@ -7823,24 +7821,24 @@ async fn test_mutual_editor_inlay_hint_cache_update(
|
||||||
|
|
||||||
cx_a.update(|cx| {
|
cx_a.update(|cx| {
|
||||||
cx.update_global(|store: &mut SettingsStore, cx| {
|
cx.update_global(|store: &mut SettingsStore, cx| {
|
||||||
store.update_user_settings::<EditorSettings>(cx, |settings| {
|
store.update_user_settings::<AllLanguageSettings>(cx, |settings| {
|
||||||
settings.inlay_hints = Some(editor::InlayHintsContent {
|
settings.defaults.inlay_hints = Some(InlayHintSettings {
|
||||||
enabled: Some(true),
|
enabled: true,
|
||||||
show_type_hints: Some(true),
|
show_type_hints: true,
|
||||||
show_parameter_hints: Some(false),
|
show_parameter_hints: false,
|
||||||
show_other_hints: Some(true),
|
show_other_hints: true,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
cx_b.update(|cx| {
|
cx_b.update(|cx| {
|
||||||
cx.update_global(|store: &mut SettingsStore, cx| {
|
cx.update_global(|store: &mut SettingsStore, cx| {
|
||||||
store.update_user_settings::<EditorSettings>(cx, |settings| {
|
store.update_user_settings::<AllLanguageSettings>(cx, |settings| {
|
||||||
settings.inlay_hints = Some(editor::InlayHintsContent {
|
settings.defaults.inlay_hints = Some(InlayHintSettings {
|
||||||
enabled: Some(true),
|
enabled: true,
|
||||||
show_type_hints: Some(true),
|
show_type_hints: true,
|
||||||
show_parameter_hints: Some(false),
|
show_parameter_hints: false,
|
||||||
show_other_hints: Some(true),
|
show_other_hints: true,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -31,7 +31,7 @@ use collections::{BTreeMap, Bound, HashMap, HashSet, VecDeque};
|
||||||
use copilot::Copilot;
|
use copilot::Copilot;
|
||||||
pub use display_map::DisplayPoint;
|
pub use display_map::DisplayPoint;
|
||||||
use display_map::*;
|
use display_map::*;
|
||||||
pub use editor_settings::{EditorSettings, InlayHints, InlayHintsContent};
|
pub use editor_settings::EditorSettings;
|
||||||
pub use element::{
|
pub use element::{
|
||||||
Cursor, EditorElement, HighlightedRange, HighlightedRangeLine, LineWithInvisibles,
|
Cursor, EditorElement, HighlightedRange, HighlightedRangeLine, LineWithInvisibles,
|
||||||
};
|
};
|
||||||
|
@ -58,7 +58,7 @@ pub use items::MAX_TAB_TITLE_LEN;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
pub use language::{char_kind, CharKind};
|
pub use language::{char_kind, CharKind};
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::{self, all_language_settings},
|
language_settings::{self, all_language_settings, InlayHintSettings},
|
||||||
AutoindentMode, BracketPair, Buffer, CodeAction, CodeLabel, Completion, CursorShape,
|
AutoindentMode, BracketPair, Buffer, CodeAction, CodeLabel, Completion, CursorShape,
|
||||||
Diagnostic, DiagnosticSeverity, File, IndentKind, IndentSize, Language, OffsetRangeExt,
|
Diagnostic, DiagnosticSeverity, File, IndentKind, IndentSize, Language, OffsetRangeExt,
|
||||||
OffsetUtf16, Point, Selection, SelectionGoal, TransactionId,
|
OffsetUtf16, Point, Selection, SelectionGoal, TransactionId,
|
||||||
|
@ -88,7 +88,7 @@ use std::{
|
||||||
cmp::{self, Ordering, Reverse},
|
cmp::{self, Ordering, Reverse},
|
||||||
mem,
|
mem,
|
||||||
num::NonZeroU32,
|
num::NonZeroU32,
|
||||||
ops::{Deref, DerefMut, Range},
|
ops::{ControlFlow, Deref, DerefMut, Range},
|
||||||
path::Path,
|
path::Path,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
|
@ -1197,7 +1197,7 @@ enum GotoDefinitionKind {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
enum InlayRefreshReason {
|
enum InlayRefreshReason {
|
||||||
SettingsChange(editor_settings::InlayHints),
|
SettingsChange(InlayHintSettings),
|
||||||
NewLinesShown,
|
NewLinesShown,
|
||||||
ExcerptEdited,
|
ExcerptEdited,
|
||||||
RefreshRequested,
|
RefreshRequested,
|
||||||
|
@ -1320,6 +1320,12 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inlay_hint_settings = inlay_hint_settings(
|
||||||
|
selections.newest_anchor().head(),
|
||||||
|
&buffer.read(cx).snapshot(cx),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
handle: cx.weak_handle(),
|
handle: cx.weak_handle(),
|
||||||
buffer: buffer.clone(),
|
buffer: buffer.clone(),
|
||||||
|
@ -1370,7 +1376,7 @@ impl Editor {
|
||||||
hover_state: Default::default(),
|
hover_state: Default::default(),
|
||||||
link_go_to_definition_state: Default::default(),
|
link_go_to_definition_state: Default::default(),
|
||||||
copilot_state: Default::default(),
|
copilot_state: Default::default(),
|
||||||
inlay_hint_cache: InlayHintCache::new(settings::get::<EditorSettings>(cx).inlay_hints),
|
inlay_hint_cache: InlayHintCache::new(inlay_hint_settings),
|
||||||
gutter_hovered: false,
|
gutter_hovered: false,
|
||||||
_subscriptions: vec![
|
_subscriptions: vec![
|
||||||
cx.observe(&buffer, Self::on_buffer_changed),
|
cx.observe(&buffer, Self::on_buffer_changed),
|
||||||
|
@ -2607,35 +2613,38 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refresh_inlays(&mut self, reason: InlayRefreshReason, cx: &mut ViewContext<Self>) {
|
fn refresh_inlays(&mut self, reason: InlayRefreshReason, cx: &mut ViewContext<Self>) {
|
||||||
if self.project.is_none()
|
if self.project.is_none() || self.mode != EditorMode::Full {
|
||||||
|| self.mode != EditorMode::Full
|
|
||||||
|| !settings::get::<EditorSettings>(cx).inlay_hints.enabled
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let invalidate_cache = match reason {
|
let invalidate_cache = match reason {
|
||||||
InlayRefreshReason::SettingsChange(new_settings) => {
|
InlayRefreshReason::SettingsChange(new_settings) => {
|
||||||
let new_splice = self.inlay_hint_cache.update_settings(
|
match self.inlay_hint_cache.update_settings(
|
||||||
&self.buffer,
|
&self.buffer,
|
||||||
new_settings,
|
new_settings,
|
||||||
self.visible_inlay_hints(cx),
|
self.visible_inlay_hints(cx),
|
||||||
cx,
|
cx,
|
||||||
);
|
) {
|
||||||
if let Some(InlaySplice {
|
ControlFlow::Break(Some(InlaySplice {
|
||||||
to_remove,
|
to_remove,
|
||||||
to_insert,
|
to_insert,
|
||||||
}) = new_splice
|
})) => {
|
||||||
{
|
self.splice_inlay_hints(to_remove, to_insert, cx);
|
||||||
self.splice_inlay_hints(to_remove, to_insert, cx);
|
return;
|
||||||
|
}
|
||||||
|
ControlFlow::Break(None) => return,
|
||||||
|
ControlFlow::Continue(()) => InvalidationStrategy::Forced,
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
InlayRefreshReason::NewLinesShown => InvalidationStrategy::None,
|
InlayRefreshReason::NewLinesShown => InvalidationStrategy::None,
|
||||||
InlayRefreshReason::ExcerptEdited => InvalidationStrategy::OnConflict,
|
InlayRefreshReason::ExcerptEdited => InvalidationStrategy::OnConflict,
|
||||||
InlayRefreshReason::RefreshRequested => InvalidationStrategy::Forced,
|
InlayRefreshReason::RefreshRequested => InvalidationStrategy::Forced,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !self.inlay_hint_cache.enabled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let excerpts_to_query = self
|
let excerpts_to_query = self
|
||||||
.excerpt_visible_offsets(cx)
|
.excerpt_visible_offsets(cx)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -7298,7 +7307,11 @@ impl Editor {
|
||||||
fn settings_changed(&mut self, cx: &mut ViewContext<Self>) {
|
fn settings_changed(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
self.refresh_copilot_suggestions(true, cx);
|
self.refresh_copilot_suggestions(true, cx);
|
||||||
self.refresh_inlays(
|
self.refresh_inlays(
|
||||||
InlayRefreshReason::SettingsChange(settings::get::<EditorSettings>(cx).inlay_hints),
|
InlayRefreshReason::SettingsChange(inlay_hint_settings(
|
||||||
|
self.selections.newest_anchor().head(),
|
||||||
|
&self.buffer.read(cx).snapshot(cx),
|
||||||
|
cx,
|
||||||
|
)),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -7596,6 +7609,19 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn inlay_hint_settings(
|
||||||
|
location: Anchor,
|
||||||
|
snapshot: &MultiBufferSnapshot,
|
||||||
|
cx: &mut ViewContext<'_, '_, Editor>,
|
||||||
|
) -> InlayHintSettings {
|
||||||
|
let file = snapshot.file_at(location);
|
||||||
|
let language = snapshot.language_at(location);
|
||||||
|
let settings = all_language_settings(file, cx);
|
||||||
|
settings
|
||||||
|
.language(language.map(|l| l.name()).as_deref())
|
||||||
|
.inlay_hints
|
||||||
|
}
|
||||||
|
|
||||||
fn consume_contiguous_rows(
|
fn consume_contiguous_rows(
|
||||||
contiguous_row_selections: &mut Vec<Selection<Point>>,
|
contiguous_row_selections: &mut Vec<Selection<Point>>,
|
||||||
selection: &Selection<Point>,
|
selection: &Selection<Point>,
|
||||||
|
|
|
@ -9,7 +9,6 @@ pub struct EditorSettings {
|
||||||
pub show_completions_on_input: bool,
|
pub show_completions_on_input: bool,
|
||||||
pub use_on_type_format: bool,
|
pub use_on_type_format: bool,
|
||||||
pub scrollbar: Scrollbar,
|
pub scrollbar: Scrollbar,
|
||||||
pub inlay_hints: InlayHints,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||||
|
@ -18,14 +17,6 @@ pub struct Scrollbar {
|
||||||
pub git_diff: bool,
|
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)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum ShowScrollbar {
|
pub enum ShowScrollbar {
|
||||||
|
@ -42,7 +33,6 @@ pub struct EditorSettingsContent {
|
||||||
pub show_completions_on_input: Option<bool>,
|
pub show_completions_on_input: Option<bool>,
|
||||||
pub use_on_type_format: Option<bool>,
|
pub use_on_type_format: Option<bool>,
|
||||||
pub scrollbar: Option<ScrollbarContent>,
|
pub scrollbar: Option<ScrollbarContent>,
|
||||||
pub inlay_hints: Option<InlayHintsContent>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||||
|
@ -51,14 +41,6 @@ pub struct ScrollbarContent {
|
||||||
pub git_diff: Option<bool>,
|
pub git_diff: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
|
||||||
pub struct InlayHintsContent {
|
|
||||||
pub enabled: Option<bool>,
|
|
||||||
pub show_type_hints: Option<bool>,
|
|
||||||
pub show_parameter_hints: Option<bool>,
|
|
||||||
pub show_other_hints: Option<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Setting for EditorSettings {
|
impl Setting for EditorSettings {
|
||||||
const KEY: Option<&'static str> = None;
|
const KEY: Option<&'static str> = None;
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,29 @@
|
||||||
use std::{cmp, ops::Range, sync::Arc};
|
use std::{
|
||||||
|
cmp,
|
||||||
|
ops::{ControlFlow, Range},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
display_map::Inlay, editor_settings, Anchor, Editor, ExcerptId, InlayId, MultiBuffer,
|
display_map::Inlay, Anchor, Editor, ExcerptId, InlayId, MultiBuffer, MultiBufferSnapshot,
|
||||||
MultiBufferSnapshot,
|
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clock::Global;
|
use clock::Global;
|
||||||
use gpui::{ModelHandle, Task, ViewContext};
|
use gpui::{ModelHandle, Task, ViewContext};
|
||||||
use language::{Buffer, BufferSnapshot};
|
use language::{language_settings::InlayHintKind, Buffer, BufferSnapshot};
|
||||||
use log::error;
|
use log::error;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use project::{InlayHint, InlayHintKind};
|
use project::InlayHint;
|
||||||
|
|
||||||
use collections::{hash_map, HashMap, HashSet};
|
use collections::{hash_map, HashMap, HashSet};
|
||||||
|
use language::language_settings::InlayHintSettings;
|
||||||
use util::post_inc;
|
use util::post_inc;
|
||||||
|
|
||||||
pub struct InlayHintCache {
|
pub struct InlayHintCache {
|
||||||
pub hints: HashMap<ExcerptId, Arc<RwLock<CachedExcerptHints>>>,
|
pub hints: HashMap<ExcerptId, Arc<RwLock<CachedExcerptHints>>>,
|
||||||
pub allowed_hint_kinds: HashSet<Option<InlayHintKind>>,
|
pub allowed_hint_kinds: HashSet<Option<InlayHintKind>>,
|
||||||
pub version: usize,
|
pub version: usize,
|
||||||
|
pub enabled: bool,
|
||||||
update_tasks: HashMap<ExcerptId, UpdateTask>,
|
update_tasks: HashMap<ExcerptId, UpdateTask>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,9 +143,10 @@ struct ExcerptHintsUpdate {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InlayHintCache {
|
impl InlayHintCache {
|
||||||
pub fn new(inlay_hint_settings: editor_settings::InlayHints) -> Self {
|
pub fn new(inlay_hint_settings: InlayHintSettings) -> Self {
|
||||||
Self {
|
Self {
|
||||||
allowed_hint_kinds: allowed_hint_types(inlay_hint_settings),
|
allowed_hint_kinds: inlay_hint_settings.enabled_inlay_hint_kinds(),
|
||||||
|
enabled: inlay_hint_settings.enabled,
|
||||||
hints: HashMap::default(),
|
hints: HashMap::default(),
|
||||||
update_tasks: HashMap::default(),
|
update_tasks: HashMap::default(),
|
||||||
version: 0,
|
version: 0,
|
||||||
|
@ -150,38 +156,53 @@ impl InlayHintCache {
|
||||||
pub fn update_settings(
|
pub fn update_settings(
|
||||||
&mut self,
|
&mut self,
|
||||||
multi_buffer: &ModelHandle<MultiBuffer>,
|
multi_buffer: &ModelHandle<MultiBuffer>,
|
||||||
inlay_hint_settings: editor_settings::InlayHints,
|
new_hint_settings: InlayHintSettings,
|
||||||
visible_hints: Vec<Inlay>,
|
visible_hints: Vec<Inlay>,
|
||||||
cx: &mut ViewContext<Editor>,
|
cx: &mut ViewContext<Editor>,
|
||||||
) -> Option<InlaySplice> {
|
) -> ControlFlow<Option<InlaySplice>> {
|
||||||
let new_allowed_hint_kinds = allowed_hint_types(inlay_hint_settings);
|
dbg!(new_hint_settings);
|
||||||
if !inlay_hint_settings.enabled {
|
let new_allowed_hint_kinds = new_hint_settings.enabled_inlay_hint_kinds();
|
||||||
if self.hints.is_empty() {
|
match (self.enabled, new_hint_settings.enabled) {
|
||||||
|
(false, false) => {
|
||||||
self.allowed_hint_kinds = new_allowed_hint_kinds;
|
self.allowed_hint_kinds = new_allowed_hint_kinds;
|
||||||
None
|
ControlFlow::Break(None)
|
||||||
} else {
|
|
||||||
self.clear();
|
|
||||||
self.allowed_hint_kinds = new_allowed_hint_kinds;
|
|
||||||
Some(InlaySplice {
|
|
||||||
to_remove: visible_hints.iter().map(|inlay| inlay.id).collect(),
|
|
||||||
to_insert: Vec::new(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
} else if new_allowed_hint_kinds == self.allowed_hint_kinds {
|
(true, true) => {
|
||||||
None
|
if new_allowed_hint_kinds == self.allowed_hint_kinds {
|
||||||
} else {
|
ControlFlow::Break(None)
|
||||||
let new_splice = self.new_allowed_hint_kinds_splice(
|
} else {
|
||||||
multi_buffer,
|
let new_splice = self.new_allowed_hint_kinds_splice(
|
||||||
&visible_hints,
|
multi_buffer,
|
||||||
&new_allowed_hint_kinds,
|
&visible_hints,
|
||||||
cx,
|
&new_allowed_hint_kinds,
|
||||||
);
|
cx,
|
||||||
if new_splice.is_some() {
|
);
|
||||||
self.version += 1;
|
if new_splice.is_some() {
|
||||||
self.update_tasks.clear();
|
self.version += 1;
|
||||||
self.allowed_hint_kinds = new_allowed_hint_kinds;
|
self.update_tasks.clear();
|
||||||
|
self.allowed_hint_kinds = new_allowed_hint_kinds;
|
||||||
|
}
|
||||||
|
ControlFlow::Break(new_splice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(true, false) => {
|
||||||
|
self.enabled = new_hint_settings.enabled;
|
||||||
|
self.allowed_hint_kinds = new_allowed_hint_kinds;
|
||||||
|
if self.hints.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.enabled = new_hint_settings.enabled;
|
||||||
|
self.allowed_hint_kinds = new_allowed_hint_kinds;
|
||||||
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
new_splice
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +212,9 @@ impl InlayHintCache {
|
||||||
invalidate: InvalidationStrategy,
|
invalidate: InvalidationStrategy,
|
||||||
cx: &mut ViewContext<Editor>,
|
cx: &mut ViewContext<Editor>,
|
||||||
) {
|
) {
|
||||||
|
if !self.enabled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let update_tasks = &mut self.update_tasks;
|
let update_tasks = &mut self.update_tasks;
|
||||||
let invalidate_cache = matches!(
|
let invalidate_cache = matches!(
|
||||||
invalidate,
|
invalidate,
|
||||||
|
@ -754,22 +778,6 @@ fn calculate_hint_updates(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allowed_hint_types(
|
|
||||||
inlay_hint_settings: editor_settings::InlayHints,
|
|
||||||
) -> HashSet<Option<InlayHintKind>> {
|
|
||||||
let mut new_allowed_hint_types = HashSet::default();
|
|
||||||
if inlay_hint_settings.show_type_hints {
|
|
||||||
new_allowed_hint_types.insert(Some(InlayHintKind::Type));
|
|
||||||
}
|
|
||||||
if inlay_hint_settings.show_parameter_hints {
|
|
||||||
new_allowed_hint_types.insert(Some(InlayHintKind::Parameter));
|
|
||||||
}
|
|
||||||
if inlay_hint_settings.show_other_hints {
|
|
||||||
new_allowed_hint_types.insert(None);
|
|
||||||
}
|
|
||||||
new_allowed_hint_types
|
|
||||||
}
|
|
||||||
|
|
||||||
struct HintFetchRanges {
|
struct HintFetchRanges {
|
||||||
visible_range: Range<language::Anchor>,
|
visible_range: Range<language::Anchor>,
|
||||||
other_ranges: Vec<Range<language::Anchor>>,
|
other_ranges: Vec<Range<language::Anchor>>,
|
||||||
|
@ -788,18 +796,19 @@ fn contains_position(
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::sync::atomic::{AtomicU32, Ordering};
|
use std::sync::atomic::{AtomicU32, Ordering};
|
||||||
|
|
||||||
use crate::serde_json::json;
|
use crate::{serde_json::json, InlayHintSettings};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use gpui::{TestAppContext, ViewHandle};
|
use gpui::{TestAppContext, ViewHandle};
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::AllLanguageSettingsContent, FakeLspAdapter, Language, LanguageConfig,
|
language_settings::{AllLanguageSettings, AllLanguageSettingsContent},
|
||||||
|
FakeLspAdapter, Language, LanguageConfig,
|
||||||
};
|
};
|
||||||
use lsp::FakeLanguageServer;
|
use lsp::FakeLanguageServer;
|
||||||
use project::{FakeFs, Project};
|
use project::{FakeFs, Project};
|
||||||
use settings::SettingsStore;
|
use settings::SettingsStore;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
use crate::{editor_tests::update_test_settings, EditorSettings};
|
use crate::editor_tests::update_test_settings;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -926,16 +935,13 @@ mod tests {
|
||||||
) -> (&'static str, ViewHandle<Editor>, FakeLanguageServer) {
|
) -> (&'static str, ViewHandle<Editor>, FakeLanguageServer) {
|
||||||
cx.update(|cx| {
|
cx.update(|cx| {
|
||||||
cx.update_global(|store: &mut SettingsStore, cx| {
|
cx.update_global(|store: &mut SettingsStore, cx| {
|
||||||
store.update_user_settings::<EditorSettings>(cx, |settings| {
|
store.update_user_settings::<AllLanguageSettings>(cx, |settings| {
|
||||||
settings.inlay_hints = Some(crate::InlayHintsContent {
|
settings.defaults.inlay_hints = Some(InlayHintSettings {
|
||||||
enabled: Some(true),
|
enabled: true,
|
||||||
show_type_hints: Some(
|
show_type_hints: allowed_hint_kinds.contains(&Some(InlayHintKind::Type)),
|
||||||
allowed_hint_kinds.contains(&Some(InlayHintKind::Type)),
|
show_parameter_hints: allowed_hint_kinds
|
||||||
),
|
.contains(&Some(InlayHintKind::Parameter)),
|
||||||
show_parameter_hints: Some(
|
show_other_hints: allowed_hint_kinds.contains(&None),
|
||||||
allowed_hint_kinds.contains(&Some(InlayHintKind::Parameter)),
|
|
||||||
),
|
|
||||||
show_other_hints: Some(allowed_hint_kinds.contains(&None)),
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{File, Language};
|
use crate::{File, Language};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use collections::HashMap;
|
use collections::{HashMap, HashSet};
|
||||||
use globset::GlobMatcher;
|
use globset::GlobMatcher;
|
||||||
use gpui::AppContext;
|
use gpui::AppContext;
|
||||||
use schemars::{
|
use schemars::{
|
||||||
|
@ -52,6 +52,7 @@ pub struct LanguageSettings {
|
||||||
pub show_copilot_suggestions: bool,
|
pub show_copilot_suggestions: bool,
|
||||||
pub show_whitespaces: ShowWhitespaceSetting,
|
pub show_whitespaces: ShowWhitespaceSetting,
|
||||||
pub extend_comment_on_newline: bool,
|
pub extend_comment_on_newline: bool,
|
||||||
|
pub inlay_hints: InlayHintSettings,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
|
@ -98,6 +99,8 @@ pub struct LanguageSettingsContent {
|
||||||
pub show_whitespaces: Option<ShowWhitespaceSetting>,
|
pub show_whitespaces: Option<ShowWhitespaceSetting>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub extend_comment_on_newline: Option<bool>,
|
pub extend_comment_on_newline: Option<bool>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub inlay_hints: Option<InlayHintSettings>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||||
|
@ -150,6 +153,41 @@ pub enum Formatter {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||||
|
pub struct InlayHintSettings {
|
||||||
|
#[serde(default)]
|
||||||
|
pub enabled: bool,
|
||||||
|
#[serde(default = "default_true")]
|
||||||
|
pub show_type_hints: bool,
|
||||||
|
#[serde(default = "default_true")]
|
||||||
|
pub show_parameter_hints: bool,
|
||||||
|
#[serde(default = "default_true")]
|
||||||
|
pub show_other_hints: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_true() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InlayHintSettings {
|
||||||
|
pub fn enabled_inlay_hint_kinds(&self) -> HashSet<Option<InlayHintKind>> {
|
||||||
|
let mut kinds = HashSet::default();
|
||||||
|
if !self.enabled {
|
||||||
|
return kinds;
|
||||||
|
}
|
||||||
|
if self.show_type_hints {
|
||||||
|
kinds.insert(Some(InlayHintKind::Type));
|
||||||
|
}
|
||||||
|
if self.show_parameter_hints {
|
||||||
|
kinds.insert(Some(InlayHintKind::Parameter));
|
||||||
|
}
|
||||||
|
if self.show_other_hints {
|
||||||
|
kinds.insert(None);
|
||||||
|
}
|
||||||
|
kinds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AllLanguageSettings {
|
impl AllLanguageSettings {
|
||||||
pub fn language<'a>(&'a self, language_name: Option<&str>) -> &'a LanguageSettings {
|
pub fn language<'a>(&'a self, language_name: Option<&str>) -> &'a LanguageSettings {
|
||||||
if let Some(name) = language_name {
|
if let Some(name) = language_name {
|
||||||
|
@ -184,6 +222,29 @@ impl AllLanguageSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum InlayHintKind {
|
||||||
|
Type,
|
||||||
|
Parameter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InlayHintKind {
|
||||||
|
pub fn from_name(name: &str) -> Option<Self> {
|
||||||
|
match name {
|
||||||
|
"type" => Some(InlayHintKind::Type),
|
||||||
|
"parameter" => Some(InlayHintKind::Parameter),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
InlayHintKind::Type => "type",
|
||||||
|
InlayHintKind::Parameter => "parameter",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl settings::Setting for AllLanguageSettings {
|
impl settings::Setting for AllLanguageSettings {
|
||||||
const KEY: Option<&'static str> = None;
|
const KEY: Option<&'static str> = None;
|
||||||
|
|
||||||
|
@ -347,6 +408,7 @@ fn merge_settings(settings: &mut LanguageSettings, src: &LanguageSettingsContent
|
||||||
&mut settings.extend_comment_on_newline,
|
&mut settings.extend_comment_on_newline,
|
||||||
src.extend_comment_on_newline,
|
src.extend_comment_on_newline,
|
||||||
);
|
);
|
||||||
|
merge(&mut settings.inlay_hints, src.inlay_hints);
|
||||||
fn merge<T>(target: &mut T, value: Option<T>) {
|
fn merge<T>(target: &mut T, value: Option<T>) {
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
*target = value;
|
*target = value;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
DocumentHighlight, Hover, HoverBlock, HoverBlockKind, InlayHint, InlayHintKind, InlayHintLabel,
|
DocumentHighlight, Hover, HoverBlock, HoverBlockKind, InlayHint, InlayHintLabel,
|
||||||
InlayHintLabelPart, InlayHintLabelPartTooltip, InlayHintTooltip, Location, LocationLink,
|
InlayHintLabelPart, InlayHintLabelPartTooltip, InlayHintTooltip, Location, LocationLink,
|
||||||
MarkupContent, Project, ProjectTransaction,
|
MarkupContent, Project, ProjectTransaction,
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@ use client::proto::{self, PeerId};
|
||||||
use fs::LineEnding;
|
use fs::LineEnding;
|
||||||
use gpui::{AppContext, AsyncAppContext, ModelHandle};
|
use gpui::{AppContext, AsyncAppContext, ModelHandle};
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::language_settings,
|
language_settings::{language_settings, InlayHintKind},
|
||||||
point_from_lsp, point_to_lsp,
|
point_from_lsp, point_to_lsp,
|
||||||
proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
|
proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
|
||||||
range_from_lsp, range_to_lsp, Anchor, Bias, Buffer, CachedLspAdapter, CharKind, CodeAction,
|
range_from_lsp, range_to_lsp, Anchor, Bias, Buffer, CachedLspAdapter, CharKind, CodeAction,
|
||||||
|
|
|
@ -31,7 +31,7 @@ use gpui::{
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::{
|
use language::{
|
||||||
language_settings::{language_settings, FormatOnSave, Formatter},
|
language_settings::{language_settings, FormatOnSave, Formatter, InlayHintKind},
|
||||||
point_to_lsp,
|
point_to_lsp,
|
||||||
proto::{
|
proto::{
|
||||||
deserialize_anchor, deserialize_fingerprint, deserialize_line_ending, deserialize_version,
|
deserialize_anchor, deserialize_fingerprint, deserialize_line_ending, deserialize_version,
|
||||||
|
@ -339,29 +339,6 @@ pub struct InlayHint {
|
||||||
pub tooltip: Option<InlayHintTooltip>,
|
pub tooltip: Option<InlayHintTooltip>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
||||||
pub enum InlayHintKind {
|
|
||||||
Type,
|
|
||||||
Parameter,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InlayHintKind {
|
|
||||||
pub fn from_name(name: &str) -> Option<Self> {
|
|
||||||
match name {
|
|
||||||
"type" => Some(InlayHintKind::Type),
|
|
||||||
"parameter" => Some(InlayHintKind::Parameter),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn name(&self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
InlayHintKind::Type => "type",
|
|
||||||
InlayHintKind::Parameter => "parameter",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InlayHint {
|
impl InlayHint {
|
||||||
pub fn text(&self) -> String {
|
pub fn text(&self) -> String {
|
||||||
match &self.label {
|
match &self.label {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue