fix: better inline preview for postfix completion

This commit is contained in:
roife 2024-04-15 22:16:22 +08:00
parent 2cbc2841d8
commit 76a8a976f3

View File

@ -12,6 +12,7 @@
use stdx::never; use stdx::never;
use syntax::{ use syntax::{
ast::{self, make, AstNode, AstToken}, ast::{self, make, AstNode, AstToken},
format_smolstr,
SyntaxKind::{BLOCK_EXPR, EXPR_STMT, FOR_EXPR, IF_EXPR, LOOP_EXPR, STMT_LIST, WHILE_EXPR}, SyntaxKind::{BLOCK_EXPR, EXPR_STMT, FOR_EXPR, IF_EXPR, LOOP_EXPR, STMT_LIST, WHILE_EXPR},
TextRange, TextSize, TextRange, TextSize,
}; };
@ -55,7 +56,8 @@ pub(crate) fn complete_postfix(
None => return, None => return,
}; };
let postfix_snippet = match build_postfix_snippet_builder(ctx, cap, dot_receiver) { let postfix_snippet =
match build_postfix_snippet_builder(ctx, cap, dot_receiver, &receiver_text) {
Some(it) => it, Some(it) => it,
None => return, None => return,
}; };
@ -173,7 +175,8 @@ pub(crate) fn complete_postfix(
let (dot_receiver, node_to_replace_with) = include_references(dot_receiver); let (dot_receiver, node_to_replace_with) = include_references(dot_receiver);
let receiver_text = let receiver_text =
get_receiver_text(&node_to_replace_with, receiver_is_ambiguous_float_literal); get_receiver_text(&node_to_replace_with, receiver_is_ambiguous_float_literal);
let postfix_snippet = match build_postfix_snippet_builder(ctx, cap, &dot_receiver) { let postfix_snippet =
match build_postfix_snippet_builder(ctx, cap, &dot_receiver, &receiver_text) {
Some(it) => it, Some(it) => it,
None => return, None => return,
}; };
@ -317,6 +320,7 @@ fn build_postfix_snippet_builder<'ctx>(
ctx: &'ctx CompletionContext<'_>, ctx: &'ctx CompletionContext<'_>,
cap: SnippetCap, cap: SnippetCap,
receiver: &'ctx ast::Expr, receiver: &'ctx ast::Expr,
receiver_text: &'ctx str,
) -> Option<impl Fn(&str, &str, &str) -> Builder + 'ctx> { ) -> Option<impl Fn(&str, &str, &str) -> Builder + 'ctx> {
let receiver_range = ctx.sema.original_range_opt(receiver.syntax())?.range; let receiver_range = ctx.sema.original_range_opt(receiver.syntax())?.range;
if ctx.source_range().end() < receiver_range.start() { if ctx.source_range().end() < receiver_range.start() {
@ -332,13 +336,16 @@ fn build_postfix_snippet_builder<'ctx>(
fn build<'ctx>( fn build<'ctx>(
ctx: &'ctx CompletionContext<'_>, ctx: &'ctx CompletionContext<'_>,
cap: SnippetCap, cap: SnippetCap,
receiver_text: &'ctx str,
delete_range: TextRange, delete_range: TextRange,
) -> impl Fn(&str, &str, &str) -> Builder + 'ctx { ) -> impl Fn(&str, &str, &str) -> Builder + 'ctx {
move |label, detail, snippet| { move |label, detail, snippet| {
let edit = TextEdit::replace(delete_range, snippet.to_owned()); let edit = TextEdit::replace(delete_range, snippet.to_owned());
let mut item = let mut item = CompletionItem::new(CompletionItemKind::Snippet, delete_range, label);
CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), label);
item.detail(detail).snippet_edit(cap, edit); item.detail(detail).snippet_edit(cap, edit);
// Editors may filter completion item with the text within delete_range, so we need to
// include the receiver text in the lookup for editors to find the completion item.
item.lookup_by(format_smolstr!("{}.{}", receiver_text, label));
let postfix_match = if ctx.original_token.text() == label { let postfix_match = if ctx.original_token.text() == label {
cov_mark::hit!(postfix_exact_match_is_high_priority); cov_mark::hit!(postfix_exact_match_is_high_priority);
Some(CompletionRelevancePostfixMatch::Exact) Some(CompletionRelevancePostfixMatch::Exact)
@ -351,7 +358,7 @@ fn build<'ctx>(
item item
} }
} }
Some(build(ctx, cap, delete_range)) Some(build(ctx, cap, receiver_text, delete_range))
} }
fn add_custom_postfix_completions( fn add_custom_postfix_completions(