From eda4046a057d279b9f4acda923b56aa1845f15da Mon Sep 17 00:00:00 2001 From: Aleksei Trifonov Date: Fri, 1 Apr 2022 20:50:27 +0300 Subject: [PATCH] Introduce postfix item types --- .../ide_completion/src/completions/postfix.rs | 15 ++++--- .../ide_completion/src/completions/record.rs | 4 +- crates/ide_completion/src/item.rs | 43 ++++++++++++------- crates/ide_completion/src/lib.rs | 5 ++- crates/ide_completion/src/render.rs | 16 +++---- 5 files changed, 50 insertions(+), 33 deletions(-) diff --git a/crates/ide_completion/src/completions/postfix.rs b/crates/ide_completion/src/completions/postfix.rs index 45ae590405..302694ea7c 100644 --- a/crates/ide_completion/src/completions/postfix.rs +++ b/crates/ide_completion/src/completions/postfix.rs @@ -12,9 +12,11 @@ use syntax::{ use text_edit::TextEdit; use crate::{ - completions::postfix::format_like::add_format_like_completions, context::CompletionContext, - item::Builder, patterns::ImmediateLocation, CompletionItem, CompletionItemKind, - CompletionRelevance, Completions, SnippetScope, + completions::postfix::format_like::add_format_like_completions, + context::CompletionContext, + item::{Builder, CompletionRelevancePostfixMatch}, + patterns::ImmediateLocation, + CompletionItem, CompletionItemKind, CompletionRelevance, Completions, SnippetScope, }; pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { @@ -240,11 +242,12 @@ fn build_postfix_snippet_builder<'ctx>( let mut item = CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), label); item.detail(detail).snippet_edit(cap, edit); - let relevance = if ctx.original_token.text() == label { - CompletionRelevance { exact_postfix_snippet_match: true, ..Default::default() } + let postfix_match = if ctx.original_token.text() == label { + Some(CompletionRelevancePostfixMatch::Exact) } else { - CompletionRelevance { is_postfix: true, ..Default::default() } + Some(CompletionRelevancePostfixMatch::NonExact) }; + let relevance = CompletionRelevance { postfix_match, ..Default::default() }; item.set_relevance(relevance); item } diff --git a/crates/ide_completion/src/completions/record.rs b/crates/ide_completion/src/completions/record.rs index 5509ec922f..4b8210de0b 100644 --- a/crates/ide_completion/src/completions/record.rs +++ b/crates/ide_completion/src/completions/record.rs @@ -4,7 +4,7 @@ use syntax::{ast::Expr, T}; use crate::{ patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind, - CompletionRelevance, Completions, + CompletionRelevance, CompletionRelevancePostfixMatch, Completions, }; pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { @@ -45,7 +45,7 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> let completion_text = completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text); item.insert_text(completion_text).set_relevance(CompletionRelevance { - exact_postfix_snippet_match: true, + postfix_match: Some(CompletionRelevancePostfixMatch::Exact), ..Default::default() }); item.add_to(acc); diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs index 7948e19af9..89cbddbad3 100644 --- a/crates/ide_completion/src/item.rs +++ b/crates/ide_completion/src/item.rs @@ -143,17 +143,8 @@ pub struct CompletionRelevance { pub is_op_method: bool, /// Set for item completions that are private but in the workspace. pub is_private_editable: bool, - /// This is set in cases like these: - /// - /// ``` - /// (a > b).not$0 - /// ``` - /// - /// Basically, we want to guarantee that postfix snippets always takes - /// precedence over everything else. - pub exact_postfix_snippet_match: bool, - /// Set in cases when item is postfix, but not exact - pub is_postfix: bool, + /// Set for postfix snippet item completions + pub postfix_match: Option, } #[derive(Debug, Clone, Copy, Eq, PartialEq)] @@ -180,6 +171,21 @@ pub enum CompletionRelevanceTypeMatch { Exact, } +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub enum CompletionRelevancePostfixMatch { + /// Set in cases when item is postfix, but not exact + NonExact, + /// This is set in cases like these: + /// + /// ``` + /// (a > b).not$0 + /// ``` + /// + /// Basically, we want to guarantee that postfix snippets always takes + /// precedence over everything else. + Exact, +} + impl CompletionRelevance { const BASE_LINE: u32 = 3; /// Provides a relevance score. Higher values are more relevant. @@ -201,7 +207,7 @@ impl CompletionRelevance { if self.is_private_editable { score -= 1; } - if self.is_postfix { + if self.postfix_match.is_some() { score -= 3; } @@ -217,7 +223,7 @@ impl CompletionRelevance { if self.is_local { score += 1; } - if self.exact_postfix_snippet_match { + if self.postfix_match == Some(CompletionRelevancePostfixMatch::Exact) { score += 100; } @@ -536,7 +542,9 @@ mod tests { use itertools::Itertools; use test_utils::assert_eq_text; - use super::{CompletionRelevance, CompletionRelevanceTypeMatch}; + use super::{ + CompletionRelevance, CompletionRelevancePostfixMatch, CompletionRelevanceTypeMatch, + }; /// Check that these are CompletionRelevance are sorted in ascending order /// by their relevance score. @@ -579,7 +587,10 @@ mod tests { // This test asserts that the relevance score for these items is ascending, and // that any items in the same vec have the same score. let expected_relevance_order = vec![ - vec![CompletionRelevance { is_postfix: true, ..CompletionRelevance::default() }], + vec![CompletionRelevance { + postfix_match: Some(CompletionRelevancePostfixMatch::NonExact), + ..CompletionRelevance::default() + }], vec![CompletionRelevance { is_op_method: true, is_private_editable: true, @@ -619,7 +630,7 @@ mod tests { ..CompletionRelevance::default() }], vec![CompletionRelevance { - exact_postfix_snippet_match: true, + postfix_match: Some(CompletionRelevancePostfixMatch::Exact), ..CompletionRelevance::default() }], ]; diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs index 422bda6460..c2880e4c67 100644 --- a/crates/ide_completion/src/lib.rs +++ b/crates/ide_completion/src/lib.rs @@ -28,7 +28,10 @@ use crate::{completions::Completions, context::CompletionContext}; pub use crate::{ config::CompletionConfig, - item::{CompletionItem, CompletionItemKind, CompletionRelevance, ImportEdit}, + item::{ + CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevancePostfixMatch, + ImportEdit, + }, snippet::{Snippet, SnippetScope}, }; diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs index 652cd52f80..a18c064960 100644 --- a/crates/ide_completion/src/render.rs +++ b/crates/ide_completion/src/render.rs @@ -365,7 +365,7 @@ mod tests { use crate::{ item::CompletionRelevanceTypeMatch, tests::{check_edit, do_completion, get_all_items, TEST_CONFIG}, - CompletionItem, CompletionItemKind, CompletionRelevance, + CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevancePostfixMatch, }; #[track_caller] @@ -432,7 +432,10 @@ mod tests { ), (relevance.exact_name_match, "name"), (relevance.is_local, "local"), - (relevance.exact_postfix_snippet_match, "snippet"), + ( + relevance.postfix_match == Some(CompletionRelevancePostfixMatch::Exact), + "snippet", + ), (relevance.is_op_method, "op_method"), ] .into_iter() @@ -614,8 +617,7 @@ fn main() { let _: m::Spam = S$0 } is_local: false, is_op_method: false, is_private_editable: false, - exact_postfix_snippet_match: false, - is_postfix: false, + postfix_match: None, }, }, CompletionItem { @@ -636,8 +638,7 @@ fn main() { let _: m::Spam = S$0 } is_local: false, is_op_method: false, is_private_editable: false, - exact_postfix_snippet_match: false, - is_postfix: false, + postfix_match: None, }, }, ] @@ -724,8 +725,7 @@ fn foo() { A { the$0 } } is_local: false, is_op_method: false, is_private_editable: false, - exact_postfix_snippet_match: false, - is_postfix: false, + postfix_match: None, }, }, ]