mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Add keywords completions on source file position
This commit is contained in:
parent
16bbf4ab7f
commit
912f38200f
3 changed files with 124 additions and 21 deletions
|
@ -66,48 +66,83 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
|
|||
return;
|
||||
}
|
||||
if ctx.unsafe_is_prev {
|
||||
add_keyword(ctx, acc, "fn", "fn $0() {}", ctx.is_new_item || ctx.block_expr_parent);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"fn",
|
||||
"fn $0() {}",
|
||||
ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"trait",
|
||||
"trait $0 {}",
|
||||
(ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent,
|
||||
(ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent)
|
||||
|| ctx.block_expr_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"impl",
|
||||
"impl $0 {}",
|
||||
(ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent,
|
||||
(ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent)
|
||||
|| ctx.block_expr_parent,
|
||||
);
|
||||
return;
|
||||
}
|
||||
add_keyword(ctx, acc, "fn", "fn $0() {}", ctx.is_new_item || ctx.block_expr_parent);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"fn",
|
||||
"fn $0() {}",
|
||||
ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"use",
|
||||
"use ",
|
||||
(ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent,
|
||||
(ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent)
|
||||
|| ctx.block_expr_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"impl",
|
||||
"impl $0 {}",
|
||||
(ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent,
|
||||
(ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent)
|
||||
|| ctx.block_expr_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"trait",
|
||||
"trait $0 {}",
|
||||
(ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent,
|
||||
(ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent)
|
||||
|| ctx.block_expr_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"enum",
|
||||
"enum $0 {}",
|
||||
ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"struct",
|
||||
"struct $0 {}",
|
||||
ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"union",
|
||||
"union $0 {}",
|
||||
ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent,
|
||||
);
|
||||
add_keyword(ctx, acc, "enum", "enum $0 {}", ctx.is_new_item && !has_trait_or_impl_parent);
|
||||
add_keyword(ctx, acc, "struct", "struct $0 {}", ctx.is_new_item && !has_trait_or_impl_parent);
|
||||
add_keyword(ctx, acc, "union", "union $0 {}", ctx.is_new_item && !has_trait_or_impl_parent);
|
||||
add_keyword(ctx, acc, "match", "match $0 {}", ctx.block_expr_parent || ctx.is_match_arm);
|
||||
add_keyword(ctx, acc, "loop", "loop {$0}", ctx.block_expr_parent || ctx.is_match_arm);
|
||||
add_keyword(ctx, acc, "while", "while $0 {}", ctx.block_expr_parent);
|
||||
|
@ -127,37 +162,58 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
|
|||
acc,
|
||||
"mod",
|
||||
"mod $0 {}",
|
||||
(ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent,
|
||||
(ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent)
|
||||
|| ctx.block_expr_parent,
|
||||
);
|
||||
add_keyword(ctx, acc, "mut", "mut ", ctx.bind_pat_parent || ctx.ref_pat_parent);
|
||||
add_keyword(ctx, acc, "const", "const ", ctx.is_new_item || ctx.block_expr_parent);
|
||||
add_keyword(ctx, acc, "type", "type ", ctx.is_new_item || ctx.block_expr_parent);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"const",
|
||||
"const ",
|
||||
ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"type",
|
||||
"type ",
|
||||
ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"static",
|
||||
"static ",
|
||||
(ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent,
|
||||
(ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent)
|
||||
|| ctx.block_expr_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"extern",
|
||||
"extern ",
|
||||
(ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent,
|
||||
(ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent)
|
||||
|| ctx.block_expr_parent,
|
||||
);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"unsafe",
|
||||
"unsafe ",
|
||||
ctx.is_new_item || ctx.block_expr_parent || ctx.is_match_arm,
|
||||
ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent || ctx.is_match_arm,
|
||||
);
|
||||
add_keyword(ctx, acc, "continue", "continue;", ctx.in_loop_body && ctx.can_be_stmt);
|
||||
add_keyword(ctx, acc, "break", "break;", ctx.in_loop_body && ctx.can_be_stmt);
|
||||
add_keyword(ctx, acc, "continue", "continue", ctx.in_loop_body && !ctx.can_be_stmt);
|
||||
add_keyword(ctx, acc, "break", "break", ctx.in_loop_body && !ctx.can_be_stmt);
|
||||
add_keyword(ctx, acc, "pub", "pub ", ctx.is_new_item && !ctx.has_trait_parent);
|
||||
add_keyword(
|
||||
ctx,
|
||||
acc,
|
||||
"pub",
|
||||
"pub ",
|
||||
ctx.has_item_list_or_source_file_parent && !ctx.has_trait_parent,
|
||||
);
|
||||
|
||||
if !ctx.is_trivial_path {
|
||||
return;
|
||||
|
@ -226,6 +282,31 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keywords_at_source_file_level() {
|
||||
assert_debug_snapshot!(
|
||||
get_keyword_completions(r"m<|>"),
|
||||
@r###"
|
||||
[
|
||||
"kw const",
|
||||
"kw enum",
|
||||
"kw extern",
|
||||
"kw fn",
|
||||
"kw impl",
|
||||
"kw mod",
|
||||
"kw pub",
|
||||
"kw static",
|
||||
"kw struct",
|
||||
"kw trait",
|
||||
"kw type",
|
||||
"kw union",
|
||||
"kw unsafe",
|
||||
"kw use",
|
||||
]
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keywords_in_function() {
|
||||
assert_debug_snapshot!(
|
||||
|
|
|
@ -13,8 +13,8 @@ use ra_text_edit::Indel;
|
|||
|
||||
use super::patterns::{
|
||||
has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_impl_parent,
|
||||
has_ref_parent, has_trait_as_prev_sibling, has_trait_parent, if_is_prev, is_in_loop_body,
|
||||
is_match_arm, unsafe_is_prev,
|
||||
has_item_list_or_source_file_parent, has_ref_parent, has_trait_as_prev_sibling,
|
||||
has_trait_parent, if_is_prev, is_in_loop_body, is_match_arm, unsafe_is_prev,
|
||||
};
|
||||
use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition};
|
||||
use test_utils::mark;
|
||||
|
@ -76,6 +76,7 @@ pub(crate) struct CompletionContext<'a> {
|
|||
pub(super) trait_as_prev_sibling: bool,
|
||||
pub(super) impl_as_prev_sibling: bool,
|
||||
pub(super) is_match_arm: bool,
|
||||
pub(super) has_item_list_or_source_file_parent: bool,
|
||||
}
|
||||
|
||||
impl<'a> CompletionContext<'a> {
|
||||
|
@ -145,6 +146,7 @@ impl<'a> CompletionContext<'a> {
|
|||
impl_as_prev_sibling: false,
|
||||
if_is_prev: false,
|
||||
is_match_arm: false,
|
||||
has_item_list_or_source_file_parent: false,
|
||||
};
|
||||
|
||||
let mut original_file = original_file.syntax().clone();
|
||||
|
@ -229,6 +231,8 @@ impl<'a> CompletionContext<'a> {
|
|||
self.impl_as_prev_sibling = has_impl_as_prev_sibling(syntax_element.clone());
|
||||
self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone());
|
||||
self.is_match_arm = is_match_arm(syntax_element.clone());
|
||||
self.has_item_list_or_source_file_parent =
|
||||
has_item_list_or_source_file_parent(syntax_element.clone());
|
||||
}
|
||||
|
||||
fn fill(
|
||||
|
|
|
@ -38,6 +38,14 @@ pub(crate) fn has_ref_parent(element: SyntaxElement) -> bool {
|
|||
.is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn has_item_list_or_source_file_parent(element: SyntaxElement) -> bool {
|
||||
let ancestor = not_same_range_ancestor(element);
|
||||
if !ancestor.is_some() {
|
||||
return true;
|
||||
}
|
||||
ancestor.filter(|it| it.kind() == SOURCE_FILE || it.kind() == ITEM_LIST).is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn is_match_arm(element: SyntaxElement) -> bool {
|
||||
not_same_range_ancestor(element.clone()).filter(|it| it.kind() == MATCH_ARM).is_some()
|
||||
&& previous_sibling_or_ancestor_sibling(element)
|
||||
|
@ -139,8 +147,8 @@ fn previous_sibling_or_ancestor_sibling(element: SyntaxElement) -> Option<Syntax
|
|||
mod tests {
|
||||
use super::{
|
||||
has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_impl_parent,
|
||||
has_ref_parent, has_trait_as_prev_sibling, has_trait_parent, if_is_prev, is_match_arm,
|
||||
unsafe_is_prev,
|
||||
has_item_list_or_source_file_parent, has_ref_parent, has_trait_as_prev_sibling,
|
||||
has_trait_parent, if_is_prev, is_match_arm, unsafe_is_prev,
|
||||
};
|
||||
use crate::completion::test_utils::check_pattern_is_applicable;
|
||||
|
||||
|
@ -203,4 +211,14 @@ mod tests {
|
|||
fn test_is_match_arm() {
|
||||
check_pattern_is_applicable(r"fn my_fn() { match () { () => m<|> } }", is_match_arm);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_has_source_file_parent() {
|
||||
check_pattern_is_applicable(r"i<|>", has_item_list_or_source_file_parent);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_has_item_list_parent() {
|
||||
check_pattern_is_applicable(r"impl { f<|> }", has_item_list_or_source_file_parent);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue