-
Notifications
You must be signed in to change notification settings - Fork 121
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
add support for refactor-open (qualify and unqualify) code action #399
Conversation
I don't mind the names. This is one of those things that's easy enough to learn by example.
If the code action won't do anything, the edit it computes should be empty. Can we filter it out then? |
Unfortunately, merlin always returns edits, even if those edits when applied do not change the document at all. (I could check whether edits do anything by applying them before returning the code action, but that seems expensive) Other notes:
open Import
module Bin = Stdune.Bin
let _PATH =
lazy
(Bin.parse_path
(Dune__exe.Import.Option.value ~default:"" (Dune__exe.Import.Unix_env.get Dune__exe.Import.Unix_env.initial "PATH"))) Meanwhile, do you happen to know if that's also the case with refactor-open in merlin's emacs mode? I will try to fix this anyway.
|
No idea. I don't use the emacs mode.
Is this for tests or something? We don't have .merlin files anymore. Let's see if @voodoos can help us out. |
A due update:
I would appreciate your take on whether we should merge this PR as is and wait for upstream merlin to merge fix-PRs, or merge those in ocaml-lsp merlin. Both are fine with me.
Yes, I needed to write some tests for merlin, but I figured this out. |
Do you think this feature is useful to users in its current form? |
Let's aim to merge this for the release after the next one. I hope by then we'll get a feel whether ocaml/merlin is willing to merge. |
@rgrinberg I think that this feature has improved quite a bit in merlin and should be useful to ocaml-lsp users as well :-) I think this PR is ready as soon as we switch to using the latest merlin master (I think you'd prefer to do that yourself? otherwise, I can make a PR). I included b975615 in this PR as well:
I can squash all but b975615 for cleaner history; lmk if you'd like that. Other feedback/proposals are also welcome. |
ocaml-lsp-server/test/e2e/__tests__/textDocument-codeAction.test.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR looks good but we can't rely on the following special libraries in the tests: unix
, str
, dynlink
.
@@ -48,6 +48,12 @@ | |||
|
|||
- Change the formatting-on-save error notification to a warning notification (#472) | |||
|
|||
- Bug fix: do not show "random" documentation on hover |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this already in the merlin change list? We usually do not replicate merlin's change list here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is already in the merlin changes list, but since this bug has been reported several times in both ocaml-lsp & vscode-ocaml-platform, I thought it is useful for users to see it fixed.
I think that merlin is ocaml-lsp's backend, but the end user shouldn't be lurking in merlin Changes to see what's new in ocaml-lsp -- maybe we could at least add a link to their Changes inside the ocaml-lsp-vendored merlin source.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, the change entry in merlin is "locate: reset global state from all entry points (#1364)", which is cryptic, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is cryptic. But that can be mended on merlin's side. I'd prefer to see the links to the corresponding change list entries where the fix was done.
I think that merlin is ocaml-lsp's backend, but the end user shouldn't be lurking in merlin Changes to see what's new in ocaml-lsp -- maybe we could at least add a link to their Changes inside the ocaml-lsp-vendored merlin source.
We could have a policy of replicating only the relevant merlin changes in our repo. The problem is that I often lack context as to what is relevant to lsp, and it is extra work. We can bring it up with the rest of the team to see what they think.
CHANGES: ## Features - Add a new code action `Add missing rec keyword`, which is available when adding a `rec` keyword can fix `Unbound value ...` error, e.g., ```ocaml let fact n = if n = 0 then 1 else n * fact (n - 1) (* ^^^^ Unbound value fact *) ``` Adding `rec` to the definition of `fact` will fix the problem. The new code action offers adding `rec`. - Jump to the first hole on calling `Destruct` code action (only with client VSCode OCaml Platform) (ocaml/ocaml-lsp#468) Example: when a user invokes `Destruct` code action on `Some 1`, this code is replaced by `match Some 1 with None -> _ | Some _ -> _`, where the 1st and 3rd underscores are "typed holes", a concept created by Merlin to be able to put "holes" in OCaml code. With this change, now for VSCode OCaml Platform users, on such invocation of `Destruct`, the cursor will jump to the first typed hole and select it, so that user can start editing right away. - Use ocamlformat to properly format type snippets. This feature requires the `ocamlformat-rpc` opam package to be installed. (ocaml/ocaml-lsp#386) - Add completion support for polymorphic variants, when it is possible to pin down the precise type. Examples (`<|>` stands for the cursor) when completion will work (ocaml/ocaml-lsp#473) Function application: ``` let foo (a: [`Alpha | `Beta]) = () foo `A<|> ``` Type explicitly shown: ``` let a : [`Alpha | `Beta] = `B<|> ``` Note: this is actually a bug fix, since we were ignoring the backtick when constructing the prefix for completion. - Parse merlin errors (best effort) into a more structured form. This allows reporting all locations as "related information" (ocaml/ocaml-lsp#475) - Add support for Merlin `Construct` command as completion suggestions, i.e., show complex expressions that could complete the typed hole. (ocaml/ocaml-lsp#472) - Add a code action `Construct an expression` that is shown when the cursor is at the end of the typed hole, i.e., `_|`, where `|` is the cursor. The code action simply triggers the client (currently only VS Code is supported) to show completion suggestions. (ocaml/ocaml-lsp#472) - Change the formatting-on-save error notification to a warning notification (ocaml/ocaml-lsp#472) - Code action to qualify ("put module name in identifiers") and unqualify ("remove module name from identifiers") module names in identifiers (ocaml/ocaml-lsp#399) Starting from: ```ocaml open Unix let times = Unix.times () let f x = x.Unix.tms_stime, x.Unix.tms_utime ``` Calling "remove module name from identifiers" with the cursor on the open statement will produce: ```ocaml open Unix let times = times () let f x = x.tms_stime, x.tms_utime ``` Calling "put module name in identifiers" will restore: ```ocaml open Unix let times = Unix.times () let f x = x.Unix.tms_stime, x.Unix.tms_utime ``` ## Fixes - Do not show "random" documentation on hover - fixed by [merlin#1364](ocaml/merlin#1364) - fixes duplicate: - [ocaml-lsp#344](ocaml/ocaml-lsp#344) - [vscode-ocaml-platform#111](ocamllabs/vscode-ocaml-platform#111) - Correctly rename a variable used as a named/optional argument (ocaml/ocaml-lsp#478) - When reporting an error at the beginning of the file, use the first line not the second (ocaml/ocaml-lsp#489)
CHANGES: ## Features - Add a new code action `Add missing rec keyword`, which is available when adding a `rec` keyword can fix `Unbound value ...` error, e.g., ```ocaml let fact n = if n = 0 then 1 else n * fact (n - 1) (* ^^^^ Unbound value fact *) ``` Adding `rec` to the definition of `fact` will fix the problem. The new code action offers adding `rec`. - Use ocamlformat to properly format type snippets. This feature requires the `ocamlformat-rpc` opam package to be installed. (ocaml/ocaml-lsp#386) - Add completion support for polymorphic variants, when it is possible to pin down the precise type. Examples (`<|>` stands for the cursor) when completion will work (ocaml/ocaml-lsp#473) Function application: ``` let foo (a: [`Alpha | `Beta]) = () foo `A<|> ``` Type explicitly shown: ``` let a : [`Alpha | `Beta] = `B<|> ``` Note: this is actually a bug fix, since we were ignoring the backtick when constructing the prefix for completion. - Parse merlin errors (best effort) into a more structured form. This allows reporting all locations as "related information" (ocaml/ocaml-lsp#475) - Add support for Merlin `Construct` command as completion suggestions, i.e., show complex expressions that could complete the typed hole. (ocaml/ocaml-lsp#472) - Add a code action `Construct an expression` that is shown when the cursor is at the end of the typed hole, i.e., `_|`, where `|` is the cursor. The code action simply triggers the client (currently only VS Code is supported) to show completion suggestions. (ocaml/ocaml-lsp#472) - Change the formatting-on-save error notification to a warning notification (ocaml/ocaml-lsp#472) - Code action to qualify ("put module name in identifiers") and unqualify ("remove module name from identifiers") module names in identifiers (ocaml/ocaml-lsp#399) Starting from: ```ocaml open Unix let times = Unix.times () let f x = x.Unix.tms_stime, x.Unix.tms_utime ``` Calling "remove module name from identifiers" with the cursor on the open statement will produce: ```ocaml open Unix let times = times () let f x = x.tms_stime, x.tms_utime ``` Calling "put module name in identifiers" will restore: ```ocaml open Unix let times = Unix.times () let f x = x.Unix.tms_stime, x.Unix.tms_utime ``` ## Fixes - Do not show "random" documentation on hover - fixed by [merlin#1364](ocaml/merlin#1364) - fixes duplicate: - [ocaml-lsp#344](ocaml/ocaml-lsp#344) - [vscode-ocaml-platform#111](ocamllabs/vscode-ocaml-platform#111) - Correctly rename a variable used as a named/optional argument (ocaml/ocaml-lsp#478) - When reporting an error at the beginning of the file, use the first line not the second (ocaml/ocaml-lsp#489)
Reservations I have:
Blockers:
open
statement, but they can be shown even if the code action won't do anything, e.g.,refactor-open qualify
qualifies with full paths, e.g., foropen Import
, it doesDune__exe.Import.foo...
.To-do