Inlay Hints in neovim

Hello!

Has anyone been able to set up inlay hints for the ocamllsp within neovim? It’s about the only thing I miss from vscode compared to neovim.

This is my config.

ocamllsp = {
  cmd = { "ocamllsp" },
  filetypes = { "ocaml", "menhir", "ocamlinterface", "ocamlocamllex",
    "reason", "dune" },
  root_dir = require("lspconfig").util.root_pattern("*.opam", "esy.json",                   
    "package.json", ".git", "dune-project", "dune-workspace"),
  settings = {
    ocamllsp = {
      extendedHover = true,
      codelens = true,
      duneDiagnostics = true,
      inlayHints = true,
      syntaxDocumentation = true,                                                             
      merlinJumpCodeActions = true,
    },
  },
},

I tried working with simrat39/inlay-hints.nvim but wasn’t able to get it working. Has anyone else been lucky with inlay hints? It’s really nice to see the function definition above the function. I had it working in the past but not sure when it disappeared.

3 Likes

Yeah I got inlay hints working with the following config:

  settings = {
    codelens = { enable = true },
    inlayHints = { hintPatternVariables = true, hintLetBindings = true },
    extendedHover = { enable = true },
    syntaxDocumentation = { enable = true },
    merlinJumpCodeActions = { enable = true },
  }

I do also use a patched version of ocamllsp, that sets the -avoid-ghost-location flag to false when it makes the request to merlin. It’s probably completely unnecessary, but I prefer it.
The patch I use:

diff --git a/ocaml-lsp-server/src/inlay_hints.ml b/ocaml-lsp-server/src/inlay_hints.ml
index 8e87a309..82d1a427 100644
--- a/ocaml-lsp-server/src/inlay_hints.ml
+++ b/ocaml-lsp-server/src/inlay_hints.ml
@@ -34,7 +34,7 @@ let compute (state : State.t) { InlayHintParams.range; textDocument = { uri }; _
         and stop = range.end_ |> Position.logical in
         let command =
           Query_protocol.Inlay_hints
-            (start, stop, hint_let_bindings, hint_pattern_variables, not inside_test)
+            (start, stop, hint_let_bindings, hint_pattern_variables, false)
         in
         let hints = Query_commands.dispatch pipeline command in
         List.filter_map

I hope that helps!

2 Likes

Oh yes, also make sure inlay hints are enabled, I have it on an lspAttach autocommand that enables them.

Something along these lines:

vim.api.nvim_create_autocmd('LspAttach', {
  callback = function(args)
    local client = assert(vim.lsp.get_client_by_id(args.data.client_id))
    if client.server_capabilities.inlayHintProvider then
      vim.lsp.inlay_hint.enable(true)
    end
  end,
})
2 Likes

How did you apply the patch to the lsp server? Did you just clone the repo and build it from source?

I struggled a lot to get this to work.

Finally it worked for me using @Blue-Berry’s settings (Thanks!) above when I compiled ocaml-lsp-server on the master branch (using ocaml 5.3.0)

(Note that merlin needs to be pinned to main branch also otherwise ocaml-lsp-server master does not compile)

1 Like

It’s probably not applicable to most but I use a nix development shell, created from a flake, which handles the patch.

devShells = {
  default = mkShell {
    inputsFrom = [self'.packages.default];
    buildInputs = with ocamlPackages; [
      utop
      ocamlformat
      # patch ocaml-lsp so that inlay hints dont hide ghost values
      (ocamlPackages.ocaml-lsp.overrideAttrs (oldAttrs: {
        patches = [
          ./inlay-hints.patch
        ];
      }))
    ];
  };
};

If I wasn’t using nix, the easiest would probably be to make a fork and set up an action to automatically stay up to date.

However, in the newest version of the LSP it seems like the issue I was patching for seems not existent, so I won’t be patching in the latest versions.

1 Like

Thanks @Blue-Berry!

Also, I found that after pinning merlin/lib and ocaml-lsp-server to:

opam pin add merlin https://github.com/ocaml/merlin.git#main
opam pin add merlin-lib https://github.com/ocaml/merlin.git#main
opam pin add ocaml-lsp-server https://github.com/ocaml/ocaml-lsp.git#master

There now is an additional inlay_hint parameter that isn’t in the opam released branch yet, hintFunctionParams.

settings = {
    extendedHover = {enable = true},
    standardHover = {enable = true},
    codelens = {enable = true},
    duneDiagnostics = {enable = true},
    inlayHints = {
        hintPatternVariables = true,
        hintLetBindings = true,
        hintFunctionParams = true
    },
    syntaxDocumentation = {enable = true},
    merlinJumpCodeActions = {enable = true}
}

Additionally I overrode the lsp that is coming from mason in NVIM that is sometimes being invoked by using the command:
cp -f ~/.opam/default/bin/ocamllsp ~/.local/share/nvim/mason/packages/ocaml-lsp/bin/ocamllsp

You can see screenshot of my setup below, I modified the Code Lenses to show up above the functions as well just like in VSCode:

3 Likes

Wow! I didn’t know about inlay hints, but I’ve definitely wanted for such a feature! I use vim, but I’ll try neovim, now. Is there a similar feature for emacs?

I know almost nothing about Emacs, but it’s worth checking out ocaml-eglot which is an Emacs minor mode, I believe it provides support for inlay hints.

1 Like

Nice! I’m very curious how you adjusted code lens, I had a similar look before I switched from a custom virt-text implementation to using the built-in one. I quite like the look you have, would you mind sharing?

I too am using plain vim; how close can we get to this within vim 9?

In theory, very close Inlay hints by puremourning · Pull Request #4045 · ycm-core/YouCompleteMe · GitHub (I haven’t used vim or any vim specific plugins in years)

1 Like