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

Implement window/showMessageRequest #5492

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

ayoub-benali
Copy link
Contributor

@ayoub-benali ayoub-benali commented Jan 10, 2023

Picker does already a good job I think

image

Todo:

  • Capture window/showMessageRequest and show the choices to the user
  • Render the message
  • Render the MessageType
  • Handle when popup is dismissed

Any pointers regarding how to render the message on top of the input correctly prompt would be really helpful

Fix #4699

@ayoub-benali ayoub-benali marked this pull request as draft January 10, 2023 23:24
@the-mikedavis
Copy link
Member

A menu would probably be more appropriate for this than a picker:

let mut picker = ui::Menu::new(actions, (), move |editor, code_action, event| {
if event != PromptEvent::Validate {
return;
}
// always present here
let code_action = code_action.unwrap();
match code_action {
lsp::CodeActionOrCommand::Command(command) => {
log::debug!("code action command: {:?}", command);
execute_lsp_command(editor, command.clone());
}
lsp::CodeActionOrCommand::CodeAction(code_action) => {
log::debug!("code action: {:?}", code_action);
if let Some(ref workspace_edit) = code_action.edit {
log::debug!("edit: {:?}", workspace_edit);
apply_workspace_edit(editor, offset_encoding, workspace_edit);
}
// if code action provides both edit and command first the edit
// should be applied and then the command
if let Some(command) = &code_action.command {
execute_lsp_command(editor, command.clone());
}
}
}
});

@the-mikedavis the-mikedavis added A-language-server Area: Language server client A-helix-term Area: Helix term improvements labels Jan 11, 2023
@ayoub-benali
Copy link
Contributor Author

I think it is too small as you can see:
image

And it might look worse once I add the message coming with the request

@ayoub-benali
Copy link
Contributor Author

Here is how it looks like when the message is added in the picker

image

I still need to fix the prompt in this example

@pascalkuthe
Copy link
Member

I agree with @ayoub-benali here.
The menu seems better suited for "inline" actions and less well suited for a large popup like this.

In fact I originally suggested the picker on matrix.

Nvim also handles this as a larger popup:

image

I think reusing the picker here is nice so there are fewer specical cased UI elements (and the PR is easier to review).
Altough it's true that the filtering capabilities of the picker don't really fit here.
Perhaps it might make more sense to create a new view that is a copy of the picker, rip out any filtering related logic and functionality and reuse the top line to display the message?

@ayoub-benali
Copy link
Contributor Author

I just noticed that lsp-workspace-command uses the same picker and as you can see the list can be quite long. The filtering capabilities do help because the user can just start typing rather than having to scroll a long list.

image

window/showMessageRequest could contain similar long action list

@ayoub-benali
Copy link
Contributor Author

ayoub-benali commented Jan 13, 2023

After discussion with @pascalkuthe I moved the LSP message to the right. This way we can better handle messages that could span over one line.

Usually LSP messages are short, but I will enable softwrap once #5420 is merged.

For metals this how the build message is displayed:

image

And this is for the file creation:

image

@pascalkuthe
Copy link
Member

Is there anything still missing? Otherwise you can mark this PR as ready for review.

@ayoub-benali
Copy link
Contributor Author

almost, I am just working on sending the response to the server when the file picker is dismissed. I had to add a function to the constructor and update all the call sites ^^

@ayoub-benali ayoub-benali marked this pull request as ready for review January 14, 2023 16:34
}

