mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-26 11:59:49 +00:00
Trigger VSCode to rename after extract variable assist is applied
When the user applies the "Extract Variable" assist, the cursor is positioned at the newly inserted variable. This commit adds a command to the assist that triggers the rename action in VSCode. This way, the user can quickly rename the variable after applying the assist. Fixes part of: #17579
This commit is contained in:
parent
5577e4e3b1
commit
8efe8a8528
17 changed files with 80 additions and 33 deletions
|
@ -185,11 +185,11 @@ impl Assists {
|
|||
return None;
|
||||
}
|
||||
|
||||
let mut trigger_signature_help = false;
|
||||
let mut command = None;
|
||||
let source_change = if self.resolve.should_resolve(&id) {
|
||||
let mut builder = SourceChangeBuilder::new(self.file);
|
||||
f(&mut builder);
|
||||
trigger_signature_help = builder.trigger_signature_help;
|
||||
command = builder.command.take();
|
||||
Some(builder.finish())
|
||||
} else {
|
||||
None
|
||||
|
@ -197,7 +197,7 @@ impl Assists {
|
|||
|
||||
let label = Label::new(label);
|
||||
let group = group.cloned();
|
||||
self.buf.push(Assist { id, label, group, target, source_change, trigger_signature_help });
|
||||
self.buf.push(Assist { id, label, group, target, source_change, command });
|
||||
Some(())
|
||||
}
|
||||
|
||||
|
|
|
@ -135,6 +135,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
|
|||
}
|
||||
}
|
||||
}
|
||||
edit.rename();
|
||||
}
|
||||
Anchor::Replace(stmt) => {
|
||||
cov_mark::hit!(test_extract_var_expr_stmt);
|
||||
|
@ -149,6 +150,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
|
|||
}
|
||||
}
|
||||
}
|
||||
edit.rename();
|
||||
}
|
||||
Anchor::WrapInBlock(to_wrap) => {
|
||||
let indent_to = to_wrap.indent_level();
|
||||
|
@ -192,6 +194,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
|
|||
}
|
||||
}
|
||||
}
|
||||
edit.rename();
|
||||
|
||||
// fixup indentation of block
|
||||
block.indent(indent_to);
|
||||
|
|
|
@ -454,7 +454,7 @@ pub fn test_some_range(a: int) -> bool {
|
|||
group: None,
|
||||
target: 59..60,
|
||||
source_change: None,
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&extract_into_variable_assist);
|
||||
|
@ -470,7 +470,7 @@ pub fn test_some_range(a: int) -> bool {
|
|||
group: None,
|
||||
target: 59..60,
|
||||
source_change: None,
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&extract_into_function_assist);
|
||||
|
@ -500,7 +500,7 @@ pub fn test_some_range(a: int) -> bool {
|
|||
group: None,
|
||||
target: 59..60,
|
||||
source_change: None,
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&extract_into_variable_assist);
|
||||
|
@ -516,7 +516,7 @@ pub fn test_some_range(a: int) -> bool {
|
|||
group: None,
|
||||
target: 59..60,
|
||||
source_change: None,
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&extract_into_function_assist);
|
||||
|
@ -587,7 +587,9 @@ pub fn test_some_range(a: int) -> bool {
|
|||
is_snippet: true,
|
||||
},
|
||||
),
|
||||
trigger_signature_help: false,
|
||||
command: Some(
|
||||
Rename,
|
||||
),
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&extract_into_variable_assist);
|
||||
|
@ -603,7 +605,7 @@ pub fn test_some_range(a: int) -> bool {
|
|||
group: None,
|
||||
target: 59..60,
|
||||
source_change: None,
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&extract_into_function_assist);
|
||||
|
@ -666,7 +668,9 @@ pub fn test_some_range(a: int) -> bool {
|
|||
is_snippet: true,
|
||||
},
|
||||
),
|
||||
trigger_signature_help: false,
|
||||
command: Some(
|
||||
Rename,
|
||||
),
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&extract_into_variable_assist);
|
||||
|
@ -715,7 +719,7 @@ pub fn test_some_range(a: int) -> bool {
|
|||
is_snippet: true,
|
||||
},
|
||||
),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&extract_into_function_assist);
|
||||
|
|
|
@ -29,7 +29,16 @@ pub struct Assist {
|
|||
/// cumbersome, especially if you want to embed an assist into another data
|
||||
/// structure, such as a diagnostic.
|
||||
pub source_change: Option<SourceChange>,
|
||||
pub trigger_signature_help: bool,
|
||||
/// The command to execute after the assist is applied.
|
||||
pub command: Option<Command>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Command {
|
||||
/// Show the parameter hints popup.
|
||||
TriggerSignatureHelp,
|
||||
/// Rename the just inserted item.
|
||||
Rename,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
use std::{collections::hash_map::Entry, iter, mem};
|
||||
|
||||
use crate::SnippetCap;
|
||||
use crate::{assists::Command, SnippetCap};
|
||||
use base_db::{AnchoredPathBuf, FileId};
|
||||
use itertools::Itertools;
|
||||
use nohash_hasher::IntMap;
|
||||
|
@ -194,7 +194,7 @@ pub struct SourceChangeBuilder {
|
|||
pub edit: TextEditBuilder,
|
||||
pub file_id: FileId,
|
||||
pub source_change: SourceChange,
|
||||
pub trigger_signature_help: bool,
|
||||
pub command: Option<Command>,
|
||||
|
||||
/// Maps the original, immutable `SyntaxNode` to a `clone_for_update` twin.
|
||||
pub mutated_tree: Option<TreeMutator>,
|
||||
|
@ -236,7 +236,7 @@ impl SourceChangeBuilder {
|
|||
edit: TextEdit::builder(),
|
||||
file_id,
|
||||
source_change: SourceChange::default(),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
mutated_tree: None,
|
||||
snippet_builder: None,
|
||||
}
|
||||
|
@ -304,8 +304,15 @@ impl SourceChangeBuilder {
|
|||
let file_system_edit = FileSystemEdit::MoveFile { src, dst };
|
||||
self.source_change.push_file_system_edit(file_system_edit);
|
||||
}
|
||||
|
||||
/// Triggers the parameter hint popup after the assist is applied
|
||||
pub fn trigger_signature_help(&mut self) {
|
||||
self.trigger_signature_help = true;
|
||||
self.command = Some(Command::TriggerSignatureHelp);
|
||||
}
|
||||
|
||||
/// Renames the item at the cursor position after the assist is applied
|
||||
pub fn rename(&mut self) {
|
||||
self.command = Some(Command::Rename);
|
||||
}
|
||||
|
||||
/// Adds a tabstop snippet to place the cursor before `node`
|
||||
|
|
|
@ -98,7 +98,7 @@ fn quickfix_for_redundant_assoc_item(
|
|||
group: None,
|
||||
target: range,
|
||||
source_change: Some(source_change_builder.finish()),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}])
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option<Vec<Assist>
|
|||
original_range.file_id,
|
||||
TextEdit::replace(original_range.range, code),
|
||||
)),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ fn add_variant_to_union(
|
|||
group: None,
|
||||
target: error_range.range,
|
||||
source_change: Some(src_change_builder.finish()),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ fn add_field_to_struct_fix(
|
|||
group: None,
|
||||
target: error_range.range,
|
||||
source_change: Some(src_change_builder.finish()),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
})
|
||||
}
|
||||
None => {
|
||||
|
@ -204,7 +204,7 @@ fn add_field_to_struct_fix(
|
|||
group: None,
|
||||
target: error_range.range,
|
||||
source_change: Some(src_change_builder.finish()),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
})
|
||||
}
|
||||
Some(FieldList::TupleFieldList(_tuple)) => {
|
||||
|
@ -266,7 +266,7 @@ fn method_fix(
|
|||
file_id,
|
||||
TextEdit::insert(range.end(), "()".to_owned()),
|
||||
)),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
})
|
||||
}
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -108,7 +108,7 @@ fn field_fix(
|
|||
(file_id, TextEdit::insert(range.start(), "(".to_owned())),
|
||||
(file_id, TextEdit::insert(range.end(), ")".to_owned())),
|
||||
])),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ fn assoc_func_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedMethodCall) -
|
|||
file_id,
|
||||
TextEdit::replace(range, assoc_func_call_expr_string),
|
||||
)),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -73,7 +73,7 @@ fn fixes(
|
|||
diagnostic_range.file_id,
|
||||
TextEdit::replace(name_range, format!("_{}", var_name.display(db))),
|
||||
)),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}])
|
||||
}
|
||||
|
||||
|
|
|
@ -613,7 +613,7 @@ fn unresolved_fix(id: &'static str, label: &str, target: TextRange) -> Assist {
|
|||
group: None,
|
||||
target,
|
||||
source_change: None,
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ pub(crate) fn ssr_assists(
|
|||
group: Some(GroupLabel("Apply SSR".into())),
|
||||
target: comment_range,
|
||||
source_change,
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
};
|
||||
|
||||
ssr_assists.push(assist);
|
||||
|
@ -143,7 +143,7 @@ mod tests {
|
|||
is_snippet: false,
|
||||
},
|
||||
),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&apply_in_file_assist);
|
||||
|
@ -196,7 +196,7 @@ mod tests {
|
|||
is_snippet: false,
|
||||
},
|
||||
),
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&apply_in_workspace_assist);
|
||||
|
@ -236,7 +236,7 @@ mod tests {
|
|||
),
|
||||
target: 10..21,
|
||||
source_change: None,
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&apply_in_file_assist);
|
||||
|
@ -256,7 +256,7 @@ mod tests {
|
|||
),
|
||||
target: 10..21,
|
||||
source_change: None,
|
||||
trigger_signature_help: false,
|
||||
command: None,
|
||||
}
|
||||
"#]]
|
||||
.assert_debug_eq(&apply_in_workspace_assist);
|
||||
|
|
|
@ -1135,6 +1135,7 @@ pub struct ClientCommandsConfig {
|
|||
pub show_reference: bool,
|
||||
pub goto_location: bool,
|
||||
pub trigger_parameter_hints: bool,
|
||||
pub rename: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -1901,6 +1902,7 @@ impl Config {
|
|||
show_reference: get("rust-analyzer.showReferences"),
|
||||
goto_location: get("rust-analyzer.gotoLocation"),
|
||||
trigger_parameter_hints: get("editor.action.triggerParameterHints"),
|
||||
rename: get("editor.action.rename"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ use ide::{
|
|||
NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp,
|
||||
SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
|
||||
};
|
||||
use ide_db::{rust_doc::format_docs, FxHasher};
|
||||
use ide_db::{assists, rust_doc::format_docs, FxHasher};
|
||||
use itertools::Itertools;
|
||||
use paths::{Utf8Component, Utf8Prefix};
|
||||
use semver::VersionReq;
|
||||
|
@ -1336,8 +1336,14 @@ pub(crate) fn code_action(
|
|||
command: None,
|
||||
};
|
||||
|
||||
if assist.trigger_signature_help && snap.config.client_commands().trigger_parameter_hints {
|
||||
if assist.command == Some(assists::Command::TriggerSignatureHelp)
|
||||
&& snap.config.client_commands().trigger_parameter_hints
|
||||
{
|
||||
res.command = Some(command::trigger_parameter_hints());
|
||||
} else if assist.command == Some(assists::Command::Rename)
|
||||
&& snap.config.client_commands().rename
|
||||
{
|
||||
res.command = Some(command::rename());
|
||||
}
|
||||
|
||||
match (assist.source_change, resolve_data) {
|
||||
|
@ -1715,6 +1721,14 @@ pub(crate) mod command {
|
|||
arguments: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn rename() -> lsp_types::Command {
|
||||
lsp_types::Command {
|
||||
title: "rename".into(),
|
||||
command: "rust-analyzer.rename".into(),
|
||||
arguments: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn implementation_title(count: usize) -> String {
|
||||
|
|
|
@ -348,6 +348,7 @@ class ExperimentalFeatures implements lc.StaticFeature {
|
|||
"rust-analyzer.showReferences",
|
||||
"rust-analyzer.gotoLocation",
|
||||
"editor.action.triggerParameterHints",
|
||||
"editor.action.rename",
|
||||
],
|
||||
},
|
||||
...capabilities.experimental,
|
||||
|
|
|
@ -118,6 +118,12 @@ export function triggerParameterHints(_: CtxInit): Cmd {
|
|||
};
|
||||
}
|
||||
|
||||
export function rename(_: CtxInit): Cmd {
|
||||
return async () => {
|
||||
await vscode.commands.executeCommand("editor.action.rename");
|
||||
};
|
||||
}
|
||||
|
||||
export function openLogs(ctx: CtxInit): Cmd {
|
||||
return async () => {
|
||||
if (ctx.client.outputChannel) {
|
||||
|
|
|
@ -190,6 +190,7 @@ function createCommands(): Record<string, CommandFactory> {
|
|||
runSingle: { enabled: commands.runSingle },
|
||||
showReferences: { enabled: commands.showReferences },
|
||||
triggerParameterHints: { enabled: commands.triggerParameterHints },
|
||||
rename: { enabled: commands.rename },
|
||||
openLogs: { enabled: commands.openLogs },
|
||||
revealDependency: { enabled: commands.revealDependency },
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue