Auto merge of #17431 - roife:fix-issue-17428, r=Veykril

feat: add space after specific keywords in completion

fix #17428.

When completing some specific keywords, it would be convenient if r-a could automatically add a space afterwards.

This PR implements this feature for the following keywords:

- Visibility: `pub`, `pub(crate)`, `pub(super)`, `pub(in xxx)`
- Pattern: `ref` / `mut`
- Others: `unsafe` / `for` / `where`
This commit is contained in:
bors 2024-06-19 08:26:32 +00:00
commit 50ba0c0d56
9 changed files with 193 additions and 24 deletions

View File

@ -20,9 +20,9 @@ pub(crate) fn complete_field_list_tuple_variant(
} = path_ctx
{
let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
add_keyword("pub(crate)", "pub(crate)");
add_keyword("pub(super)", "pub(super)");
add_keyword("pub", "pub");
add_keyword("pub(crate)", "pub(crate) $0");
add_keyword("pub(super)", "pub(super) $0");
add_keyword("pub", "pub $0");
}
}
@ -32,8 +32,8 @@ pub(crate) fn complete_field_list_record_variant(
) {
if ctx.qualifier_ctx.vis_node.is_none() {
let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
add_keyword("pub(crate)", "pub(crate)");
add_keyword("pub(super)", "pub(super)");
add_keyword("pub", "pub");
add_keyword("pub(crate)", "pub(crate) $0");
add_keyword("pub(super)", "pub(super) $0");
add_keyword("pub", "pub $0");
}
}

View File

@ -79,7 +79,7 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
let in_trait = matches!(kind, Some(ItemListKind::Trait));
let in_trait_impl = matches!(kind, Some(ItemListKind::TraitImpl(_)));
let in_inherent_impl = matches!(kind, Some(ItemListKind::Impl));
let no_qualifiers = ctx.qualifier_ctx.vis_node.is_none();
let no_vis_qualifiers = ctx.qualifier_ctx.vis_node.is_none();
let in_block = kind.is_none();
if !in_trait_impl {
@ -89,7 +89,7 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
}
if in_item_list {
add_keyword("trait", "trait $1 {\n $0\n}");
if no_qualifiers {
if no_vis_qualifiers {
add_keyword("impl", "impl $1 {\n $0\n}");
}
}
@ -104,15 +104,15 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
add_keyword("trait", "trait $1 {\n $0\n}");
add_keyword("union", "union $1 {\n $0\n}");
add_keyword("use", "use $0");
if no_qualifiers {
if no_vis_qualifiers {
add_keyword("impl", "impl $1 {\n $0\n}");
}
}
if !in_trait && !in_block && no_qualifiers {
add_keyword("pub(crate)", "pub(crate)");
add_keyword("pub(super)", "pub(super)");
add_keyword("pub", "pub");
if !in_trait && !in_block && no_vis_qualifiers {
add_keyword("pub(crate)", "pub(crate) $0");
add_keyword("pub(super)", "pub(super) $0");
add_keyword("pub", "pub $0");
}
if in_extern_block {
@ -126,7 +126,7 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
}
add_keyword("fn", "fn $1($2) {\n $0\n}");
add_keyword("unsafe", "unsafe");
add_keyword("unsafe", "unsafe $0");
add_keyword("const", "const $0");
}
}

View File

