diff --git a/.vintrc.yaml b/.vintrc.yaml index 68ebea167..c96daa077 100644 --- a/.vintrc.yaml +++ b/.vintrc.yaml @@ -3,7 +3,7 @@ cmdargs: policies: ProhibitUnusedVariable: - enabled: true + enabled: false ProhibitImplicitScopeVariable: enabled: true ProhibitNoAbortFunction: diff --git a/autoload/lsp.vim b/autoload/lsp.vim index 49600c67a..c15ac8b36 100644 --- a/autoload/lsp.vim +++ b/autoload/lsp.vim @@ -115,7 +115,7 @@ endfunction " "exited", "starting", "failed", "running", "not running" function! lsp#get_server_status(...) abort if a:0 == 0 - let l:strs = map(keys(s:servers), {k, v -> v . ": " . s:server_status(v)}) + let l:strs = map(keys(s:servers), {k, v -> v . ': ' . s:server_status(v)}) return join(l:strs, "\n") else return s:server_status(a:1) @@ -189,7 +189,7 @@ function! s:register_events() abort if exists('##TextChangedP') autocmd TextChangedP * call s:on_text_document_did_change() endif - if g:lsp_diagnostics_echo_cursor || g:lsp_highlight_references_enabled + if g:lsp_diagnostics_echo_cursor || g:lsp_diagnostics_float_cursor || g:lsp_highlight_references_enabled autocmd CursorMoved * call s:on_cursor_moved() endif autocmd BufWinEnter,BufWinLeave,InsertEnter * call lsp#ui#vim#references#clean_references() @@ -243,6 +243,8 @@ function! s:on_cursor_moved() abort if g:lsp_diagnostics_echo_cursor call lsp#ui#vim#diagnostics#echo#cursor_moved() + elseif g:lsp_diagnostics_float_cursor && lsp#ui#vim#output#float_supported() + call lsp#ui#vim#diagnostics#float#cursor_moved() endif if g:lsp_highlight_references_enabled @@ -517,7 +519,7 @@ function! s:ensure_init(buf, server_name, cb) abort if has_key(l:server_info, 'capabilities') let l:capabilities = l:server_info['capabilities'] else - let l:capabilities = call(g:lsp_get_supported_capabilities[0], [server_info]) + let l:capabilities = call(g:lsp_get_supported_capabilities[0], [l:server_info]) endif let l:request = { @@ -886,8 +888,8 @@ function! s:add_didchange_queue(buf) abort call add(s:didchange_queue, a:buf) call lsp#log('s:send_didchange_queue() will be triggered') call timer_stop(s:didchange_timer) - let lazy = &updatetime > 1000 ? &updatetime : 1000 - let s:didchange_timer = timer_start(lazy, function('s:send_didchange_queue')) + let l:lazy = &updatetime > 1000 ? &updatetime : 1000 + let s:didchange_timer = timer_start(l:lazy, function('s:send_didchange_queue')) endfunction function! s:send_didchange_queue(...) abort diff --git a/autoload/lsp/client.vim b/autoload/lsp/client.vim index 0c589b9f1..60a7277da 100644 --- a/autoload/lsp/client.vim +++ b/autoload/lsp/client.vim @@ -1,5 +1,5 @@ -let s:save_cpo = &cpo -set cpo&vim +let s:save_cpo = &cpoptions +set cpoptions&vim let s:clients = {} " { client_id: ctx } @@ -268,10 +268,10 @@ function! s:lsp_get_last_request_id(id) abort endfunction function! s:lsp_is_error(obj_or_response) abort - let vt = type(a:obj_or_response) - if vt == type('') + let l:vt = type(a:obj_or_response) + if l:vt == type('') return len(a:obj_or_response) > 0 - elseif vt == type({}) + elseif l:vt == type({}) return has_key(a:obj_or_response, 'error') endif return 0 @@ -330,6 +330,6 @@ endfunction " }}} -let &cpo = s:save_cpo +let &cpoptions = s:save_cpo unlet s:save_cpo " vim sw=4 ts=4 et diff --git a/autoload/lsp/ui/vim.vim b/autoload/lsp/ui/vim.vim index 625756cc2..fa1ad47fc 100644 --- a/autoload/lsp/ui/vim.vim +++ b/autoload/lsp/ui/vim.vim @@ -249,14 +249,14 @@ function! lsp#ui#vim#document_format() abort endfunction function! lsp#ui#vim#stop_server(...) abort - let l:name = get(a:000, 0, '') - for l:server in lsp#get_whitelisted_servers() - if !empty(l:name) && l:server != l:name - continue - endif - echo 'Stopping' l:server 'server ...' - call lsp#stop_server(server) - endfor + let l:name = get(a:000, 0, '') + for l:server in lsp#get_whitelisted_servers() + if !empty(l:name) && l:server != l:name + continue + endif + echo 'Stopping' l:server 'server ...' + call lsp#stop_server(l:server) + endfor endfunction function! s:get_selection_pos(type) abort @@ -439,15 +439,15 @@ function! s:handle_location(ctx, server, type, data) abort "ctx = {counter, list if has_key(l:loc,'viewstart') " showing a locationLink let l:view = l:lines[l:loc['viewstart'] : l:loc['viewend']] call lsp#ui#vim#output#preview(a:server, l:view, { - \ 'statusline': ' LSP Peek ' . a:type, - \ 'filetype': &filetype - \ }) + \ 'statusline': ' LSP Peek ' . a:type, + \ 'filetype': &filetype + \ }) else " showing a location call lsp#ui#vim#output#preview(a:server, l:lines, { - \ 'statusline': ' LSP Peek ' . a:type, - \ 'cursor': { 'line': l:loc['lnum'], 'col': l:loc['col'], 'align': g:lsp_peek_alignment }, - \ 'filetype': &filetype - \ }) + \ 'statusline': ' LSP Peek ' . a:type, + \ 'cursor': { 'line': l:loc['lnum'], 'col': l:loc['col'], 'align': g:lsp_peek_alignment }, + \ 'filetype': &filetype + \ }) endif endif endif @@ -582,9 +582,9 @@ function! s:get_treeitem_for_tree_hierarchy(Callback, object) dict abort endfunction function! lsp#ui#vim#code_action() abort - call lsp#ui#vim#code_action#do({ - \ 'sync': v:false, - \ 'selection': v:false, - \ 'query': '', - \ }) + call lsp#ui#vim#code_action#do({ + \ 'sync': v:false, + \ 'selection': v:false, + \ 'query': '', + \ }) endfunction diff --git a/autoload/lsp/ui/vim/diagnostics.vim b/autoload/lsp/ui/vim/diagnostics.vim index 90e16501f..3d5982c1a 100644 --- a/autoload/lsp/ui/vim/diagnostics.vim +++ b/autoload/lsp/ui/vim/diagnostics.vim @@ -35,7 +35,7 @@ function! lsp#ui#vim#diagnostics#document_diagnostics() abort endif let l:result = [] - for [l:server_name, l:data] in items(l:diagnostics) + for l:data in values(l:diagnostics) let l:result += lsp#ui#vim#utils#diagnostics_to_loc_list(l:data) endfor diff --git a/autoload/lsp/ui/vim/diagnostics/echo.vim b/autoload/lsp/ui/vim/diagnostics/echo.vim index ab0c9f487..e3b868e47 100644 --- a/autoload/lsp/ui/vim/diagnostics/echo.vim +++ b/autoload/lsp/ui/vim/diagnostics/echo.vim @@ -1,6 +1,6 @@ function! lsp#ui#vim#diagnostics#echo#cursor_moved() abort if mode() isnot# 'n' - " dont' show echo only in normal mode + " show echo only in normal mode return endif diff --git a/autoload/lsp/ui/vim/diagnostics/float.vim b/autoload/lsp/ui/vim/diagnostics/float.vim new file mode 100644 index 000000000..e34cecba2 --- /dev/null +++ b/autoload/lsp/ui/vim/diagnostics/float.vim @@ -0,0 +1,32 @@ +function! lsp#ui#vim#diagnostics#float#cursor_moved() abort + call s:stop_cursor_moved_timer() + + let l:current_pos = getcurpos()[0:2] + + " use timer to avoid recalculation + if !exists('s:last_pos') || l:current_pos != s:last_pos + let s:last_pos = l:current_pos + let s:cursor_moved_timer = timer_start(g:lsp_diagnostics_float_delay, function('s:float_diagnostics_under_cursor')) + endif +endfunction + +function! s:float_diagnostics_under_cursor(...) abort + let l:diagnostic = lsp#ui#vim#diagnostics#get_diagnostics_under_cursor() + if !empty(l:diagnostic) && has_key(l:diagnostic, 'message') + let l:lines = split(l:diagnostic['message'], '\n', 1) + call lsp#ui#vim#output#preview('', l:lines, { + \ 'statusline': ' LSP Diagnostics' + \}) + let s:displaying_message = 1 + elseif get(s:, 'displaying_message', 0) + call lsp#ui#vim#output#closepreview() + let s:displaying_message = 0 + endif +endfunction + +function! s:stop_cursor_moved_timer() abort + if exists('s:cursor_moved_timer') + call timer_stop(s:cursor_moved_timer) + unlet s:cursor_moved_timer + endif +endfunction diff --git a/autoload/lsp/ui/vim/output.vim b/autoload/lsp/ui/vim/output.vim index a99c49547..59db9ed32 100644 --- a/autoload/lsp/ui/vim/output.vim +++ b/autoload/lsp/ui/vim/output.vim @@ -11,58 +11,58 @@ function! s:vim_popup_closed(...) abort endfunction function! lsp#ui#vim#output#closepreview() abort - if win_getid() == s:winid - " Don't close if window got focus - return - endif - "closing floats in vim8.1 must use popup_close() (nvim could use nvim_win_close but pclose - "works) - if s:use_vim_popup && s:winid - call popup_close(s:winid) - else - pclose - endif - let s:winid = v:false - let s:preview_data = v:false - augroup lsp_float_preview_close - augroup end - autocmd! lsp_float_preview_close CursorMoved,CursorMovedI,VimResized * - doautocmd User lsp_float_closed + if win_getid() ==# s:winid + " Don't close if window got focus + return + endif + "closing floats in vim8.1 must use popup_close() (nvim could use nvim_win_close but pclose + "works) + if s:use_vim_popup && s:winid + call popup_close(s:winid) + else + pclose + endif + let s:winid = v:false + let s:preview_data = v:false + augroup lsp_float_preview_close + augroup end + autocmd! lsp_float_preview_close CursorMoved,CursorMovedI,VimResized * + doautocmd User lsp_float_closed endfunction function! lsp#ui#vim#output#focuspreview() abort - " This does not work for vim8.1 popup but will work for nvim and old preview - if s:winid - if win_getid() != s:winid - let s:prevwin = win_getid() - call win_gotoid(s:winid) - elseif s:prevwin - " Temporarily disable hooks - " TODO: remove this when closing logic is able to distinguish different move directions - autocmd! lsp_float_preview_close CursorMoved,CursorMovedI,VimResized * - call win_gotoid(s:prevwin) - call s:add_float_closing_hooks() - let s:prevwin = v:false + " This does not work for vim8.1 popup but will work for nvim and old preview + if s:winid + if win_getid() !=# s:winid + let s:prevwin = win_getid() + call win_gotoid(s:winid) + elseif s:prevwin + " Temporarily disable hooks + " TODO: remove this when closing logic is able to distinguish different move directions + autocmd! lsp_float_preview_close CursorMoved,CursorMovedI,VimResized * + call win_gotoid(s:prevwin) + call s:add_float_closing_hooks() + let s:prevwin = v:false + endif endif - endif endfunction function! s:bufwidth() abort - let width = winwidth(0) - let numberwidth = max([&numberwidth, strlen(line('$'))+1]) - let numwidth = (&number || &relativenumber)? numberwidth : 0 - let foldwidth = &foldcolumn - - if &signcolumn ==? 'yes' - let signwidth = 2 - elseif &signcolumn ==? 'auto' - let signs = execute(printf('sign place buffer=%d', bufnr(''))) - let signs = split(signs, "\n") - let signwidth = len(signs)>2? 2: 0 - else - let signwidth = 0 - endif - return width - numwidth - foldwidth - signwidth + let l:width = winwidth(0) + let l:numberwidth = max([&numberwidth, strlen(line('$'))+1]) + let l:numwidth = (&number || &relativenumber)? l:numberwidth : 0 + let l:foldwidth = &foldcolumn + + if &signcolumn ==? 'yes' + let l:signwidth = 2 + elseif &signcolumn ==? 'auto' + let l:signs = execute(printf('sign place buffer=%d', bufnr(''))) + let l:signs = split(l:signs, "\n") + let l:signwidth = len(l:signs)>2? 2: 0 + else + let l:signwidth = 0 + endif + return l:width - l:numwidth - l:foldwidth - l:signwidth endfunction @@ -73,118 +73,118 @@ function! s:get_float_positioning(height, width) abort " TODO: add option to configure it 'docked' at the bottom/top/right let l:y = winline() if l:y + l:height >= winheight(0) - " Float does not fit - if l:y > l:height - " Fits above - let l:y = winline() - l:height - 1 - elseif l:y - 2 > winheight(0) - l:y - " Take space above cursor - let l:y = 1 - let l:height = winline()-2 - else - " Take space below cursor - let l:height = winheight(0) -l:y - endif + " Float does not fit + if l:y > l:height + " Fits above + let l:y = winline() - l:height - 1 + elseif l:y - 2 > winheight(0) - l:y + " Take space above cursor + let l:y = 1 + let l:height = winline()-2 + else + " Take space below cursor + let l:height = winheight(0) -l:y + endif endif let l:col = col('.') let l:style = 'minimal' " Positioning is not window but screen relative let l:opts = { - \ 'relative': 'win', - \ 'row': l:y, - \ 'col': l:col, - \ 'width': l:width, - \ 'height': l:height, - \ 'style': l:style, - \ } + \ 'relative': 'win', + \ 'row': l:y, + \ 'col': l:col, + \ 'width': l:width, + \ 'height': l:height, + \ 'style': l:style, + \ } return l:opts endfunction function! lsp#ui#vim#output#floatingpreview(data) abort - if s:use_nvim_float - let l:buf = nvim_create_buf(v:false, v:true) - call setbufvar(l:buf, '&signcolumn', 'no') + if s:use_nvim_float + let l:buf = nvim_create_buf(v:false, v:true) + call setbufvar(l:buf, '&signcolumn', 'no') - " Try to get as much space around the cursor, but at least 10x10 - let l:width = max([s:bufwidth(), 10]) - let l:height = max([&lines - winline() + 1, winline() - 1, 10]) + " Try to get as much space around the cursor, but at least 10x10 + let l:width = max([s:bufwidth(), 10]) + let l:height = max([&lines - winline() + 1, winline() - 1, 10]) - if g:lsp_preview_max_height > 0 - let l:height = min([g:lsp_preview_max_height, l:height]) - endif + if g:lsp_preview_max_height > 0 + let l:height = min([g:lsp_preview_max_height, l:height]) + endif - let l:opts = s:get_float_positioning(l:height, l:width) - - let s:winid = nvim_open_win(buf, v:true, l:opts) - call nvim_win_set_option(s:winid, 'winhl', 'Normal:Pmenu,NormalNC:Pmenu') - call nvim_win_set_option(s:winid, 'foldenable', v:false) - call nvim_win_set_option(s:winid, 'wrap', v:true) - call nvim_win_set_option(s:winid, 'statusline', '') - call nvim_win_set_option(s:winid, 'number', v:false) - call nvim_win_set_option(s:winid, 'relativenumber', v:false) - call nvim_win_set_option(s:winid, 'cursorline', v:false) - " Enable closing the preview with esc, but map only in the scratch buffer - nmap :pclose - elseif s:use_vim_popup - let l:options = { - \ 'moved': 'any', - \ 'border': [1, 1, 1, 1], - \ 'callback': function('s:vim_popup_closed') - \ } + let l:opts = s:get_float_positioning(l:height, l:width) + + let s:winid = nvim_open_win(l:buf, v:true, l:opts) + call nvim_win_set_option(s:winid, 'winhl', 'Normal:Pmenu,NormalNC:Pmenu') + call nvim_win_set_option(s:winid, 'foldenable', v:false) + call nvim_win_set_option(s:winid, 'wrap', v:true) + call nvim_win_set_option(s:winid, 'statusline', '') + call nvim_win_set_option(s:winid, 'number', v:false) + call nvim_win_set_option(s:winid, 'relativenumber', v:false) + call nvim_win_set_option(s:winid, 'cursorline', v:false) + " Enable closing the preview with esc, but map only in the scratch buffer + nmap :pclose + elseif s:use_vim_popup + let l:options = { + \ 'moved': 'any', + \ 'border': [1, 1, 1, 1], + \ 'callback': function('s:vim_popup_closed') + \ } - if g:lsp_preview_max_width > 0 - let l:options['maxwidth'] = g:lsp_preview_max_width - endif + if g:lsp_preview_max_width > 0 + let l:options['maxwidth'] = g:lsp_preview_max_width + endif - if g:lsp_preview_max_height > 0 - let l:options['maxheight'] = g:lsp_preview_max_height - endif + if g:lsp_preview_max_height > 0 + let l:options['maxheight'] = g:lsp_preview_max_height + endif - let s:winid = popup_atcursor('...', l:options) - endif - return s:winid + let s:winid = popup_atcursor('...', l:options) + endif + return s:winid endfunction function! s:setcontent(lines, ft) abort - if s:use_vim_popup - " vim popup - call setbufline(winbufnr(s:winid), 1, a:lines) - let l:lightline_toggle = v:false - if exists('#lightline') && !has('nvim') - " Lightline does not work in popups but does not recognize it yet. - " It is ugly to have an check for an other plugin here, better fix lightline... - let l:lightline_toggle = v:true - call lightline#disable() - endif - call win_execute(s:winid, 'setlocal filetype=' . a:ft . '.lsp-hover') - if l:lightline_toggle - call lightline#enable() - endif - else - " nvim floating or preview - call setline(1, a:lines) + if s:use_vim_popup + " vim popup + call setbufline(winbufnr(s:winid), 1, a:lines) + let l:lightline_toggle = v:false + if exists('#lightline') && !has('nvim') + " Lightline does not work in popups but does not recognize it yet. + " It is ugly to have an check for an other plugin here, better fix lightline... + let l:lightline_toggle = v:true + call lightline#disable() + endif + call win_execute(s:winid, 'setlocal filetype=' . a:ft . '.lsp-hover') + if l:lightline_toggle + call lightline#enable() + endif + else + " nvim floating or preview + call setline(1, a:lines) - setlocal readonly nomodifiable - silent! let &l:filetype = a:ft . '.lsp-hover' - endif + setlocal readonly nomodifiable + silent! let &l:filetype = a:ft . '.lsp-hover' + endif endfunction function! s:adjust_float_placement(bufferlines, maxwidth) abort if s:use_nvim_float - let l:win_config = {} - let l:height = min([winheight(s:winid), a:bufferlines]) - let l:width = min([winwidth(s:winid), a:maxwidth]) - let l:win_config = s:get_float_positioning(l:height, l:width) - call nvim_win_set_config(s:winid, l:win_config ) + let l:win_config = {} + let l:height = min([winheight(s:winid), a:bufferlines]) + let l:width = min([winwidth(s:winid), a:maxwidth]) + let l:win_config = s:get_float_positioning(l:height, l:width) + call nvim_win_set_config(s:winid, l:win_config ) endif endfunction function! s:add_float_closing_hooks() abort if g:lsp_preview_autoclose - augroup lsp_float_preview_close - autocmd! lsp_float_preview_close CursorMoved,CursorMovedI,VimResized * - autocmd CursorMoved,CursorMovedI,VimResized * call lsp#ui#vim#output#closepreview() - augroup END + augroup lsp_float_preview_close + autocmd! lsp_float_preview_close CursorMoved,CursorMovedI,VimResized * + autocmd CursorMoved,CursorMovedI,VimResized * call lsp#ui#vim#output#closepreview() + augroup END endif endfunction @@ -194,10 +194,10 @@ endfunction function! s:open_preview(data) abort if s:use_vim_popup || s:use_nvim_float - let l:winid = lsp#ui#vim#output#floatingpreview(a:data) + let l:winid = lsp#ui#vim#output#floatingpreview(a:data) else - execute &previewheight.'new' - let l:winid = win_getid() + execute &previewheight.'new' + let l:winid = win_getid() endif return l:winid endfunction @@ -208,37 +208,37 @@ function! s:set_cursor(current_window_id, options) abort endif if s:use_nvim_float - " 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 + " 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) + 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) + " Finally, go back to the original window + call win_gotoid(a:current_window_id) - let &scrolloff = l:old_scrolloff + let &scrolloff = l:old_scrolloff elseif s:use_vim_popup - " Vim popups - function! AlignVimPopup(timer) closure abort - call s:align_preview(a:options) - endfunction - call timer_start(0, function('AlignVimPopup')) + " 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) + " 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') + \ !has_key(a:options['cursor'], 'align') return endif @@ -256,13 +256,13 @@ function! s:align_preview(options) abort 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' - \ } + \ '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'] @@ -286,13 +286,17 @@ function! s:align_preview(options) abort endif endfunction +function! lsp#ui#vim#output#float_supported() abort + return s:use_vim_popup || s:use_nvim_float +endfunction + function! lsp#ui#vim#output#preview(server, data, options) abort - if s:winid && type(s:preview_data) == type(a:data) - \ && s:preview_data == a:data - \ && type(g:lsp_preview_doubletap) == 3 - \ && len(g:lsp_preview_doubletap) >= 1 - \ && type(g:lsp_preview_doubletap[0]) == 2 - \ && index(['i', 's'], mode()[0]) == -1 + if s:winid && type(s:preview_data) ==# type(a:data) + \ && s:preview_data ==# a:data + \ && type(g:lsp_preview_doubletap) ==# 3 + \ && len(g:lsp_preview_doubletap) >= 1 + \ && type(g:lsp_preview_doubletap[0]) ==# 2 + \ && index(['i', 's'], mode()[0]) ==# -1 echo '' return call(g:lsp_preview_doubletap[0], []) endif @@ -310,8 +314,8 @@ function! lsp#ui#vim#output#preview(server, data, options) abort " If the server response is empty content, we don't display anything. if empty(l:lines) && empty(l:syntax_lines) - echo '' - return + echo '' + return endif let s:winid = s:open_preview(a:data) @@ -320,12 +324,10 @@ function! lsp#ui#vim#output#preview(server, data, options) abort let l:ft = a:options['filetype'] endif - let l:server_info = lsp#get_server_info(a:server) - try - let l:do_conceal = l:server_info['config']['hover_conceal'] - catch - let l:do_conceal = g:lsp_hover_conceal - endtry + let l:do_conceal = g:lsp_hover_conceal + let l:server_info = a:server !=# '' ? lsp#get_server_info(a:server) : {} + let l:config = get(l:server_info, 'config', {}) + let l:do_conceal = get(l:config, 'hover_conceal', l:do_conceal) call setbufvar(winbufnr(s:winid), 'lsp_syntax_highlights', l:syntax_lines) call setbufvar(winbufnr(s:winid), 'lsp_do_conceal', l:do_conceal) @@ -334,17 +336,17 @@ function! lsp#ui#vim#output#preview(server, data, options) abort " Get size information while still having the buffer active let l:maxwidth = max(map(getline(1, '$'), 'strdisplaywidth(v:val)')) if g:lsp_preview_max_width > 0 - let l:bufferlines = 0 - let l:maxwidth = min([g:lsp_preview_max_width, l:maxwidth]) - - " Determine, for each line, how many "virtual" lines it spans, and add - " these together for all lines in the buffer - for l:line in getline(1, '$') - let l:num_lines = str2nr(string(ceil(strdisplaywidth(l:line) * 1.0 / g:lsp_preview_max_width))) - let l:bufferlines += max([l:num_lines, 1]) - endfor + let l:bufferlines = 0 + let l:maxwidth = min([g:lsp_preview_max_width, l:maxwidth]) + + " Determine, for each line, how many "virtual" lines it spans, and add + " these together for all lines in the buffer + for l:line in getline(1, '$') + let l:num_lines = str2nr(string(ceil(strdisplaywidth(l:line) * 1.0 / g:lsp_preview_max_width))) + let l:bufferlines += max([l:num_lines, 1]) + endfor else - let l:bufferlines = line('$') + let l:bufferlines = line('$') endif if s:use_preview @@ -362,22 +364,22 @@ function! lsp#ui#vim#output#preview(server, data, options) abort echo '' if s:winid && (s:use_vim_popup || s:use_nvim_float) - if s:use_nvim_float - " 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() - elseif s:use_vim_popup - " Vim popups - call s:set_cursor(l:current_window_id, a:options) - endif + if s:use_nvim_float + " 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() + elseif s:use_vim_popup + " Vim popups + call s:set_cursor(l:current_window_id, a:options) + endif - doautocmd User lsp_float_opened + doautocmd User lsp_float_opened endif if !g:lsp_preview_keep_focus - " set the focus to the preview window - call win_gotoid(s:winid) + " set the focus to the preview window + call win_gotoid(s:winid) endif return '' endfunction @@ -387,19 +389,19 @@ function! s:escape_string_for_display(str) abort endfunction function! s:append(data, lines, syntax_lines) abort - if type(a:data) == type([]) + if type(a:data) ==# type([]) for l:entry in a:data - call s:append(entry, a:lines, a:syntax_lines) + call s:append(l:entry, a:lines, a:syntax_lines) endfor return 'markdown' - elseif type(a:data) == type('') + elseif type(a:data) ==# type('') if !empty(a:data) call extend(a:lines, split(s:escape_string_for_display(a:data), "\n", v:true)) endif return 'markdown' - elseif type(a:data) == type({}) && has_key(a:data, 'language') + elseif type(a:data) ==# type({}) && has_key(a:data, 'language') if !empty(a:data.value) let l:new_lines = split(s:escape_string_for_display(a:data.value), '\n') @@ -413,9 +415,9 @@ function! s:append(data, lines, syntax_lines) abort endif return 'markdown' - elseif type(a:data) == type({}) && has_key(a:data, 'kind') + elseif type(a:data) ==# type({}) && has_key(a:data, 'kind') if !empty(a:data.value) - call extend(a:lines, split(s:escape_string_for_display(a:data.value), '\n', v:true)) + call extend(a:lines, split(s:escape_string_for_display(a:data.value), '\n', v:true)) endif return a:data.kind ==? 'plaintext' ? 'text' : a:data.kind diff --git a/autoload/lsp/ui/vim/signature_help.vim b/autoload/lsp/ui/vim/signature_help.vim index 4369e50ba..c9b62369a 100644 --- a/autoload/lsp/ui/vim/signature_help.vim +++ b/autoload/lsp/ui/vim/signature_help.vim @@ -19,7 +19,7 @@ function! lsp#ui#vim#signature_help#get_signature_help_under_cursor() abort \ 'method': 'textDocument/signatureHelp', \ 'params': { \ 'textDocument': lsp#get_text_document_identifier(), - \ 'position': position, + \ 'position': l:position, \ }, \ 'on_notification': function('s:handle_signature_help', [l:server]), \ }) diff --git a/autoload/lsp/utils.vim b/autoload/lsp/utils.vim index ec4c03f72..b1b58ad60 100644 --- a/autoload/lsp/utils.vim +++ b/autoload/lsp/utils.vim @@ -28,12 +28,12 @@ function! s:encode_uri(path, start_pos_encode, default_prefix) abort let l:result = strpart(a:path, 0, a:start_pos_encode) - for i in range(a:start_pos_encode, len(l:path) - 1) + for l:i in range(a:start_pos_encode, len(l:path) - 1) " Don't encode '/' here, `path` is expected to be a valid path. - if l:path[i] =~# '^[a-zA-Z0-9_.~/-]$' - let l:result .= l:path[i] + if l:path[l:i] =~# '^[a-zA-Z0-9_.~/-]$' + let l:result .= l:path[l:i] else - let l:result .= s:urlencode_char(l:path[i]) + let l:result .= s:urlencode_char(l:path[l:i]) endif endfor @@ -116,8 +116,8 @@ endfunction function! lsp#utils#find_nearest_parent_file_directory(path, filename) abort if type(a:filename) == 3 let l:matched_paths = {} - for current_name in a:filename - let l:path = lsp#utils#find_nearest_parent_file_directory(a:path, current_name) + for l:current_name in a:filename + let l:path = lsp#utils#find_nearest_parent_file_directory(a:path, l:current_name) if !empty(l:path) if has_key(l:matched_paths, l:path) diff --git a/autoload/lsp/utils/buffer.vim b/autoload/lsp/utils/buffer.vim index b20d44f0b..99a3c793b 100644 --- a/autoload/lsp/utils/buffer.vim +++ b/autoload/lsp/utils/buffer.vim @@ -56,7 +56,7 @@ function! lsp#utils#buffer#_open_lsp_location(location) abort endif execute l:cmd . ' | call cursor('.l:start_line.','.l:start_col.')' - normal V + normal! V call setpos("'<", [l:bufnr, l:start_line, l:start_col]) call setpos("'>", [l:bufnr, l:end_line, l:end_col]) endfunction diff --git a/autoload/lsp/utils/workspace_config.vim b/autoload/lsp/utils/workspace_config.vim index 261e87d86..5da8541ec 100644 --- a/autoload/lsp/utils/workspace_config.vim +++ b/autoload/lsp/utils/workspace_config.vim @@ -3,7 +3,7 @@ function! lsp#utils#workspace_config#get_value(server_name, item) abort let l:server_info = lsp#get_server_info(a:server_name) let l:config = l:server_info['workspace_config'] - for section in split(a:item['section'], '\.') + for l:section in split(a:item['section'], '\.') let l:config = l:config[l:section] endfor diff --git a/doc/vim-lsp.txt b/doc/vim-lsp.txt index 05701667d..f8fca4055 100644 --- a/doc/vim-lsp.txt +++ b/doc/vim-lsp.txt @@ -20,6 +20,9 @@ CONTENTS *vim-lsp-contents* g:lsp_insert_text_enabled |g:lsp_insert_text_enabled| g:lsp_text_edit_enabled |g:lsp_text_edit_enabled| g:lsp_diagnostics_echo_cursor |g:lsp_diagnostics_echo_cursor| + g:lsp_diagnostics_echo_delay |g:lsp_diagnostics_echo_delay| + g:lsp_diagnostics_float_cursor |g:lsp_diagnostics_float_cursor| + g:lsp_diagnostics_float_delay |g:lsp_diagnostics_float_delay| g:lsp_signs_enabled |g:lsp_signs_enabled| g:lsp_signs_priority |g:lsp_signs_priority| g:lsp_signs_priority_map |g:lsp_signs_priority_map| @@ -344,6 +347,42 @@ g:lsp_diagnostics_echo_cursor *g:lsp_diagnostics_echo_cursor* let g:lsp_diagnostics_echo_cursor = 1 let g:lsp_diagnostics_echo_cursor = 0 +g:lsp_diagnostics_echo_delay *g:lsp_diagnostics_echo_delay* + Type: |Number| + Default: `500` + + Delay milliseconds to echo diagnostic error for the current line to status. Requires + Enables echo of diagnostic error for the current line to status. Requires + |g:lsp_diagnostics_enabled| and |g:lsp_diagnostics_echo_cursor| set to 1. + + Example: > + let g:lsp_diagnostics_echo_delay = 200 + let g:lsp_diagnostics_echo_delay = 1000 + +g:lsp_diagnostics_float_cursor *g:lsp_diagnostics_float_cursor* + Type: |Number| + Default: `0` + + Enables a floating window of diagnostic error for the current line to status. Requires + nvim_win_open() or popup_create is available, and |g:lsp_diagnostics_enabled| set to 1. + + Example: > + let g:lsp_diagnostics_float_cursor = 1 + let g:lsp_diagnostics_float_cursor = 0 + +g:lsp_diagnostics_float_delay *g:lsp_diagnostics_float_delay* + Type: |Number| + Default: `500` + + Delay milliseconds to show diagnostic error for the current line to status + in a float window. Requires Enables float of diagnostic error for the + current line to status. Requires |g:lsp_diagnostics_enabled| and + |g:lsp_diagnostics_echo_cursor| set to 1. + + Example: > + let g:lsp_diagnostics_echo_delay = 200 + let g:lsp_diagnostics_echo_delay = 1000 + g:lsp_signs_enabled *g:lsp_signs_enabled* Type: |Number| Default: `1` for vim/neovim with patch 8.1.0772 diff --git a/plugin/lsp.vim b/plugin/lsp.vim index 146e6d429..17068adeb 100644 --- a/plugin/lsp.vim +++ b/plugin/lsp.vim @@ -23,6 +23,8 @@ let g:lsp_signs_priority_map = get(g:, 'lsp_signs_priority_map', {}) let g:lsp_diagnostics_enabled = get(g:, 'lsp_diagnostics_enabled', 1) let g:lsp_diagnostics_echo_cursor = get(g:, 'lsp_diagnostics_echo_cursor', 0) let g:lsp_diagnostics_echo_delay = get(g:, 'lsp_diagnostics_echo_delay', 500) +let g:lsp_diagnostics_float_cursor = get(g:, 'lsp_diagnostics_float_cursor', 0) +let g:lsp_diagnostics_float_delay = get(g:, 'lsp_diagnostics_float_delay', 500) let g:lsp_next_sign_id = get(g:, 'lsp_next_sign_id', 6999) let g:lsp_preview_keep_focus = get(g:, 'lsp_preview_keep_focus', 1) let g:lsp_use_event_queue = get(g:, 'lsp_use_event_queue', has('nvim') || has('patch-8.1.0889'))