Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Range hover support #836

Closed
fannheyward opened this issue Aug 9, 2021 · 8 comments · Fixed by #839
Closed

Range hover support #836

fannheyward opened this issue Aug 9, 2021 · 8 comments · Fixed by #839

Comments

@fannheyward
Copy link
Owner

the problem is I did find a better way to make Range hover work with nnoremap K. Do you have any ideas?

You're using getSelectedRange while expecting Vim to be in visual mode, however :<C-U> kind of mappings (e.g. xmap <Plug>(coc-codeaction-selected)) exit visual mode before executing the range and therefore that check will not pass.

While you could use <cmd> mappings to avoid exiting visual mode, exiting is needed to get the visual mode range with '< and '> like here (as far as I'm aware it's not possible to do that while staying in visual mode, you have to exit it first for those marks' positions to be updated).

So, in short, the solution is to make the mapping work like xmap <Plug>(coc-codeaction-selected) where you'll detect visualmode() when the mapping is triggered, not after. Here's the doCodeAction code for reference and you'll see that it fetches the visual range using the marks' positions as mentioned.

Originally posted by @resolritter in #256 (comment)

@fannheyward
Copy link
Owner Author

@resolritter

the problem is I did find a better way

Sorry I made a mistake here, what I said is didn't find a better way.

rust-analyzer extends the hover request, accepts a position or range and returns document. So the range is passed in coc's doHover action.

We have this mapping now:

" Use K to show documentation in preview window.
nnoremap <silent> K :call <SID>show_documentation()<CR>

function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  elseif (coc#rpc#ready())
    call CocActionAsync('doHover')
  else
    execute '!' . &keywordprg . " " . expand('<cword>')
  endif
endfunction

How do we use Range hover alone with basic hover action ?

@resolritter
Copy link

resolritter commented Aug 9, 2021

First of all, to me a range hover only makes sense either in visual mode (the range is the visual area) or using text objects (the range is the area of the text object). In this post I'll be talking only about the visual mode case.

It would work like xmap <Plug>(coc-codeaction-selected) and that's the implementation reference you would follow. If you want to use K: vnoremap <silent> K :<C-u>call CocActionAsync('hoverRange', visualmode())<CR>

<Plug(coc-codeaction-selected) is defined here: link. cocActionAsync will forward the visualmode() argument from the mapping to request_async and that is how we get the mode parameter in doCodeAction. Note that visual mode is received as a function parameter instead of being detected inside of the Node.js code as you're doing in here; it should be that way because using <C-U> mappings will exit visual mode and update the '< and '> positions, therefore by the time you are doing that if (mode) it has already exited visual mode and the condition will fail.

coc.vim already has a doHover for range but the purpose seems different. I'm not familiar enough with the code to tell if you would be able to customize it.

@fannheyward
Copy link
Owner Author

coc.vim already has a doHover for range

This range is used for highlight.

I got your point of visualmode problem, calls visualmode andgetSelectedRange in coc-rust-analyzer side won't work as expect. The problem is that we need to add action like hoverRange in coc side, then forward the mode parameter and get range in Node.js side to use.

@resolritter
Copy link

If you can't modify the coc.vim source for some reason, then it's possible to use <cmd> mappings (Neovim-only IIRC) which does not exit visual mode and therefore your if (mode) check would pass. In that case, after the check you would execute some Vim command from Node.js to exit visual mode (needed to get the '< and '> positions updated, which is what getSelectedRange retrieves).

@fannheyward
Copy link
Owner Author

If you can't modify the coc.vim source for some reason

Because the range hover is not in LSP now, IDK we can add it to coc yes or not. Maybe later microsoft/language-server-protocol#377 ?

it's possible to use mappings (Neovim-only IIRC) which does not exit visual mode

How to use <cmd> mappings?

@resolritter
Copy link

For <cmd> mappings you'll simply call the function: xmap K <cmd>call CocAction('doHover')<CR>

Instead of calling visualmode() you should call mode()

  fun! EchoMode()
    echo mode() " mode is 'v'
  endfun
  vnoremap <silent> <buffer> K <cmd>call EchoMode()<CR>

It finally clicked for me that the middleware provideHover can be called with 'doHover' (I was not understanding how you were going to trigger it before). If this is still open by the end of this week I can try to implement it and submit a pull request.

@fannheyward
Copy link
Owner Author

It finally clicked for me that the middleware provideHover can be called with 'doHover'

It's my fault, I should point this out in the beginning.

fannheyward added a commit that referenced this issue Aug 11, 2021
@fannheyward
Copy link
Owner Author

@resolritter I've made this PR, can you give it a review?

Also, if you want to test this, you need to patch coc to make it allow float hover in v mode:

diff --git a/src/handler/hover.ts b/src/handler/hover.ts
index 23fcb770..521af161 100644
--- a/src/handler/hover.ts
+++ b/src/handler/hover.ts
@@ -152,7 +152,7 @@ export default class HoverHandler {
     }
     if (target == 'float') {
       let opts: FloatWinConfig = {
-        modes: ['n'],
+        modes: ['n', 'v'],
         maxWidth: this.config.floatMaxWidth,
         maxHeight: this.config.floatMaxHeight,
         autoHide: this.config.autoHide,

fannheyward added a commit that referenced this issue Aug 12, 2021
* feat: range hover

close #836
FYI #256

* fix: range hover
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants