Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signature help #1331

Closed
archseer opened this issue Dec 22, 2021 Discussed in #1329 · 1 comment · Fixed by #1755
Closed

Signature help #1331

archseer opened this issue Dec 22, 2021 Discussed in #1329 · 1 comment · Fixed by #1755
Labels
A-language-server Area: Language server client C-enhancement Category: Improvements

Comments

@archseer
Copy link
Member

Discussed in #1329

Originally posted by matoous December 22, 2021
Another nice functionality that can be built on top of LSPs is signature help. Vim equivalent: https://github.com/ray-x/lsp_signature.nvim. While helpful it also clutters the UI quite a bit, especially when combined with autocomplete. Something worth considering?

@archseer
Copy link
Member Author

I started working on this in June:

Command

fn signature_help(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
let language_server = match doc.language_server() {
Some(language_server) => language_server,
None => return,
};
let pos = pos_to_lsp_pos(
doc.text(),
doc.selection(view.id)
.primary()
.cursor(doc.text().slice(..)),
language_server.offset_encoding(),
);
let future = language_server.text_document_signature_help(doc.identifier(), pos, None);
cx.callback(
future,
move |_editor: &mut Editor,
_compositor: &mut Compositor,
response: Option<lsp::SignatureHelp>| {
if let Some(signature_help) = response {
log::info!("{:?}", signature_help);
// signatures
// active_signature
// active_parameter
// render as:
// signature
// ----------
// doc
// with active param highlighted
}
},
);
}

Hook

fn signature_help(cx: &mut Context, ch: char) {
// if ch matches signature_help char, trigger
let doc = doc_mut!(cx.editor);
let language_server = match doc.language_server() {
Some(language_server) => language_server,
None => return,
};
let capabilities = language_server.capabilities();
if let lsp::ServerCapabilities {
signature_help_provider:
Some(lsp::SignatureHelpOptions {
trigger_characters: Some(triggers),
// TODO: retrigger_characters
..
}),
..
} = capabilities
{
// TODO: what if trigger is multiple chars long
let is_trigger = triggers.iter().any(|trigger| trigger.contains(ch));
if is_trigger {
super::signature_help(cx);
}
}
// SignatureHelp {
// signatures: [
// SignatureInformation {
// label: "fn open(&mut self, path: PathBuf, action: Action) -> Result<DocumentId, Error>",
// documentation: None,
// parameters: Some(
// [ParameterInformation { label: Simple("path: PathBuf"), documentation: None },
// ParameterInformation { label: Simple("action: Action"), documentation: None }]
// ),
// active_parameter: Some(0)
// }
// ],
// active_signature: None, active_parameter: Some(0)
// }
}

(That TODO should be a NOTE, since the code is implementing post-insert hooks)

// TODO: need a post insert hook too for certain triggers (autocomplete, signature help, etc)
// this could also generically look at Transaction, but it's a bit annoying to look at
// Operation instead of Change.
for hook in &[language_server_completion, signature_help] {

It's now possible to get a Change iterator:

pub fn changes_iter(&self) -> ChangeIterator {
self.changes.changes_iter()
}

Some work would need to be done to have a stateful component similar to completion so we could update it when it gets re-triggered (i.e. ( opens it, then , re-triggers with next parameter's data)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-language-server Area: Language server client C-enhancement Category: Improvements
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant