mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
Merge #7102
7102: Fix completion of Default struct update syntax r=Veykril a=nick96 Previously the inserted text was always `..Default::default()` which ends up as `...Default::default()` if `.` was typed. Now checks if the current token is `.` and inserts `.Default::default()` if it is, so `..Default::default()` is correctly completed. I think there's probably a better way to implement this context aware completion because I've seen it in other parts of rust-analyzer as a user but I'm not sure how to do it. Fixes #6969 Co-authored-by: Nick Spain <nicholas.spain@stileeducation.com>
This commit is contained in:
commit
f687d738be
1 changed files with 66 additions and 2 deletions
|
@ -20,13 +20,17 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
|
||||||
|
|
||||||
let missing_fields = ctx.sema.record_literal_missing_fields(record_lit);
|
let missing_fields = ctx.sema.record_literal_missing_fields(record_lit);
|
||||||
if impl_default_trait && !missing_fields.is_empty() {
|
if impl_default_trait && !missing_fields.is_empty() {
|
||||||
|
let completion_text = "..Default::default()";
|
||||||
|
let completion_text = completion_text
|
||||||
|
.strip_prefix(ctx.token.to_string().as_str())
|
||||||
|
.unwrap_or(completion_text);
|
||||||
acc.add(
|
acc.add(
|
||||||
CompletionItem::new(
|
CompletionItem::new(
|
||||||
CompletionKind::Snippet,
|
CompletionKind::Snippet,
|
||||||
ctx.source_range(),
|
ctx.source_range(),
|
||||||
"..Default::default()",
|
"..Default::default()",
|
||||||
)
|
)
|
||||||
.insert_text("..Default::default()")
|
.insert_text(completion_text)
|
||||||
.kind(CompletionItemKind::Field)
|
.kind(CompletionItemKind::Field)
|
||||||
.build(),
|
.build(),
|
||||||
);
|
);
|
||||||
|
@ -48,7 +52,10 @@ mod tests {
|
||||||
use expect_test::{expect, Expect};
|
use expect_test::{expect, Expect};
|
||||||
use ide_db::helpers::FamousDefs;
|
use ide_db::helpers::FamousDefs;
|
||||||
|
|
||||||
use crate::{test_utils::completion_list, CompletionKind};
|
use crate::{
|
||||||
|
test_utils::{self, completion_list},
|
||||||
|
CompletionKind,
|
||||||
|
};
|
||||||
|
|
||||||
fn check(ra_fixture: &str, expect: Expect) {
|
fn check(ra_fixture: &str, expect: Expect) {
|
||||||
let actual = completion_list(ra_fixture, CompletionKind::Reference);
|
let actual = completion_list(ra_fixture, CompletionKind::Reference);
|
||||||
|
@ -63,6 +70,18 @@ mod tests {
|
||||||
expect.assert_eq(&actual);
|
expect.assert_eq(&actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
|
||||||
|
test_utils::check_edit(
|
||||||
|
what,
|
||||||
|
&format!(
|
||||||
|
"//- /main.rs crate:main deps:core{}\n{}",
|
||||||
|
ra_fixture_before,
|
||||||
|
FamousDefs::FIXTURE,
|
||||||
|
),
|
||||||
|
&(ra_fixture_after.to_owned() + "\n"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_record_literal_field_default() {
|
fn test_record_literal_field_default() {
|
||||||
let test_code = r#"
|
let test_code = r#"
|
||||||
|
@ -101,6 +120,51 @@ fn process(f: S) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_record_literal_field_default_completion() {
|
||||||
|
check_edit(
|
||||||
|
"..Default::default()",
|
||||||
|
r#"
|
||||||
|
struct S { foo: u32, bar: usize }
|
||||||
|
|
||||||
|
impl core::default::Default for S {
|
||||||
|
fn default() -> Self {
|
||||||
|
S {
|
||||||
|
foo: 0,
|
||||||
|
bar: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process(f: S) {
|
||||||
|
let other = S {
|
||||||
|
foo: 5,
|
||||||
|
.<|>
|
||||||
|
};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
struct S { foo: u32, bar: usize }
|
||||||
|
|
||||||
|
impl core::default::Default for S {
|
||||||
|
fn default() -> Self {
|
||||||
|
S {
|
||||||
|
foo: 0,
|
||||||
|
bar: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process(f: S) {
|
||||||
|
let other = S {
|
||||||
|
foo: 5,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_record_literal_field_without_default() {
|
fn test_record_literal_field_without_default() {
|
||||||
let test_code = r#"
|
let test_code = r#"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue