X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/5a4872f466ebd76ddd532bdf2798554421c53df4..fe3919e725e156d751069662d11e38f7b4791de1:/.vim/bundle/vim-lsp/autoload/lsp/internal/diagnostics/float.vim diff --git a/.vim/bundle/vim-lsp/autoload/lsp/internal/diagnostics/float.vim b/.vim/bundle/vim-lsp/autoload/lsp/internal/diagnostics/float.vim new file mode 100644 index 00000000..f7f40a15 --- /dev/null +++ b/.vim/bundle/vim-lsp/autoload/lsp/internal/diagnostics/float.vim @@ -0,0 +1,123 @@ +" internal state for whether it is enabled or not to avoid multiple subscriptions +let s:enabled = 0 + +let s:Markdown = vital#lsp#import('VS.Vim.Syntax.Markdown') +let s:MarkupContent = vital#lsp#import('VS.LSP.MarkupContent') +let s:FloatingWindow = vital#lsp#import('VS.Vim.Window.FloatingWindow') +let s:Window = vital#lsp#import('VS.Vim.Window') +let s:Buffer = vital#lsp#import('VS.Vim.Buffer') + +function! lsp#internal#diagnostics#float#_enable() abort + " don't even bother registering if the feature is disabled + if !lsp#ui#vim#output#float_supported() | return | endif + if !g:lsp_diagnostics_float_cursor | return | endif + + if s:enabled | return | endif + let s:enabled = 1 + + let s:Dispose = lsp#callbag#pipe( + \ lsp#callbag#merge( + \ lsp#callbag#fromEvent(['CursorMoved', 'CursorHold']), + \ lsp#callbag#pipe( + \ lsp#callbag#fromEvent(['InsertEnter']), + \ lsp#callbag#filter({_->!g:lsp_diagnostics_float_insert_mode_enabled}), + \ lsp#callbag#tap({_->s:hide_float()}), + \ ) + \ ), + \ lsp#callbag#filter({_->g:lsp_diagnostics_float_cursor}), + \ lsp#callbag#tap({_->s:hide_float()}), + \ lsp#callbag#debounceTime(g:lsp_diagnostics_float_delay), + \ lsp#callbag#map({_->{'bufnr': bufnr('%'), 'curpos': getcurpos()[0:2], 'changedtick': b:changedtick }}), + \ lsp#callbag#distinctUntilChanged({a,b -> a['bufnr'] == b['bufnr'] && a['curpos'] == b['curpos'] && a['changedtick'] == b['changedtick']}), + \ lsp#callbag#filter({_->mode() is# 'n'}), + \ lsp#callbag#filter({_->getbufvar(bufnr('%'), '&buftype') !=# 'terminal' }), + \ lsp#callbag#map({_->lsp#internal#diagnostics#under_cursor#get_diagnostic()}), + \ lsp#callbag#subscribe({x->s:show_float(x)}), + \ ) +endfunction + +function! lsp#internal#diagnostics#float#_disable() abort + if !s:enabled | return | endif + if exists('s:Dispose') + call s:Dispose() + unlet s:Dispose + endif + let s:enabled = 0 +endfunction + +function! s:show_float(diagnostic) abort + let l:doc_win = s:get_doc_win() + if !empty(a:diagnostic) && has_key(a:diagnostic, 'message') + " Update contents. + call deletebufline(l:doc_win.get_bufnr(), 1, '$') + call setbufline(l:doc_win.get_bufnr(), 1, lsp#utils#_split_by_eol(a:diagnostic['message'])) + + " Compute size. + if g:lsp_float_max_width >= 1 + let l:maxwidth = g:lsp_float_max_width + elseif g:lsp_float_max_width == 0 + let l:maxwidth = &columns + else + let l:maxwidth = float2nr(&columns * 0.4) + endif + let l:size = l:doc_win.get_size({ + \ 'maxwidth': l:maxwidth, + \ 'maxheight': float2nr(&lines * 0.4), + \ }) + + " Compute position. + let l:pos = s:compute_position(l:size) + + " Open window. + call l:doc_win.open({ + \ 'row': l:pos[0], + \ 'col': l:pos[1], + \ 'width': l:size.width, + \ 'height': l:size.height, + \ 'border': v:true, + \ 'topline': 1, + \ }) + else + call s:hide_float() + endif +endfunction + +function! s:hide_float() abort + let l:doc_win = s:get_doc_win() + call l:doc_win.close() +endfunction + +function! s:get_doc_win() abort + if exists('s:doc_win') + return s:doc_win + endif + + let s:doc_win = s:FloatingWindow.new({ + \ 'on_opened': { -> execute('doautocmd User lsp_float_opened') }, + \ 'on_closed': { -> execute('doautocmd User lsp_float_closed') } + \ }) + call s:doc_win.set_var('&wrap', 1) + call s:doc_win.set_var('&conceallevel', 2) + noautocmd silent let l:bufnr = s:Buffer.create() + call s:doc_win.set_bufnr(l:bufnr) + call setbufvar(s:doc_win.get_bufnr(), '&buftype', 'nofile') + call setbufvar(s:doc_win.get_bufnr(), '&bufhidden', 'hide') + call setbufvar(s:doc_win.get_bufnr(), '&buflisted', 0) + call setbufvar(s:doc_win.get_bufnr(), '&swapfile', 0) + return s:doc_win +endfunction + +function! s:compute_position(size) abort + let l:pos = screenpos(0, line('.'), col('.')) + if l:pos.row == 0 && l:pos.col == 0 + let l:pos = {'curscol': screencol(), 'row': screenrow()} + endif + let l:pos = [l:pos.row + 1, l:pos.curscol + 1] + if l:pos[0] + a:size.height > &lines + let l:pos[0] = l:pos[0] - a:size.height - 3 + endif + if l:pos[1] + a:size.width > &columns + let l:pos[1] = l:pos[1] - a:size.width - 3 + endif + return l:pos +endfunction