Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
8770afe
Add LspPeekDefinition
thomasfaingnaert Jun 25, 2019
5264784
Add documentation
thomasfaingnaert Jun 25, 2019
e19f815
Add lsp-peek-definition mapping to documentation
thomasfaingnaert Jun 25, 2019
6ea1402
Add link to Vim preview-window help
thomasfaingnaert Jun 25, 2019
a765c96
Merge branch 'master' into peek-definition
thomasfaingnaert Jun 26, 2019
9461c92
Rewrite LspPeekDefinition using preview window
thomasfaingnaert Jun 26, 2019
3f7e0e3
Implement peek for Vim popup window
thomasfaingnaert Jun 26, 2019
2639a81
Make LspPeekDefinition work in Neovim
thomasfaingnaert Jun 26, 2019
ed325ef
Support align in Neovim
thomasfaingnaert Jun 26, 2019
0c836a0
Fix linter errors
thomasfaingnaert Jun 26, 2019
e68dd90
Extract duplicate code to s:align_preview function
thomasfaingnaert Jun 26, 2019
5a5beeb
Merge branch 'master' into peek-definition
thomasfaingnaert Jun 27, 2019
c92e9c7
Merge setlocal settings in one line
thomasfaingnaert Jun 27, 2019
d4ad588
Remove suppress_close
thomasfaingnaert Jun 27, 2019
a8805a8
Clean up cursor movement for preview window
thomasfaingnaert Jun 27, 2019
f83140a
Move Neovim cursor code to separate function
thomasfaingnaert Jun 27, 2019
a9e7e60
Allow customising peek alignment
thomasfaingnaert Jun 27, 2019
4f4fd6e
Move Vim alignment code to separate function
thomasfaingnaert Jun 27, 2019
ccaf0f9
Implement Vim alignment of popup window
thomasfaingnaert Jun 27, 2019
b315c0b
Cleanup
thomasfaingnaert Jun 27, 2019
1eac0cb
Remove extraneous lines
thomasfaingnaert Jun 27, 2019
14c96ef
Move set_cursor logic
thomasfaingnaert Jun 27, 2019
806b5fc
Move scrolloff setting
thomasfaingnaert Jun 27, 2019
e81d0c7
Make function calls a bit more consistent
thomasfaingnaert Jun 27, 2019
e024a42
Vim popup window fixes
thomasfaingnaert Jun 27, 2019
44d5ff7
Remove extraneous call
thomasfaingnaert Jun 27, 2019
ab8ea58
Fix Vim alignment
thomasfaingnaert Jun 27, 2019
86f559c
Remove hardcoded width
thomasfaingnaert Jun 27, 2019
c9ecc55
Add abort to closure function
thomasfaingnaert Jun 27, 2019
1ee290e
Fix artifacts
thomasfaingnaert Jun 27, 2019
fefa218
Fix wrong height if popup above cursor
thomasfaingnaert Jun 30, 2019
5074476
Add remaining Peek commands
thomasfaingnaert Jun 30, 2019
7ed35dc
Merge branch 'master' into peek-definition
thomasfaingnaert Jul 18, 2019
18fcb43
Fix wrong positioning of Vim popup
thomasfaingnaert Jul 19, 2019
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
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,26 @@ For more information, refer to the readme and documentation of the respective pl
| Command | Description|
|--|--|
|`:LspCodeAction`| Gets a list of possible commands that can be applied to a file so it can be fixed (quick fix) |
|`:LspDeclaration`| Go to declaration |
|`:LspDefinition`| Go to definition |
|`:LspDeclaration`| Go to the declaration of the word under the cursor, and open in the current window |
|`:LspDefinition`| Go to the definition of the word under the cursor, and open in the current window |
|`:LspDocumentDiagnostics`| Get current document diagnostics information |
|`:LspDocumentFormat`| Format entire document |
|`:LspDocumentRangeFormat`| Format document selection |
|`:LspDocumentSymbol`| Show document symbols |
|`:LspHover`| Show hover information |
|`:LspImplementation` | Show implementation of interface |
|`:LspImplementation` | Show implementation of interface in the current window |
|`:LspNextError`| jump to next error |
|`:LspNextReference`| jump to next reference to the symbol under cursor |
|`:LspPeekDeclaration`| Go to the declaration of the word under the cursor, but open in preview window |
|`:LspPeekDefinition`| Go to the definition of the word under the cursor, but open in preview window |
|`:LspPeekImplementation`| Go to the implementation of an interface, but open in preview window |
|`:LspPeekTypeDefinition`| Go to the type definition of the word under the cursor, but open in preview window |
|`:LspPreviousError`| jump to previous error |
|`:LspPreviousReference`| jump to previous reference to the symbol under cursor |
|`:LspReferences`| Find references |
|`:LspRename`| Rename symbol |
|`:LspStatus` | Show the status of the language server |
|`:LspTypeDefinition`| Go to type definition |
|`:LspTypeDefinition`| Go to the type definition of the word under the cursor, and open in the current window |
|`:LspWorkspaceSymbol`| Search/Show workspace symbol |