@ -14,9 +14,9 @@ pub(crate) fn complete_for_and_where(
match keyword_item {
Item::Impl(it) => {
if it.for_token().is_none() && it.trait_().is_none() && it.self_ty().is_some() {
add_keyword("for", "for");
add_keyword("for", "for $0");
}
add_keyword("where", "where");
add_keyword("where", "where $0");
}
Item::Enum(_)
| Item::Fn(_)
@ -24,7 +24,7 @@ pub(crate) fn complete_for_and_where(
| Item::Trait(_)
| Item::TypeAlias(_)
| Item::Union(_) => {
add_keyword("where", "where");
add_keyword("where", "where $0");
}
_ => (),
}

View File

@ -14,25 +14,27 @@ pub(crate) fn complete_pattern(
ctx: &CompletionContext<'_>,
pattern_ctx: &PatternContext,
) {
let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
match pattern_ctx.parent_pat.as_ref() {
Some(Pat::RangePat(_) | Pat::BoxPat(_)) => (),
Some(Pat::RefPat(r)) => {
if r.mut_token().is_none() {
acc.add_keyword(ctx, "mut");
add_keyword("mut", "mut $0");
}
}
_ => {
let tok = ctx.token.text_range().start();
match (pattern_ctx.ref_token.as_ref(), pattern_ctx.mut_token.as_ref()) {
(None, None) => {
acc.add_keyword(ctx, "ref");
acc.add_keyword(ctx, "mut");
add_keyword("ref", "ref $0");
add_keyword("mut", "mut $0");
}
(None, Some(m)) if tok < m.text_range().start() => {
acc.add_keyword(ctx, "ref");
add_keyword("ref", "ref $0");
}
(Some(r), None) if tok > r.text_range().end() => {
acc.add_keyword(ctx, "mut");
add_keyword("mut", "mut $0");
}
_ => (),
}

View File

@ -668,7 +668,7 @@ fn main() {
check_edit(
"unsafe",
r#"fn main() { let x = true else {panic!()}.$0}"#,
r#"fn main() { let x = true else {panic!()}.unsafe}"#,
r#"fn main() { let x = true else {panic!()}.unsafe $0}"#,
);
}

View File

@ -33,7 +33,7 @@ pub(crate) fn complete_vis_path(
Qualified::No => {
if !has_in_token {
cov_mark::hit!(kw_completion_in);
acc.add_keyword(ctx, "in");
acc.add_keyword_snippet(ctx, "in", "in $0");
}
acc.add_nameref_keywords(ctx);
}

View File

@ -6,6 +6,8 @@ use expect_test::{expect, Expect};
use crate::tests::{completion_list, BASE_ITEMS_FIXTURE};
use super::check_edit;
fn check(ra_fixture: &str, expect: Expect) {
let actual = completion_list(&format!("{BASE_ITEMS_FIXTURE}{ra_fixture}"));
expect.assert_eq(&actual)
@ -152,3 +154,90 @@ struct Foo {
"#]],
)
}
#[test]
fn add_space_after_vis_kw() {
check_edit(
"pub(crate)",
r"
$0
",
r#"
pub(crate) $0
"#,
);
check_edit(
"pub",
r"
$0
",
r#"
pub $0
"#,
);
check_edit(
"pub(super)",
r"
$0
",
r#"
pub(super) $0
"#,
);
check_edit(
"in",
r"
pub($0)
",
r#"
pub(in $0)
"#,
);
}
#[test]
fn add_space_after_unsafe_kw() {
check_edit(
"unsafe",
r"
$0
",
r#"
unsafe $0
"#,
);
}
#[test]
fn add_space_after_for_where_kw() {
check_edit(
"for",
r#"
struct S {}
impl Copy $0
"#,
r#"
struct S {}
impl Copy for $0
"#,
);
check_edit(
"where",
r#"
struct S {}
impl Copy for S $0
"#,
r#"
struct S {}
impl Copy for S where $0
"#,
);
}

View File

@ -819,3 +819,34 @@ pub enum Enum {
"#]],
);
}
#[test]
fn add_space_after_mut_ref_kw() {
check_edit(
"mut",
r#"
fn foo() {
let $0
}
"#,
r#"
fn foo() {
let mut $0
}
"#,
);
check_edit(
"ref",
r#"
fn foo() {
let $0
}
"#,
r#"
fn foo() {
let ref $0
}
"#,
);
}

View File

@ -2,6 +2,8 @@ use expect_test::{expect, Expect};
use crate::tests::completion_list;
use super::check_edit;
fn check(ra_fixture: &str, expect: Expect) {
let actual = completion_list(ra_fixture);
expect.assert_eq(&actual);
@ -301,3 +303,48 @@ fn foo() {
expect![[r#""#]],
)
}
#[test]
fn add_space_after_vis_kw() {
check_edit(
"pub(crate)",
r"
pub(crate) struct S {
$0
}
",
r#"
pub(crate) struct S {
pub(crate) $0
}
"#,
);
check_edit(
"pub",
r"
pub struct S {
$0
}
",
r#"
pub struct S {
pub $0
}
"#,
);
check_edit(
"pub(super)",
r"
pub(super) struct S {
$0
}
",
r#"
pub(super) struct S {
pub(super) $0
}
"#,
);
}