},
};
-pub use crate::completion::completion_item::{CompletionItem, InsertText, CompletionItemKind};
+pub use crate::completion::completion_item::{CompletionItem, CompletionItemKind, InsertTextFormat};
/// Main entry point for completion. We run completion as a two-phase process.
///
Some(acc)
}
-
-#[cfg(test)]
-fn check_completion(code: &str, expected_completions: &str, kind: CompletionKind) {
- use crate::mock_analysis::{single_file_with_position, analysis_and_position};
- let (analysis, position) = if code.contains("//-") {
- analysis_and_position(code)
- } else {
- single_file_with_position(code)
- };
- let completions = completions(&analysis.db, position).unwrap();
- completions.assert_match(expected_completions, kind);
-}
use hir::{Ty, Def};
-use crate::completion::{CompletionContext, Completions, CompletionKind, CompletionItem, CompletionItemKind};
+use crate::completion::{CompletionContext, Completions, CompletionItem, CompletionItemKind};
+use crate::completion::completion_item::CompletionKind;
/// Complete dot accesses, i.e. fields or methods (currently only fields).
pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
for field in s.fields(ctx.db) {
CompletionItem::new(
CompletionKind::Reference,
+ ctx,
field.name().to_string(),
)
.kind(CompletionItemKind::Field)
}
Ty::Tuple(fields) => {
for (i, _ty) in fields.iter().enumerate() {
- CompletionItem::new(CompletionKind::Reference, i.to_string())
+ CompletionItem::new(CompletionKind::Reference, ctx, i.to_string())
.kind(CompletionItemKind::Field)
.add_to(acc);
}
receiver.iterate_methods(ctx.db, |func| {
let sig = func.signature(ctx.db);
if sig.has_self_param() {
- CompletionItem::new(CompletionKind::Reference, sig.name().to_string())
+ CompletionItem::new(CompletionKind::Reference, ctx, sig.name().to_string())
.from_function(ctx, func)
.kind(CompletionItemKind::Method)
.add_to(acc);
#[cfg(test)]
mod tests {
use crate::completion::*;
+ use crate::completion::completion_item::check_completion;
- fn check_ref_completion(code: &str, expected_completions: &str) {
- check_completion(code, expected_completions, CompletionKind::Reference);
+ fn check_ref_completion(name: &str, code: &str) {
+ check_completion(name, code, CompletionKind::Reference);
}
#[test]
fn test_struct_field_completion() {
check_ref_completion(
+ "struct_field_completion",
r"
struct A { the_field: u32 }
fn foo(a: A) {
a.<|>
}
",
- r#"the_field "u32""#,
);
}
#[test]
fn test_struct_field_completion_self() {
check_ref_completion(
+ "struct_field_completion_self",
r"
struct A { the_field: (u32,) }
impl A {
}
}
",
- r#"the_field "(u32,)"
- foo "foo($0)""#,
);
}
#[test]
fn test_struct_field_completion_autoderef() {
check_ref_completion(
+ "struct_field_completion_autoderef",
r"
struct A { the_field: (u32, i32) }
impl A {
}
}
",
- r#"the_field "(u32, i32)"
- foo "foo($0)""#,
);
}
#[test]
fn test_no_struct_field_completion_for_method_call() {
check_ref_completion(
+ "no_struct_field_completion_for_method_call",
r"
struct A { the_field: u32 }
fn foo(a: A) {
a.<|>()
}
",
- r#""#,
);
}
#[test]
fn test_method_completion() {
check_ref_completion(
+ "method_completion",
r"
struct A {}
impl A {
a.<|>
}
",
- r#"the_method "the_method($0)""#,
);
}
#[test]
fn test_no_non_self_method() {
check_ref_completion(
+ "no_non_self_method",
r"
struct A {}
impl A {
a.<|>
}
",
- r#""#,
);
}
}
}
})
.for_each(|(label, lookup)| {
- CompletionItem::new(CompletionKind::Magic, label)
+ CompletionItem::new(CompletionKind::Magic, ctx, label)
.lookup_by(lookup)
.add_to(acc)
});
#[cfg(test)]
mod tests {
use crate::completion::*;
+ use crate::completion::completion_item::check_completion;
- fn check_magic_completion(code: &str, expected_completions: &str) {
- check_completion(code, expected_completions, CompletionKind::Magic);
+ fn check_magic_completion(name: &str, code: &str) {
+ check_completion(name, code, CompletionKind::Magic);
}
#[test]
fn test_param_completion_last_param() {
check_magic_completion(
+ "param_completion_last_param",
r"
fn foo(file_id: FileId) {}
fn bar(file_id: FileId) {}
fn baz(file<|>) {}
",
- r#"file_id "file_id: FileId""#,
);
}
#[test]
fn test_param_completion_nth_param() {
check_magic_completion(
+ "param_completion_nth_param",
r"
fn foo(file_id: FileId) {}
fn bar(file_id: FileId) {}
fn baz(file<|>, x: i32) {}
",
- r#"file_id "file_id: FileId""#,
);
}
#[test]
fn test_param_completion_trait_param() {
check_magic_completion(
+ "param_completion_trait_param",
r"
pub(crate) trait SourceRoot {
pub fn contains(&self, file_id: FileId) -> bool;
pub fn syntax(&self, file<|>)
}
",
- r#"file_id "file_id: FileId""#,
);
}
}
// complete keyword "crate" in use stmt
match (ctx.use_item_syntax.as_ref(), ctx.path_prefix.as_ref()) {
(Some(_), None) => {
- CompletionItem::new(CompletionKind::Keyword, "crate")
+ CompletionItem::new(CompletionKind::Keyword, ctx, "crate")
.kind(CompletionItemKind::Keyword)
- .lookup_by("crate")
- .snippet("crate::")
+ .insert_text("crate::")
.add_to(acc);
- CompletionItem::new(CompletionKind::Keyword, "self")
+ CompletionItem::new(CompletionKind::Keyword, ctx, "self")
.kind(CompletionItemKind::Keyword)
- .lookup_by("self")
.add_to(acc);
- CompletionItem::new(CompletionKind::Keyword, "super")
+ CompletionItem::new(CompletionKind::Keyword, ctx, "super")
.kind(CompletionItemKind::Keyword)
- .lookup_by("super")
+ .insert_text("super::")
.add_to(acc);
}
(Some(_), Some(_)) => {
- CompletionItem::new(CompletionKind::Keyword, "self")
+ CompletionItem::new(CompletionKind::Keyword, ctx, "self")
.kind(CompletionItemKind::Keyword)
- .lookup_by("self")
.add_to(acc);
- CompletionItem::new(CompletionKind::Keyword, "super")
+ CompletionItem::new(CompletionKind::Keyword, ctx, "super")
.kind(CompletionItemKind::Keyword)
- .lookup_by("super")
+ .insert_text("super::")
.add_to(acc);
}
_ => {}
}
}
-fn keyword(kw: &str, snippet: &str) -> CompletionItem {
- CompletionItem::new(CompletionKind::Keyword, kw)
+fn keyword(ctx: &CompletionContext, kw: &str, snippet: &str) -> CompletionItem {
+ CompletionItem::new(CompletionKind::Keyword, ctx, kw)
.kind(CompletionItemKind::Keyword)
.snippet(snippet)
.build()
Some(it) => it,
None => return,
};
- acc.add(keyword("if", "if $0 {}"));
- acc.add(keyword("match", "match $0 {}"));
- acc.add(keyword("while", "while $0 {}"));
- acc.add(keyword("loop", "loop {$0}"));
+ acc.add(keyword(ctx, "if", "if $0 {}"));
+ acc.add(keyword(ctx, "match", "match $0 {}"));
+ acc.add(keyword(ctx, "while", "while $0 {}"));
+ acc.add(keyword(ctx, "loop", "loop {$0}"));
if ctx.after_if {
- acc.add(keyword("else", "else {$0}"));
- acc.add(keyword("else if", "else if $0 {}"));
+ acc.add(keyword(ctx, "else", "else {$0}"));
+ acc.add(keyword(ctx, "else if", "else if $0 {}"));
}
if is_in_loop_body(ctx.leaf) {
if ctx.can_be_stmt {
- acc.add(keyword("continue", "continue;"));
- acc.add(keyword("break", "break;"));
+ acc.add(keyword(ctx, "continue", "continue;"));
+ acc.add(keyword(ctx, "break", "break;"));
} else {
- acc.add(keyword("continue", "continue"));
- acc.add(keyword("break", "break"));
+ acc.add(keyword(ctx, "continue", "continue"));
+ acc.add(keyword(ctx, "break", "break"));
}
}
- acc.add_all(complete_return(fn_def, ctx.can_be_stmt));
+ acc.add_all(complete_return(ctx, fn_def, ctx.can_be_stmt));
}
fn is_in_loop_body(leaf: &SyntaxNode) -> bool {
false
}
-fn complete_return(fn_def: &ast::FnDef, can_be_stmt: bool) -> Option<CompletionItem> {
+fn complete_return(
+ ctx: &CompletionContext,
+ fn_def: &ast::FnDef,
+ can_be_stmt: bool,
+) -> Option<CompletionItem> {
let snip = match (can_be_stmt, fn_def.ret_type().is_some()) {
(true, true) => "return $0;",
(true, false) => "return;",
(false, true) => "return $0",
(false, false) => "return",
};
- Some(keyword("return", snip))
+ Some(keyword(ctx, "return", snip))
}
#[cfg(test)]
mod tests {
- use crate::completion::{CompletionKind, check_completion};
- fn check_keyword_completion(code: &str, expected_completions: &str) {
- check_completion(code, expected_completions, CompletionKind::Keyword);
+ use crate::completion::CompletionKind;
+ use crate::completion::completion_item::check_completion;
+
+ fn check_keyword_completion(name: &str, code: &str) {
+ check_completion(name, code, CompletionKind::Keyword);
}
#[test]
fn completes_keywords_in_use_stmt() {
check_keyword_completion(
+ "keywords_in_use_stmt1",
r"
use <|>
",
- r#"
- crate "crate" "crate::"
- self "self"
- super "super"
- "#,
);
check_keyword_completion(
+ "keywords_in_use_stmt2",
r"
use a::<|>
",
- r#"
- self "self"
- super "super"
- "#,
);
check_keyword_completion(
+ "keywords_in_use_stmt3",
r"
use a::{b, <|>}
",
- r#"
- self "self"
- super "super"
- "#,
);
}
#[test]
fn completes_various_keywords_in_function() {
check_keyword_completion(
+ "keywords_in_function1",
r"
fn quux() {
<|>
}
",
- r#"
- if "if $0 {}"
- match "match $0 {}"
- while "while $0 {}"
- loop "loop {$0}"
- return "return;"
- "#,
);
}
#[test]
fn completes_else_after_if() {
check_keyword_completion(
+ "keywords_in_function2",
r"
fn quux() {
if true {
} <|>
}
",
- r#"
- if "if $0 {}"
- match "match $0 {}"
- while "while $0 {}"
- loop "loop {$0}"
- else "else {$0}"
- else if "else if $0 {}"
- return "return;"
- "#,
);
}
#[test]
fn test_completion_return_value() {
check_keyword_completion(
+ "keywords_in_function3",
r"
fn quux() -> i32 {
<|>
92
}
",
- r#"
- if "if $0 {}"
- match "match $0 {}"
- while "while $0 {}"
- loop "loop {$0}"
- return "return $0;"
- "#,
);
check_keyword_completion(
+ "keywords_in_function4",
r"
fn quux() {
<|>
92
}
",
- r#"
- if "if $0 {}"
- match "match $0 {}"
- while "while $0 {}"
- loop "loop {$0}"
- return "return;"
- "#,
);
}
#[test]
fn dont_add_semi_after_return_if_not_a_statement() {
check_keyword_completion(
+ "dont_add_semi_after_return_if_not_a_statement",
r"
fn quux() -> i32 {
match () {
}
}
",
- r#"
- if "if $0 {}"
- match "match $0 {}"
- while "while $0 {}"
- loop "loop {$0}"
- return "return $0"
- "#,
);
}
#[test]
fn last_return_in_block_has_semi() {
check_keyword_completion(
+ "last_return_in_block_has_semi1",
r"
fn quux() -> i32 {
if condition {
}
}
",
- r#"
- if "if $0 {}"
- match "match $0 {}"
- while "while $0 {}"
- loop "loop {$0}"
- return "return $0;"
- "#,
);
check_keyword_completion(
+ "last_return_in_block_has_semi2",
r"
fn quux() -> i32 {
if condition {
x
}
",
- r#"
- if "if $0 {}"
- match "match $0 {}"
- while "while $0 {}"
- loop "loop {$0}"
- return "return $0;"
- "#,
);
}
#[test]
fn completes_break_and_continue_in_loops() {
check_keyword_completion(
+ "completes_break_and_continue_in_loops1",
r"
fn quux() -> i32 {
loop { <|> }
}
",
- r#"
- if "if $0 {}"
- match "match $0 {}"
- while "while $0 {}"
- loop "loop {$0}"
- continue "continue;"
- break "break;"
- return "return $0;"
- "#,
);
+
// No completion: lambda isolates control flow
check_keyword_completion(
+ "completes_break_and_continue_in_loops2",
r"
fn quux() -> i32 {
loop { || { <|> } }
}
",
- r#"
- if "if $0 {}"
- match "match $0 {}"
- while "while $0 {}"
- loop "loop {$0}"
- return "return $0;"
- "#,
);
}
#[test]
fn no_semi_after_break_continue_in_expr() {
check_keyword_completion(
+ "no_semi_after_break_continue_in_expr",
r"
fn f() {
loop {
}
}
",
- r#"
- if "if $0 {}"
- match "match $0 {}"
- while "while $0 {}"
- loop "loop {$0}"
- continue "continue"
- break "break"
- return "return"
- "#,
)
}
}
hir::Def::Module(module) => {
let module_scope = module.scope(ctx.db);
for (name, res) in module_scope.entries() {
- CompletionItem::new(CompletionKind::Reference, name.to_string())
+ CompletionItem::new(CompletionKind::Reference, ctx, name.to_string())
.from_resolution(ctx, res)
.add_to(acc);
}
e.variants(ctx.db)
.into_iter()
.for_each(|(variant_name, _variant)| {
- CompletionItem::new(CompletionKind::Reference, variant_name.to_string())
+ CompletionItem::new(CompletionKind::Reference, ctx, variant_name.to_string())
.kind(CompletionItemKind::EnumVariant)
.add_to(acc)
});
#[cfg(test)]
mod tests {
- use crate::completion::{CompletionKind, check_completion};
+ use crate::completion::CompletionKind;
+ use crate::completion::completion_item::check_completion;
fn check_reference_completion(code: &str, expected_completions: &str) {
check_completion(code, expected_completions, CompletionKind::Reference);
#[test]
fn completes_use_item_starting_with_self() {
check_reference_completion(
+ "use_item_starting_with_self",
r"
use self::m::<|>;
struct Bar;
}
",
- "Bar",
);
}
#[test]
fn completes_use_item_starting_with_crate() {
check_reference_completion(
+ "use_item_starting_with_crate",
"
//- /lib.rs
mod foo;
//- /foo.rs
use crate::Sp<|>
",
- "Spam;foo",
);
}
#[test]
fn completes_nested_use_tree() {
check_reference_completion(
+ "nested_use_tree",
"
//- /lib.rs
mod foo;
//- /foo.rs
use crate::{Sp<|>};
",
- "Spam;foo",
);
}
#[test]
fn completes_deeply_nested_use_tree() {
check_reference_completion(
+ "deeply_nested_use_tree",
"
//- /lib.rs
mod foo;
//- /foo.rs
use crate::{bar::{baz::Sp<|>}};
",
- "Spam",
);
}
#[test]
fn completes_enum_variant() {
check_reference_completion(
+ "reference_completion",
"
//- /lib.rs
enum E { Foo, Bar(i32) }
fn foo() { let _ = E::<|> }
",
- "Foo;Bar",
);
}
#[test]
fn dont_render_function_parens_in_use_item() {
check_reference_completion(
+ "dont_render_function_parens_in_use_item",
"
//- /lib.rs
mod m { pub fn foo() {} }
use crate::m::f<|>;
",
- "foo",
)
}
#[test]
fn dont_render_function_parens_if_already_call() {
check_reference_completion(
+ "dont_render_function_parens_if_already_call",
"
//- /lib.rs
fn frobnicate() {}
frob<|>();
}
",
- "main;frobnicate",
)
}
}
use rustc_hash::FxHashSet;
-use ra_syntax::{AstNode, TextUnit};
-
+use ra_syntax::ast::AstNode;
use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext};
pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
};
if let Some(function) = &ctx.function {
let scopes = function.scopes(ctx.db);
- complete_fn(acc, &scopes, ctx.offset);
+ complete_fn(acc, &scopes, ctx);
}
let module_scope = module.scope(ctx.db);
}
})
.for_each(|(name, res)| {
- CompletionItem::new(CompletionKind::Reference, name.to_string())
+ CompletionItem::new(CompletionKind::Reference, ctx, name.to_string())
.from_resolution(ctx, res)
.add_to(acc)
});
}
-fn complete_fn(acc: &mut Completions, scopes: &hir::ScopesWithSyntaxMapping, offset: TextUnit) {
+fn complete_fn(
+ acc: &mut Completions,
+ scopes: &hir::ScopesWithSyntaxMapping,
+ ctx: &CompletionContext,
+) {
let mut shadowed = FxHashSet::default();
scopes
- .scope_chain_for_offset(offset)
+ .scope_chain_for_offset(ctx.offset)
.flat_map(|scope| scopes.scopes.entries(scope).iter())
.filter(|entry| shadowed.insert(entry.name()))
.for_each(|entry| {
- CompletionItem::new(CompletionKind::Reference, entry.name().to_string())
+ CompletionItem::new(CompletionKind::Reference, ctx, entry.name().to_string())
.kind(CompletionItemKind::Binding)
.add_to(acc)
});
#[cfg(test)]
mod tests {
- use crate::completion::{CompletionKind, check_completion};
+ use crate::completion::CompletionKind;
+ use crate::completion::completion_item::check_completion;
- fn check_reference_completion(code: &str, expected_completions: &str) {
- check_completion(code, expected_completions, CompletionKind::Reference);
+ fn check_reference_completion(name: &str, code: &str) {
+ check_completion(name, code, CompletionKind::Reference);
}
#[test]
fn completes_bindings_from_let() {
check_reference_completion(
+ "bindings_from_let",
r"
fn quux(x: i32) {
let y = 92;
let z = ();
}
",
- r#"y;x;quux "quux($0)""#,
);
}
#[test]
fn completes_bindings_from_if_let() {
check_reference_completion(
+ "bindings_from_if_let",
r"
fn quux() {
if let Some(x) = foo() {
}
}
",
- r#"b;a;quux "quux()$0""#,
);
}
#[test]
fn completes_bindings_from_for() {
check_reference_completion(
+ "bindings_from_for",
r"
fn quux() {
for x in &[1, 2, 3] {
}
}
",
- r#"x;quux "quux()$0""#,
);
}
#[test]
fn completes_module_items() {
check_reference_completion(
+ "module_items",
r"
struct Foo;
enum Baz {}
<|>
}
",
- r#"quux "quux()$0";Foo;Baz"#,
);
}
#[test]
fn completes_module_items_in_nested_modules() {
check_reference_completion(
+ "module_items_in_nested_modules",
r"
struct Foo;
mod m {
fn quux() { <|> }
}
",
- r#"quux "quux()$0";Bar"#,
);
}
#[test]
fn completes_return_type() {
check_reference_completion(
+ "return_type",
r"
struct Foo;
fn x() -> <|>
",
- r#"Foo;x "x()$0""#,
)
}
#[test]
fn dont_show_both_completions_for_shadowing() {
check_reference_completion(
+ "dont_show_both_completions_for_shadowing",
r"
fn foo() -> {
let bar = 92;
}
}
",
- r#"bar;foo "foo()$0""#,
)
}
#[test]
fn completes_self_in_methods() {
- check_reference_completion(r"impl S { fn foo(&self) { <|> } }", "self")
+ check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }")
}
#[test]
fn inserts_parens_for_function_calls() {
check_reference_completion(
+ "inserts_parens_for_function_calls1",
r"
fn no_args() {}
fn main() { no_<|> }
",
- r#"no_args "no_args()$0"
- main "main()$0""#,
);
check_reference_completion(
+ "inserts_parens_for_function_calls2",
r"
fn with_args(x: i32, y: String) {}
fn main() { with_<|> }
",
- r#"main "main()$0"
- with_args "with_args($0)""#,
);
}
}
use crate::completion::{CompletionItem, Completions, CompletionKind, CompletionItemKind, CompletionContext, completion_item::Builder};
-fn snippet(label: &str, snippet: &str) -> Builder {
- CompletionItem::new(CompletionKind::Snippet, label)
+fn snippet<'a>(ctx: &'a CompletionContext<'a>, label: &str, snippet: &str) -> Builder<'a> {
+ CompletionItem::new(CompletionKind::Snippet, ctx, label)
.snippet(snippet)
.kind(CompletionItemKind::Snippet)
}
if !(ctx.is_trivial_path && ctx.function_syntax.is_some()) {
return;
}
- snippet("pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc);
- snippet("ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc);
+ snippet(ctx, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc);
+ snippet(ctx, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc);
}
pub(super) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionContext) {
return;
}
snippet(
+ ctx,
"Test function",
"\
#[test]
.lookup_by("tfn")
.add_to(acc);
- snippet("pub(crate)", "pub(crate) $0").add_to(acc);
+ snippet(ctx, "pub(crate)", "pub(crate) $0").add_to(acc);
}
#[cfg(test)]
mod tests {
- use crate::completion::{CompletionKind, check_completion};
- fn check_snippet_completion(code: &str, expected_completions: &str) {
- check_completion(code, expected_completions, CompletionKind::Snippet);
+ use crate::completion::CompletionKind;
+ use crate::completion::completion_item::check_completion;
+
+ fn check_snippet_completion(name: &str, code: &str) {
+ check_completion(name, code, CompletionKind::Snippet);
}
#[test]
fn completes_snippets_in_expressions() {
- check_snippet_completion(
- r"fn foo(x: i32) { <|> }",
- r##"
- pd "eprintln!(\"$0 = {:?}\", $0);"
- ppd "eprintln!(\"$0 = {:#?}\", $0);"
- "##,
- );
+ check_snippet_completion("snippets_in_expressions", r"fn foo(x: i32) { <|> }");
}
#[test]
fn completes_snippets_in_items() {
- // check_snippet_completion(r"
- // <|>
- // ",
- // r##"[CompletionItem { label: "Test function", lookup: None, snippet: Some("#[test]\nfn test_${1:feature}() {\n$0\n}"##,
- // );
check_snippet_completion(
+ "snippets_in_items",
r"
#[cfg(test)]
mod tests {
<|>
}
",
- r##"
- tfn "Test function" "#[test]\nfn ${1:feature}() {\n $0\n}"
- pub(crate) "pub(crate) $0"
- "##,
);
}
}
/// `CompletionContext` is created early during completion to figure out, where
/// exactly is the cursor, syntax-wise.
#[derive(Debug)]
-pub(super) struct CompletionContext<'a> {
+pub(crate) struct CompletionContext<'a> {
pub(super) db: &'a db::RootDatabase,
pub(super) offset: TextUnit,
pub(super) leaf: &'a SyntaxNode,
Some(ctx)
}
+ pub(crate) fn leaf_range(&self) -> TextRange {
+ self.leaf.range()
+ }
+
fn fill(&mut self, original_file: &'a SourceFile, offset: TextUnit) {
// Insert a fake ident to get a valid parse tree. We will use this file
// to determine context, though the original_file will be used for
use hir::PerNs;
+use ra_text_edit::{
+ AtomTextEdit,
+ TextEdit,
+};
-use crate::completion::CompletionContext;
+use crate::completion::completion_context::CompletionContext;
/// `CompletionItem` describes a single completion variant in the editor pop-up.
/// It is basically a POD with various properties. To construct a
/// completion.
completion_kind: CompletionKind,
label: String,
+ kind: Option<CompletionItemKind>,
detail: Option<String>,
lookup: Option<String>,
- snippet: Option<String>,
- kind: Option<CompletionItemKind>,
-}
-
-pub enum InsertText {
- PlainText { text: String },
- Snippet { text: String },
+ /// The format of the insert text. The format applies to both the `insert_text` property
+ /// and the `insert` property of a provided `text_edit`.
+ insert_text_format: InsertTextFormat,
+ /// An edit which is applied to a document when selecting this completion. When an edit is
+ /// provided the value of `insert_text` is ignored.
+ ///
+ /// *Note:* The range of the edit must be a single line range and it must contain the position
+ /// at which completion has been requested.
+ ///
+ /// *Note:* If sending a range that overlaps a string, the string should match the relevant
+ /// part of the replacement text, or be filtered out.
+ text_edit: Option<AtomTextEdit>,
+ /// An optional array of additional text edits that are applied when
+ /// selecting this completion. Edits must not overlap (including the same insert position)
+ /// with the main edit nor with themselves.
+ ///
+ /// Additional text edits should be used to change text unrelated to the current cursor position
+ /// (for example adding an import statement at the top of the file if the completion item will
+ /// insert an unqualified type).
+ additional_text_edits: Option<TextEdit>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Method,
}
-#[derive(Debug, PartialEq, Eq)]
+#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub(crate) enum CompletionKind {
/// Parser-based keyword completion.
Keyword,
Snippet,
}
+#[derive(Debug, PartialEq, Eq, Copy, Clone)]
+pub enum InsertTextFormat {
+ PlainText,
+ Snippet,
+}
+
impl CompletionItem {
- pub(crate) fn new(completion_kind: CompletionKind, label: impl Into<String>) -> Builder {
+ pub(crate) fn new<'a>(
+ completion_kind: CompletionKind,
+ ctx: &'a CompletionContext,
+ label: impl Into<String>,
+ ) -> Builder<'a> {
let label = label.into();
Builder {
+ ctx,
completion_kind,
label,
+ insert_text: None,
+ insert_text_format: InsertTextFormat::PlainText,
detail: None,
lookup: None,
- snippet: None,
kind: None,
+ text_edit: None,
+ additional_text_edits: None,
}
}
/// What user sees in pop-up in the UI.
.map(|it| it.as_str())
.unwrap_or(self.label())
}
- /// What is inserted.
- pub fn insert_text(&self) -> InsertText {
- match &self.snippet {
- None => InsertText::PlainText {
- text: self.label.clone(),
- },
- Some(it) => InsertText::Snippet { text: it.clone() },
- }
+
+ pub fn insert_text_format(&self) -> InsertTextFormat {
+ self.insert_text_format.clone()
}
pub fn kind(&self) -> Option<CompletionItemKind> {
self.kind
}
+ pub fn text_edit(&mut self) -> Option<&AtomTextEdit> {
+ self.text_edit.as_ref()
+ }
+ pub fn take_additional_text_edits(&mut self) -> Option<TextEdit> {
+ self.additional_text_edits.take()
+ }
}
/// A helper to make `CompletionItem`s.
#[must_use]
-pub(crate) struct Builder {
+pub(crate) struct Builder<'a> {
+ ctx: &'a CompletionContext<'a>,
completion_kind: CompletionKind,
label: String,
+ insert_text: Option<String>,
+ insert_text_format: InsertTextFormat,
detail: Option<String>,
lookup: Option<String>,
- snippet: Option<String>,
kind: Option<CompletionItemKind>,
+ text_edit: Option<AtomTextEdit>,
+ additional_text_edits: Option<TextEdit>,
}
-impl Builder {
+impl<'a> Builder<'a> {
pub(crate) fn add_to(self, acc: &mut Completions) {
acc.add(self.build())
}
pub(crate) fn build(self) -> CompletionItem {
+ let self_text_edit = self.text_edit;
+ let self_insert_text = self.insert_text;
+ let text_edit = match (self_text_edit, self_insert_text) {
+ (Some(text_edit), ..) => Some(text_edit),
+ (None, Some(insert_text)) => {
+ Some(AtomTextEdit::replace(self.ctx.leaf_range(), insert_text))
+ }
+ _ => None,
+ };
+
CompletionItem {
label: self.label,
detail: self.detail,
+ insert_text_format: self.insert_text_format,
lookup: self.lookup,
- snippet: self.snippet,
kind: self.kind,
completion_kind: self.completion_kind,
+ text_edit,
+ additional_text_edits: self.additional_text_edits,
}
}
- pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder {
+ pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder<'a> {
self.lookup = Some(lookup.into());
self
}
- pub(crate) fn snippet(mut self, snippet: impl Into<String>) -> Builder {
- self.snippet = Some(snippet.into());
+ pub(crate) fn insert_text(mut self, insert_text: impl Into<String>) -> Builder<'a> {
+ self.insert_text = Some(insert_text.into());
+ self
+ }
+ pub(crate) fn insert_text_format(
+ mut self,
+ insert_text_format: InsertTextFormat,
+ ) -> Builder<'a> {
+ self.insert_text_format = insert_text_format;
self
}
- pub(crate) fn kind(mut self, kind: CompletionItemKind) -> Builder {
+ pub(crate) fn snippet(mut self, snippet: impl Into<String>) -> Builder<'a> {
+ self.insert_text_format = InsertTextFormat::Snippet;
+ self.insert_text(snippet)
+ }
+ pub(crate) fn kind(mut self, kind: CompletionItemKind) -> Builder<'a> {
self.kind = Some(kind);
self
}
+ pub(crate) fn text_edit(mut self, text_edit: AtomTextEdit) -> Builder<'a> {
+ self.text_edit = Some(text_edit);
+ self
+ }
+ pub(crate) fn additional_text_edits(mut self, additional_text_edits: TextEdit) -> Builder<'a> {
+ self.additional_text_edits = Some(additional_text_edits);
+ self
+ }
#[allow(unused)]
- pub(crate) fn detail(self, detail: impl Into<String>) -> Builder {
+ pub(crate) fn detail(self, detail: impl Into<String>) -> Builder<'a> {
self.set_detail(Some(detail))
}
- pub(crate) fn set_detail(mut self, detail: Option<impl Into<String>>) -> Builder {
+ pub(crate) fn set_detail(mut self, detail: Option<impl Into<String>>) -> Builder<'a> {
self.detail = detail.map(Into::into);
self
}
mut self,
ctx: &CompletionContext,
resolution: &hir::Resolution,
- ) -> Builder {
+ ) -> Builder<'a> {
let resolved = resolution.def_id.map(|d| d.resolve(ctx.db));
let kind = match resolved {
PerNs {
mut self,
ctx: &CompletionContext,
function: hir::Function,
- ) -> Builder {
+ ) -> Builder<'a> {
// If not an import, add parenthesis automatically.
if ctx.use_item_syntax.is_none() && !ctx.is_call {
if function.signature(ctx.db).params().is_empty() {
- self.snippet = Some(format!("{}()$0", self.label));
+ self.insert_text = Some(format!("{}()$0", self.label));
} else {
- self.snippet = Some(format!("{}($0)", self.label));
+ self.insert_text = Some(format!("{}($0)", self.label));
}
+ self.insert_text_format = InsertTextFormat::Snippet;
}
self.kind = Some(CompletionItemKind::Function);
self
}
}
-impl Into<CompletionItem> for Builder {
+impl<'a> Into<CompletionItem> for Builder<'a> {
fn into(self) -> CompletionItem {
self.build()
}
{
items.into_iter().for_each(|item| self.add(item.into()))
}
-
- #[cfg(test)]
- pub(crate) fn assert_match(&self, expected: &str, kind: CompletionKind) {
- let expected = normalize(expected);
- let actual = self.debug_render(kind);
- test_utils::assert_eq_text!(expected.as_str(), actual.as_str(),);
-
- /// Normalize the textual representation of `Completions`:
- /// replace `;` with newlines, normalize whitespace
- fn normalize(expected: &str) -> String {
- use ra_syntax::{tokenize, TextUnit, TextRange, SyntaxKind::SEMI};
- let mut res = String::new();
- for line in expected.trim().lines() {
- let line = line.trim();
- let mut start_offset: TextUnit = 0.into();
- // Yep, we use rust tokenize in completion tests :-)
- for token in tokenize(line) {
- let range = TextRange::offset_len(start_offset, token.len);
- start_offset += token.len;
- if token.kind == SEMI {
- res.push('\n');
- } else {
- res.push_str(&line[range]);
- }
- }
-
- res.push('\n');
- }
- res
- }
- }
-
- #[cfg(test)]
- fn debug_render(&self, kind: CompletionKind) -> String {
- let mut res = String::new();
- for c in self.buf.iter() {
- if c.completion_kind == kind {
- if let Some(lookup) = &c.lookup {
- res.push_str(lookup);
- res.push_str(&format!(" {:?}", c.label));
- } else {
- res.push_str(&c.label);
- }
- if let Some(detail) = &c.detail {
- res.push_str(&format!(" {:?}", detail));
- }
- if let Some(snippet) = &c.snippet {
- res.push_str(&format!(" {:?}", snippet));
- }
- res.push('\n');
- }
- }
- res
- }
}
impl Into<Vec<CompletionItem>> for Completions {
self.buf
}
}
+
+#[cfg(test)]
+pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind) {
+ use crate::mock_analysis::{single_file_with_position, analysis_and_position};
+ use crate::completion::completions;
+ use insta::assert_debug_snapshot_matches;
+ let (analysis, position) = if code.contains("//-") {
+ analysis_and_position(code)
+ } else {
+ single_file_with_position(code)
+ };
+ let completions = completions(&analysis.db, position).unwrap();
+ let completion_items: Vec<CompletionItem> = completions.into();
+ let kind_completions: Vec<CompletionItem> = completion_items
+ .into_iter()
+ .filter(|c| c.completion_kind == kind)
+ .collect();
+ assert_debug_snapshot_matches!(test_name, kind_completions);
+}
--- /dev/null
+Created: 2019-01-19T13:42:17.835266+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "x",
+ kind: Some(
+ Binding
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "quux",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [62; 100),
+ insert: "quux()$0"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.835796+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "b",
+ kind: Some(
+ Binding
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "a",
+ kind: Some(
+ Binding
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "quux",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [213; 231),
+ insert: "quux()$0"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.835351+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "y",
+ kind: Some(
+ Binding
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "x",
+ kind: Some(
+ Binding
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "quux",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [78; 79),
+ insert: "quux($0)"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.819543+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "if",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [54; 56),
+ insert: "if $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "match",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [54; 56),
+ insert: "match $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "while",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [54; 56),
+ insert: "while $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "loop",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [54; 56),
+ insert: "loop {$0}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "continue",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [54; 56),
+ insert: "continue;"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "break",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [54; 56),
+ insert: "break;"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "return",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [54; 56),
+ insert: "return $0;"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.830288+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "if",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [59; 61),
+ insert: "if $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "match",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [59; 61),
+ insert: "match $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "while",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [59; 61),
+ insert: "while $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "loop",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [59; 61),
+ insert: "loop {$0}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "return",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [59; 61),
+ insert: "return $0;"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:50:41.824939+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Postfix,
+ label: "not",
+ kind: None,
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [78; 78),
+ insert: "!not"
+ }
+ ),
+ additional_text_edits: Some(
+ TextEdit {
+ atoms: [
+ AtomTextEdit {
+ delete: [72; 78),
+ insert: ""
+ }
+ ]
+ }
+ )
+ },
+ CompletionItem {
+ completion_kind: Postfix,
+ label: "if",
+ kind: None,
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [78; 78),
+ insert: "if bar {$0}"
+ }
+ ),
+ additional_text_edits: Some(
+ TextEdit {
+ atoms: [
+ AtomTextEdit {
+ delete: [72; 78),
+ insert: ""
+ }
+ ]
+ }
+ )
+ },
+ CompletionItem {
+ completion_kind: Postfix,
+ label: "match",
+ kind: None,
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [78; 78),
+ insert: "match bar {\n${1:_} => {$0\\},\n}"
+ }
+ ),
+ additional_text_edits: Some(
+ TextEdit {
+ atoms: [
+ AtomTextEdit {
+ delete: [72; 78),
+ insert: ""
+ }
+ ]
+ }
+ )
+ },
+ CompletionItem {
+ completion_kind: Postfix,
+ label: "while",
+ kind: None,
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [78; 78),
+ insert: "while bar {\n$0\n}"
+ }
+ ),
+ additional_text_edits: Some(
+ TextEdit {
+ atoms: [
+ AtomTextEdit {
+ delete: [72; 78),
+ insert: ""
+ }
+ ]
+ }
+ )
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:53:16.799862+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "Spam",
+ kind: Some(
+ Struct
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.821375+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "if",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [84; 102),
+ insert: "if $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "match",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [84; 102),
+ insert: "match $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "while",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [84; 102),
+ insert: "while $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "loop",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [84; 102),
+ insert: "loop {$0}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "return",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [84; 102),
+ insert: "return $0"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:53:16.799845+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "main",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "frobnicate",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:53:16.799820+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "foo",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.841643+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "bar",
+ kind: Some(
+ Binding
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "foo",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [108; 146),
+ insert: "foo()$0"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.844671+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "no_args",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [53; 56),
+ insert: "no_args()$0"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "main",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [53; 56),
+ insert: "main()$0"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.849139+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "main",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [72; 77),
+ insert: "main()$0"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "with_args",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [72; 77),
+ insert: "with_args($0)"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.819926+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "if",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [24; 54),
+ insert: "if $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "match",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [24; 54),
+ insert: "match $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "while",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [24; 54),
+ insert: "while $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "loop",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [24; 54),
+ insert: "loop {$0}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "return",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [24; 54),
+ insert: "return;"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.819839+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "if",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [91; 105),
+ insert: "if $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "match",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [91; 105),
+ insert: "match $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "while",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [91; 105),
+ insert: "while $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "loop",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [91; 105),
+ insert: "loop {$0}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "else",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [91; 105),
+ insert: "else {$0}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "else if",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [91; 105),
+ insert: "else if $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "return",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [91; 105),
+ insert: "return;"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.822255+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "if",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [31; 65),
+ insert: "if $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "match",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [31; 65),
+ insert: "match $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "while",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [31; 65),
+ insert: "while $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "loop",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [31; 65),
+ insert: "loop {$0}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "return",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [31; 65),
+ insert: "return $0;"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.830680+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "if",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [24; 58),
+ insert: "if $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "match",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [24; 58),
+ insert: "match $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "while",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [24; 58),
+ insert: "while $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "loop",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [24; 58),
+ insert: "loop {$0}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "return",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [24; 58),
+ insert: "return;"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.819227+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "crate",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [16; 30),
+ insert: "crate::"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "self",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "super",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [16; 30),
+ insert: "super::"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.822990+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "self",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "super",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [18; 20),
+ insert: "super::"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.826915+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "self",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "super",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [23; 24),
+ insert: "super::"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.821139+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "if",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [62; 100),
+ insert: "if $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "match",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [62; 100),
+ insert: "match $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "while",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [62; 100),
+ insert: "while $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "loop",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [62; 100),
+ insert: "loop {$0}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "return",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [62; 100),
+ insert: "return $0;"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.829078+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "if",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [62; 100),
+ insert: "if $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "match",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [62; 100),
+ insert: "match $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "while",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [62; 100),
+ insert: "while $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "loop",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [62; 100),
+ insert: "loop {$0}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "return",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [62; 100),
+ insert: "return $0;"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.817204+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "the_method",
+ kind: Some(
+ Method
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [143; 144),
+ insert: "the_method($0)"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.835687+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "quux",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [72; 102),
+ insert: "quux()$0"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "Foo",
+ kind: Some(
+ Struct
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "Baz",
+ kind: Some(
+ Enum
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.836102+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "quux",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [100; 102),
+ insert: "quux()$0"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "Bar",
+ kind: Some(
+ Struct
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:53:16.799743+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "Spam",
+ kind: Some(
+ Struct
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "foo",
+ kind: Some(
+ Module
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:34:11.702251+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[]
--- /dev/null
+Created: 2019-01-19T13:42:17.821881+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "if",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [106; 108),
+ insert: "if $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "match",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [106; 108),
+ insert: "match $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "while",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [106; 108),
+ insert: "while $0 {}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "loop",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [106; 108),
+ insert: "loop {$0}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "continue",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [106; 108),
+ insert: "continue"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "break",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [106; 108),
+ insert: "break"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Keyword,
+ label: "return",
+ kind: Some(
+ Keyword
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [106; 108),
+ insert: "return"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:34:11.702201+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[]
--- /dev/null
+Created: 2019-01-19T11:27:14.070727+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Magic,
+ label: "file_id: FileId",
+ kind: None,
+ detail: None,
+ lookup: Some(
+ "file_id"
+ ),
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:29:09.355053+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Magic,
+ label: "file_id: FileId",
+ kind: None,
+ detail: None,
+ lookup: Some(
+ "file_id"
+ ),
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:29:09.355066+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Magic,
+ label: "file_id: FileId",
+ kind: None,
+ detail: None,
+ lookup: Some(
+ "file_id"
+ ),
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:53:16.799765+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "Foo",
+ kind: Some(
+ EnumVariant
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "Bar",
+ kind: Some(
+ EnumVariant
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.837692+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "Foo",
+ kind: Some(
+ Struct
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "x",
+ kind: Some(
+ Function
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [46; 60),
+ insert: "x()$0"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:59:18.394156+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "self",
+ kind: Some(
+ Binding
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.844708+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Snippet,
+ label: "pd",
+ kind: Some(
+ Snippet
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [16; 18),
+ insert: "eprintln!(\"$0 = {:?}\", $0);"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Snippet,
+ label: "ppd",
+ kind: Some(
+ Snippet
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [16; 18),
+ insert: "eprintln!(\"$0 = {:#?}\", $0);"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.845616+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Snippet,
+ label: "Test function",
+ kind: Some(
+ Snippet
+ ),
+ detail: None,
+ lookup: Some(
+ "tfn"
+ ),
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [49; 79),
+ insert: "#[test]\nfn ${1:feature}() {\n $0\n}"
+ }
+ ),
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Snippet,
+ label: "pub(crate)",
+ kind: Some(
+ Snippet
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [49; 79),
+ insert: "pub(crate) $0"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:34:11.702218+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "the_field",
+ kind: Some(
+ Field
+ ),
+ detail: Some(
+ "u32"
+ ),
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.817216+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "the_field",
+ kind: Some(
+ Field
+ ),
+ detail: Some(
+ "(u32, i32)"
+ ),
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "foo",
+ kind: Some(
+ Method
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [125; 126),
+ insert: "foo($0)"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T13:42:17.817207+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "the_field",
+ kind: Some(
+ Field
+ ),
+ detail: Some(
+ "(u32,)"
+ ),
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "foo",
+ kind: Some(
+ Method
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: Snippet,
+ text_edit: Some(
+ AtomTextEdit {
+ delete: [120; 121),
+ insert: "foo($0)"
+ }
+ ),
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:53:16.799683+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "Spam",
+ kind: Some(
+ Struct
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ },
+ CompletionItem {
+ completion_kind: Reference,
+ label: "foo",
+ kind: Some(
+ Module
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
--- /dev/null
+Created: 2019-01-19T11:53:16.799788+00:00
+Creator: insta@0.1.4
+Source: crates/ra_ide_api/src/completion/completion_item.rs
+
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "Bar",
+ kind: Some(
+ Struct
+ ),
+ detail: None,
+ lookup: None,
+ insert_text_format: PlainText,
+ text_edit: None,
+ additional_text_edits: None
+ }
+]
};
pub use crate::{
- completion::{CompletionItem, CompletionItemKind, InsertText},
+ completion::{CompletionItem, CompletionItemKind, InsertTextFormat},
runnables::{Runnable, RunnableKind},
navigation_target::NavigationTarget,
};
use lsp_types::{
- self, CreateFile, DocumentChangeOperation, DocumentChanges, InsertTextFormat, Location, LocationLink,
+ self, CreateFile, DocumentChangeOperation, DocumentChanges, Location, LocationLink,
Position, Range, RenameFile, ResourceOp, SymbolKind, TextDocumentEdit, TextDocumentIdentifier,
TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier,
WorkspaceEdit,
};
use ra_ide_api::{
CompletionItem, CompletionItemKind, FileId, FilePosition, FileRange, FileSystemEdit,
- InsertText, NavigationTarget, SourceChange, SourceFileEdit, RangeInfo,
- LineCol, LineIndex, translate_offset_with_edit
+ NavigationTarget, SourceChange, SourceFileEdit, RangeInfo,
+ LineCol, LineIndex, translate_offset_with_edit, InsertTextFormat
};
use ra_syntax::{SyntaxKind, TextRange, TextUnit};
use ra_text_edit::{AtomTextEdit, TextEdit};
}
}
-impl Conv for CompletionItem {
+impl ConvWith for CompletionItem {
+ type Ctx = LineIndex;
type Output = ::lsp_types::CompletionItem;
- fn conv(self) -> <Self as Conv>::Output {
- let mut res = ::lsp_types::CompletionItem {
+ fn conv_with(mut self, ctx: &LineIndex) -> ::lsp_types::CompletionItem {
+ let text_edit = self.text_edit().map(|t| t.conv_with(ctx));
+ let additonal_text_edit = self
+ .take_additional_text_edits()
+ .map(|it| it.conv_with(ctx));
+
+ let mut res = lsp_types::CompletionItem {
label: self.label().to_string(),
detail: self.detail().map(|it| it.to_string()),
filter_text: Some(self.lookup().to_string()),
kind: self.kind().map(|it| it.conv()),
+ text_edit,
+ additional_text_edits: additonal_text_edit,
..Default::default()
};
- match self.insert_text() {
- InsertText::PlainText { text } => {
- res.insert_text = Some(text);
- res.insert_text_format = Some(InsertTextFormat::PlainText);
- }
- InsertText::Snippet { text } => {
- res.insert_text = Some(text);
- res.insert_text_format = Some(InsertTextFormat::Snippet);
- }
- }
+ res.insert_text_format = Some(match self.insert_text_format() {
+ InsertTextFormat::Snippet => lsp_types::InsertTextFormat::Snippet,
+ InsertTextFormat::PlainText => lsp_types::InsertTextFormat::PlainText,
+ });
+
res
}
}
None => return Ok(None),
Some(items) => items,
};
- let items = items.into_iter().map(|item| item.conv()).collect();
+ let line_index = world.analysis().file_line_index(position.file_id);
+ let items = items
+ .into_iter()
+ .map(|item| item.conv_with(&line_index))
+ .collect();
Ok(Some(req::CompletionResponse::Array(items)))
}