From 5d1a63c6951d27a9f900d661e38735cc30bc8258 Mon Sep 17 00:00:00 2001 From: gfreezy Date: Mon, 21 Jan 2019 13:19:51 +0800 Subject: postfix completion --- crates/ra_ide_api/src/completion.rs | 3 +- .../ra_ide_api/src/completion/complete_postfix.rs | 95 +++++++++++++++++++ .../ra_ide_api/src/completion/completion_item.rs | 6 ++ .../completion_item__completion_postfix.snap | 102 --------------------- ...ompletion_item__filter_postfix_completion1.snap | 94 +++++++++++++++++++ ...ompletion_item__filter_postfix_completion2.snap | 94 +++++++++++++++++++ ...ompletion_item__filter_postfix_completion3.snap | 94 +++++++++++++++++++ 7 files changed, 385 insertions(+), 103 deletions(-) create mode 100644 crates/ra_ide_api/src/completion/complete_postfix.rs delete mode 100644 crates/ra_ide_api/src/completion/snapshots/completion_item__completion_postfix.snap create mode 100644 crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion1.snap create mode 100644 crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion2.snap create mode 100644 crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion3.snap diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs index 855f5d964..565d57c37 100644 --- a/crates/ra_ide_api/src/completion.rs +++ b/crates/ra_ide_api/src/completion.rs @@ -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) } diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide_api/src/completion/complete_postfix.rs new file mode 100644 index 000000000..cf0252a00 --- /dev/null +++ b/crates/ra_ide_api/src/completion/complete_postfix.rs @@ -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<|> + } + "#, + ); + } +} diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs index f46d9e581..c892ad846 100644 --- a/crates/ra_ide_api/src/completion/completion_item.rs +++ b/crates/ra_ide_api/src/completion/completion_item.rs @@ -18,7 +18,12 @@ pub struct CompletionItem { lookup: Option, insert_text: Option, 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, } @@ -49,6 +54,7 @@ pub(crate) enum CompletionKind { /// "Secret sauce" completions. Magic, Snippet, + Postfix, } #[derive(Debug, PartialEq, Eq, Copy, Clone)] diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__completion_postfix.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__completion_postfix.snap deleted file mode 100644 index 60b5a7424..000000000 --- a/crates/ra_ide_api/src/completion/snapshots/completion_item__completion_postfix.snap +++ /dev/null @@ -1,102 +0,0 @@ -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: "" - } - ] - } - ) - } -] diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion1.snap new file mode 100644 index 000000000..a0abd00cc --- /dev/null +++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion1.snap @@ -0,0 +1,94 @@ +Created: 2019-01-21T05:12:32.815475+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; 76), + 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; 76), + 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; 76), + 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; 76), + text_edit: Some( + TextEdit { + atoms: [ + AtomTextEdit { + delete: [72; 76), + insert: "" + } + ] + } + ) + } +] diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion2.snap new file mode 100644 index 000000000..3b3ee8d43 --- /dev/null +++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion2.snap @@ -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: "" + } + ] + } + ) + } +] diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion3.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion3.snap new file mode 100644 index 000000000..31e8f008c --- /dev/null +++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion3.snap @@ -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: "" + } + ] + } + ) + } +] -- cgit v1.2.3