impl<T: Item> Picker<T> {
pub fn new(
options: Vec<T>,
editor_data: T::Data,
callback_fn: impl Fn(&mut Context, &T, Action) + 'static,
on_close_fn: impl Fn(&mut Context) + 'static,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this function so that we can run it when the picker is dismissed but since it is not needed in the other context, I don't know if there is a better way

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this mostly works fine but I think you could merge these two callbacks here and pass None when the picker is closed:

callback_fn: impl Fn(&mut Context, &T, Option<Action>) + 'static,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So callback_fn should be invoked here with None just before close_fn ?

key!(Esc) | ctrl!('c') => {
return close_fn;
}

EDIT: done in 267af0d and made the item &T optional rather than the action

@@ -36,6 +36,7 @@ pub const MAX_FILE_SIZE_FOR_PREVIEW: u64 = 10 * 1024 * 1024;
pub enum PathOrId {
Id(DocumentId),
Path(PathBuf),
Text(Rope),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This to show the same message in the "preview" part of the file picker

@ayoub-benali
Copy link
Contributor Author

If your favorite language server doesn't implement this request, you can still test this feature by:

  1. Installing Metals https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers#metals
  2. Cloning this example project and opening via Helix in the root
  3. Opening any .sbt or .scala file, the build message should appear.

Once the build is done or you click Don't show again you will have to delete the .metal directory and open Helix again to force the message again.

@@ -114,7 +125,7 @@ impl<T: Item> FilePicker<T> {
pub fn new(
options: Vec<T>,
editor_data: T::Data,
callback_fn: impl Fn(&mut Context, &T, Action) + 'static,
callback_fn: impl Fn(&mut Context, Option<&T>, Action) + 'static,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The None case allows us to represent when the picker is dismissed, otherwise we have to define a separate on_close method, you can see the attempt here: 34f1555
EDIT: rebasing on master was a mess because I had several commits for commands.rs and picker.rs so I squashed my commits to make my life easier.

@pascalkuthe pascalkuthe added the S-waiting-on-review Status: Awaiting review from a maintainer. label Jan 17, 2023
return close_fn;
}
alt!(Enter) => {
if let Some(option) = self.selection() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't needed anymore since the None case is handled in the callback function

@ayoub-benali ayoub-benali force-pushed the show-message-request branch 2 times, most recently from d3e8b0e to ea0abce Compare January 22, 2023 14:50
LEI added a commit to LEI/helix that referenced this pull request Feb 25, 2023
- Opening untrusted_files in NewWindow is not supported, yet?
- VS Code empty_window equivalent is a scratch buffer, does it have a cwd?
- Manage trusted workspaces as a simple list of paths for now?
- Plan for local/remote trusted folders and workspaces
- Plan for plugin extensions support (disabled, limited)

TODO:
- [x] Disable LSP and ? in restricted mode
- [x] User configuration (new TOML entry)
- [ ] Persist user preferences (trusted folder choices)
- [x] Show current workspace status (badge?)
- [ ] Add a command to quickly toggle workspace status (Manage Workspace Trust)
- [x] Use picker as prompt: helix-editor#5492
@ayoub-benali
Copy link
Contributor Author

Hi @the-mikedavis, sorry to ping you but Is it possible to give this PR a review ?
window/showMessageRequest is required in Metals to import the build otherwise nothing works in scala projects.
I made sure to often keep this PR conflict free with master but it is getting harder as more core changes have been merged

helix-lsp/src/client.rs Outdated Show resolved Hide resolved
helix-term/src/application.rs Outdated Show resolved Hide resolved
helix-term/src/commands.rs Outdated Show resolved Hide resolved
helix-term/src/ui/picker.rs Show resolved Hide resolved
This is done by taking advantage of the preview panel in the file picker to show the request message
I changed the Picker callback function to account for when the picker is dismissed
Copy link
Member

@the-mikedavis the-mikedavis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some minor comments but otherwise I think this looks good.

In the long run I think I would prefer a custom component for this kind of UI. Using the picker's preview to show a message feels inconsistent to me: the picker preview is otherwise always used for showing supporting information about the currently selected option instead of context about why the picker is open. When I open a picker my eyes are always on the options first and then the preview if needed. This is a relatively small change though to add a feature so I think we can leave that off for future implementation/discussion

helix-term/src/application.rs Outdated Show resolved Hide resolved
helix-term/src/commands/dap.rs Outdated Show resolved Hide resolved
helix-term/src/commands/dap.rs Outdated Show resolved Hide resolved
helix-term/src/commands/dap.rs Outdated Show resolved Hide resolved
helix-term/src/ui/mod.rs Outdated Show resolved Hide resolved
helix-term/src/ui/picker.rs Outdated Show resolved Hide resolved
ayoub-benali and others added 6 commits March 21, 2023 09:57
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
@ayoub-benali
Copy link
Contributor Author

Hi @archseer, any chance to give this a review ? :)

@NomisIV
Copy link
Contributor

NomisIV commented Aug 1, 2023

Any chance we could get this merged? I would personally find this very useful!
The PR seems to be ready for merge after one more review and a rebase on master. We're almost there :)

@ayoub-benali
Copy link
Contributor Author

Hi @NomisIV, I rebased this PR multiple time but it doesn't help as long as @archseer doesn't have time to review.
This same applies to #5535

@igor-ramazanov
Copy link

I would really love to see this merged.
Thank you very much for your contribution @ayoub-benali!

I am also using Metals for working with Scala.

For now I am building and patching Helix locally like I did with #5535, but I am struggling with rebasing and resolving conflicts in this PR with master branch or latest 23.05 tag to do the same.

@ayoub-benali Could you or someone else, please, resolve the conflicts, at least with the latest 23.05 branch?

@igor-ramazanov
Copy link

Can we include this into the next release?

@filipwiech
Copy link

Hello @the-mikedavis, @pascalkuthe and @archseer! 🙂
Sorry to ping you like this, but this PR has been sitting reviewed and approved by 2 maintainers for months now. It would be really great to get this merged, since it's part of the LSP specification and some servers (like for example Scala's Metals mentioned in the original issue) use it to provide core features without which usability and user experience are impacted quite heavily. Any chance to see this progress? Is there anything still needed to be done here? 🙂
Thank you for your work on this amazing editor (and big thanks to the author of this PR for the contribution)! 🙂

@hakan-demirli
Copy link

I have tried to rebase this to current master and miserably failed. Currently metals (a scala LSP) is unusable without this PR. I am using neovim as a substitute which is pita.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-helix-term Area: Helix term improvements A-language-server Area: Language server client S-waiting-on-review Status: Awaiting review from a maintainer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement window/showMessageRequest in LSP client
7 participants