### Diagnostics
Expand Down
34 changes: 21 additions & 13 deletions autoload/lsp/ui/vim.vim
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ function! s:not_supported(what) abort
return lsp#utils#error(a:what.' not supported for '.&filetype)
endfunction

function! lsp#ui#vim#implementation() abort
function! lsp#ui#vim#implementation(in_preview) abort
let l:servers = filter(lsp#get_whitelisted_servers(), 'lsp#capabilities#has_implementation_provider(v:val)')
let s:last_req_id = s:last_req_id + 1
call setqflist([])
Expand All @@ -13,7 +13,7 @@ function! lsp#ui#vim#implementation() abort
call s:not_supported('Retrieving implementation')
return
endif
let l:ctx = { 'counter': len(l:servers), 'list':[], 'last_req_id': s:last_req_id, 'jump_if_one': 1 }
let l:ctx = { 'counter': len(l:servers), 'list':[], 'last_req_id': s:last_req_id, 'jump_if_one': 1, 'in_preview': a:in_preview }
for l:server in l:servers
call lsp#send_request(l:server, {
\ 'method': 'textDocument/implementation',
Expand All @@ -28,7 +28,7 @@ function! lsp#ui#vim#implementation() abort
echo 'Retrieving implementation ...'
endfunction

function! lsp#ui#vim#type_definition() abort
function! lsp#ui#vim#type_definition(in_preview) abort
let l:servers = filter(lsp#get_whitelisted_servers(), 'lsp#capabilities#has_type_definition_provider(v:val)')
let s:last_req_id = s:last_req_id + 1
call setqflist([])
Expand All @@ -37,7 +37,7 @@ function! lsp#ui#vim#type_definition() abort
call s:not_supported('Retrieving type definition')
return
endif
let l:ctx = { 'counter': len(l:servers), 'list':[], 'last_req_id': s:last_req_id, 'jump_if_one': 1 }
let l:ctx = { 'counter': len(l:servers), 'list':[], 'last_req_id': s:last_req_id, 'jump_if_one': 1, 'in_preview': a:in_preview }
for l:server in l:servers
call lsp#send_request(l:server, {
\ 'method': 'textDocument/typeDefinition',
Expand All @@ -52,7 +52,7 @@ function! lsp#ui#vim#type_definition() abort
echo 'Retrieving type definition ...'
endfunction

function! lsp#ui#vim#declaration() abort
function! lsp#ui#vim#declaration(in_preview) abort
let l:servers = filter(lsp#get_whitelisted_servers(), 'lsp#capabilities#has_declaration_provider(v:val)')
let s:last_req_id = s:last_req_id + 1
call setqflist([])
Expand All @@ -62,7 +62,7 @@ function! lsp#ui#vim#declaration() abort
return
endif

let l:ctx = { 'counter': len(l:servers), 'list':[], 'last_req_id': s:last_req_id, 'jump_if_one': 1 }
let l:ctx = { 'counter': len(l:servers), 'list':[], 'last_req_id': s:last_req_id, 'jump_if_one': 1, 'in_preview': a:in_preview }
for l:server in l:servers
call lsp#send_request(l:server, {
\ 'method': 'textDocument/declaration',
Expand All @@ -77,7 +77,7 @@ function! lsp#ui#vim#declaration() abort
echo 'Retrieving declaration ...'
endfunction

function! lsp#ui#vim#definition() abort
function! lsp#ui#vim#definition(in_preview) abort
let l:servers = filter(lsp#get_whitelisted_servers(), 'lsp#capabilities#has_definition_provider(v:val)')
let s:last_req_id = s:last_req_id + 1
call setqflist([])
Expand All @@ -87,7 +87,7 @@ function! lsp#ui#vim#definition() abort
return
endif

let l:ctx = { 'counter': len(l:servers), 'list':[], 'last_req_id': s:last_req_id, 'jump_if_one': 1 }
let l:ctx = { 'counter': len(l:servers), 'list':[], 'last_req_id': s:last_req_id, 'jump_if_one': 1, 'in_preview': a:in_preview }
for l:server in l:servers
call lsp#send_request(l:server, {
\ 'method': 'textDocument/definition',
Expand All @@ -108,7 +108,7 @@ function! lsp#ui#vim#references() abort

call setqflist([])

let l:ctx = { 'counter': len(l:servers), 'list':[], 'last_req_id': s:last_req_id, 'jump_if_one': 0 }
let l:ctx = { 'counter': len(l:servers), 'list':[], 'last_req_id': s:last_req_id, 'jump_if_one': 0, 'in_preview': 0 }
if len(l:servers) == 0
call s:not_supported('Retrieving references')
return
Expand Down Expand Up @@ -418,7 +418,7 @@ function! s:handle_symbol(server, last_req_id, type, data) abort
endif
endfunction

function! s:handle_location(ctx, server, type, data) abort "ctx = {counter, list, jump_if_one, last_req_id}
function! s:handle_location(ctx, server, type, data) abort "ctx = {counter, list, jump_if_one, last_req_id, in_preview}
if a:ctx['last_req_id'] != s:last_req_id
return
endif
Expand All @@ -443,9 +443,10 @@ function! s:handle_location(ctx, server, type, data) abort "ctx = {counter, list
call settagstack(winid, {'curidx': len(gettagstack(winid)['items']) + 1})
endif

if len(a:ctx['list']) == 1 && a:ctx['jump_if_one']
let l:loc = a:ctx['list'][0]

if len(a:ctx['list']) == 1 && a:ctx['jump_if_one'] && !a:ctx['in_preview']
normal! m'
let l:loc = a:ctx['list'][0]
let l:buffer = bufnr(l:loc['filename'])
if &modified && !&hidden
let l:cmd = l:buffer !=# -1 ? 'sb ' . l:buffer : 'split ' . fnameescape(l:loc['filename'])
Expand All @@ -455,10 +456,17 @@ function! s:handle_location(ctx, server, type, data) abort "ctx = {counter, list
execute l:cmd . ' | call cursor('.l:loc['lnum'].','.l:loc['col'].')'
echo 'Retrieved ' . a:type
redraw
else
elseif !a:ctx['in_preview']
call setqflist(a:ctx['list'])
echo 'Retrieved ' . a:type
botright copen
else
let l:lines = readfile(fnameescape(l:loc['filename']))
call lsp#ui#vim#output#preview(l:lines, {
\ 'statusline': ' LSP Peek ' . a:type,
\ 'cursor': { 'line': l:loc['lnum'], 'col': l:loc['col'], 'align': g:lsp_peek_alignment },
\ 'filetype': &filetype
\ })
endif
endif
endif
Expand Down
2 changes: 1 addition & 1 deletion autoload/lsp/ui/vim/hover.vim
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function! s:handle_hover(server, data) abort
endif

if !empty(a:data['response']['result']) && !empty(a:data['response']['result']['contents'])
call lsp#ui#vim#output#preview(a:data['response']['result']['contents'])
call lsp#ui#vim#output#preview(a:data['response']['result']['contents'], {'statusline': ' LSP Hover'})
return
else
call lsp#utils#error('No hover information found')
Expand Down
111 changes: 107 additions & 4 deletions autoload/lsp/ui/vim/output.vim
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,91 @@ function! s:open_preview(data) abort
return l:winid
endfunction

function! lsp#ui#vim#output#preview(data) abort
function! s:set_cursor(current_window_id, options) abort
if !has_key(a:options, 'cursor')
return
endif

if s:supports_floating && g:lsp_preview_float && has('nvim')
" Neovim floats
" Go back to the preview window to set the cursor
call win_gotoid(s:winid)
let l:old_scrolloff = &scrolloff
let &scrolloff = 0

call nvim_win_set_cursor(s:winid, [a:options['cursor']['line'], a:options['cursor']['col']])
call s:align_preview(a:options)

" Finally, go back to the original window
call win_gotoid(a:current_window_id)

let &scrolloff = l:old_scrolloff
elseif s:supports_floating && g:lsp_preview_float && !has('nvim')
" Vim popups
function! AlignVimPopup(timer) closure abort
call s:align_preview(a:options)
endfunction
call timer_start(0, function('AlignVimPopup'))
else
" Preview
" Don't use 'scrolloff', it might mess up the cursor's position
let &l:scrolloff = 0
call cursor(a:options['cursor']['line'], a:options['cursor']['col'])
call s:align_preview(a:options)
endif
endfunction

function! s:align_preview(options) abort
if !has_key(a:options, 'cursor') ||
\ !has_key(a:options['cursor'], 'align')
return
endif

let l:align = a:options['cursor']['align']

if s:supports_floating && g:lsp_preview_float && !has('nvim')
" Vim popups
let l:pos = popup_getpos(s:winid)
let l:below = winline() < winheight(0) / 2
if l:below
let l:height = min([l:pos['core_height'], winheight(0) - winline() - 2])
else
let l:height = min([l:pos['core_height'], winline() - 3])
endif
let l:width = l:pos['core_width']

let l:options = {
\ 'minwidth': l:width,
\ 'maxwidth': l:width,
\ 'minheight': l:height,
\ 'maxheight': l:height,
\ 'pos': l:below ? 'topleft' : 'botleft',
\ 'line': l:below ? 'cursor+1' : 'cursor-1'
\ }

if l:align ==? 'top'
let l:options['firstline'] = a:options['cursor']['line']
elseif l:align ==? 'center'
let l:options['firstline'] = a:options['cursor']['line'] - (l:height - 1) / 2
elseif l:align ==? 'bottom'
let l:options['firstline'] = a:options['cursor']['line'] - l:height + 1
endif

call popup_setoptions(s:winid, l:options)
redraw!
else
" Preview and Neovim floats
if l:align ==? 'top'
normal! zt
elseif l:align ==? 'center'
normal! zz
elseif l:align ==? 'bottom'
normal! zb
endif
endif
endfunction

function! lsp#ui#vim#output#preview(data, options) abort
if s:winid && type(s:preview_data) == type(a:data)
\ && s:preview_data == a:data
\ && type(g:lsp_preview_doubletap) == 3
Expand All @@ -209,21 +293,40 @@ function! lsp#ui#vim#output#preview(data) abort
let s:preview_data = a:data
let l:lines = []
let l:ft = s:append(a:data, l:lines)

if has_key(a:options, 'filetype')
let l:ft = a:options['filetype']
endif

call s:setcontent(l:lines, l:ft)

" Get size information while still having the buffer active
let l:bufferlines = line('$')
let l:maxwidth = max(map(getline(1, '$'), 'strdisplaywidth(v:val)'))

" restore focus to the previous window
if !s:supports_floating || !g:lsp_preview_float
" Set statusline
if has_key(a:options, 'statusline')
let &l:statusline = a:options['statusline']
endif

call s:set_cursor(l:current_window_id, a:options)
endif

" Go to the previous window to adjust positioning
call win_gotoid(l:current_window_id)

echo ''

if s:supports_floating && s:winid && g:lsp_preview_float
if has('nvim')
" Neovim floats
call s:adjust_float_placement(l:bufferlines, l:maxwidth)
call s:set_cursor(l:current_window_id, a:options)
call s:add_float_closing_hooks()
else
" Vim popups
call s:set_cursor(l:current_window_id, a:options)
endif
doautocmd User lsp_float_opened
endif
Expand All @@ -243,7 +346,7 @@ function! s:append(data, lines) abort

return 'markdown'
elseif type(a:data) == type('')
call extend(a:lines, split(a:data, "\n"))
call extend(a:lines, split(a:data, "\n", v:true))

return 'markdown'
elseif type(a:data) == type({}) && has_key(a:data, 'language')
Expand All @@ -253,7 +356,7 @@ function! s:append(data, lines) abort

return 'markdown'
elseif type(a:data) == type({}) && has_key(a:data, 'kind')
call extend(a:lines, split(a:data.value, '\n'))
call extend(a:lines, split(a:data.value, '\n', v:true))

return a:data.kind ==? 'plaintext' ? 'text' : a:data.kind
endif
Expand Down
Loading