mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 13:18:47 +00:00
Introduce postfix item types
This commit is contained in:
parent
41d8369d1c
commit
eda4046a05
5 changed files with 50 additions and 33 deletions
|
@ -12,9 +12,11 @@ use syntax::{
|
||||||
use text_edit::TextEdit;
|
use text_edit::TextEdit;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
completions::postfix::format_like::add_format_like_completions, context::CompletionContext,
|
completions::postfix::format_like::add_format_like_completions,
|
||||||
item::Builder, patterns::ImmediateLocation, CompletionItem, CompletionItemKind,
|
context::CompletionContext,
|
||||||
CompletionRelevance, Completions, SnippetScope,
|
item::{Builder, CompletionRelevancePostfixMatch},
|
||||||
|
patterns::ImmediateLocation,
|
||||||
|
CompletionItem, CompletionItemKind, CompletionRelevance, Completions, SnippetScope,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
|
@ -240,11 +242,12 @@ fn build_postfix_snippet_builder<'ctx>(
|
||||||
let mut item =
|
let mut item =
|
||||||
CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), label);
|
CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), label);
|
||||||
item.detail(detail).snippet_edit(cap, edit);
|
item.detail(detail).snippet_edit(cap, edit);
|
||||||
let relevance = if ctx.original_token.text() == label {
|
let postfix_match = if ctx.original_token.text() == label {
|
||||||
CompletionRelevance { exact_postfix_snippet_match: true, ..Default::default() }
|
Some(CompletionRelevancePostfixMatch::Exact)
|
||||||
} else {
|
} else {
|
||||||
CompletionRelevance { is_postfix: true, ..Default::default() }
|
Some(CompletionRelevancePostfixMatch::NonExact)
|
||||||
};
|
};
|
||||||
|
let relevance = CompletionRelevance { postfix_match, ..Default::default() };
|
||||||
item.set_relevance(relevance);
|
item.set_relevance(relevance);
|
||||||
item
|
item
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use syntax::{ast::Expr, T};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind,
|
patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind,
|
||||||
CompletionRelevance, Completions,
|
CompletionRelevance, CompletionRelevancePostfixMatch, Completions,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
|
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 =
|
let completion_text =
|
||||||
completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text);
|
completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text);
|
||||||
item.insert_text(completion_text).set_relevance(CompletionRelevance {
|
item.insert_text(completion_text).set_relevance(CompletionRelevance {
|
||||||
exact_postfix_snippet_match: true,
|
postfix_match: Some(CompletionRelevancePostfixMatch::Exact),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
item.add_to(acc);
|
item.add_to(acc);
|
||||||
|
|
|
@ -143,17 +143,8 @@ pub struct CompletionRelevance {
|
||||||
pub is_op_method: bool,
|
pub is_op_method: bool,
|
||||||
/// Set for item completions that are private but in the workspace.
|
/// Set for item completions that are private but in the workspace.
|
||||||
pub is_private_editable: bool,
|
pub is_private_editable: bool,
|
||||||
/// This is set in cases like these:
|
/// Set for postfix snippet item completions
|
||||||
///
|
pub postfix_match: Option<CompletionRelevancePostfixMatch>,
|
||||||
/// ```
|
|
||||||
/// (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,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
@ -180,6 +171,21 @@ pub enum CompletionRelevanceTypeMatch {
|
||||||
Exact,
|
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 {
|
impl CompletionRelevance {
|
||||||
const BASE_LINE: u32 = 3;
|
const BASE_LINE: u32 = 3;
|
||||||
/// Provides a relevance score. Higher values are more relevant.
|
/// Provides a relevance score. Higher values are more relevant.
|
||||||
|
@ -201,7 +207,7 @@ impl CompletionRelevance {
|
||||||
if self.is_private_editable {
|
if self.is_private_editable {
|
||||||
score -= 1;
|
score -= 1;
|
||||||
}
|
}
|
||||||
if self.is_postfix {
|
if self.postfix_match.is_some() {
|
||||||
score -= 3;
|
score -= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +223,7 @@ impl CompletionRelevance {
|
||||||
if self.is_local {
|
if self.is_local {
|
||||||
score += 1;
|
score += 1;
|
||||||
}
|
}
|
||||||
if self.exact_postfix_snippet_match {
|
if self.postfix_match == Some(CompletionRelevancePostfixMatch::Exact) {
|
||||||
score += 100;
|
score += 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,7 +542,9 @@ mod tests {
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use test_utils::assert_eq_text;
|
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
|
/// Check that these are CompletionRelevance are sorted in ascending order
|
||||||
/// by their relevance score.
|
/// by their relevance score.
|
||||||
|
@ -579,7 +587,10 @@ mod tests {
|
||||||
// This test asserts that the relevance score for these items is ascending, and
|
// This test asserts that the relevance score for these items is ascending, and
|
||||||
// that any items in the same vec have the same score.
|
// that any items in the same vec have the same score.
|
||||||
let expected_relevance_order = vec![
|
let expected_relevance_order = vec![
|
||||||
vec![CompletionRelevance { is_postfix: true, ..CompletionRelevance::default() }],
|
vec![CompletionRelevance {
|
||||||
|
postfix_match: Some(CompletionRelevancePostfixMatch::NonExact),
|
||||||
|
..CompletionRelevance::default()
|
||||||
|
}],
|
||||||
vec![CompletionRelevance {
|
vec![CompletionRelevance {
|
||||||
is_op_method: true,
|
is_op_method: true,
|
||||||
is_private_editable: true,
|
is_private_editable: true,
|
||||||
|
@ -619,7 +630,7 @@ mod tests {
|
||||||
..CompletionRelevance::default()
|
..CompletionRelevance::default()
|
||||||
}],
|
}],
|
||||||
vec![CompletionRelevance {
|
vec![CompletionRelevance {
|
||||||
exact_postfix_snippet_match: true,
|
postfix_match: Some(CompletionRelevancePostfixMatch::Exact),
|
||||||
..CompletionRelevance::default()
|
..CompletionRelevance::default()
|
||||||
}],
|
}],
|
||||||
];
|
];
|
||||||
|
|
|
@ -28,7 +28,10 @@ use crate::{completions::Completions, context::CompletionContext};
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
config::CompletionConfig,
|
config::CompletionConfig,
|
||||||
item::{CompletionItem, CompletionItemKind, CompletionRelevance, ImportEdit},
|
item::{
|
||||||
|
CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevancePostfixMatch,
|
||||||
|
ImportEdit,
|
||||||
|
},
|
||||||
snippet::{Snippet, SnippetScope},
|
snippet::{Snippet, SnippetScope},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -365,7 +365,7 @@ mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
item::CompletionRelevanceTypeMatch,
|
item::CompletionRelevanceTypeMatch,
|
||||||
tests::{check_edit, do_completion, get_all_items, TEST_CONFIG},
|
tests::{check_edit, do_completion, get_all_items, TEST_CONFIG},
|
||||||
CompletionItem, CompletionItemKind, CompletionRelevance,
|
CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevancePostfixMatch,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
@ -432,7 +432,10 @@ mod tests {
|
||||||
),
|
),
|
||||||
(relevance.exact_name_match, "name"),
|
(relevance.exact_name_match, "name"),
|
||||||
(relevance.is_local, "local"),
|
(relevance.is_local, "local"),
|
||||||
(relevance.exact_postfix_snippet_match, "snippet"),
|
(
|
||||||
|
relevance.postfix_match == Some(CompletionRelevancePostfixMatch::Exact),
|
||||||
|
"snippet",
|
||||||
|
),
|
||||||
(relevance.is_op_method, "op_method"),
|
(relevance.is_op_method, "op_method"),
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -614,8 +617,7 @@ fn main() { let _: m::Spam = S$0 }
|
||||||
is_local: false,
|
is_local: false,
|
||||||
is_op_method: false,
|
is_op_method: false,
|
||||||
is_private_editable: false,
|
is_private_editable: false,
|
||||||
exact_postfix_snippet_match: false,
|
postfix_match: None,
|
||||||
is_postfix: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CompletionItem {
|
CompletionItem {
|
||||||
|
@ -636,8 +638,7 @@ fn main() { let _: m::Spam = S$0 }
|
||||||
is_local: false,
|
is_local: false,
|
||||||
is_op_method: false,
|
is_op_method: false,
|
||||||
is_private_editable: false,
|
is_private_editable: false,
|
||||||
exact_postfix_snippet_match: false,
|
postfix_match: None,
|
||||||
is_postfix: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -724,8 +725,7 @@ fn foo() { A { the$0 } }
|
||||||
is_local: false,
|
is_local: false,
|
||||||
is_op_method: false,
|
is_op_method: false,
|
||||||
is_private_editable: false,
|
is_private_editable: false,
|
||||||
exact_postfix_snippet_match: false,
|
postfix_match: None,
|
||||||
is_postfix: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue