Skip to content

Instantly share code, notes, and snippets.

@Konfekt
Created April 20, 2024 06:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Konfekt/b1f53d4aa497b123759c79e8bcaf6004 to your computer and use it in GitHub Desktop.
Save Konfekt/b1f53d4aa497b123759c79e8bcaf6004 to your computer and use it in GitHub Desktop.
use arrow keys or Ctrl-J/K to scroll in Vim's popup window
" Use arrow keys or Ctrl-J/K to scroll in popup window.
" Also useful for terminals that maps the mouse wheel scrolls to arrow keys
" For example Urxvt with its Vtwheel extension
" From https://fortime.ws/blog/2020/03/14/20200312-01/
function! s:IsScrollPopup()
let winids = popup_list()
if empty(winids) | return {} | endif
let winid = winids[0]
" if the popup window is hidden, then bypass the keystrokes
if !popup_getpos(winid).visible | return {} | endif
return winid
endfunction
function! ScrollPopup(stepsize, key)
let winid = s:IsScrollPopup()
if empty(winid) | return a:key | endif
let buf_lastline = str2nr(trim(win_execute(winid, "echo line('$')")))
" if the popup window text is wrapped, then use minimal scroll stepsize
let bufwidth = max(map(range(1, buf_lastline), 'len(getline(v:val))'))
let stepsize = winwidth(winid) >= bufwidth ? a:stepsize :
\ a:stepsize > 0 ? 1 : -1
let pp = popup_getpos(winid)
" line screen line of the popup, one-based
" width width of the whole popup in screen cells
" height height of the whole popup in screen cells
" core_col screen column of the text box
" core_line screen line of the text box
" core_width width of the text box in screen cells
" core_height height of the text box in screen cells
" firstline line of the buffer at top
" lastline line of the buffer at the bottom
let firstline = pp.firstline + stepsize
if firstline < 1
let firstline = 1
elseif pp.lastline + stepsize > buf_lastline
let firstline = buf_lastline + pp.firstline - pp.lastline
endif
" if a scrollbar is shown, then the height changes
call popup_setoptions(winid, {'firstline': firstline,
\ 'scrollbar': 0, 'fixed': 1, 'flip': 0,
\ 'resize': 0, 'mousemoved': [0, 0, 0], 'cursorline': 0})
return ''
endfunction
inoremap <expr> <down> ScrollPopup( 3, '<down>')
inoremap <expr> <up> ScrollPopup(-3, '<up>')
nnoremap <expr> <down> ScrollPopup( 3, '<down>')
nnoremap <expr> <up> ScrollPopup(-3, '<up>')
nnoremap <expr> <c-j> ScrollPopup( 3, '<c-j>')
nnoremap <expr> <c-k> ScrollPopup(-3, '<c-k>')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment