Skip to content

Commit

Permalink
lsp: Implement textDocument/signatureHelp for `ProjectClientState::…
Browse files Browse the repository at this point in the history
…Local` environment (#12909)

Closes #5155
Closes #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](#4879),
[5155](#5155))

---------

Co-authored-by: Kirill Bulatov <[email protected]>
  • Loading branch information
tomoikey and SomeoneToIgnore authored Jul 11, 2024
1 parent 6a11184 commit 291d64c
Show file tree
Hide file tree
Showing 19 changed files with 1,994 additions and 11 deletions.
1 change: 1 addition & 0 deletions assets/keymaps/default-linux.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"ctrl-k ctrl-r": "editor::RevertSelectedHunks",
"ctrl-'": "editor::ToggleHunkDiff",
"ctrl-\"": "editor::ExpandAllHunkDiffs",
"ctrl-i": "editor::ShowSignatureHelp",
"alt-g b": "editor::ToggleGitBlame"
}
},
Expand Down
3 changes: 2 additions & 1 deletion assets/keymaps/default-macos.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@
"cmd-alt-z": "editor::RevertSelectedHunks",
"cmd-'": "editor::ToggleHunkDiff",
"cmd-\"": "editor::ExpandAllHunkDiffs",
"cmd-alt-g b": "editor::ToggleGitBlame"
"cmd-alt-g b": "editor::ToggleGitBlame",
"cmd-i": "editor::ShowSignatureHelp"
}
},
{
Expand Down
5 changes: 5 additions & 0 deletions assets/settings/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@
// The debounce delay before re-querying the language server for completion
// documentation when not included in original completion list.
"completion_documentation_secondary_query_debounce": 300,
// Show method signatures in the editor, when inside parentheses.
"auto_signature_help": false,
/// Whether to show the signature help after completion or a bracket pair inserted.
/// If `auto_signature_help` is enabled, this setting will be treated as enabled also.
"show_signature_help_after_edits": true,
// Whether to show wrap guides (vertical rulers) in the editor.
// Setting this to true will show a guide at the 'preferred_line_length' value
// if softwrap is set to 'preferred_line_length', and will show any
Expand Down
5 changes: 4 additions & 1 deletion crates/collab/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,10 @@ impl Server {
app_state.config.openai_api_key.clone(),
)
})
});
})
.add_request_handler(user_handler(
forward_read_only_project_request::<proto::GetSignatureHelp>,
));

Arc::new(server)
}
Expand Down
2 changes: 2 additions & 0 deletions crates/editor/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,14 @@ gpui::actions!(
SelectPageUp,
ShowCharacterPalette,
ShowInlineCompletion,
ShowSignatureHelp,
ShuffleLines,
SortLinesCaseInsensitive,
SortLinesCaseSensitive,
SplitSelectionIntoLines,
Tab,
TabPrev,
ToggleAutoSignatureHelp,
ToggleGitBlame,
ToggleGitBlameInline,
ToggleSelectionMenu,
Expand Down
46 changes: 42 additions & 4 deletions crates/editor/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -3004,6 +3024,7 @@ impl Editor {
),
&bracket_pair.start[..prefix_len],
));

if autoclose
&& bracket_pair.close
&& following_text_allows_autoclose
Expand All @@ -3021,7 +3042,7 @@ impl Editor {
selection.range(),
format!("{}{}", text, bracket_pair.end).into(),
));
brace_inserted = true;
bracket_inserted = true;
continue;
}
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -3224,14 +3245,22 @@ 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)
{
on_type_format_task.detach_and_log_err(cx);
}
}

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);
Expand Down Expand Up @@ -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(())
Expand Down Expand Up @@ -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("");
Expand Down
12 changes: 12 additions & 0 deletions crates/editor/src/editor_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub struct EditorSettings {
#[serde(default)]
pub double_click_in_multibuffer: DoubleClickInMultibuffer,
pub search_wrap: bool,
pub auto_signature_help: bool,
pub show_signature_help_after_edits: bool,
#[serde(default)]
pub jupyter: Jupyter,
}
Expand Down Expand Up @@ -234,6 +236,16 @@ pub struct EditorSettingsContent {
/// Default: true
pub search_wrap: Option<bool>,

/// Whether to automatically show a signature help pop-up or not.
///
/// Default: false
pub auto_signature_help: Option<bool>,

/// Whether to show the signature help pop-up after completions or bracket pairs inserted.
///
/// Default: true
pub show_signature_help_after_edits: Option<bool>,

/// Jupyter REPL settings.
pub jupyter: Option<Jupyter>,
}
Expand Down
Loading

0 comments on commit 291d64c

Please sign in to comment.