Merge pull request #18993 from ChayimFriedman2/iter-config

feat: Provide a config to control auto-insertion of `await` and `iter()`
This commit is contained in:
Lukas Wirth 2025-01-24 13:31:30 +00:00 committed by GitHub
commit 1329e6be49
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 111 additions and 56 deletions

View file

@ -42,6 +42,7 @@ pub(crate) fn complete_dot(
item.detail("expr.await"); item.detail("expr.await");
item.add_to(acc, ctx.db); item.add_to(acc, ctx.db);
if ctx.config.enable_auto_await {
// Completions that skip `.await`, e.g. `.await.foo()`. // Completions that skip `.await`, e.g. `.await.foo()`.
let dot_access_kind = match &dot_access.kind { let dot_access_kind = match &dot_access.kind {
DotAccessKind::Field { receiver_is_ambiguous_float_literal: _ } => { DotAccessKind::Field { receiver_is_ambiguous_float_literal: _ } => {
@ -51,7 +52,10 @@ pub(crate) fn complete_dot(
}; };
let dot_access = DotAccess { let dot_access = DotAccess {
receiver: dot_access.receiver.clone(), receiver: dot_access.receiver.clone(),
receiver_ty: Some(hir::TypeInfo { original: future_output.clone(), adjusted: None }), receiver_ty: Some(hir::TypeInfo {
original: future_output.clone(),
adjusted: None,
}),
kind: dot_access_kind, kind: dot_access_kind,
ctx: dot_access.ctx, ctx: dot_access.ctx,
}; };
@ -59,7 +63,9 @@ pub(crate) fn complete_dot(
acc, acc,
ctx, ctx,
&future_output, &future_output,
|acc, field, ty| acc.add_field(ctx, &dot_access, Some(await_str.clone()), field, &ty), |acc, field, ty| {
acc.add_field(ctx, &dot_access, Some(await_str.clone()), field, &ty)
},
|acc, field, ty| acc.add_tuple_field(ctx, Some(await_str.clone()), field, &ty), |acc, field, ty| acc.add_tuple_field(ctx, Some(await_str.clone()), field, &ty),
is_field_access, is_field_access,
is_method_access_with_parens, is_method_access_with_parens,
@ -68,6 +74,7 @@ pub(crate) fn complete_dot(
acc.add_method(ctx, &dot_access, func, Some(await_str.clone()), None) acc.add_method(ctx, &dot_access, func, Some(await_str.clone()), None)
}); });
} }
}
complete_fields( complete_fields(
acc, acc,
@ -82,6 +89,7 @@ pub(crate) fn complete_dot(
acc.add_method(ctx, dot_access, func, None, None) acc.add_method(ctx, dot_access, func, None, None)
}); });
if ctx.config.enable_auto_iter {
// FIXME: // FIXME:
// Checking for the existence of `iter()` is complicated in our setup, because we need to substitute // Checking for the existence of `iter()` is complicated in our setup, because we need to substitute
// its return type, so we instead check for `<&Self as IntoIterator>::IntoIter`. // its return type, so we instead check for `<&Self as IntoIterator>::IntoIter`.
@ -116,6 +124,7 @@ pub(crate) fn complete_dot(
acc.add_method(ctx, &dot_access, func, Some(iter_sym.clone()), None) acc.add_method(ctx, &dot_access, func, Some(iter_sym.clone()), None)
}); });
} }
}
} }
pub(crate) fn complete_undotted_self( pub(crate) fn complete_undotted_self(

View file

@ -14,6 +14,8 @@ pub struct CompletionConfig<'a> {
pub enable_postfix_completions: bool, pub enable_postfix_completions: bool,
pub enable_imports_on_the_fly: bool, pub enable_imports_on_the_fly: bool,
pub enable_self_on_the_fly: bool, pub enable_self_on_the_fly: bool,
pub enable_auto_iter: bool,
pub enable_auto_await: bool,
pub enable_private_editable: bool, pub enable_private_editable: bool,
pub enable_term_search: bool, pub enable_term_search: bool,
pub term_search_fuel: u64, pub term_search_fuel: u64,

View file

@ -87,6 +87,8 @@ pub(crate) const TEST_CONFIG: CompletionConfig<'_> = CompletionConfig {
fields_to_resolve: CompletionFieldsToResolve::empty(), fields_to_resolve: CompletionFieldsToResolve::empty(),
exclude_flyimport: vec![], exclude_flyimport: vec![],
exclude_traits: &[], exclude_traits: &[],
enable_auto_await: true,
enable_auto_iter: true,
}; };
pub(crate) fn completion_list(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String { pub(crate) fn completion_list(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String {

View file

@ -453,6 +453,10 @@ config_data! {
/// ///
/// In `match` arms it completes a comma instead. /// In `match` arms it completes a comma instead.
completion_addSemicolonToUnit: bool = true, completion_addSemicolonToUnit: bool = true,
/// Toggles the additional completions that automatically show method calls and field accesses with `await` prefixed to them when completing on a future.
completion_autoAwait_enable: bool = true,
/// Toggles the additional completions that automatically show method calls with `iter()` or `into_iter()` prefixed to them when completing on a type that has them.
completion_autoIter_enable: bool = true,
/// Toggles the additional completions that automatically add imports when completed. /// Toggles the additional completions that automatically add imports when completed.
/// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled. /// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.
completion_autoimport_enable: bool = true, completion_autoimport_enable: bool = true,
@ -1484,6 +1488,8 @@ impl Config {
enable_imports_on_the_fly: self.completion_autoimport_enable(source_root).to_owned() enable_imports_on_the_fly: self.completion_autoimport_enable(source_root).to_owned()
&& self.caps.completion_item_edit_resolve(), && self.caps.completion_item_edit_resolve(),
enable_self_on_the_fly: self.completion_autoself_enable(source_root).to_owned(), enable_self_on_the_fly: self.completion_autoself_enable(source_root).to_owned(),
enable_auto_iter: *self.completion_autoIter_enable(source_root),
enable_auto_await: *self.completion_autoAwait_enable(source_root),
enable_private_editable: self.completion_privateEditable_enable(source_root).to_owned(), enable_private_editable: self.completion_privateEditable_enable(source_root).to_owned(),
full_function_signatures: self full_function_signatures: self
.completion_fullFunctionSignatures_enable(source_root) .completion_fullFunctionSignatures_enable(source_root)

View file

@ -176,6 +176,8 @@ fn integrated_completion_benchmark() {
fields_to_resolve: CompletionFieldsToResolve::empty(), fields_to_resolve: CompletionFieldsToResolve::empty(),
exclude_flyimport: vec![], exclude_flyimport: vec![],
exclude_traits: &[], exclude_traits: &[],
enable_auto_await: true,
enable_auto_iter: true,
}; };
let position = let position =
FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() }; FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
@ -226,6 +228,8 @@ fn integrated_completion_benchmark() {
fields_to_resolve: CompletionFieldsToResolve::empty(), fields_to_resolve: CompletionFieldsToResolve::empty(),
exclude_flyimport: vec![], exclude_flyimport: vec![],
exclude_traits: &[], exclude_traits: &[],
enable_auto_await: true,
enable_auto_iter: true,
}; };
let position = let position =
FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() }; FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
@ -274,6 +278,8 @@ fn integrated_completion_benchmark() {
fields_to_resolve: CompletionFieldsToResolve::empty(), fields_to_resolve: CompletionFieldsToResolve::empty(),
exclude_flyimport: vec![], exclude_flyimport: vec![],
exclude_traits: &[], exclude_traits: &[],
enable_auto_await: true,
enable_auto_iter: true,
}; };
let position = let position =
FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() }; FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };

