]> git.lizzy.rs Git - rust.git/commitdiff
Make sure that adding a snippet requires corresponding capability
authorAleksey Kladov <aleksey.kladov@gmail.com>
Fri, 24 Apr 2020 00:26:38 +0000 (02:26 +0200)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Fri, 24 Apr 2020 00:26:38 +0000 (02:26 +0200)
crates/ra_ide/src/completion/complete_keyword.rs
crates/ra_ide/src/completion/complete_postfix.rs
crates/ra_ide/src/completion/complete_snippet.rs
crates/ra_ide/src/completion/complete_trait_impl.rs
crates/ra_ide/src/completion/completion_item.rs
crates/ra_ide/src/completion/presentation.rs

index 38f9c34e72b46cd95d87bd1254b1a45a565f5d1b..adefb290e81d98dd09c11a7ffa7c09edf64c1ef6 100644 (file)
@@ -42,10 +42,14 @@ pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionC
 }
 
 fn keyword(ctx: &CompletionContext, kw: &str, snippet: &str) -> CompletionItem {
-    CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), kw)
-        .kind(CompletionItemKind::Keyword)
-        .insert_snippet(snippet)
-        .build()
+    let res = CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), kw)
+        .kind(CompletionItemKind::Keyword);
+
+    match ctx.config.snippet_cap {
+        Some(cap) => res.insert_snippet(cap, snippet),
+        _ => res.insert_text(if snippet.contains('$') { kw } else { snippet }),
+    }
+    .build()
 }
 
 pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
index 29c2881c621c9fa47543acbbdea646d4b2fda517..8d397b0feafb316e76f83764634a70ab0d6b6451 100644 (file)
@@ -6,6 +6,7 @@
 };
 use ra_text_edit::TextEdit;
 
