-
Notifications
You must be signed in to change notification settings - Fork 124
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
Construct as completion suggestions #472
Conversation
040446a
to
11a3aeb
Compare
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.
Thanks for your efforts. I did an initial review and the PR should be good to go after some minor fixes.
ocaml-lsp-server/test/e2e/__tests__/textDocument-completion.test.ts
Outdated
Show resolved
Hide resolved
I would wait until it is possible to insert snippets with code actions before exploring this. It would be very confusing UI if the editor only offers snippets only via completions. |
* we don't need to pair completion entries with a fixed range * use more self-explanatory names for variables * add comments to where it's not obvious why we're doing this * make newlines more consistent
(AFAIU, await in an async function is useless if we don't await that function itself)
…aram of request) does not have `data` field. We return the completion item itself if the `data` field is missing. We need this for the "merlin construct as completions" feature
…ode action `Construct an expression`
* add comments to explain the code action
syntactically or in AST form
especially vscode-specific commands
* do not put two separate task in merlin thread; do requests in one
036c29e
to
fcd625b
Compare
I hope that trying to make two merlin dispatches at once (fcd625b) is worth the complexity. But I tried to make the code modular, readable, and maintainable. |
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.
I hope that trying to make two merlin dispatches at once (fcd625b) is worth the complexity. But I tried to make the code modular, readable, and maintainable.
It's definitely worth it.
The new code looks much better. Some more minor tweaks and it should be good to go.
ocaml-lsp-server/test/e2e/__tests__/textDocument-completion.test.ts
Outdated
Show resolved
Hide resolved
Signed-off-by: Rudi Grinberg <[email protected]>
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.
Pushed a few tweaks.
Looks good to go.
600e4ec
to
6f9a240
Compare
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)
Implements support for merlin
Construct
.The main reservation that I have so far is that we're not flexible enough about the
depth
parameter forConstruct
. How can we fix this?From our discussion with voodoos:
Local
param forConstruct
isn't ready yet, and we should specifydepth
param later, when it's more efficient.To discuss: Maybe it makes more sense to replace
_
s with snippets, eg calling construct in_ arg1 arg2
will result in(fun _ _ -> _) arg1 arg2
and the cursor will jump to the third underscore (typed hole), while the user likely wants to change the function arguments first.Otherwise, I used the implementation myself. It seems quite good to me. Demo (the demo used Construct with param set to `Local to use local values, which we turned off now)
Screen.Recording.2021-07-06.at.23.13.40.mov