View file

@ -274,6 +274,16 @@ Whether to automatically add a semicolon when completing unit-returning function
In `match` arms it completes a comma instead. In `match` arms it completes a comma instead.
-- --
[[rust-analyzer.completion.autoAwait.enable]]rust-analyzer.completion.autoAwait.enable (default: `true`)::
+
--
Toggles the additional completions that automatically show method calls and field accesses with `await` prefixed to them when completing on a future.
--
[[rust-analyzer.completion.autoIter.enable]]rust-analyzer.completion.autoIter.enable (default: `true`)::
+
--
Toggles the additional completions that automatically show method calls with `iter()` or `into_iter()` prefixed to them when completing on a type that has them.
--
[[rust-analyzer.completion.autoimport.enable]]rust-analyzer.completion.autoimport.enable (default: `true`):: [[rust-analyzer.completion.autoimport.enable]]rust-analyzer.completion.autoimport.enable (default: `true`)::
+ +
-- --

View file

@ -1143,6 +1143,26 @@
} }
} }
}, },
{
"title": "completion",
"properties": {
"rust-analyzer.completion.autoAwait.enable": {
"markdownDescription": "Toggles the additional completions that automatically show method calls and field accesses with `await` prefixed to them when completing on a future.",
"default": true,
"type": "boolean"
}
}
},
{
"title": "completion",
"properties": {
"rust-analyzer.completion.autoIter.enable": {
"markdownDescription": "Toggles the additional completions that automatically show method calls with `iter()` or `into_iter()` prefixed to them when completing on a type that has them.",
"default": true,
"type": "boolean"
}
}
},
{ {
"title": "completion", "title": "completion",
"properties": { "properties": {