Add setting to disable inline completions in language scopes (#20508)

Thorsten Ball and Bennet created

This adds a setting to disable inline completions in language scopes to,
for example, disable them in comments or strings.

This setting can be made per language.

Examples:

```json
{
  "languages": {
    "Go": {
      "inline_completions_disabled_in": ["comment", "string"]
    }
  }
}
```

```json
{
  "inline_completions_disabled_in": ["comment"]
}
```

Closes #9133

Release Notes:

- Added language setting to disable inline comments in certain scopes.
Example: `{"languages": {"Go": {"inline_completions_disabled_in":
["comment", "string"]}}}`

Co-authored-by: Bennet <bennet@zed.dev>

Change summary

assets/settings/default.json             |  3 ++
crates/editor/src/editor.rs              | 25 +++++++++++++++++++
crates/language/src/language_settings.rs | 15 +++++++++++
docs/src/configuring-zed.md              | 34 ++++++++++++++++++++++++++
4 files changed, 77 insertions(+)

Detailed changes

assets/settings/default.json 🔗

@@ -193,6 +193,9 @@
   // Controls whether inline completions are shown immediately (true)
   // or manually by triggering `editor::ShowInlineCompletion` (false).
   "show_inline_completions": true,
+  // Controls whether inline completions are shown in a given language scope.
+  // Example: ["string", "comment"]
+  "inline_completions_disabled_in": [],
   // Whether to show tabs and spaces in the editor.
   // This setting can take three values:
   //

crates/editor/src/editor.rs 🔗

@@ -2510,6 +2510,10 @@ impl Editor {
             return false;
         }
 
+        if self.inline_completions_disabled_in_scope(buffer, buffer_position, cx) {
+            return false;
+        }
+
         if let Some(provider) = self.inline_completion_provider() {
             if let Some(show_inline_completions) = self.show_inline_completions_override {
                 show_inline_completions
@@ -2521,6 +2525,27 @@ impl Editor {
         }
     }
 
+    fn inline_completions_disabled_in_scope(
+        &self,
+        buffer: &Model<Buffer>,
+        buffer_position: language::Anchor,
+        cx: &AppContext,
+    ) -> bool {
+        let snapshot = buffer.read(cx).snapshot();
+        let settings = snapshot.settings_at(buffer_position, cx);
+
+        let Some(scope) = snapshot.language_scope_at(buffer_position) else {
+            return false;
+        };
+
+        scope.override_name().map_or(false, |scope_name| {
+            settings
+                .inline_completions_disabled_in
+                .iter()
+                .any(|s| s == scope_name)
+        })
+    }
+
     pub fn set_use_modal_editing(&mut self, to: bool) {
         self.use_modal_editing = to;
     }

crates/language/src/language_settings.rs 🔗

@@ -112,6 +112,9 @@ pub struct LanguageSettings {
     /// Controls whether inline completions are shown immediately (true)
     /// or manually by triggering `editor::ShowInlineCompletion` (false).
     pub show_inline_completions: bool,
+    /// Controls whether inline completions are shown in the given language
+    /// scopes.
+    pub inline_completions_disabled_in: Vec<String>,
     /// Whether to show tabs and spaces in the editor.
     pub show_whitespaces: ShowWhitespaceSetting,
     /// Whether to start a new line with a comment when a previous line is a comment as well.
@@ -318,6 +321,14 @@ pub struct LanguageSettingsContent {
     /// Default: true
     #[serde(default)]
     pub show_inline_completions: Option<bool>,
+    /// Controls whether inline completions are shown in the given language
+    /// scopes.
+    ///
+    /// Example: ["string", "comment"]
+    ///
+    /// Default: []
+    #[serde(default)]
+    pub inline_completions_disabled_in: Option<Vec<String>>,
     /// Whether to show tabs and spaces in the editor.
     #[serde(default)]
     pub show_whitespaces: Option<ShowWhitespaceSetting>,
@@ -1164,6 +1175,10 @@ fn merge_settings(settings: &mut LanguageSettings, src: &LanguageSettingsContent
         &mut settings.show_inline_completions,
         src.show_inline_completions,
     );
+    merge(
+        &mut settings.inline_completions_disabled_in,
+        src.inline_completions_disabled_in.clone(),
+    );
     merge(&mut settings.show_whitespaces, src.show_whitespaces);
     merge(
         &mut settings.extend_comment_on_newline,

docs/src/configuring-zed.md 🔗

@@ -359,6 +359,40 @@ There are two options to choose from:
 
 List of `string` values
 
+## Inline Completions Disabled in
+
+- Description: A list of language scopes in which inline completions should be disabled.
+- Setting: `inline_completions_disabled_in`
+- Default: `[]`
+
+**Options**
+
+List of `string` values
+
+1. Don't show inline completions in comments:
+
+```json
+"disabled_in": ["comment"]
+```
+
+2. Don't show inline completions in strings and comments:
+
+```json
+"disabled_in": ["comment", "string"]
+```
+
+3. Only in Go, don't show inline completions in strings and comments:
+
+```json
+{
+  "languages": {
+    "Go": {
+      "inline_completions_disabled_in": ["comment", "string"]
+    }
+  }
+}
+```
+
 ## Current Line Highlight
 
 - Description: How to highlight the current line in the editor.