Created
April 20, 2024 06:56
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" 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