Symbol type on hover?

Flipping the discussion from Symbol type via keyboard? around:

Is there a good way to get the type on mouse hover in GUI Vim? Using plain Merlin / using some LSP plugin?

I’m using the plugin that comes with Merlin, the binding is <Leader>t. (<Leader> is \ by default)

My config related to Merlin: (.vim/after/ftplugin/ocaml.vim)

let g:merlin_split_method = "never"

" C-c: Clear merlin highlights
autocmd User ClearHighlight call merlin#StopHighlight()

if !exists('*MerlinLocateMli')
  function! MerlinLocateMli()
    let old_pref = g:merlin_locate_preference
    let g:merlin_locate_preference = 'mli'
    call merlin#Locate()
    let g:merlin_locate_preference = old_pref
  endfunction
endif

nmap <buffer> gD :call MerlinLocateMli()<return>

nmap <buffer> <Leader>e :MerlinErrorCheck<return>

gD for jumping to a declaration (.mli instead of .ml; there’s gd for jumping to a definition), \e to check for errors.

I would definitely try LSP instead as the plugin has many quircks (slow, big error messages if merlin isnt installed) and has inflexible and specific bindings. However, the plugin has more feature than the LSP (eg. deconstruct)

Deconstruct and module (de)qualification have been added to ocamllsp

1 Like

I’ve been using t for type info from the keyboard, too. Direct Merlin plugin. I was looking specifically for type information displayed as a balloon window on mouse-hover. This would allow me to quickly get types as I read code without having to navigate the cursor to the value I’m looking at at this instant (as opposed to writing, where the keyboard shortcut is fine).

Would mouse over work e.g. with ALE and ocaml LSP?

Displaying info in a popup is something that a LSP client might do but I’ve never tried so I don’t know for sure, sorry. Vim has popup since a few years only so they might be rare.

Ok, I found a way that works somewhat well on cursory testing.

function! MerlinTypeString()
	MerlinPy vim.command("let l:type = " + merlin.vim_type_enclosing())
	return type['type']
endfunction

augroup MerlinBalloon
	au!
	if has('balloon_multiline')
		au FileType ocaml setlocal balloonexpr=MerlinTypeString()
		au FileType ocaml nnoremap <leader>be :set ballooneval!<cr>
	endif
augroup END

When you move the mouse and then stop movement, it will show the type at the cursor. So when your mouse pointer stopped somewhere else, the result may not be what you thought. If you click once, the cursor will be at the mouse pointer so then everything is as expected.

Looking into merlin.py, I did not see a quick way to make it follow the mouse pointer without displacing the cursor. Maybe someone else can?

The key shortcut is for convenience to toggle hover actions.

I’m not sure I understand that sentence.
If you’re able to get a your mouse pointer position (in a “line, column” form) then it should be easy to ask merlin for a type at that position (rather than at the cursor’s position).
Can you show me how you do the first part? Then I can help with the second one.

Well, all I did so far was what I pasted above. In merlin.py, there does not seem to be a function type_pos that does “type at position (l, c)”; instead there is a function “type at cursor”; it’s not split up like that.
Vim provides a way to tell the mouse position to the balloonexpr, so indeed the only thing that is missing is a function type_pos. If I’m not mistaken this requires patching merlin.vim which I refrained from.

from the vim docs:

						     *'balloonexpr'* *'bexpr'*
'balloonexpr' 'bexpr'	string	(default "")
			global or local to buffer |global-local|
			{only available when compiled with the |+balloon_eval|
			feature}
	Expression for text to show in evaluation balloon.  It is only used
	when 'ballooneval' or 'balloonevalterm' is on.  These variables can be
	used:

	v:beval_bufnr	number of the buffer in which balloon is going to show
	v:beval_winnr	number of the window
	v:beval_winid	ID of the window
	v:beval_lnum	line number
	v:beval_col	column number (byte index)
	v:beval_text	word under or after the mouse pointer

Don’t!
We’d welcome a PR doing that split :slight_smile:

1 Like

OK! I came up with something.