I’m just getting started with OCaml development, using VSCode as a primary editor. I’m using the ocamllabs.ocaml-platform extension and it’s working quite well so far, but I have a few questions.
I’m aware that Merlin provides all of the nice IDE-like features, but I think I’m missing some sort of link between my Dune and Merlin configurations. Specifically, I don’t know of a way to make Merlin aware of any changes in my project’s modules until I build them with something like:
ocamlbuild src/foo.cmi
and Merlin sees the changes in my _build directory. So if I change the type of some function in one module and update a function to accept that new type in a different module, Merlin will display an error in the editor indicating that it’s not aware of that new type until I build the other module. And even when Merlin complains like that, I can dune build just fine.
I know that this is how Merlin works and I don’t think anything is wrong with it, but it seems like the cmi files that Merlin gets its information from should have some way to be automatically generated/updated? Am I missing some piece of a more common, better workflow? I’ve looked for sources online describing a better workflow with this but haven’t had any luck.
Would very much appreciate any pointers or ideas that might help me smooth this out!
If you’re starting a new project, don’t use ocamlbuild, use dune. If you’re working on an existing project, in the long run (even in the medium run) it’s best to port it away from ocamlbuild to dune.
Okay cool, I didn’t now about dune build -w! Now I’m using that, however I’m finding that Merlin is still not picking up on any of Dune’s build results. For example, my project is in a state where Dune is reporting a type error, but Merlin still thinks the types are lining up and therefore the text-editor is not showing such an error. Here’s a screenshot that I hope demonstrates it:
The editor plugin still reports no errors after a reload, and I think it’s because I have Merlin looking at different build results than Dune. Dune is building and putting results in ./_build/default/src while my Merlin .merlin config has:
S src
B _build/src
So, should Merlin be looking in ./_build/default/src? Because when I change my Merlin config to look there, it no longer recognizes any of my modules and I get a lot of errors. Happy to provide more info on my configuration if necessary, thank you for the help!
We don’t configure Merlin directly, the editor plugin does that. Try deleting all .merlin files in the project and starting from a fresh build, reloading the window, etc.
Ah okay! I’ve gotten rid of my Merlin configuration and rebuilt the project, now the editor plugin is giving me this error, even though I’ve ran dune build and have dune build -w going:
For some reason, after executing those steps exactly, it is still giving me the Project isn't built error, along with Unbound module errors. I am using an opam switch for the project, so my dune files are as follows:
Did the build actually generate .merlin files like it was supposed to? In the docs there is a (merlin) field which apparently tells dune to use this context for merlin. That kinda sounds like, without this field being present in the context, dune won’t generate .merlin files.
If I were you I would ask if a dune-context file is strictly necessary for the project. Is it a very complex project which needs multiple contexts? Normally dune projects can start out pretty simple, with just a dune file … maybe a dune-project file at most.
Adding the (merlin) field to the dune-workspace file worked! The reason I introduced a dune-workspace file to the project was because I was using an opam switch, which was installing the project dependencies in the project’s _opam directory. Dune was still looking for packages in the global opam package database, so I added the workspace file to make it use the local packages. In hindsight, it seems like a switch wasn’t really necessary, I just wasn’t sure how opam would handle multiple versions of the same packages being installed.
Ah, OK. You’re using a local opam switch. That’s probably a good idea for having a sandboxed build. I just didn’t realize it would interact with dune like that.