Add per-language settings `show_completions_on_input` and `show_completion_documentation` (#21722)

Michael Sloan created

Release Notes:

- Added `show_completions_on_input` and `show_completion_documentation`
per-language settings. These settings were available before, but were
not configurable per-language.

Change summary

crates/editor/src/editor.rs              | 27 +++++++++++++++----------
crates/editor/src/editor_settings.rs     | 12 -----------
crates/editor/src/editor_tests.rs        |  8 +-----
crates/language/src/language_settings.rs | 24 +++++++++++++++++++++++
docs/src/configuring-languages.md        |  2 +
5 files changed, 44 insertions(+), 29 deletions(-)

Detailed changes

crates/editor/src/editor.rs πŸ”—

@@ -1006,12 +1006,14 @@ struct CompletionsMenu {
     scroll_handle: UniformListScrollHandle,
     resolve_completions: bool,
     aside_was_displayed: Cell<bool>,
+    show_completion_documentation: bool,
 }
 
 impl CompletionsMenu {
     fn new(
         id: CompletionId,
         sort_completions: bool,
+        show_completion_documentation: bool,
         initial_position: Anchor,
         buffer: Model<Buffer>,
         completions: Box<[Completion]>,
@@ -1040,6 +1042,7 @@ impl CompletionsMenu {
             scroll_handle: UniformListScrollHandle::new(),
             resolve_completions: true,
             aside_was_displayed: Cell::new(aside_was_displayed),
+            show_completion_documentation: show_completion_documentation,
         }
     }
 
@@ -1094,6 +1097,7 @@ impl CompletionsMenu {
             scroll_handle: UniformListScrollHandle::new(),
             resolve_completions: false,
             aside_was_displayed: Cell::new(false),
+            show_completion_documentation: false,
         }
     }
 
@@ -1192,9 +1196,7 @@ impl CompletionsMenu {
         workspace: Option<WeakView<Workspace>>,
         cx: &mut ViewContext<Editor>,
     ) -> AnyElement {
-        let settings = EditorSettings::get_global(cx);
-        let show_completion_documentation = settings.show_completion_documentation;
-
+        let show_completion_documentation = self.show_completion_documentation;
         let widest_completion_ix = self
             .matches
             .iter()
@@ -4459,6 +4461,11 @@ impl Editor {
             } else {
                 return;
             };
+        let show_completion_documentation = buffer
+            .read(cx)
+            .snapshot()
+            .settings_at(buffer_position, cx)
+            .show_completion_documentation;
 
         let query = Self::completion_query(&self.buffer.read(cx).read(cx), position);
 
@@ -4496,6 +4503,7 @@ impl Editor {
                     let mut menu = CompletionsMenu::new(
                         id,
                         sort_completions,
+                        show_completion_documentation,
                         position,
                         buffer.clone(),
                         completions.into(),
@@ -14174,10 +14182,6 @@ impl CompletionProvider for Model<Project> {
         trigger_in_words: bool,
         cx: &mut ViewContext<Editor>,
     ) -> bool {
-        if !EditorSettings::get_global(cx).show_completions_on_input {
-            return false;
-        }
-
         let mut chars = text.chars();
         let char = if let Some(char) = chars.next() {
             char
@@ -14189,10 +14193,11 @@ impl CompletionProvider for Model<Project> {
         }
 
         let buffer = buffer.read(cx);
-        let classifier = buffer
-            .snapshot()
-            .char_classifier_at(position)
-            .for_completion(true);
+        let snapshot = buffer.snapshot();
+        if !snapshot.settings_at(position, cx).show_completions_on_input {
+            return false;
+        }
+        let classifier = snapshot.char_classifier_at(position).for_completion(true);
         if trigger_in_words && classifier.is_word(char) {
             return true;
         }

crates/editor/src/editor_settings.rs πŸ”—

@@ -10,8 +10,6 @@ pub struct EditorSettings {
     pub cursor_shape: Option<CursorShape>,
     pub current_line_highlight: CurrentLineHighlight,
     pub hover_popover_enabled: bool,
-    pub show_completions_on_input: bool,
-    pub show_completion_documentation: bool,
     pub toolbar: Toolbar,
     pub scrollbar: Scrollbar,
     pub gutter: Gutter,
@@ -193,16 +191,6 @@ pub struct EditorSettingsContent {
     /// Default: true
     pub hover_popover_enabled: Option<bool>,
 
-    /// Whether to pop the completions menu while typing in an editor without
-    /// explicitly requesting it.
-    ///
-    /// Default: true
-    pub show_completions_on_input: Option<bool>,
-    /// Whether to display inline and alongside documentation for items in the
-    /// completions menu.
-    ///
-    /// Default: true
-    pub show_completion_documentation: Option<bool>,
     /// Toolbar related settings
     pub toolbar: Option<ToolbarContent>,
     /// Scrollbar related settings

crates/editor/src/editor_tests.rs πŸ”—

@@ -8376,12 +8376,8 @@ async fn test_completion(cx: &mut gpui::TestAppContext) {
     handle_resolve_completion_request(&mut cx, None).await;
     apply_additional_edits.await.unwrap();
 
-    cx.update(|cx| {
-        cx.update_global::<SettingsStore, _>(|settings, cx| {
-            settings.update_user_settings::<EditorSettings>(cx, |settings| {
-                settings.show_completions_on_input = Some(false);
-            });
-        })
+    update_test_language_settings(&mut cx, |settings| {
+        settings.defaults.show_completions_on_input = Some(false);
     });
     cx.set_state("editorˇ");
     cx.simulate_keystroke(".");

crates/language/src/language_settings.rs πŸ”—

@@ -138,6 +138,12 @@ pub struct LanguageSettings {
     pub linked_edits: bool,
     /// Task configuration for this language.
     pub tasks: LanguageTaskConfig,
+    /// Whether to pop the completions menu while typing in an editor without
+    /// explicitly requesting it.
+    pub show_completions_on_input: bool,
+    /// Whether to display inline and alongside documentation for items in the
+    /// completions menu.
+    pub show_completion_documentation: bool,
 }
 
 impl LanguageSettings {
@@ -382,6 +388,16 @@ pub struct LanguageSettingsContent {
     ///
     /// Default: {}
     pub tasks: Option<LanguageTaskConfig>,
+    /// Whether to pop the completions menu while typing in an editor without
+    /// explicitly requesting it.
+    ///
+    /// Default: true
+    pub show_completions_on_input: Option<bool>,
+    /// Whether to display inline and alongside documentation for items in the
+    /// completions menu.
+    ///
+    /// Default: true
+    pub show_completion_documentation: Option<bool>,
 }
 
 /// The contents of the inline completion settings.
@@ -1186,6 +1202,14 @@ fn merge_settings(settings: &mut LanguageSettings, src: &LanguageSettingsContent
         src.extend_comment_on_newline,
     );
     merge(&mut settings.inlay_hints, src.inlay_hints);
+    merge(
+        &mut settings.show_completions_on_input,
+        src.show_completions_on_input,
+    );
+    merge(
+        &mut settings.show_completion_documentation,
+        src.show_completion_documentation,
+    );
 }
 
 /// Allows to enable/disable formatting with Prettier

docs/src/configuring-languages.md πŸ”—

@@ -56,6 +56,8 @@ You can customize a wide range of settings for each language, including:
 - [`hard_tabs`](./configuring-zed.md#hard-tabs): Use tabs instead of spaces for indentation
 - [`preferred_line_length`](./configuring-zed.md#preferred-line-length): The recommended maximum line length
 - [`soft_wrap`](./configuring-zed.md#soft-wrap): How to wrap long lines of code
+- [`show_completions_on_input`](./configuring-zed.md#show-completions-on-input): Whether or not to show completions as you type
+- [`show_completion_documentation`](./configuring-zed.md#show-completion-documentation): Whether to display inline and alongside documentation for items in the completions menu
 
 These settings allow you to maintain specific coding styles across different languages and projects.