Skip to content

Commit 80f3c87

Browse files
committed
add keyboard scrolling and dismiss to floating preview popups
vim floating preview windows had no keyboard scrolling support so long hover or detail content was inaccessible without a mouse, adds a popup filter with ctrl-n/ctrl-p for line scroll, ctrl-d/ctrl-u for page scroll, and escape to dismiss
1 parent ba8b9cb commit 80f3c87

3 files changed

Lines changed: 92 additions & 0 deletions

File tree

autoload/ale/floating_preview.vim

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,32 @@ function! s:NvimCreate(options) abort
144144
let w:preview = {'id': l:winid, 'buffer': l:buffer}
145145
endfunction
146146

147+
function! ale#floating_preview#PopupFilter(winid, key) abort
148+
if a:key is# "\<C-n>" || a:key is# "\<ScrollWheelDown>"
149+
call win_execute(a:winid, "normal! \<C-e>")
150+
151+
return 1
152+
elseif a:key is# "\<C-p>" || a:key is# "\<ScrollWheelUp>"
153+
call win_execute(a:winid, "normal! \<C-y>")
154+
155+
return 1
156+
elseif a:key is# "\<C-d>"
157+
call win_execute(a:winid, "normal! \<C-d>")
158+
159+
return 1
160+
elseif a:key is# "\<C-u>"
161+
call win_execute(a:winid, "normal! \<C-u>")
162+
163+
return 1
164+
elseif a:key is# "\<Esc>"
165+
call popup_close(a:winid)
166+
167+
return 1
168+
endif
169+
170+
return 0
171+
endfunction
172+
147173
function! s:VimCreate(options) abort
148174
" default options
149175
let l:popup_opts = extend({
@@ -164,6 +190,9 @@ function! s:VimCreate(options) abort
164190
\ get(g:ale_floating_window_border, 4, '+'),
165191
\ get(g:ale_floating_window_border, 5, '+'),
166192
\ ],
193+
\ 'scrollbar': 1,
194+
\ 'filter': function('ale#floating_preview#PopupFilter'),
195+
\ 'filtermode': 'n',
167196
\ 'moved': 'any',
168197
\ }, s:GetPopupOpts())
169198

doc/ale.txt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,36 @@ or |g:ale_floating_preview| is set to `true` or `1`, the hover information
835835
will show in a floating window. The borders of the floating preview window can
836836
be customized by setting |g:ale_floating_window_border|.
837837

838+
For Vim with |popupwin|, floating preview windows can be scrolled with the
839+
keyboard and dismissed with |<Esc>|. The following keys are supported:
840+
841+
|<C-n>| - Scroll down one line
842+
|<C-p>| - Scroll up one line
843+
|<C-d>| - Scroll down half a page
844+
|<C-u>| - Scroll up half a page
845+
|<Esc>| - Close the popup
846+
847+
Mouse scroll wheel also works when |'mouse'| is enabled. The filter can be
848+
overridden via |g:ale_floating_preview_popup_opts| by providing a custom
849+
`filter` key. For example, to scroll with `j` and `k` instead: >
850+
851+
function! MyPopupFilter(winid, key) abort
852+
if a:key is# 'j'
853+
call win_execute(a:winid, "normal! \<C-e>")
854+
return 1
855+
elseif a:key is# 'k'
856+
call win_execute(a:winid, "normal! \<C-y>")
857+
return 1
858+
elseif a:key is# "\<Esc>"
859+
call popup_close(a:winid)
860+
return 1
861+
endif
862+
return 0
863+
endfunction
864+
865+
let g:ale_floating_preview_popup_opts = {'filter': function('MyPopupFilter')}
866+
<
867+
838868
For Vim 8.1+ terminals, mouse hovering is disabled by default. Enabling
839869
|balloonexpr| commands in terminals can cause scrolling issues in terminals,
840870
so ALE will not attempt to show balloons unless |g:ale_set_balloons| is set to

test/test_floating_preview.vader

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,36 @@ Execute(Floating preview is not used with ALEDetail by default):
9191
ALEDetail
9292

9393
AssertEqual 0, g:floating_preview_show_called
94+
95+
Execute(PopupFilter should handle scroll down keys):
96+
runtime autoload/ale/floating_preview.vim
97+
98+
AssertEqual 1, ale#floating_preview#PopupFilter(0, "\<C-n>")
99+
AssertEqual 1, ale#floating_preview#PopupFilter(0, "\<ScrollWheelDown>")
100+
101+
Execute(PopupFilter should handle scroll up keys):
102+
runtime autoload/ale/floating_preview.vim
103+
104+
AssertEqual 1, ale#floating_preview#PopupFilter(0, "\<C-p>")
105+
AssertEqual 1, ale#floating_preview#PopupFilter(0, "\<ScrollWheelUp>")
106+
107+
Execute(PopupFilter should handle page scroll keys):
108+
runtime autoload/ale/floating_preview.vim
109+
110+
AssertEqual 1, ale#floating_preview#PopupFilter(0, "\<C-d>")
111+
AssertEqual 1, ale#floating_preview#PopupFilter(0, "\<C-u>")
112+
113+
Execute(PopupFilter should handle Escape to close):
114+
runtime autoload/ale/floating_preview.vim
115+
116+
if has('popupwin')
117+
let l:popup_id = popup_create(['test'], {})
118+
AssertEqual 1, ale#floating_preview#PopupFilter(l:popup_id, "\<Esc>")
119+
endif
120+
121+
Execute(PopupFilter should pass through unhandled keys):
122+
runtime autoload/ale/floating_preview.vim
123+
124+
AssertEqual 0, ale#floating_preview#PopupFilter(0, 'j')
125+
AssertEqual 0, ale#floating_preview#PopupFilter(0, 'k')
126+
AssertEqual 0, ale#floating_preview#PopupFilter(0, 'q')

0 commit comments

Comments
 (0)