Merlin: Goto definition inside installed libraries



I raised an issue on GitHub a little while ago about not being able to use MerlinLocate from inside installed libraries (I can jump to them from my project but then I hit a dead end from there). @trefis advised moving the discussion here.

From what I understand, to jump to definition Merlin needs .merlin files, which Dune auto-generates for your project but are not available for libraries installed through Opam. Excluding them seems to be a deliberate choice, which confuses me, since jumping through definitions and implementations of libraries is important to understand and work with them. My questions are:

  1. Am I correct that this is a design choice as opposed to a technical challenge, and if so, can this choice be revisited?
  2. If .merlin files will not be released, what is the best way to get jump to definition working locally? Should I create .merlin files in the opam directory tree (and if so what should they look like and where should they be placed)? Or should I symlink to the installed libraries from my project – or copy them to my project – so that Dune is able to generate Merlin files for them?
  3. Is this something that the Duniverse project will resolve?


In the general case, the source code of an installed library is not available. So there is no definition to jump to, except maybe the declaration in an MLI file but even that is not required for the compiler to link the library. Are you assuming a different setup where the library source code is available?


Yes, I am assuming source is available, though that’s a fair point. The source does seem to be available for libraries like core and async, and I imagine for several others as well. So I suppose my questions should be qualified with that assumption.


Note that for topkg packages you can set TOPKG_CONF_DEBUGGER_SUPPORT=true in your environment before opam installing topkg packages. This should install sources for these packages.


Like I said, in the general case a package in Opam does not install its source code and therefore you can’t jump to a definition. However, in a project built with Dune or Jbuilder you can unpack the code of selected libraries in your project, where they will be built and visible for Merlin. See Dune Scopes.


Can you elaborate on how to get this to work? What my directory structure needs to be / what files I need (dune, dune-project, core.opam, etc. what needs to be created and placed where)? I’ve tried several iterations but none of them seem to be respected and the documentation on this is sparse.


I am working an a small webapp that uses Opium, Moustache and Ezjsonm as libraries. When I unpack them in the top-level of my project (opam source moustache, …) and build the project as before, now the unpacked sources will be used and I can jump to any code inside them using Merlin. My own code, dune files and so on are completely unchanged.

β”œβ”€β”€ Makefile
β”œβ”€β”€ checkout.opam
β”œβ”€β”€ db
β”‚   β”œβ”€β”€ Makefile
β”‚   β”œβ”€β”€ club.csv
β”‚   β”œβ”€β”€ crew.csv
β”‚   β”œβ”€β”€ db
β”‚   β”œβ”€β”€ db-export.sql
β”‚   β”œβ”€β”€ db.db
β”‚   β”œβ”€β”€ db.sql
β”‚   β”œβ”€β”€ equipment.csv
β”‚   └── purpose.csv
β”œβ”€β”€ dune-project
β”œβ”€β”€ ezjsonm.0.6.0
β”‚   β”œβ”€β”€
β”‚   β”œβ”€β”€ LICENSE
β”‚   β”œβ”€β”€
β”‚   β”œβ”€β”€ ezjsonm-lwt.opam
β”‚   β”œβ”€β”€ ezjsonm.opam
β”‚   β”œβ”€β”€ lib
β”‚   β”œβ”€β”€ lib_test
β”‚   └── pkg
β”œβ”€β”€ html
β”‚   β”œβ”€β”€ css
β”‚   β”œβ”€β”€ index.html
β”‚   └── index.json
β”œβ”€β”€ mustache.3.0.2
β”‚   β”œβ”€β”€
β”‚   β”œβ”€β”€
β”‚   β”œβ”€β”€ Makefile
β”‚   β”œβ”€β”€
β”‚   β”œβ”€β”€ examples
β”‚   β”œβ”€β”€ lib
β”‚   β”œβ”€β”€ lib_test
β”‚   β”œβ”€β”€ mustache.descr
β”‚   β”œβ”€β”€ mustache.opam
β”‚   β”œβ”€β”€ pkg
β”‚   β”œβ”€β”€ specs
β”‚   └── test
β”œβ”€β”€ opium.0.16.0
β”‚   β”œβ”€β”€ Makefile
β”‚   β”œβ”€β”€
β”‚   β”œβ”€β”€
β”‚   β”œβ”€β”€ VERSION
β”‚   β”œβ”€β”€ dune-project
β”‚   β”œβ”€β”€
β”‚   β”œβ”€β”€ examples
β”‚   β”œβ”€β”€
β”‚   β”œβ”€β”€ lib_test
β”‚   β”œβ”€β”€ opium
β”‚   β”œβ”€β”€ opium.opam
β”‚   β”œβ”€β”€ opium_kernel
β”‚   β”œβ”€β”€ opium_kernel.opam
β”‚   └── pkg
└── src
    β”œβ”€β”€ dune
    β”œβ”€β”€ main.mli


Does this work for libraries that were not themselves built with dune? When I try opam source-ing core, core_kernel, base, etc. and their dependencies into a vendor/ directory, dune builds them fine but MerlinLocate seems to ignore them. I suspect (though am not sure) this is because these libraries are missing dune files, as they have jbuild files instead. If this is the issue, is there a way to reliably translate the jbuild file into the needed dune file (they follow similar formats but I don’t think they are 1:1)?


This should work with jbuild files as well. I don’t know about the Janes Street projects in particular.