mirror of
https://github.com/prabirshrestha/vim-lsp.git
synced 2025-12-14 20:35:59 +01:00
Create preview window instead of using quickfix list (#78)
* Create preview window instead of using quickfix list This removes from us burden of providing formatting for content as this is now simple as setting proper filetype. * Create custom filetype for preview window This will allow users to provide their own mappings and features in hover window easily. * Add proper statusline for LSP Hover * Guard and undo_ftplugin * Support all LSP hover syntaxes
This commit is contained in:
committed by
Prabir Shrestha
parent
a15344352f
commit
203d682e30
@@ -1,13 +1,23 @@
|
|||||||
let s:last_req_id = 0
|
let s:last_req_id = 0
|
||||||
let s:diagnostics = {} " { uri: { 'server_name': response } }
|
let s:diagnostics = {} " { uri: { 'server_name': response } }
|
||||||
|
|
||||||
|
function! s:error_msg(msg) abort
|
||||||
|
echohl ErrorMsg
|
||||||
|
echom a:msg
|
||||||
|
echohl NONE
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:not_supported(what) abort
|
||||||
|
return s:error_msg(a:what.' not supported for '.&filetype)
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! lsp#ui#vim#definition() abort
|
function! lsp#ui#vim#definition() abort
|
||||||
let l:servers = filter(lsp#get_whitelisted_servers(), 'lsp#capabilities#has_definition_provider(v:val)')
|
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
|
let s:last_req_id = s:last_req_id + 1
|
||||||
call setqflist([])
|
call setqflist([])
|
||||||
|
|
||||||
if len(l:servers) == 0
|
if len(l:servers) == 0
|
||||||
echom 'Retrieving definition not supported for ' . &filetype
|
call s:not_supported('Retrieving definition')
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -34,7 +44,7 @@ function! lsp#ui#vim#references() abort
|
|||||||
|
|
||||||
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 }
|
||||||
if len(l:servers) == 0
|
if len(l:servers) == 0
|
||||||
echom 'Retrieving references not supported for ' . &filetype
|
call s:not_supported('Retrieving references')
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -57,10 +67,8 @@ function! lsp#ui#vim#hover() abort
|
|||||||
let l:servers = filter(lsp#get_whitelisted_servers(), 'lsp#capabilities#has_hover_provider(v:val)')
|
let l:servers = filter(lsp#get_whitelisted_servers(), 'lsp#capabilities#has_hover_provider(v:val)')
|
||||||
let s:last_req_id = s:last_req_id + 1
|
let s:last_req_id = s:last_req_id + 1
|
||||||
|
|
||||||
call setqflist([])
|
|
||||||
|
|
||||||
if len(l:servers) == 0
|
if len(l:servers) == 0
|
||||||
echom 'Retrieving hover not supported for ' . &filetype
|
call s:not_supported('Retrieving hover')
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -83,7 +91,7 @@ function! lsp#ui#vim#rename() abort
|
|||||||
let s:last_req_id = s:last_req_id + 1
|
let s:last_req_id = s:last_req_id + 1
|
||||||
|
|
||||||
if len(l:servers) == 0
|
if len(l:servers) == 0
|
||||||
echom 'Renaming not supported for ' . &filetype
|
call s:not_supported('Renaming')
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -115,7 +123,7 @@ function! lsp#ui#vim#document_format() abort
|
|||||||
let s:last_req_id = s:last_req_id + 1
|
let s:last_req_id = s:last_req_id + 1
|
||||||
|
|
||||||
if len(l:servers) == 0
|
if len(l:servers) == 0
|
||||||
echom 'Document formatting not supported for ' . &filetype
|
call s:not_supported('Document formatting')
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -156,7 +164,7 @@ function! lsp#ui#vim#document_range_format() abort
|
|||||||
let s:last_req_id = s:last_req_id + 1
|
let s:last_req_id = s:last_req_id + 1
|
||||||
|
|
||||||
if len(l:servers) == 0
|
if len(l:servers) == 0
|
||||||
echom 'Document range formatting not supported for ' . &filetype
|
call s:not_supported('Document range formatting')
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -190,7 +198,7 @@ function! lsp#ui#vim#workspace_symbol() abort
|
|||||||
call setqflist([])
|
call setqflist([])
|
||||||
|
|
||||||
if len(l:servers) == 0
|
if len(l:servers) == 0
|
||||||
echom 'Retrieving workspace symbols not supported for ' . &filetype
|
call s:not_supported('Retrieving workspace symbols')
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -216,7 +224,7 @@ function! lsp#ui#vim#document_symbol() abort
|
|||||||
call setqflist([])
|
call setqflist([])
|
||||||
|
|
||||||
if len(l:servers) == 0
|
if len(l:servers) == 0
|
||||||
echom 'Retrieving symbols not supported for ' . &filetype
|
call s:not_supported('Retrieving symbols')
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -247,7 +255,7 @@ endfunction
|
|||||||
function! lsp#ui#vim#document_diagnostics() abort
|
function! lsp#ui#vim#document_diagnostics() abort
|
||||||
let l:uri = lsp#utils#get_buffer_uri()
|
let l:uri = lsp#utils#get_buffer_uri()
|
||||||
if !has_key(s:diagnostics, l:uri)
|
if !has_key(s:diagnostics, l:uri)
|
||||||
echom 'No diagnostics results'
|
call s:error_msg('No diagnostics results')
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -262,7 +270,7 @@ function! lsp#ui#vim#document_diagnostics() abort
|
|||||||
" autocmd FileType qf setlocal wrap
|
" autocmd FileType qf setlocal wrap
|
||||||
|
|
||||||
if empty(l:result)
|
if empty(l:result)
|
||||||
echom 'No diagnostics results found'
|
call s:error_msg('No diagnostics results found')
|
||||||
else
|
else
|
||||||
echom 'Retrieved diagnostics results'
|
echom 'Retrieved diagnostics results'
|
||||||
botright copen
|
botright copen
|
||||||
@@ -275,7 +283,7 @@ function! s:handle_symbol(server, last_req_id, type, data) abort
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if lsp#client#is_error(a:data)
|
if lsp#client#is_error(a:data)
|
||||||
echom 'Failed to retrieve '. a:type . ' for ' . a:server
|
call s:error_msg('Failed to retrieve '. a:type . ' for ' . a:server)
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -284,7 +292,7 @@ function! s:handle_symbol(server, last_req_id, type, data) abort
|
|||||||
call setqflist(l:list)
|
call setqflist(l:list)
|
||||||
|
|
||||||
if empty(l:list)
|
if empty(l:list)
|
||||||
echom 'No ' . a:type .' found'
|
call s:error_msg('No ' . a:type .' found')
|
||||||
else
|
else
|
||||||
echom 'Retrieved ' . a:type
|
echom 'Retrieved ' . a:type
|
||||||
botright copen
|
botright copen
|
||||||
@@ -299,14 +307,14 @@ function! s:handle_location(ctx, server, type, data) abort "ctx = {counter, list
|
|||||||
let a:ctx['counter'] = a:ctx['counter'] - 1
|
let a:ctx['counter'] = a:ctx['counter'] - 1
|
||||||
|
|
||||||
if lsp#client#is_error(a:data)
|
if lsp#client#is_error(a:data)
|
||||||
echom 'Failed to retrieve '. a:type . ' for ' . a:server
|
call s:error_msg('Failed to retrieve '. a:type . ' for ' . a:server)
|
||||||
else
|
else
|
||||||
let a:ctx['list'] = a:ctx['list'] + lsp#ui#vim#utils#locations_to_loc_list(a:data)
|
let a:ctx['list'] = a:ctx['list'] + lsp#ui#vim#utils#locations_to_loc_list(a:data)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if a:ctx['counter'] == 0
|
if a:ctx['counter'] == 0
|
||||||
if empty(a:ctx['list'])
|
if empty(a:ctx['list'])
|
||||||
echom 'No ' . a:type .' found'
|
call s:error_msg('No ' . a:type .' found')
|
||||||
else
|
else
|
||||||
if len(a:ctx['list']) == 1 && a:ctx['jump_if_one']
|
if len(a:ctx['list']) == 1 && a:ctx['jump_if_one']
|
||||||
normal! m'
|
normal! m'
|
||||||
@@ -330,7 +338,7 @@ function! s:handle_hover(server, last_req_id, type, data) abort
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if lsp#client#is_error(a:data)
|
if lsp#client#is_error(a:data)
|
||||||
echom 'Failed to retrieve '. a:type . ' for ' . a:server
|
call s:error_msg('Failed to retrieve '. a:type . ' for ' . a:server)
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -339,34 +347,16 @@ function! s:handle_hover(server, last_req_id, type, data) abort
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if empty(a:data['response']['result'])
|
if empty(a:data['response']['result'])
|
||||||
echom 'No ' . a:type .' found'
|
call s:error_msg('No ' . a:type .' found')
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:contents = a:data['response']['result']['contents']
|
let l:contents = a:data['response']['result']['contents']
|
||||||
|
|
||||||
if type(l:contents) == type('')
|
|
||||||
let l:contents = [{ 'text': s:markdown_to_text(l:contents) }]
|
|
||||||
elseif type(l:contents) == type([])
|
|
||||||
let l:contents = []
|
|
||||||
for l:content in a:data['response']['result']['contents']
|
|
||||||
if type(l:content) == type('')
|
|
||||||
call add(l:contents, { 'text': s:markdown_to_text(l:content) })
|
|
||||||
elseif type(l:content) == type({})
|
|
||||||
call add(l:contents, { 'text': s:markdown_to_text(l:content['value']) })
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
|
|
||||||
call setqflist(l:contents)
|
|
||||||
|
|
||||||
" autocmd FileType qf setlocal wrap
|
|
||||||
|
|
||||||
if empty(l:contents)
|
if empty(l:contents)
|
||||||
echom 'No ' . a:type .' found'
|
call s:error_msg('No ' . a:type .' found')
|
||||||
else
|
else
|
||||||
echom 'Retrieved ' . a:type
|
echo lsp#ui#vim#output#preview(l:contents)
|
||||||
botright copen
|
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -376,7 +366,7 @@ function! s:handle_workspace_edit(server, last_req_id, type, data) abort
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if lsp#client#is_error(a:data)
|
if lsp#client#is_error(a:data)
|
||||||
echom 'Failed to retrieve '. a:type . ' for ' . a:server
|
call s:error_msg('Failed to retrieve '. a:type . ' for ' . a:server)
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -391,7 +381,7 @@ function! s:handle_text_edit(server, last_req_id, type, data) abort
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if lsp#client#is_error(a:data['response'])
|
if lsp#client#is_error(a:data['response'])
|
||||||
echom 'Failed to '. a:type . ' for ' . a:server
|
call s:error_msg('Failed to '. a:type . ' for ' . a:server)
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -440,8 +430,3 @@ function! s:apply_text_edits(uri, text_edits) abort
|
|||||||
set nopaste
|
set nopaste
|
||||||
endtry
|
endtry
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:markdown_to_text(markdown) abort
|
|
||||||
" TODO: convert markdown to normal text
|
|
||||||
return a:markdown
|
|
||||||
endfunction
|
|
||||||
|
|||||||
38
autoload/lsp/ui/vim/output.vim
Normal file
38
autoload/lsp/ui/vim/output.vim
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
function! lsp#ui#vim#output#preview(data) abort
|
||||||
|
" Close any previously opened preview window
|
||||||
|
pclose
|
||||||
|
|
||||||
|
execute &previewheight.'new'
|
||||||
|
|
||||||
|
let l:ft = s:append(a:data)
|
||||||
|
" Delete first empty line
|
||||||
|
0delete
|
||||||
|
|
||||||
|
setlocal readonly nomodifiable
|
||||||
|
|
||||||
|
let &l:filetype = l:ft . '.lsp-hover'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:append(data) abort
|
||||||
|
if type(a:data) == type([])
|
||||||
|
for l:entry in a:data
|
||||||
|
call s:append(entry)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return 'markdown'
|
||||||
|
elseif type(a:data) == type('')
|
||||||
|
put =a:data
|
||||||
|
|
||||||
|
return 'markdown'
|
||||||
|
elseif type(a:data) == type({}) && has_key(a:data, 'language')
|
||||||
|
put ='```'.a:data.language
|
||||||
|
put =a:data.value
|
||||||
|
put ='```'
|
||||||
|
|
||||||
|
return 'markdown'
|
||||||
|
elseif type(a:data) == type({}) && has_key(a:data, 'kind')
|
||||||
|
put =a:data.value
|
||||||
|
|
||||||
|
return a:data.kind == 'plaintext' ? 'text' : a:data.kind
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
@@ -127,7 +127,6 @@ function! s:is_file_uri(uri) abort
|
|||||||
return stridx(a:uri, 'file:///') == 0
|
return stridx(a:uri, 'file:///') == 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
function! s:get_symbol_text_from_kind(kind) abort
|
function! s:get_symbol_text_from_kind(kind) abort
|
||||||
return has_key(s:symbol_kinds, a:kind) ? s:symbol_kinds[a:kind] : 'unknown symbol ' . a:kind
|
return has_key(s:symbol_kinds, a:kind) ? s:symbol_kinds[a:kind] : 'unknown symbol ' . a:kind
|
||||||
endfunction
|
endfunction
|
||||||
|
|||||||
@@ -84,3 +84,7 @@ else
|
|||||||
return [matchstr(a:expr, a:pattern), match(a:expr, a:pattern), matchend(a:expr, a:pattern)]
|
return [matchstr(a:expr, a:pattern), match(a:expr, a:pattern), matchend(a:expr, a:pattern)]
|
||||||
endfunction
|
endfunction
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
function! lsp#utils#empty_complete(...) abort
|
||||||
|
return []
|
||||||
|
endfunction
|
||||||
|
|||||||
14
ftplugin/lsp-hover.vim
Normal file
14
ftplugin/lsp-hover.vim
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
" No usual did_ftplugin header here as we NEED to run this always
|
||||||
|
|
||||||
|
setlocal previewwindow buftype=nofile bufhidden=wipe noswapfile nobuflisted
|
||||||
|
setlocal nocursorline nofoldenable
|
||||||
|
|
||||||
|
if has('syntax')
|
||||||
|
setlocal nospell
|
||||||
|
endif
|
||||||
|
|
||||||
|
let &l:statusline = ' LSP Hover'
|
||||||
|
|
||||||
|
let b:undo_ftplugin = 'setlocal pvw< bt< bh< swf< bl< cul< fen<' .
|
||||||
|
\ (has('syntax') ? ' spell<' : '') .
|
||||||
|
\ ' | unlet! g:markdown_fenced_languages'
|
||||||
@@ -16,7 +16,7 @@ endif
|
|||||||
command! LspDefinition call lsp#ui#vim#definition()
|
command! LspDefinition call lsp#ui#vim#definition()
|
||||||
command! LspDocumentSymbol call lsp#ui#vim#document_symbol()
|
command! LspDocumentSymbol call lsp#ui#vim#document_symbol()
|
||||||
command! LspDocumentDiagnostics call lsp#ui#vim#document_diagnostics()
|
command! LspDocumentDiagnostics call lsp#ui#vim#document_diagnostics()
|
||||||
command! LspHover call lsp#ui#vim#hover()
|
command! -nargs=? -complete=customlist,lsp#utils#empty_complete LspHover call lsp#ui#vim#hover()
|
||||||
command! LspReferences call lsp#ui#vim#references()
|
command! LspReferences call lsp#ui#vim#references()
|
||||||
command! LspRename call lsp#ui#vim#rename()
|
command! LspRename call lsp#ui#vim#rename()
|
||||||
command! LspWorkspaceSymbol call lsp#ui#vim#workspace_symbol()
|
command! LspWorkspaceSymbol call lsp#ui#vim#workspace_symbol()
|
||||||
|
|||||||
Reference in New Issue
Block a user