From c6ffffccbdfdcf084d5e280d4f47ed6d970bee56 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 19 Apr 2022 18:37:18 +0200 Subject: [PATCH] Allows triggering commands after an assist edit --- crates/ide/src/ssr.rs | 5 +++++ crates/ide_assists/src/assist_context.rs | 9 +++++++- .../src/handlers/add_turbo_fish.rs | 21 +++++++++++-------- crates/ide_assists/src/tests.rs | 8 +++++++ crates/ide_db/src/assists.rs | 1 + .../src/handlers/unresolved_module.rs | 2 ++ crates/ide_diagnostics/src/lib.rs | 1 + .../test_data/clippy_pass_by_ref.txt | 1 + .../test_data/rustc_unused_variable.txt | 1 + .../rustc_unused_variable_as_hint.txt | 1 + .../rustc_unused_variable_as_info.txt | 1 + .../test_data/snap_multi_line_fix.txt | 1 + .../rust-analyzer/src/diagnostics/to_proto.rs | 1 + crates/rust-analyzer/src/handlers.rs | 5 +++-- crates/rust-analyzer/src/lsp_ext.rs | 5 ++--- crates/rust-analyzer/src/to_proto.rs | 6 ++++++ docs/dev/lsp-extensions.md | 2 +- editors/code/src/commands.ts | 3 +++ 18 files changed, 58 insertions(+), 16 deletions(-) diff --git a/crates/ide/src/ssr.rs b/crates/ide/src/ssr.rs index 6142a0eafd..ba9a7f62e6 100644 --- a/crates/ide/src/ssr.rs +++ b/crates/ide/src/ssr.rs @@ -45,6 +45,7 @@ pub(crate) fn ssr_assists( group: Some(GroupLabel("Apply SSR".into())), target: comment_range, source_change, + trigger_signature_help: false, }; ssr_assists.push(assist); @@ -140,6 +141,7 @@ mod tests { is_snippet: false, }, ), + trigger_signature_help: false, } "#]] .assert_debug_eq(&apply_in_file_assist); @@ -186,6 +188,7 @@ mod tests { is_snippet: false, }, ), + trigger_signature_help: false, } "#]] .assert_debug_eq(&apply_in_workspace_assist); @@ -225,6 +228,7 @@ mod tests { ), target: 10..21, source_change: None, + trigger_signature_help: false, } "#]] .assert_debug_eq(&apply_in_file_assist); @@ -244,6 +248,7 @@ mod tests { ), target: 10..21, source_change: None, + trigger_signature_help: false, } "#]] .assert_debug_eq(&apply_in_workspace_assist); diff --git a/crates/ide_assists/src/assist_context.rs b/crates/ide_assists/src/assist_context.rs index fd46aa2479..ec85faaf46 100644 --- a/crates/ide_assists/src/assist_context.rs +++ b/crates/ide_assists/src/assist_context.rs @@ -193,9 +193,11 @@ impl Assists { return None; } + let mut trigger_signature_help = false; let source_change = if self.resolve.should_resolve(&id) { let mut builder = AssistBuilder::new(self.file); f(&mut builder); + trigger_signature_help = builder.trigger_signature_help; Some(builder.finish()) } else { None @@ -203,7 +205,7 @@ impl Assists { let label = Label::new(label); let group = group.cloned(); - self.buf.push(Assist { id, label, group, target, source_change }); + self.buf.push(Assist { id, label, group, target, source_change, trigger_signature_help }); Some(()) } @@ -219,6 +221,7 @@ pub(crate) struct AssistBuilder { edit: TextEditBuilder, file_id: FileId, source_change: SourceChange, + trigger_signature_help: bool, /// Maps the original, immutable `SyntaxNode` to a `clone_for_update` twin. mutated_tree: Option, @@ -252,6 +255,7 @@ impl AssistBuilder { edit: TextEdit::builder(), file_id, source_change: SourceChange::default(), + trigger_signature_help: false, mutated_tree: None, } } @@ -332,6 +336,9 @@ impl AssistBuilder { let file_system_edit = FileSystemEdit::MoveFile { src, dst }; self.source_change.push_file_system_edit(file_system_edit); } + pub(crate) fn trigger_signature_help(&mut self) { + self.trigger_signature_help = true; + } fn finish(mut self) -> SourceChange { self.commit(); diff --git a/crates/ide_assists/src/handlers/add_turbo_fish.rs b/crates/ide_assists/src/handlers/add_turbo_fish.rs index c3d27f7ea6..a82dca9db0 100644 --- a/crates/ide_assists/src/handlers/add_turbo_fish.rs +++ b/crates/ide_assists/src/handlers/add_turbo_fish.rs @@ -89,15 +89,18 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<( AssistId("add_turbo_fish", AssistKind::RefactorRewrite), "Add `::<>`", ident.text_range(), - |builder| match ctx.config.snippet_cap { - Some(cap) => { - let snip = format!("::<{}>", get_snippet_fish_head(number_of_arguments)); - builder.insert_snippet(cap, ident.text_range().end(), snip) - } - None => { - let fish_head = std::iter::repeat("_").take(number_of_arguments).format(", "); - let snip = format!("::<{}>", fish_head); - builder.insert(ident.text_range().end(), snip); + |builder| { + builder.trigger_signature_help(); + match ctx.config.snippet_cap { + Some(cap) => { + let snip = format!("::<{}>", get_snippet_fish_head(number_of_arguments)); + builder.insert_snippet(cap, ident.text_range().end(), snip) + } + None => { + let fish_head = std::iter::repeat("_").take(number_of_arguments).format(", "); + let snip = format!("::<{}>", fish_head); + builder.insert(ident.text_range().end(), snip); + } } }, ) diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs index b3a0bd2773..6b57f9962c 100644 --- a/crates/ide_assists/src/tests.rs +++ b/crates/ide_assists/src/tests.rs @@ -341,6 +341,7 @@ pub fn test_some_range(a: int) -> bool { group: None, target: 59..60, source_change: None, + trigger_signature_help: false, } "#]] .assert_debug_eq(&extract_into_variable_assist); @@ -356,6 +357,7 @@ pub fn test_some_range(a: int) -> bool { group: None, target: 59..60, source_change: None, + trigger_signature_help: false, } "#]] .assert_debug_eq(&extract_into_function_assist); @@ -385,6 +387,7 @@ pub fn test_some_range(a: int) -> bool { group: None, target: 59..60, source_change: None, + trigger_signature_help: false, } "#]] .assert_debug_eq(&extract_into_variable_assist); @@ -400,6 +403,7 @@ pub fn test_some_range(a: int) -> bool { group: None, target: 59..60, source_change: None, + trigger_signature_help: false, } "#]] .assert_debug_eq(&extract_into_function_assist); @@ -450,6 +454,7 @@ pub fn test_some_range(a: int) -> bool { is_snippet: true, }, ), + trigger_signature_help: false, } "#]] .assert_debug_eq(&extract_into_variable_assist); @@ -465,6 +470,7 @@ pub fn test_some_range(a: int) -> bool { group: None, target: 59..60, source_change: None, + trigger_signature_help: false, } "#]] .assert_debug_eq(&extract_into_function_assist); @@ -507,6 +513,7 @@ pub fn test_some_range(a: int) -> bool { is_snippet: true, }, ), + trigger_signature_help: false, } "#]] .assert_debug_eq(&extract_into_variable_assist); @@ -543,6 +550,7 @@ pub fn test_some_range(a: int) -> bool { is_snippet: true, }, ), + trigger_signature_help: false, } "#]] .assert_debug_eq(&extract_into_function_assist); diff --git a/crates/ide_db/src/assists.rs b/crates/ide_db/src/assists.rs index be5f063f0f..da23763dc2 100644 --- a/crates/ide_db/src/assists.rs +++ b/crates/ide_db/src/assists.rs @@ -29,6 +29,7 @@ pub struct Assist { /// cumbersome, especially if you want to embed an assist into another data /// structure, such as a diagnostic. pub source_change: Option, + pub trigger_signature_help: bool, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/crates/ide_diagnostics/src/handlers/unresolved_module.rs b/crates/ide_diagnostics/src/handlers/unresolved_module.rs index 587a3ee26d..b8f2a9e94a 100644 --- a/crates/ide_diagnostics/src/handlers/unresolved_module.rs +++ b/crates/ide_diagnostics/src/handlers/unresolved_module.rs @@ -117,6 +117,7 @@ mod baz {} is_snippet: false, }, ), + trigger_signature_help: false, }, Assist { id: AssistId( @@ -143,6 +144,7 @@ mod baz {} is_snippet: false, }, ), + trigger_signature_help: false, }, ], ), diff --git a/crates/ide_diagnostics/src/lib.rs b/crates/ide_diagnostics/src/lib.rs index 13ac0a2450..b04da2e092 100644 --- a/crates/ide_diagnostics/src/lib.rs +++ b/crates/ide_diagnostics/src/lib.rs @@ -238,5 +238,6 @@ fn unresolved_fix(id: &'static str, label: &str, target: TextRange) -> Assist { group: None, target, source_change: None, + trigger_signature_help: false, } } diff --git a/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt b/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt index 4610984acb..41c509452a 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt @@ -318,6 +318,7 @@ "quickfix", ), ), + command: None, edit: Some( SnippetWorkspaceEdit { changes: Some( diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt index 46d44192c5..1c5c336223 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt @@ -165,6 +165,7 @@ "quickfix", ), ), + command: None, edit: Some( SnippetWorkspaceEdit { changes: Some( diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt index b595487e8f..3ab3412d97 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt @@ -165,6 +165,7 @@ "quickfix", ), ), + command: None, edit: Some( SnippetWorkspaceEdit { changes: Some( diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt index 3ee50392a7..0702420aa5 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt @@ -165,6 +165,7 @@ "quickfix", ), ), + command: None, edit: Some( SnippetWorkspaceEdit { changes: Some( diff --git a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt index d7987f65ed..4365e450df 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt @@ -328,6 +328,7 @@ "quickfix", ), ), + command: None, edit: Some( SnippetWorkspaceEdit { changes: Some( diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs index 45e46c1a06..e9a192cdfb 100644 --- a/crates/rust-analyzer/src/diagnostics/to_proto.rs +++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs @@ -204,6 +204,7 @@ fn map_rust_child_diagnostic( }), is_preferred: Some(true), data: None, + command: None, }, }), }) diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index fb64eeea4f..a1b71ab143 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -1160,8 +1160,9 @@ pub(crate) fn handle_code_action_resolve( )) .into()); } - let edit = to_proto::code_action(&snap, assist.clone(), None)?.edit; - code_action.edit = edit; + let ca = to_proto::code_action(&snap, assist.clone(), None)?; + code_action.edit = ca.edit; + code_action.command = ca.command; Ok(code_action) } diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index 489a233a0a..1cfaa13327 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs @@ -311,9 +311,8 @@ pub struct CodeAction { pub group: Option, #[serde(skip_serializing_if = "Option::is_none")] pub kind: Option, - // We don't handle commands on the client-side - // #[serde(skip_serializing_if = "Option::is_none")] - // pub command: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub command: Option, #[serde(skip_serializing_if = "Option::is_none")] pub edit: Option, #[serde(skip_serializing_if = "Option::is_none")] diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index deea54cf7d..57b0e93765 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -1018,7 +1018,13 @@ pub(crate) fn code_action( edit: None, is_preferred: None, data: None, + command: None, }; + + if assist.trigger_signature_help && snap.config.client_commands().trigger_parameter_hints { + res.command = Some(command::trigger_parameter_hints()); + } + match (assist.source_change, resolve_data) { (Some(it), _) => res.edit = Some(snippet_workspace_edit(snap, it)?), (None, Some((index, code_action_params))) => { diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 46193a6ff3..2e1cee8955 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -1,5 +1,5 @@