parsonsmatt / intero-neovim

A neovim plugin for Intero, forked from ghcmod-vim
218 stars 28 forks source link

Possible to get output of :InteroType and :InteroInfo as variable? #118

Closed Tehnix closed 6 years ago

Tehnix commented 6 years ago

I'm currently trying to capture the echo output of :InteroType and :InteroInfo so I could manipulate it a bit and show it when the cursor is being held on the same word for a short while, but had little luck.

Would it be possible to have both functions have an alternate version that simply returns the output instead of echo'ing it?

parsonsmatt commented 6 years ago

The main problem with that is that the output is captured asynchronously, so there's no easy way to say "please wait for this to return."

There are a number of things that would be Easy if we had something like an MVar, but I don't know of a good way to replicate that technique in Vimscript.

This feels gross, but you might be able to do:

let s:type_output = null
intero#repl#call(...) " where the function writes to `s:type_output`
while empty(s:type_output)
  sleep(10)
endwhile
owickstrom commented 6 years ago

@Tehnix Could your cursor tooltip function itself be asynchronous and registered to receive the result of :InteroType when it's ready?

Tehnix commented 6 years ago

Async would be fine :) One other option might be being able to pass a funcref callback à la,

function! s:my_handler()
  " ...
endfunction

intero#repl#call(..., Function('s:my_handler'))
parsonsmatt commented 6 years ago

You can do:

call intero#process#add_handler(function('s:my_handler'))
call intero#repl#send("command to execute in repl")

It might be a good API addition to have eval_with(str, funcref) to wrap that idea.

Tehnix commented 6 years ago

Perfect!

For the curious, this is what I'm currently toying around with. I very much liked how Spacemacs would put the type in the bottom after a short time stopping on an identifier, so thought I'd make something similar for vim,

function! g:HaskellTypeHandler(lines)
  if len(a:lines) > 0
    let l:message = a:lines[0]
    echo l:message
  endif
endfunction

let s: wordUnderCursor = ''
function! s:displayInfoOnHover()
  let l:newWordUnderCursor = expand("<cword>")
  if s: wordUnderCursor !=# l: newWordUnderCursor
    let l:ident = intero#util#get_haskell_identifier()
    call intero#process#add_handler(function('g: HaskellTypeHandler'))
    call intero#repl#send(':type ' . l:ident)
    let s: wordUnderCursor = l: newWordUnderCursor
  endif
endfunction

" Make the update time shorter, so the info will trigger faster.
set updatetime=1000
" Get type information when you hold the cursor still for some time.
augroup haskellTypeInfoOnHover
  au!
  au CursorHold *.hs call s: displayInfoOnHover()
augroup END

Currently just an echo, but whenever https://github.com/neovim/neovim/pull/6619 gets merged I plan on moving to a floating window or something like that.

We can close this now I think :)

parsonsmatt commented 6 years ago

That is awesome! :smile: Want to upstream it?

Tehnix commented 6 years ago

Sure! It should probably be configurable though, since it will overwrite the whatever echo message is currently there (for now). Perhaps something like let g:intero_show_type_on_hover = 1?

Semi-related: Do you know if there's a way to get syntax highlighting in echo messages? For a short moment I thought I was lucky with echohl, but that doesn't seem to do the trick :/ Perhaps it's feasible to quickly parse the type string and manually insert highlights, shouldn't be that hard 🤔

parsonsmatt commented 6 years ago

I have no idea. That does not sound easy to me though :\

Tehnix commented 6 years ago

Hmm, I'll hold off with that for now. I'll make a PR either today or tomorrow when I get time again for the previous stuff though, then we can hash the details out there :)

jez commented 6 years ago

I'll second adding an explicit option for this. If I'm looking at compile output or some other stuff I had in the REPL, I don't want intero to come along and start sending commands I didn't ask for to the REPL.