feat: completions for vernac commands#1251
Conversation
|
I know there is a large refactor going on in #1046, I am happy to rebase once that is merged. |
|
|
||
| While some things can be collected by semantic analysis (such as user defined or library defined lemmas/definitions), a large part of core Rocq are compiler builtins. This includes [commands](https://rocq-prover.org/doc/V9.2.0/refman/rocq-cmdindex.html) (like `Hint Rewrite`), [options](https://rocq-prover.org/doc/V9.2.0/refman/rocq-optindex.html) (like `Set Printing All`), [Ltac1 tactics](https://rocq-prover.org/doc/V9.2.0/refman/rocq-tacindex.html) (like `eapply`), and even [attributes](https://rocq-prover.org/doc/V9.2.0/refman/rocq-attrindex.html) (like `#[refine]`). | ||
|
|
||
| The documentation and grammar for these builtins cannot be queried from `rocq-runtime` and thus need to be maintained separately. To do so, we first extend the doc generator for the official Rocq documentation to additionally generate JSON metadata description of all builtins. Then, we use those metadata files (called "indices") to serve completions to the user in a best-effort manner. |
There was a problem hiding this comment.
the grammar can be gotten from the runtime (cf Print Grammar) but is disconnected from documentation and would need some processing to be used for completion
There was a problem hiding this comment.
Would you recommend some implementation path that uses Print Grammar and connects it to the documentation?
There was a problem hiding this comment.
Would be nice to have a way that works with plugins that define their own vernac too
There was a problem hiding this comment.
IDK how feasible it would be to connect it with the doc
There was a problem hiding this comment.
The grammar described in the documentation is an edited version of the parser's grammar. Print Grammar gives you the parser's grammar. The version in the doc is edited for readability. At build time, the doc_grammar tool generates a grammar file orderedGrammar that covers the built-in commands. That is another way to get the data for command completion. This is described in doc/tools/docgram/README.md. The file includes Rocq-defined plugins. It doesn't include Ltac1- and Ltac2-defined tactics, nor does it tell you what Rocq options are available in the Set command.
724ad7f to
9cffe32
Compare
|
Nice! I think it is mandatory that the generator is merged in the rocq documentation pipeline first. vsrocq should just ask rocq this json file and use it. Did you open a PR on rocq? I think the discussion should happen there. |
|
The doc definitely needs postprocessing, eg for extraction https://rocq-prover.org/doc/master/refman/addendum/extraction.html#rocq:cmd.Extraction the doc combines a few syntaxes so the first paragraph reads "The first two forms display the extracted term(s) as a convenient preview: ..." which is impossible to understand when associated to a completion. |
That would mean users could benefit from this feature only starting 9.3 the earliest. That would leave out a large portion of users.
I will open a PR and see what can be done about it in a discussion there.
Yes, it is rather difficult. The documentation in the popup is best effort and will certainly not give optimal results...
...hence why I link to the official docs for the full description. As I wrote in the README, making the results better (same goes to snippets which are not always optimally formatted) requires more heuristics. The example with grammar is something that could be improved by being smarter in docs extraction. Similarly, we can extract which tactics/commands/etc are deprecated and send that through the LSP too. Of course, ideally I would be interested in producing a perfect JSON index that would not have snippets/descriptions which feel out of place. I am very open to discussing alternatives. |
I'm fine having in the sources of vsrocq the json file for stable rocq versions, your remark makes a lot of sense. But I also want to tool to generate it to be part of rocq, be maintained there, and the .json to be pushed next to the refman at each release. Then each Rocq release we can download and vendor the latest version. |
Sorry, but I'm very ignorant on what can be done in that popup window. Can we load remote content in a browser like window (i.e. follow the link you give) and if offline (or while downloading) use the best effort extract you use today? Does this make any sense? |
|
And for the record, I'm really happy this feature comes to existence, I've always liked the corresponding company-coq feature. If possible, I want to take full advantage of the web tech we have at hand. |
I am afraid this is not really possible. The LSP protocol expects a raw string here (either plain text or markdown). To show the refman docs here we would have to:
Even if someone would do all of that effort I believe the results would be very iffy as well.
Me too! I looked at how other editors (company-coq/coqide/coqtail/rocqlsp) implement similar completion features, and they either don't, or it is quite hacky. Granted, this solution is rather hacky too, but I firmly believe we can get in vsrocq something that is better and more robust than in other editors. |
Converting HTML to markdown will lose a lot. The formatting will be a mess (a compromise at best). Hyperlinks for grammar nonterminals and command names will break. The code may be fragile and hard to maintain. Also the conversion to markdown seems like it would be completely specific to vsRocq--supporting another IDE would need completely different code. Much better to find a way to properly display a chunk of the documentation HTML. If vs doesn't have full HTML support, then maybe consider whether there's a reasonable way to use interprocess communication so the vsRocq can direct a browser to show the right stuff on demand without the user having to explicitly request to see it. Perhaps you could use a file to communicate and a bit of Javascript in the browser to poll the file. For # 2, each command, tactic, etc. has a hyperlink defined that points to the start of the relevant text. Surely the LSP protocol could return that hyperlink instead of the HTML. There should be a way to enable autocomplete and showing the doc separately. |
I agree. And hence I would really like to avoid this if possible. Currently, I transform Sphinx doctrees which are essentially an AST for document formats. Producing markdown (or plain text like I do currently) from that is less hacky.
I don't believe this is true. A large part of VSRocq is the implementation of an LSP. The purpose is that it is editor agnostic (as long as the editor implements an LSP driver, which many editors do (Neovim, emacs, Zed, Intellij, etc)). In fact, I have a secret agenda of contributing to VSRocq's LSP server to eventually be able to use Rocq in Neovim.
Unless you mean something else, this is what we do currently.
I would really like to do that. Do you have some recommendations? For completions we can query |
Even if you generate it from the AST, it looks much worse than the HTML doc. Compare the screen shot in @gares comment above with the rendered HTML:
Enabling autocomplete and doc display seem like they should be controlled in vsRocq but unknown to the Rocq server. They're just booleans. Looks like you already have autocomplete for command names. I was not suggesting going beyond that, just having a way for users to turn what you do have on and off. However, it feels like we're not really in sync and would be tedious to write it all out in comments here. Let me know if you want to do a video call (I am in California). We can exchange views, but I'm only offering ideas and suggestions--it's your choice whether to adopt them. |
|
@jfehrle next week there will be a Rocq call on this topic: https://rocq-prover.zulipchat.com/#narrow/channel/237656-Rocq-devs-.26-plugin-devs/topic/rocq.20call You are welcome to join. |


out.mp4
This PR implements LSP completions for vernac commands. Please see the README in
language-server/dm/indicesfor a short explanation how this was achieved. Next, I want to implement completions for:Set/Unset/Testetc)These PRs are targeting builtins, ie those for which completion support has to be hardcoded. I would appreciate input from someone that works on Rocq to tell me if my indices generator (see the mentioned README) has some path to be merged into Rocq.
These indices could be also used to provide on-hover documentation for all builtins.