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

Vim8 popup scroll #1025

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions autoload/lsp/ui/vim/output.vim
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,69 @@ function! lsp#ui#vim#output#adjust_float_placement(bufferlines, maxwidth) abort
endif
endfunction


function! lsp#ui#vim#output#popup_scroll(val) abort
yongrenjie marked this conversation as resolved.
Show resolved Hide resolved
" Scroll a popup window by a:val lines downwards (or upwards if a:val is
" negative. The command :LspPopupScroll(val) calls this function. For
" example,
" lsp#ui#vim#output#popup_scroll(1)
" and
" lsp#ui#vim#output#popup_scroll(-1)
" scroll the popup window one line down and one line up respectively.

" Return early if there is no popup, or if the popup is already focused
if !s:winid || win_getid() ==# s:winid
return
endif

if s:use_vim_popup
" Vim 8 popup window
let l:pos = popup_getpos(s:winid)
if !l:pos.scrollbar | return | endif

let l:new_firstline = l:pos.firstline + a:val
let l:new_lastline = l:pos.lastline + a:val
let l:bottom_line = str2nr(trim(win_execute(s:winid, "echo line ('$')")))

if l:new_firstline < 1 " scrolling too far up
let l:new_firstline = 1
elseif l:new_lastline > l:bottom_line " scrolling too far down
let l:new_firstline = l:new_firstline + l:bottom_line - l:new_lastline
endif

call popup_setoptions(s:winid, {
\ 'firstline': l:new_firstline,
\ 'minwidth': l:pos.core_width,
\ 'maxwidth': l:pos.core_width + 1,
\ }) " Constrain min and maxwidth so that they don't change when scrolling

elseif s:use_nvim_float
" Nvim doesn't (yet) have the win_execute() function (cf.
" neovim/neovim#13664) or a way to directly move the lines like above,
" so the easiest option seems to be to temporarily give focus to the
" float window.
let l:old_winid = win_getid()
let l:value = a:val
let l:winheight = nvim_win_get_height(s:winid)
call win_gotoid(s:winid)
if l:value > 0 " extra check to make sure we don't move too far down
while l:value > 0 && line('w0') + l:winheight - 1 <= line('$')
execute "normal! \<C-e>"
let l:value -= 1
endwhile
elseif l:value < 0 " <C-y> can't move too far up, so no need for other checks
while l:value < 0
execute "normal! \<C-y>"
let l:value += 1
endwhile
endif
" need noautocmd here in order to prevent the popup window from being
" closed when losing focus if g:lsp_preview_autoclose is set to 1.
noautocmd call win_gotoid(l:old_winid)
endif

endfunction

function! s:add_float_closing_hooks() abort
if g:lsp_preview_autoclose
augroup lsp_float_preview_close
Expand Down
15 changes: 14 additions & 1 deletion doc/vim-lsp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ CONTENTS *vim-lsp-contents*
LspPeekDefinition |:LspPeekDefinition|
LspPeekImplementation |:LspPeekImplementation|
LspPeekTypeDefinition |:LspPeekTypeDefinition|
LspPopupScroll |:LspPopupScroll|
LspPreviousDiagnostic |:LspPreviousDiagnostic|
LspPreviousError |:LspPreviousError|
LspPreviousReference |:LspPreviousReference|
Expand Down Expand Up @@ -1450,7 +1451,7 @@ LspNextReference *:LspNextReference*

Jump to the next reference of the symbol under cursor.

LspNextWarning [-wrap=0] :LspNextWarning*
LspNextWarning [-wrap=0] *:LspNextWarning*

Jump to Next warning diagnostics
With '-wrap=0', stop wrapping around the end of file.
Expand Down Expand Up @@ -1554,6 +1555,18 @@ LspStopServer *:LspStopServer*

Stop all active servers.

LspPopupScroll {num} *:LspPopupScroll*

Scroll the popup window by {num} lines (positive to scroll
down, negative to scroll up). For example, to remap <C-j>
and <C-k> to scroll a popup window down and up respectively: >

nnoremap <buffer><silent><expr><C-j>
\ lsp#ui#vim#output#getpreviewwinid() ? ":LspPopupScroll 1<CR>" : "\<C-j>"
nnoremap <buffer><silent><expr><C-k>
\ lsp#ui#vim#output#getpreviewwinid() ? ":LspPopupScroll -1<CR>" : "\<C-k>"


==============================================================================
Autocommands *vim-lsp-autocommands*

Expand Down
1 change: 1 addition & 0 deletions plugin/lsp.vim
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ command! -nargs=? -complete=customlist,lsp#utils#empty_complete LspSignatureHelp
command! LspDocumentFold call lsp#ui#vim#folding#fold(0)
command! LspDocumentFoldSync call lsp#ui#vim#folding#fold(1)
command! -nargs=? LspSemanticScopes call lsp#ui#vim#semantic#display_scope_tree(<args>)
command! -nargs=1 LspPopupScroll call lsp#ui#vim#output#popup_scroll(<f-args>)

nnoremap <plug>(lsp-code-action) :<c-u>call lsp#ui#vim#code_action()<cr>
nnoremap <plug>(lsp-code-lens) :<c-u>call lsp#ui#vim#code_lens()<cr>
Expand Down