@@ -3825,7 +3825,7 @@ impl Editor {
self.selections_did_change(true, old_cursor_position, state.effects, window, cx);
if self.should_open_signature_help_automatically(old_cursor_position, cx) {
- self.show_signature_help(&ShowSignatureHelp, window, cx);
+ self.show_signature_help_auto(window, cx);
}
}
}
@@ -13677,6 +13677,185 @@ async fn test_handle_input_for_show_signature_help_auto_signature_help_true(
});
}
+#[gpui::test]
+async fn test_signature_help_delay_only_for_auto(cx: &mut TestAppContext) {
+ init_test(cx, |_| {});
+
+ let delay_ms = 500;
+ cx.update(|cx| {
+ cx.update_global::<SettingsStore, _>(|settings, cx| {
+ settings.update_user_settings(cx, |settings| {
+ settings.editor.auto_signature_help = Some(true);
+ settings.editor.show_signature_help_after_edits = Some(false);
+ settings.editor.hover_popover_delay = Some(DelayMs(delay_ms));
+ });
+ });
+ });
+
+ let mut cx = EditorLspTestContext::new_rust(
+ lsp::ServerCapabilities {
+ signature_help_provider: Some(lsp::SignatureHelpOptions::default()),
+ ..lsp::ServerCapabilities::default()
+ },
+ cx,
+ )
+ .await;
+
+ let mocked_response = lsp::SignatureHelp {
+ signatures: vec![lsp::SignatureInformation {
+ label: "fn sample(param1: u8)".to_string(),
+ documentation: None,
+ parameters: Some(vec![lsp::ParameterInformation {
+ label: lsp::ParameterLabel::Simple("param1: u8".to_string()),
+ documentation: None,
+ }]),
+ active_parameter: None,
+ }],
+ active_signature: Some(0),
+ active_parameter: Some(0),
+ };
+
+ cx.set_state(indoc! {"
+ fn main() {
+ sample(Λ);
+ }
+
+ fn sample(param1: u8) {}
+ "});
+
+ // Manual trigger should show immediately without delay
+ cx.update_editor(|editor, window, cx| {
+ editor.show_signature_help(&ShowSignatureHelp, window, cx);
+ });
+ handle_signature_help_request(&mut cx, mocked_response.clone()).await;
+ cx.run_until_parked();
+ cx.editor(|editor, _, _| {
+ assert!(
+ editor.signature_help_state.is_shown(),
+ "Manual trigger should show signature help without delay"
+ );
+ });
+
+ cx.update_editor(|editor, _, cx| {
+ editor.hide_signature_help(cx, SignatureHelpHiddenBy::Escape);
+ });
+ cx.run_until_parked();
+ cx.editor(|editor, _, _| {
+ assert!(!editor.signature_help_state.is_shown());
+ });
+
+ // Auto trigger (cursor movement into brackets) should respect delay
+ cx.set_state(indoc! {"
+ fn main() {
+ sampleΛ();
+ }
+
+ fn sample(param1: u8) {}
+ "});
+ cx.update_editor(|editor, window, cx| {
+ editor.move_right(&MoveRight, window, cx);
+ });
+ handle_signature_help_request(&mut cx, mocked_response.clone()).await;
+ cx.run_until_parked();
+ cx.editor(|editor, _, _| {
+ assert!(
+ !editor.signature_help_state.is_shown(),
+ "Auto trigger should wait for delay before showing signature help"
+ );
+ });
+
+ cx.executor()
+ .advance_clock(Duration::from_millis(delay_ms + 50));
+ cx.run_until_parked();
+ cx.editor(|editor, _, _| {
+ assert!(
+ editor.signature_help_state.is_shown(),
+ "Auto trigger should show signature help after delay elapsed"
+ );
+ });
+}
+
+#[gpui::test]
+async fn test_signature_help_after_edits_no_delay(cx: &mut TestAppContext) {
+ init_test(cx, |_| {});
+
+ let delay_ms = 500;
+ cx.update(|cx| {
+ cx.update_global::<SettingsStore, _>(|settings, cx| {
+ settings.update_user_settings(cx, |settings| {
+ settings.editor.auto_signature_help = Some(false);
+ settings.editor.show_signature_help_after_edits = Some(true);
+ settings.editor.hover_popover_delay = Some(DelayMs(delay_ms));
+ });
+ });
+ });
+
+ let mut cx = EditorLspTestContext::new_rust(
+ lsp::ServerCapabilities {
+ signature_help_provider: Some(lsp::SignatureHelpOptions::default()),
+ ..lsp::ServerCapabilities::default()
+ },
+ cx,
+ )
+ .await;
+
+ let language = Arc::new(Language::new(
+ LanguageConfig {
+ name: "Rust".into(),
+ brackets: BracketPairConfig {
+ pairs: vec![BracketPair {
+ start: "(".to_string(),
+ end: ")".to_string(),
+ close: true,
+ surround: true,
+ newline: true,
+ }],
+ ..BracketPairConfig::default()
+ },
+ autoclose_before: "})".to_string(),
+ ..LanguageConfig::default()
+ },
+ Some(tree_sitter_rust::LANGUAGE.into()),
+ ));
+ cx.language_registry().add(language.clone());
+ cx.update_buffer(|buffer, cx| {
+ buffer.set_language(Some(language), cx);
+ });
+
+ let mocked_response = lsp::SignatureHelp {
+ signatures: vec![lsp::SignatureInformation {
+ label: "fn sample(param1: u8)".to_string(),
+ documentation: None,
+ parameters: Some(vec![lsp::ParameterInformation {
+ label: lsp::ParameterLabel::Simple("param1: u8".to_string()),
+ documentation: None,
+ }]),
+ active_parameter: None,
+ }],
+ active_signature: Some(0),
+ active_parameter: Some(0),
+ };
+
+ cx.set_state(indoc! {"
+ fn main() {
+ sampleΛ
+ }
+ "});
+
+ // Typing bracket should show signature help immediately without delay
+ cx.update_editor(|editor, window, cx| {
+ editor.handle_input("(", window, cx);
+ });
+ handle_signature_help_request(&mut cx, mocked_response).await;
+ cx.run_until_parked();
+ cx.editor(|editor, _, _| {
+ assert!(
+ editor.signature_help_state.is_shown(),
+ "show_signature_help_after_edits should show signature help without delay"
+ );
+ });
+}
+
#[gpui::test]
async fn test_handle_input_with_different_show_signature_settings(cx: &mut TestAppContext) {
init_test(cx, |_| {});
@@ -166,6 +166,19 @@ impl Editor {
_: &ShowSignatureHelp,
window: &mut Window,
cx: &mut Context<Self>,
+ ) {
+ self.show_signature_help_impl(false, window, cx);
+ }
+
+ pub(super) fn show_signature_help_auto(&mut self, window: &mut Window, cx: &mut Context<Self>) {
+ self.show_signature_help_impl(true, window, cx);
+ }
+
+ fn show_signature_help_impl(
+ &mut self,
+ use_delay: bool,
+ window: &mut Window,
+ cx: &mut Context<Self>,
) {
if self.pending_rename.is_some() || self.has_visible_completions_menu() {
return;
@@ -189,7 +202,11 @@ impl Editor {
});
let language = self.language_at(position, cx);
- let signature_help_delay_ms = EditorSettings::get_global(cx).hover_popover_delay.0;
+ let signature_help_delay_ms = if use_delay {
+ EditorSettings::get_global(cx).hover_popover_delay.0
+ } else {
+ 0
+ };
self.signature_help_state
.set_task(cx.spawn_in(window, async move |editor, cx| {