582: Postfix completion r=matklad a=gfreezy

resolved #525 

Co-authored-by: gfreezy <gfreezy@gmail.com>
This commit is contained in:
bors[bot] 2019-01-21 08:12:14 +00:00
commit 237bb929f4
6 changed files with 316 additions and 34 deletions

View file

@ -7,6 +7,7 @@ mod complete_keyword;
mod complete_snippet;
mod complete_path;
mod complete_scope;
mod complete_postfix;
use ra_db::SyntaxDatabase;
@ -57,6 +58,6 @@ pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Opti
complete_path::complete_path(&mut acc, &ctx);
complete_scope::complete_scope(&mut acc, &ctx);
complete_dot::complete_dot(&mut acc, &ctx);
complete_postfix::complete_postfix(&mut acc, &ctx);
Some(acc)
}

View file

@ -0,0 +1,95 @@
use crate::{
completion::{
completion_item::{
Completions,
Builder,
CompletionKind,
},
completion_context::CompletionContext,
},
CompletionItem
};
use ra_syntax::{
ast::AstNode,
TextRange
};
use ra_text_edit::TextEditBuilder;
fn postfix_snippet(ctx: &CompletionContext, label: &str, snippet: &str) -> Builder {
let replace_range = ctx.source_range();
let receiver_range = ctx
.dot_receiver
.expect("no receiver available")
.syntax()
.range();
let delete_range = TextRange::from_to(receiver_range.start(), replace_range.start());
let mut builder = TextEditBuilder::default();
builder.delete(delete_range);
CompletionItem::new(CompletionKind::Postfix, replace_range, label)
.snippet(snippet)
.text_edit(builder.finish())
}
pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
if let Some(dot_receiver) = ctx.dot_receiver {
let receiver_text = dot_receiver.syntax().text().to_string();
postfix_snippet(ctx, "not", "!not").add_to(acc);
postfix_snippet(ctx, "if", &format!("if {} {{$0}}", receiver_text)).add_to(acc);
postfix_snippet(
ctx,
"match",
&format!("match {} {{\n${{1:_}} => {{$0\\}},\n}}", receiver_text),
)
.add_to(acc);
postfix_snippet(ctx, "while", &format!("while {} {{\n$0\n}}", receiver_text)).add_to(acc);
}
}
#[cfg(test)]
mod tests {
use crate::completion::completion_item::CompletionKind;
use crate::completion::completion_item::check_completion;
fn check_snippet_completion(code: &str, expected_completions: &str) {
check_completion(code, expected_completions, CompletionKind::Postfix);
}
#[test]
fn test_filter_postfix_completion1() {
check_snippet_completion(
"filter_postfix_completion1",
r#"
fn main() {
let bar = "a";
bar.<|>
}
"#,
);
}
#[test]
fn test_filter_postfix_completion2() {
check_snippet_completion(
"filter_postfix_completion2",
r#"
fn main() {
let bar = "a";
bar.i<|>
}
"#,
);
}
#[test]
fn test_filter_postfix_completion3() {
check_snippet_completion(
"filter_postfix_completion3",
r#"
fn main() {
let bar = "a";
bar.if<|>
}
"#,
);
}
}

View file

@ -18,7 +18,12 @@ pub struct CompletionItem {
lookup: Option<String>,
insert_text: Option<String>,
insert_text_format: InsertTextFormat,
/// Where completion occurs. `source_range` must contain the completion offset.
/// `insert_text` should start with what `source_range` points to, or VSCode
/// will filter out the completion silently.
source_range: TextRange,
/// Additional text edit, ranges in `text_edit` must never intersect with `source_range`.
/// Or VSCode will drop it silently.
text_edit: Option<TextEdit>,
}
@ -49,6 +54,7 @@ pub(crate) enum CompletionKind {
/// "Secret sauce" completions.
Magic,
Snippet,
Postfix,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]

View file

