I am very excited to announce the first release of Merlin and Ocaml-LSP with support for project-wide occurrences . More precisely, it is now possible to query for every usage of any value (and type, modules, etc.) anywhere in a project built with Dune. This is a very handy tool for code navigation !
Requirements
OCaml 5.2
Latest Dune (>= 3.16.0)
Latest Merlin (>= 5.1-502)
Latest OCaml-LSP preview (1.18.0~5.2preview)
You can uprgade by running opam update followed by opam upgrade.
Usage
Build the new @ocaml-index alias.
We recommend running the indexation in watch mode along with your usual targets: dune build @ocaml-index --watch so that the index is always up to date.
Use the Find/Peek all references feature of LSP-based plugins
or merlin-project-occurrences in emacs
or OccurrencesProjectWide in vim.
Enjoy jumping around
More information and bug reports
Bug reports and feature requests should be submitted to the Merlin issue tracker. There are already some known issues like the absence of declarations in the results and the impossibility to query from a declaration (and thus mli files). Progress on occurrences can be tracked in a pinned meta-issue. If you are interested in contributing and learning more about the feature do not hesitate to join the first public dev-meeting on Thursday !
Where should we get ocaml-index executable? In the preview it was in indexing-tools package, but right now this package seems to be absent in default opam repo.
You can opam install ocaml-index, but it should be done automatically when you upgrade since it is a dependency of the merlin and ocaml-lsp-server packages. Don’t forget to opam update before !
Not sure what you mean excatly, but jump-to-definition has always been able to jump to a transitive dependency. There was an issue, however, when using dune’s (implicit transitive deps false). That behavior should be improved with the latest release too.
It is a wide step into that direction! We did not enable it in the lsp server for renaming yet, since it requires more work to be done cleanly (like looking at syntax tricks like punning before renaming).
Additionally, we need more than the currently returned set of “usages” to perform renaming: we need to know which declaration(s) correspond to the selected item and all the usages of all the definitions that share these declarations… But it is definitely coming
Let’s say we’re working in our local project. And that project has a dependency on say Bigstringaf. If we start looking at Bigstringaf sources via the LSP and execute a search for references query on some function in Bigstringaf, will that work ?
In other words, does project wide occurences work on source code of the library dependencies ?
You should get all the occurrences of Bigstringaf.something in the sources of your project.
You won’t get occurrences of Bigstringaf.something in bigstringaf sources or anywhere else in the installed (opam switch) world. (unless you use a monorepo).
I tried this out – it works but not totally as expected. (I’m using ocaml-lsp-server)
(I tried this out on the eio source code in case anybody would like to try this out themselves)
I used Atomic.set as an example.
If I search for all occurences of Atomic.set in my project it works when I place the cursor anywhere on set – I get occurences of Atomic.set – great !!
Now I’m interested in looking for all usage of the Atomic module. So I place my cursor anywhere on Atomic and try to get occurences – it doesn’t work – is this expected ?
It is expected that occurrences of modules appearing in paths (such as Atomic in Atomic.set) are not returned. This is due to missing location information in longidents and is part of the roadmap.
Direct usages of the module, such as open Atomic should be found however.