4

How can I scroll and hide a floating window in Vim using the coc.nvim plugin?

I added these mappings to my vim.rc file but I still cannot manage it. I would expect if I press ctrl+f once I have a floating window in normal mode then it scrolls or if I press my leader key \ + h then it hides it. What do I do wrong? Thank you!

nmap <silent> <leader>h <Plug>(coc-float-hide)

"coc#util#float_scroll({forward})
"Return expr for scrolling a floating window forward or backward. ex: >

nnoremap <expr><C-f> coc#util#has_float() ? coc#util#float_scroll(1) : "\<C-f>"
nnoremap <expr><C-b> coc#util#has_float() ? coc#util#float_scroll(0) : "\<C-b>"

enter image description here

  • I use vim 8 on Mac. I read this overlay must be a popup and does not have these commands. – Lajos Nov 15 '19 at 12:13
  • 1
    Do note that vim.rc =/= vimrc – D. Ben Knoble Nov 15 '19 at 16:09
5

This is a general way to scroll popup window above or under around cursor, it first get winid by test :h popup_locate() with screen cursor position, then update firstline of the found window.

I didn't add the close map, AFAIK, it's closed automatically when you move your cursor.

Note that the beginning and ending of scroll is affected by :h 'scrolloff'

code update :

  • Removed hardcoded binding.
  • Use :h popup_getpos() to get firstline, simplify scroll logic.
  • Test entire rect instead of 2 corners in find_cursor_popup().

known issue

  • I use <esc> instead of blank as no operation, as blank doesn't trigger popup window redraw. <esc> will also trigger a bell, you may use set belloff+=esc to deal with it.
nnoremap <expr> <c-d> misc#popup#scroll_cursor_popup(1) ? '<esc>' : '<c-d>'
nnoremap <expr> <c-u> misc#popup#scroll_cursor_popup(0) ? '<esc>' : '<c-u>'

function misc#popup#find_cursor_popup(...)
  let radius = get(a:000, 0, 2)
  let srow = screenrow()
  let scol = screencol()

  " it's necessary to test entire rect, as some popup might be quite small
  for r in range(srow - radius, srow + radius)
    for c in range(scol - radius, scol + radius)
      let winid = popup_locate(r, c)
      if winid != 0
        return winid
      endif
    endfor
  endfor

  return 0
endfunction

function misc#popup#scroll_cursor_popup(down)
  let winid = misc#popup#find_cursor_popup()
  if winid == 0
    return 0
  endif

  let pp = popup_getpos(winid)
  call popup_setoptions( winid,
        \ {'firstline' : pp.firstline + ( a:down ? 1 : -1 ) } )

  return 1
endfunction

There is an open issue about this.

| improve this answer | |
  • This works. Only thing I had to update was the fn name s:find_cursor_popupis scroll_popup in the key mappings. Amazing, many thanks! – Lajos Nov 15 '19 at 14:49
  • Forgot to change map, Updated. – dedowsdi Nov 15 '19 at 14:54
  • Thank you again – Lajos Nov 15 '19 at 16:57
  • @Lajos The original script failed to locate popup in certain conditions, it's fixed now. – dedowsdi Nov 16 '19 at 3:01
  • I got 2 errors after adding those lines to .vimrc. E746: Function name does not match script file name: misc#popup#find_cursor_popup and E746: Function name does not match script file name: misc#popup#scroll_cursor_popup – sify Apr 29 at 6:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.