+use super::completion_config::SnippetCap;
 use crate::{
     completion::{
         completion_context::CompletionContext,
@@ -32,9 +33,15 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
         None => return,
     };
 
+    let cap = match ctx.config.snippet_cap {
+        Some(it) => it,
+        None => return,
+    };
+
     if receiver_ty.is_bool() || receiver_ty.is_unknown() {
         postfix_snippet(
             ctx,
+            cap,
             &dot_receiver,
             "if",
             "if expr {}",
@@ -43,6 +50,7 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
         .add_to(acc);
         postfix_snippet(
             ctx,
+            cap,
             &dot_receiver,
             "while",
             "while expr {}",
@@ -52,11 +60,20 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
     }
 
     // !&&&42 is a compiler error, ergo process it before considering the references
-    postfix_snippet(ctx, &dot_receiver, "not", "!expr", &format!("!{}", receiver_text)).add_to(acc);
+    postfix_snippet(ctx, cap, &dot_receiver, "not", "!expr", &format!("!{}", receiver_text))
+        .add_to(acc);
 
-    postfix_snippet(ctx, &dot_receiver, "ref", "&expr", &format!("&{}", receiver_text)).add_to(acc);
-    postfix_snippet(ctx, &dot_receiver, "refm", "&mut expr", &format!("&mut {}", receiver_text))
+    postfix_snippet(ctx, cap, &dot_receiver, "ref", "&expr", &format!("&{}", receiver_text))
         .add_to(acc);
+    postfix_snippet(
+        ctx,
+        cap,
+        &dot_receiver,
+        "refm",
+        "&mut expr",
+        &format!("&mut {}", receiver_text),
+    )
+    .add_to(acc);
 
     // The rest of the postfix completions create an expression that moves an argument,
     // so it's better to consider references now to avoid breaking the compilation
@@ -66,6 +83,7 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
 
     postfix_snippet(
         ctx,
+        cap,
         &dot_receiver,
         "match",
         "match expr {}",
@@ -75,6 +93,7 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
 
     postfix_snippet(
         ctx,
+        cap,
         &dot_receiver,
         "box",
         "Box::new(expr)",
@@ -82,8 +101,15 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
     )
     .add_to(acc);
 
-    postfix_snippet(ctx, &dot_receiver, "dbg", "dbg!(expr)", &format!("dbg!({})", receiver_text))
-        .add_to(acc);
+    postfix_snippet(
+        ctx,
+        cap,
+        &dot_receiver,
+        "dbg",
+        "dbg!(expr)",
+        &format!("dbg!({})", receiver_text),
+    )
+    .add_to(acc);
 }
 
 fn get_receiver_text(receiver: &ast::Expr, receiver_is_ambiguous_float_literal: bool) -> String {
@@ -108,6 +134,7 @@ fn include_references(initial_element: &ast::Expr) -> ast::Expr {
 
 fn postfix_snippet(
     ctx: &CompletionContext,
+    cap: SnippetCap,
     receiver: &ast::Expr,
     label: &str,
     detail: &str,
@@ -121,7 +148,7 @@ fn postfix_snippet(
     };
     CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label)
         .detail(detail)
-        .snippet_edit(edit)
+        .snippet_edit(cap, edit)
 }
 
 #[cfg(test)]
index f731e9b9aaabb047a3cca5c43d499470bd424362..4bccfbfed26f68ec5961d86f1db7dc4a8d25dec0 100644 (file)
@@ -1,13 +1,13 @@
 //! FIXME: write short doc here
 
 use crate::completion::{
-    completion_item::Builder, CompletionContext, CompletionItem, CompletionItemKind,
-    CompletionKind, Completions,
+    completion_config::SnippetCap, completion_item::Builder, CompletionContext, CompletionItem,
+    CompletionItemKind, CompletionKind, Completions,
 };
 
-fn snippet(ctx: &CompletionContext, label: &str, snippet: &str) -> Builder {
+fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder {
     CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), label)
-        .insert_snippet(snippet)
+        .insert_snippet(cap, snippet)
         .kind(CompletionItemKind::Snippet)
 }
 
@@ -15,17 +15,27 @@ pub(super) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionConte
     if !(ctx.is_trivial_path && ctx.function_syntax.is_some()) {
         return;
     }
+    let cap = match ctx.config.snippet_cap {
+        Some(it) => it,
+        None => return,
+    };
 
-    snippet(ctx, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc);
-    snippet(ctx, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc);
+    snippet(ctx, cap, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc);
+    snippet(ctx, cap, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc);
 }
 
 pub(super) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionContext) {
     if !ctx.is_new_item {
         return;
     }
+    let cap = match ctx.config.snippet_cap {
+        Some(it) => it,
+        None => return,
+    };
+
     snippet(
         ctx,
+        cap,
         "Test function",
         "\
 #[test]
@@ -36,8 +46,8 @@ fn ${1:feature}() {
     .lookup_by("tfn")
     .add_to(acc);
 
-    snippet(ctx, "macro_rules", "macro_rules! $1 {\n\t($2) => {\n\t\t$0\n\t};\n}").add_to(acc);
-    snippet(ctx, "pub(crate)", "pub(crate) $0").add_to(acc);
+    snippet(ctx, cap, "macro_rules", "macro_rules! $1 {\n\t($2) => {\n\t\t$0\n\t};\n}").add_to(acc);
+    snippet(ctx, cap, "pub(crate)", "pub(crate) $0").add_to(acc);
 }
 
 #[cfg(test)]
index 2ec0e7ce9df356c6d1f2a1e9a25964fc44e8436a..c39943252428df1b57663671f1747129ea7455a3 100644 (file)
@@ -122,7 +122,7 @@ fn add_function_impl(
     ctx: &CompletionContext,
     func: &hir::Function,
 ) {
-    let display = FunctionSignature::from_hir(ctx.db, *func);
+    let signature = FunctionSignature::from_hir(ctx.db, *func);
 
     let fn_name = func.name(ctx.db).to_string();
 
@@ -141,12 +141,20 @@ fn add_function_impl(
     } else {
         CompletionItemKind::Function
     };
-
-    let snippet = format!("{} {{\n    $0\n}}", display);
-
     let range = TextRange::from_to(fn_def_node.text_range().start(), ctx.source_range().end());
 
-    builder.snippet_edit(TextEdit::replace(range, snippet)).kind(completion_kind).add_to(acc);
+    match ctx.config.snippet_cap {
+        Some(cap) => {
+            let snippet = format!("{} {{\n    $0\n}}", signature);
+            builder.snippet_edit(cap, TextEdit::replace(range, snippet))
+        }
+        None => {
+            let header = format!("{} {{", signature);
+            builder.text_edit(TextEdit::replace(range, header))
+        }
+    }
+    .kind(completion_kind)
+    .add_to(acc);
 }
 
 fn add_type_alias_impl(
index edbf4a5b756da2602f4f4e7d64d00d62cca70de6..fb06cc1257d2d9b6d6be02991d1d6d812beca8a9 100644 (file)
@@ -2,6 +2,7 @@
 
 use std::fmt;
 
+use super::completion_config::SnippetCap;
 use hir::Documentation;
 use ra_syntax::TextRange;
 use ra_text_edit::TextEdit;
@@ -270,7 +271,11 @@ pub(crate) fn insert_text(mut self, insert_text: impl Into<String>) -> Builder {
         self.insert_text = Some(insert_text.into());
         self
     }
-    pub(crate) fn insert_snippet(mut self, snippet: impl Into<String>) -> Builder {
+    pub(crate) fn insert_snippet(
+        mut self,
+        _cap: SnippetCap,
+        snippet: impl Into<String>,
+    ) -> Builder {
         self.insert_text_format = InsertTextFormat::Snippet;
         self.insert_text(snippet)
     }
@@ -282,7 +287,7 @@ pub(crate) fn text_edit(mut self, edit: TextEdit) -> Builder {
         self.text_edit = Some(edit);
         self
     }
-    pub(crate) fn snippet_edit(mut self, edit: TextEdit) -> Builder {
+    pub(crate) fn snippet_edit(mut self, _cap: SnippetCap, edit: TextEdit) -> Builder {
         self.insert_text_format = InsertTextFormat::Snippet;
         self.text_edit(edit)
     }
index 78df9cbdb7ea138073a10d706e597100b81b1a19..5e2b8b920ae95c691dfed97d7ec72cca73fac1e6 100644 (file)
@@ -114,17 +114,19 @@ pub(crate) fn add_resolution(
 
         // Add `<>` for generic types
         if ctx.is_path_type && !ctx.has_type_args && ctx.config.add_call_parenthesis {
-            let has_non_default_type_params = match resolution {
-                ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db),
-                ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db),
-                _ => false,
-            };
-            if has_non_default_type_params {
-                tested_by!(inserts_angle_brackets_for_generics);
-                completion_item = completion_item
-                    .lookup_by(local_name.clone())
-                    .label(format!("{}<…>", local_name))
-                    .insert_snippet(format!("{}<$0>", local_name));
+            if let Some(cap) = ctx.config.snippet_cap {
+                let has_non_default_type_params = match resolution {
+                    ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db),
+                    ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db),
+                    _ => false,
+                };
+                if has_non_default_type_params {
+                    tested_by!(inserts_angle_brackets_for_generics);
+                    completion_item = completion_item
+                        .lookup_by(local_name.clone())
+                        .label(format!("{}<…>", local_name))
+                        .insert_snippet(cap, format!("{}<$0>", local_name));
+                }
             }
         }
 
@@ -184,13 +186,16 @@ pub(crate) fn add_macro(
                 .set_deprecated(is_deprecated(macro_, ctx.db))
                 .detail(detail);
 
-        builder = if ctx.use_item_syntax.is_some() || ctx.is_macro_call {
-            tested_by!(dont_insert_macro_call_parens_unncessary);
-            builder.insert_text(name)
-        } else {
-            let macro_braces_to_insert =
-                self.guess_macro_braces(&name, docs.as_ref().map_or("", |s| s.as_str()));
-            builder.insert_snippet(macro_declaration + macro_braces_to_insert)
+        builder = match ctx.config.snippet_cap {
+            Some(cap) if ctx.use_item_syntax.is_none() && !ctx.is_macro_call => {
+                let macro_braces_to_insert =
+                    self.guess_macro_braces(&name, docs.as_ref().map_or("", |s| s.as_str()));
+                builder.insert_snippet(cap, macro_declaration + macro_braces_to_insert)
+            }
+            _ => {
+                tested_by!(dont_insert_macro_call_parens_unncessary);
+                builder.insert_text(name)
+            }
         };
 
         self.add(builder);
@@ -366,6 +371,10 @@ fn add_call_parens(mut self, ctx: &CompletionContext, name: String, params: Para
         if ctx.use_item_syntax.is_some() || ctx.is_call {
             return self;
         }
+        let cap = match ctx.config.snippet_cap {
+            Some(it) => it,
+            None => return self,
+        };
         // If not an import, add parenthesis automatically.
         tested_by!(inserts_parens_for_function_calls);
 
@@ -387,7 +396,7 @@ fn add_call_parens(mut self, ctx: &CompletionContext, name: String, params: Para
 
             (snippet, format!("{}(…)", name))
         };
-        self.lookup_by(name).label(label).insert_snippet(snippet)
+        self.lookup_by(name).label(label).insert_snippet(cap, snippet)
     }
 }