lsp: Implement textDocument/signatureHelp for ProjectClientState::Local environment (#12909)

Closes https://github.com/zed-industries/zed/issues/5155
Closes https://github.com/zed-industries/zed/issues/4879


# Purpose
There was no way to know what to put in function signatures or struct
fields other than hovering at the moment. Therefore, it was necessary to
implement LSP's `textDocument/signatureHelp`.

I tried my best to match the surrounding coding style, but since this is
my first contribution, I believe there are various aspects that may be
lacking. I would greatly appreciate your code review.

# Description
When the window is displayed, the current argument or field at the
cursor's position is automatically bolded. If the cursor moves and there
is nothing to display, the window closes automatically.
To minimize changes and reduce the burden of review and debugging, the
SignatureHelp feature is implemented only when `is_local` is `true`.
Some `unimplemented!()` macros are embedded, but rest assured that they
are not called in this implementation.

# How to try it out
Press `cmd + i` (MacOS), `ctrl + i` (Linux).

# Enable auto signature help (2 ways)
### Add `"auto_signature_help": true` to `settings.json`
<img width="426" alt="image"
src="https://github.com/zed-industries/zed/assets/55743826/61310c39-47f9-4586-94b0-ae519dc3b37c">

Or

### Press `Auto Signature Help`. (Default `false`)
<img width="226" alt="image"
src="https://github.com/zed-industries/zed/assets/55743826/34155215-1eb5-4621-b09b-55df2f1ab6a8">

# Disable to show signature help after completion
### Add `"show_signature_help_after_completion": false` to
`settings.json`
<img width="438" alt="image"
src="https://github.com/zed-industries/zed/assets/55743826/5e5bacac-62e0-4921-9243-17e1e72d5eb6">

# Movie

https://github.com/zed-industries/zed/assets/55743826/77c12d51-b0a5-415d-8901-f93ef92098e7

# Screen Shot
<img width="628" alt="image"
src="https://github.com/zed-industries/zed/assets/55743826/3ebcf4b6-2b94-4dea-97f9-ac4f33e0291e">

<img width="637" alt="image"
src="https://github.com/zed-industries/zed/assets/55743826/6dc3eb4d-beee-460b-8dbe-d6eec6379b76">

Release Notes:

- Show function signature popovers
([4879](https://github.com/zed-industries/zed/issues/4879),
[5155](https://github.com/zed-industries/zed/issues/5155))

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
This commit is contained in:
tomoikey
2024-07-11 13:38:33 +03:00
committed by GitHub
co-authored by Kirill Bulatov
parent 6a11184ea3
commit 291d64c803
19 changed files with 1994 additions and 11 deletions
+42 -4
View File
@@ -39,8 +39,10 @@ pub mod tasks;
#[cfg(test)]
mod editor_tests;
mod signature_help;
#[cfg(any(test, feature = "test-support"))]
pub mod test;
use ::git::diff::{DiffHunk, DiffHunkStatus};
use ::git::{parse_git_remote_url, BuildPermalinkParams, GitHostingProviderRegistry};
pub(crate) use actions::*;
@@ -154,6 +156,7 @@ use workspace::{
use workspace::{OpenInTerminal, OpenTerminal, TabBarSettings, Toast};
use crate::hover_links::find_url;
use crate::signature_help::{SignatureHelpHiddenBy, SignatureHelpState};
pub const FILE_HEADER_HEIGHT: u8 = 1;
pub const MULTI_BUFFER_EXCERPT_HEADER_HEIGHT: u8 = 1;
@@ -501,6 +504,8 @@ pub struct Editor {
context_menu: RwLock<Option<ContextMenu>>,
mouse_context_menu: Option<MouseContextMenu>,
completion_tasks: Vec<(CompletionId, Task<Option<()>>)>,
signature_help_state: SignatureHelpState,
auto_signature_help: Option<bool>,
find_all_references_task_sources: Vec<Anchor>,
next_completion_id: CompletionId,
completion_documentation_pre_resolve_debounce: DebouncedDelay,
@@ -1819,6 +1824,8 @@ impl Editor {
context_menu: RwLock::new(None),
mouse_context_menu: None,
completion_tasks: Default::default(),
signature_help_state: SignatureHelpState::default(),
auto_signature_help: None,
find_all_references_task_sources: Vec::new(),
next_completion_id: 0,
completion_documentation_pre_resolve_debounce: DebouncedDelay::new(),
@@ -2411,6 +2418,15 @@ impl Editor {
self.request_autoscroll(autoscroll, cx);
}
self.selections_did_change(true, &old_cursor_position, request_completions, cx);
if self.should_open_signature_help_automatically(
&old_cursor_position,
self.signature_help_state.backspace_pressed(),
cx,
) {
self.show_signature_help(&ShowSignatureHelp, cx);
}
self.signature_help_state.set_backspace_pressed(false);
}
result
@@ -2866,6 +2882,10 @@ impl Editor {
return true;
}
if self.hide_signature_help(cx, SignatureHelpHiddenBy::Escape) {
return true;
}
if self.hide_context_menu(cx).is_some() {
return true;
}
@@ -2942,7 +2962,7 @@ impl Editor {
}
let selections = self.selections.all_adjusted(cx);
let mut brace_inserted = false;
let mut bracket_inserted = false;
let mut edits = Vec::new();
let mut linked_edits = HashMap::<_, Vec<_>>::default();
let mut new_selections = Vec::with_capacity(selections.len());
@@ -3004,6 +3024,7 @@ impl Editor {
),
&bracket_pair.start[..prefix_len],
));
if autoclose
&& bracket_pair.close
&& following_text_allows_autoclose
@@ -3021,7 +3042,7 @@ impl Editor {
selection.range(),
format!("{}{}", text, bracket_pair.end).into(),
));
brace_inserted = true;
bracket_inserted = true;
continue;
}
}
@@ -3067,7 +3088,7 @@ impl Editor {
selection.end..selection.end,
bracket_pair.end.as_str().into(),
));
brace_inserted = true;
bracket_inserted = true;
new_selections.push((
Selection {
id: selection.id,
@@ -3224,7 +3245,7 @@ impl Editor {
s.select(new_selections)
});
if !brace_inserted && EditorSettings::get_global(cx).use_on_type_format {
if !bracket_inserted && EditorSettings::get_global(cx).use_on_type_format {
if let Some(on_type_format_task) =
this.trigger_on_type_formatting(text.to_string(), cx)
{
@@ -3232,6 +3253,14 @@ impl Editor {
}
}
let editor_settings = EditorSettings::get_global(cx);
if bracket_inserted
&& (editor_settings.auto_signature_help
|| editor_settings.show_signature_help_after_edits)
{
this.show_signature_help(&ShowSignatureHelp, cx);
}
let trigger_in_words = !had_active_inline_completion;
this.trigger_completion_on_input(&text, trigger_in_words, cx);
linked_editing_ranges::refresh_linked_ranges(this, cx);
@@ -4305,6 +4334,14 @@ impl Editor {
true,
cx,
);
let editor_settings = EditorSettings::get_global(cx);
if editor_settings.show_signature_help_after_edits || editor_settings.auto_signature_help {
// After the code completion is finished, users often want to know what signatures are needed.
// so we should automatically call signature_help
self.show_signature_help(&ShowSignatureHelp, cx);
}
Some(cx.foreground_executor().spawn(async move {
apply_edits.await?;
Ok(())
@@ -5328,6 +5365,7 @@ impl Editor {
}
}
this.signature_help_state.set_backspace_pressed(true);
this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections));
this.insert("", cx);
let empty_str: Arc<str> = Arc::from("");