}
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) {
};
use ra_text_edit::TextEdit;
+use super::completion_config::SnippetCap;
use crate::{
completion::{
completion_context::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 {}",
.add_to(acc);
postfix_snippet(
ctx,
+ cap,
&dot_receiver,
"while",
"while expr {}",
}
// !&&&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
postfix_snippet(
ctx,
+ cap,
&dot_receiver,
"match",
"match expr {}",
postfix_snippet(
ctx,
+ cap,
&dot_receiver,
"box",
"Box::new(expr)",
)
.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 {
fn postfix_snippet(
ctx: &CompletionContext,
+ cap: SnippetCap,
receiver: &ast::Expr,
label: &str,
detail: &str,
};
CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label)
.detail(detail)
- .snippet_edit(edit)
+ .snippet_edit(cap, edit)
}
#[cfg(test)]
//! 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)
}
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]
.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)]
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();
} 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(
use std::fmt;
+use super::completion_config::SnippetCap;
use hir::Documentation;
use ra_syntax::TextRange;
use ra_text_edit::TextEdit;
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)
}
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)
}
// 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));
+ }
}
}
.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);
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);
(snippet, format!("{}(…)", name))
};
- self.lookup_by(name).label(label).insert_snippet(snippet)
+ self.lookup_by(name).label(label).insert_snippet(cap, snippet)
}
}