Allow disabling snippet completion by setting `snippet_sort_order` to `none` (#34565)

Arseny Kapoulkine created

This mirrors VSCode setting that inspired `snippet_sort_order` to begin
with; VSCode supports inline/top/bottom/none, with none completely
disabling snippet completion. See
https://code.visualstudio.com/docs/editing/intellisense#_snippets-in-suggestions

This is helpful for LSPs that do not allow configuring snippets via
configuration such as clangd.

Release Notes:

- Added `none` as one of the values for `snippet_sort_order` to
completely disable snippet completion.

Change summary

assets/settings/default.json            |  2 ++
crates/editor/src/code_context_menus.rs | 15 +++++++++++++++
crates/editor/src/editor_settings.rs    |  2 ++
docs/src/configuring-zed.md             |  6 ++++++
docs/src/visual-customization.md        |  2 +-
5 files changed, 26 insertions(+), 1 deletion(-)

Detailed changes

assets/settings/default.json 🔗

@@ -197,6 +197,8 @@
   //    "inline"
   // 3. Place snippets at the bottom of the completion list:
   //    "bottom"
+  // 4. Do not show snippets in the completion list:
+  //    "none"
   "snippet_sort_order": "inline",
   // How to highlight the current line in the editor.
   //

crates/editor/src/code_context_menus.rs 🔗

@@ -1074,6 +1074,20 @@ impl CompletionsMenu {
             .and_then(|q| q.chars().next())
             .and_then(|c| c.to_lowercase().next());
 
+        if snippet_sort_order == SnippetSortOrder::None {
+            matches.retain(|string_match| {
+                let completion = &completions[string_match.candidate_id];
+
+                let is_snippet = matches!(
+                    &completion.source,
+                    CompletionSource::Lsp { lsp_completion, .. }
+                    if lsp_completion.kind == Some(CompletionItemKind::SNIPPET)
+                );
+
+                !is_snippet
+            });
+        }
+
         matches.sort_unstable_by_key(|string_match| {
             let completion = &completions[string_match.candidate_id];
 
@@ -1112,6 +1126,7 @@ impl CompletionsMenu {
                     SnippetSortOrder::Top => Reverse(if is_snippet { 1 } else { 0 }),
                     SnippetSortOrder::Bottom => Reverse(if is_snippet { 0 } else { 1 }),
                     SnippetSortOrder::Inline => Reverse(0),
+                    SnippetSortOrder::None => Reverse(0),
                 };
                 let sort_positions = string_match.positions.clone();
                 let sort_exact = Reverse(if Some(completion.label.filter_text()) == query {

crates/editor/src/editor_settings.rs 🔗

@@ -395,6 +395,8 @@ pub enum SnippetSortOrder {
     Inline,
     /// Place snippets at the bottom of the completion list
     Bottom,
+    /// Do not show snippets in the completion list
+    None,
 }
 
 #[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]

docs/src/configuring-zed.md 🔗

@@ -639,6 +639,12 @@ List of `string` values
 "snippet_sort_order": "bottom"
 ```
 
+4. Do not show snippets in the completion list at all:
+
+```json
+"snippet_sort_order": "none"
+```
+
 ## Editor Scrollbar
 
 - Description: Whether or not to show the editor scrollbar and various elements in it.

docs/src/visual-customization.md 🔗

@@ -317,7 +317,7 @@ TBD: Centered layout related settings
 ### Editor Completions, Snippets, Actions, Diagnostics {#editor-lsp}
 
 ```json
-  "snippet_sort_order": "inline",        // Snippets completions: top, inline, bottom
+  "snippet_sort_order": "inline",        // Snippets completions: top, inline, bottom, none
   "show_completions_on_input": true,     // Show completions while typing
   "show_completion_documentation": true, // Show documentation in completions
   "auto_signature_help": false,          // Show method signatures inside parentheses