@ -1,4 +1,4 @@
Created: 2019-01-19T13:50:41.824939+00:00
Created: 2019-01-21T05:12:32.815475+00:00
Creator: insta@0.1.4
Source: crates/ra_ide_api/src/completion/completion_item.rs
@ -9,18 +9,16 @@ Source: crates/ra_ide_api/src/completion/completion_item.rs
kind: None,
detail: None,
lookup: None,
insert_text_format: Snippet,
text_edit: Some(
AtomTextEdit {
delete: [78; 78),
insert: "!not"
}
insert_text: Some(
"!not"
),
additional_text_edits: Some(
insert_text_format: Snippet,
source_range: [76; 76),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 78),
delete: [72; 76),
insert: ""
}
]
@ -33,18 +31,16 @@ Source: crates/ra_ide_api/src/completion/completion_item.rs
kind: None,
detail: None,
lookup: None,
insert_text_format: Snippet,
text_edit: Some(
AtomTextEdit {
delete: [78; 78),
insert: "if bar {$0}"
}
insert_text: Some(
"if bar {$0}"
),
additional_text_edits: Some(
insert_text_format: Snippet,
source_range: [76; 76),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 78),
delete: [72; 76),
insert: ""
}
]
@ -57,18 +53,16 @@ Source: crates/ra_ide_api/src/completion/completion_item.rs
kind: None,
detail: None,
lookup: None,
insert_text_format: Snippet,
text_edit: Some(
AtomTextEdit {
delete: [78; 78),
insert: "match bar {\n${1:_} => {$0\\},\n}"
}
insert_text: Some(
"match bar {\n${1:_} => {$0\\},\n}"
),
additional_text_edits: Some(
insert_text_format: Snippet,
source_range: [76; 76),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 78),
delete: [72; 76),
insert: ""
}
]
@ -81,18 +75,16 @@ Source: crates/ra_ide_api/src/completion/completion_item.rs
kind: None,
detail: None,
lookup: None,
insert_text_format: Snippet,
text_edit: Some(
AtomTextEdit {
delete: [78; 78),
insert: "while bar {\n$0\n}"
}
insert_text: Some(
"while bar {\n$0\n}"
),
additional_text_edits: Some(
insert_text_format: Snippet,
source_range: [76; 76),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 78),
delete: [72; 76),
insert: ""
}
]

View file

@ -0,0 +1,94 @@
Created: 2019-01-21T05:12:32.816092+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: Some(
"!not"
),
insert_text_format: Snippet,
source_range: [76; 77),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 76),
insert: ""
}
]
}
)
},
CompletionItem {
completion_kind: Postfix,
label: "if",
kind: None,
detail: None,
lookup: None,
insert_text: Some(
"if bar {$0}"
),
insert_text_format: Snippet,
source_range: [76; 77),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 76),
insert: ""
}
]
}
)
},
CompletionItem {
completion_kind: Postfix,
label: "match",
kind: None,
detail: None,
lookup: None,
insert_text: Some(
"match bar {\n${1:_} => {$0\\},\n}"
),
insert_text_format: Snippet,
source_range: [76; 77),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 76),
insert: ""
}
]
}
)
},
CompletionItem {
completion_kind: Postfix,
label: "while",
kind: None,
detail: None,
lookup: None,
insert_text: Some(
"while bar {\n$0\n}"
),
insert_text_format: Snippet,
source_range: [76; 77),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 76),
insert: ""
}
]
}
)
}
]

View file

@ -0,0 +1,94 @@
Created: 2019-01-21T05:19:05.341730+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: Some(
"!not"
),
insert_text_format: Snippet,
source_range: [76; 78),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 76),
insert: ""
}
]
}
)
},
CompletionItem {
completion_kind: Postfix,
label: "if",
kind: None,
detail: None,
lookup: None,
insert_text: Some(
"if bar {$0}"
),
insert_text_format: Snippet,
source_range: [76; 78),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 76),
insert: ""
}
]
}
)
},
CompletionItem {
completion_kind: Postfix,
label: "match",
kind: None,
detail: None,
lookup: None,
insert_text: Some(
"match bar {\n${1:_} => {$0\\},\n}"
),
insert_text_format: Snippet,
source_range: [76; 78),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 76),
insert: ""
}
]
}
)
},
CompletionItem {
completion_kind: Postfix,
label: "while",
kind: None,
detail: None,
lookup: None,
insert_text: Some(
"while bar {\n$0\n}"
),
insert_text_format: Snippet,
source_range: [76; 78),
text_edit: Some(
TextEdit {
atoms: [
AtomTextEdit {
delete: [72; 76),
insert: ""
}
]
}
)
}
]