Skip to content

Commit

Permalink
Create preview window instead of using quickfix list (#78)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
hauleth authored and prabirshrestha committed Jan 1, 2018
1 parent a153443 commit 203d682
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 47 deletions.
75 changes: 30 additions & 45 deletions autoload/lsp/ui/vim.vim
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
let s:last_req_id = 0
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
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([])

if len(l:servers) == 0
echom 'Retrieving definition not supported for ' . &filetype
call s:not_supported('Retrieving definition')
return
endif

Expand All @@ -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 }
if len(l:servers) == 0
echom 'Retrieving references not supported for ' . &filetype
call s:not_supported('Retrieving references')
return
endif

Expand All @@ -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 s:last_req_id = s:last_req_id + 1

call setqflist([])

if len(l:servers) == 0
echom 'Retrieving hover not supported for ' . &filetype
call s:not_supported('Retrieving hover')
return
endif

Expand All @@ -83,7 +91,7 @@ function! lsp#ui#vim#rename() abort
let s:last_req_id = s:last_req_id + 1

if len(l:servers) == 0
echom 'Renaming not supported for ' . &filetype
call s:not_supported('Renaming')
return
endif

Expand Down Expand Up @@ -115,7 +123,7 @@ function! lsp#ui#vim#document_format() abort
let s:last_req_id = s:last_req_id + 1

if len(l:servers) == 0
echom 'Document formatting not supported for ' . &filetype
call s:not_supported('Document formatting')
return
endif

Expand Down Expand Up @@ -156,7 +164,7 @@ function! lsp#ui#vim#document_range_format() abort
let s:last_req_id = s:last_req_id + 1

if len(l:servers) == 0
echom 'Document range formatting not supported for ' . &filetype
call s:not_supported('Document range formatting')
return
endif

Expand Down Expand Up @@ -190,7 +198,7 @@ function! lsp#ui#vim#workspace_symbol() abort
call setqflist([])

if len(l:servers) == 0
echom 'Retrieving workspace symbols not supported for ' . &filetype
call s:not_supported('Retrieving workspace symbols')
return
endif

Expand All @@ -216,7 +224,7 @@ function! lsp#ui#vim#document_symbol() abort
call setqflist([])

if len(l:servers) == 0
echom 'Retrieving symbols not supported for ' . &filetype
call s:not_supported('Retrieving symbols')
return
endif

Expand Down Expand Up @@ -247,7 +255,7 @@ endfunction
function! lsp#ui#vim#document_diagnostics() abort
let l:uri = lsp#utils#get_buffer_uri()
if !has_key(s:diagnostics, l:uri)
echom 'No diagnostics results'
call s:error_msg('No diagnostics results')
return
endif

Expand All @@ -262,7 +270,7 @@ function! lsp#ui#vim#document_diagnostics() abort
" autocmd FileType qf setlocal wrap

if empty(l:result)
echom 'No diagnostics results found'
call s:error_msg('No diagnostics results found')
else
echom 'Retrieved diagnostics results'
botright copen
Expand All @@ -275,7 +283,7 @@ function! s:handle_symbol(server, last_req_id, type, data) abort
endif

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
endif

Expand All @@ -284,7 +292,7 @@ function! s:handle_symbol(server, last_req_id, type, data) abort
call setqflist(l:list)

if empty(l:list)
echom 'No ' . a:type .' found'
call s:error_msg('No ' . a:type .' found')
else
echom 'Retrieved ' . a:type
botright copen
Expand All @@ -299,14 +307,14 @@ function! s:handle_location(ctx, server, type, data) abort "ctx = {counter, list
let a:ctx['counter'] = a:ctx['counter'] - 1

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
let a:ctx['list'] = a:ctx['list'] + lsp#ui#vim#utils#locations_to_loc_list(a:data)
endif

if a:ctx['counter'] == 0
if empty(a:ctx['list'])
echom 'No ' . a:type .' found'
call s:error_msg('No ' . a:type .' found')
else
if len(a:ctx['list']) == 1 && a:ctx['jump_if_one']
normal! m'
Expand All @@ -330,7 +338,7 @@ function! s:handle_hover(server, last_req_id, type, data) abort
endif

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
endif

Expand All @@ -339,34 +347,16 @@ function! s:handle_hover(server, last_req_id, type, data) abort
endif

if empty(a:data['response']['result'])
echom 'No ' . a:type .' found'
call s:error_msg('No ' . a:type .' found')
return
endif

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)
echom 'No ' . a:type .' found'
call s:error_msg('No ' . a:type .' found')
else
echom 'Retrieved ' . a:type
botright copen
echo lsp#ui#vim#output#preview(l:contents)
endif
endfunction

Expand All @@ -376,7 +366,7 @@ function! s:handle_workspace_edit(server, last_req_id, type, data) abort
endif

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
endif

Expand All @@ -391,7 +381,7 @@ function! s:handle_text_edit(server, last_req_id, type, data) abort
endif

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
endif

Expand Down Expand Up @@ -440,8 +430,3 @@ function! s:apply_text_edits(uri, text_edits) abort
set nopaste
endtry
endfunction

function! s:markdown_to_text(markdown) abort
" TODO: convert markdown to normal text
return a:markdown
endfunction
38 changes: 38 additions & 0 deletions autoload/lsp/ui/vim/output.vim
Original file line number Diff line number Diff line change
@@ -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
1 change: 0 additions & 1 deletion autoload/lsp/ui/vim/utils.vim
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ function! s:is_file_uri(uri) abort
return stridx(a:uri, 'file:///') == 0
endfunction


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
endfunction
Expand Down
4 changes: 4 additions & 0 deletions autoload/lsp/utils.vim
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,7 @@ else
return [matchstr(a:expr, a:pattern), match(a:expr, a:pattern), matchend(a:expr, a:pattern)]
endfunction
endif

function! lsp#utils#empty_complete(...) abort
return []
endfunction
14 changes: 14 additions & 0 deletions ftplugin/lsp-hover.vim
Original file line number Diff line number Diff line change
@@ -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'
2 changes: 1 addition & 1 deletion plugin/lsp.vim
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ endif
command! LspDefinition call lsp#ui#vim#definition()
command! LspDocumentSymbol call lsp#ui#vim#document_symbol()
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! LspRename call lsp#ui#vim#rename()
command! LspWorkspaceSymbol call lsp#ui#vim#workspace_symbol()
Expand Down

0 comments on commit 203d682

Please sign in to comment.