I’m excited to announce ocaml-lsp. This project contains an implementation of an LSP server for the OCaml language. The current implementation piggy backs on the widely successful merlin tool to provide completion & type inference. In the future, we’d like to use all other essential tools such as ocamlformat, odoc, dune to provide more functionality in your editors.
For now, the project isn’t yet available on opam as we’re still polishing some rough edges in the release process. Nevertheless, I invite all brave souls who are ready to experiment to give this lsp server a try. Your feedback & contributions are most welcome
Great news. I’m a little concerned though that ocaml-lsp vendors merlin. If they are indeed tightly coupled, shouldn’t they still be developed and released together? Or is there plan to de-couple them in the future?
We might decouple them further in the future but it’s not a huge concern at the moment. The issue with keeping the server inside merlin was that merlin is one of the few tools that we’d like to integrate with.
I understand the concern the concern that it’s more convenient the develop them together, but really that’s a wider concern at the level of the whole OCaml platform. This deserves it’s own discussion, but I personally think that solving this will require new package management tooling.
NeoVim 0.5.0 will also include the tree-sitter parser for syntax highlighting, which will allow way better coloring. And tree-sitter already has OCaml grammar, so implementing semantics-aware syntax highlighter will be easier. But I expect the support more or less ready for external contributions only in 0.6.0, sadly. Integrating the tool with something like GitHub Semantic (Haskell alert) will greatly improve OCaml experience on GitHub too, see the corresponding issue.
Here is an example with ALE and Neovim (tested with v0.3.8):
Install the Ale plugin. If your Vim has support for packages (Vim 8+ or Neovim) you can simply clone it in the correct subdir, no need for a plugin manager: git clone https://github.com/w0rp/ale.git .vim/pack/my-plugins/start/ale
Add this to your .vimrc:
" only invoke merlin to check for errors when
" exiting insert mode, not on each keystroke.
" enable ALE's internal completion if deoplete is not used
" only pop up completion when stopped typing for ~0.5s,
" to avoid distracting when completion is not needed
" see ale-completion-completeopt-bug
" This should be part of ALE itself, like ols.vim
\ 'lsp': 'stdio',
\ 'executable': 'ocamllsp',
\ 'command': '%e',
\ 'project_root': function('ale#handlers#ols#GetProjectRoot')
" remap 'gd' like Merlin would
nmap <silent><buffer> gd <Plug>(ale_go_to_definition_in_split)<CR>
" go back
nnoremap <silent> <LocalLeader>gb <C-O>
" show list of file:line:col of references for symbol under cursor
nmap <silent><buffer> <LocalLeader>go :ALEFindReferences -relative<CR>
" Show documentation if available, and type
nmap <silent><buffer> <LocalLeader>hh <Plug>(ale_hover)<CR>
" So I can type ,hh. More convenient than \hh.
nmap , <LocalLeader>
vmap , <LocalLeader>