-
Notifications
You must be signed in to change notification settings - Fork 305
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce floatwin/popupwin compatible layer
- Loading branch information
Showing
10 changed files
with
636 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
let s:floatwin_id = 0 | ||
|
||
let s:namespace = has('nvim') ? 'nvim' : 'vim' | ||
|
||
" | ||
" lsp#ui#vim#floatwin#screenpos | ||
" | ||
function! lsp#ui#vim#floatwin#screenpos(line, col) abort | ||
let l:pos = getpos('.') | ||
let l:scroll_x = (l:pos[2] + l:pos[3]) - wincol() | ||
let l:scroll_y = l:pos[1] - winline() | ||
let l:winpos = win_screenpos(win_getid()) | ||
return [l:winpos[0] + (a:line - l:scroll_y) - 1, l:winpos[1] + (a:col - l:scroll_x) - 1] | ||
endfunction | ||
|
||
" | ||
" lsp#ui#vim#floatwin#import | ||
" | ||
function! lsp#ui#vim#floatwin#import() abort | ||
return s:Floatwin | ||
endfunction | ||
|
||
let s:Floatwin = {} | ||
|
||
" | ||
" new | ||
" | ||
function! s:Floatwin.new(option) abort | ||
let s:floatwin_id += 1 | ||
let l:bufname = printf('lsp_floatwin-%s.lsp_floatwin', s:floatwin_id) | ||
let l:bufnr = bufnr(l:bufname, v:true) | ||
call setbufvar(l:bufnr, '&buflisted', 0) | ||
call setbufvar(l:bufnr, '&buftype', 'nofile') | ||
call setbufvar(l:bufnr, '&filetype', 'lsp_floatwin') | ||
return extend(deepcopy(s:Floatwin), { | ||
\ 'id': s:floatwin_id, | ||
\ 'bufnr': l:bufnr, | ||
\ 'max_width': get(a:option, 'max_width', &columns / 3), | ||
\ 'max_height': get(a:option, 'max_height', &lines / 2), | ||
\ 'close_on': get(a:option, 'close_on', []), | ||
\ 'screenpos': [0, 0], | ||
\ 'contents': [] | ||
\ }) | ||
endfunction | ||
|
||
" | ||
" show_tooltip | ||
" | ||
function! s:Floatwin.show_tooltip(screenpos, contents) abort | ||
let l:width = self.get_width(a:contents) | ||
let l:height = self.get_height(a:contents) | ||
|
||
let l:screenpos = copy(a:screenpos) | ||
let l:screenpos[0] -= 1 | ||
let l:screenpos[1] -= 1 | ||
|
||
" fix height. | ||
if l:screenpos[0] - l:height >= 0 | ||
let l:screenpos[0] -= l:height | ||
else | ||
let l:screenpos[0] += 1 | ||
endif | ||
|
||
" fix width. | ||
if &columns < l:screenpos[1] + l:width | ||
let l:screenpos[1] -= l:screenpos[1] + l:width - &columns | ||
endif | ||
|
||
call self.show(l:screenpos, a:contents) | ||
endfunction | ||
|
||
" | ||
" show | ||
" | ||
function! s:Floatwin.show(screenpos, contents) abort | ||
let self.screenpos = a:screenpos | ||
let self.contents = a:contents | ||
|
||
" create lines. | ||
let l:lines = [] | ||
for l:content in a:contents | ||
let l:lines += l:content | ||
endfor | ||
|
||
" update bufvars. | ||
call setbufvar(self.bufnr, 'lsp_floatwin_lines', l:lines) | ||
|
||
" show or move | ||
call lsp#ui#vim#floatwin#{s:namespace}#show(self) | ||
call setwinvar(self.winid(), '&wrap', 1) | ||
call setwinvar(self.winid(), '&conceallevel', 3) | ||
|
||
" write lines | ||
call lsp#ui#vim#floatwin#{s:namespace}#write(self, l:lines) | ||
|
||
" update syntax highlight. | ||
if has('nvim') && LspFloatwinSyntaxShouldUpdate(self.bufnr) | ||
call lsp#utils#windo(self.winid(), { -> LspFloatwinSyntaxUpdate() }) | ||
endif | ||
|
||
call self.set_close_events() | ||
endfunction | ||
|
||
" | ||
" hide | ||
" | ||
function! s:Floatwin.hide() abort | ||
augroup printf('lsp#ui#vim#floatwin#hide_%s', self.id) | ||
autocmd! | ||
augroup END | ||
call lsp#ui#vim#floatwin#{s:namespace}#hide(self) | ||
endfunction | ||
|
||
" | ||
" enter | ||
" | ||
function! s:Floatwin.enter() abort | ||
call lsp#ui#vim#floatwin#{s:namespace}#enter(self) | ||
endfunction | ||
|
||
" | ||
" is_showing | ||
" | ||
function! s:Floatwin.is_showing() abort | ||
return lsp#ui#vim#floatwin#{s:namespace}#is_showing(self) | ||
endfunction | ||
|
||
" | ||
" winid | ||
" | ||
function! s:Floatwin.winid() abort | ||
return lsp#ui#vim#floatwin#{s:namespace}#winid(self) | ||
endfunction | ||
|
||
" | ||
" set_close_events | ||
" | ||
function! s:Floatwin.set_close_events() abort | ||
let l:close_fn = printf('lsp_floatwin_close_%s', self.id) | ||
let b:[l:close_fn] = { -> self.hide() } | ||
|
||
augroup printf('lsp#ui#vim#floatwin#hide_%s', self.id) | ||
autocmd! | ||
for l:event in self.close_on | ||
execute printf('autocmd %s <buffer> call b:%s()', l:event, l:close_fn) | ||
endfor | ||
augroup END | ||
endfunction | ||
|
||
" | ||
" get_width | ||
" | ||
function! s:Floatwin.get_width(contents) abort | ||
let l:width = 0 | ||
for l:content in a:contents | ||
let l:width = max([l:width] + map(copy(l:content), { k, v -> strdisplaywidth(v) })) | ||
endfor | ||
|
||
if self.max_width != -1 | ||
return max([min([self.max_width, l:width]), 1]) | ||
endif | ||
return max([l:width, 1]) | ||
endfunction | ||
|
||
" | ||
" get_height | ||
" | ||
function! s:Floatwin.get_height(contents) abort | ||
let l:width = self.get_width(a:contents) | ||
|
||
let l:height = len(a:contents) - 1 | ||
for l:content in a:contents | ||
for l:line in l:content | ||
let l:height += max([1, float2nr(ceil(strdisplaywidth(l:line) / str2float('' . l:width)))]) | ||
endfor | ||
endfor | ||
|
||
if self.max_height != -1 | ||
return max([min([self.max_height, l:height]), 1]) | ||
endif | ||
return max([l:height, 1]) | ||
endfunction | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
" | ||
" lsp#ui#vim#floatwin#nvim#show | ||
" | ||
function! lsp#ui#vim#floatwin#nvim#show(floatwin) abort | ||
if lsp#ui#vim#floatwin#nvim#is_showing(a:floatwin) | ||
call nvim_win_set_config(a:floatwin.nvim_window, s:get_config(a:floatwin)) | ||
else | ||
let a:floatwin.nvim_window = nvim_open_win(a:floatwin.bufnr, v:false, s:get_config(a:floatwin)) | ||
endif | ||
endfunction | ||
|
||
" | ||
" lsp#ui#vim#floatwin#nvim#hide | ||
" | ||
function! lsp#ui#vim#floatwin#nvim#hide(floatwin) abort | ||
if lsp#ui#vim#floatwin#nvim#is_showing(a:floatwin) | ||
call nvim_win_close(a:floatwin.nvim_window, v:true) | ||
let a:floatwin.nvim_window = v:null | ||
endif | ||
endfunction | ||
|
||
" | ||
" lsp#ui#vim#floatwin#nvim#write | ||
" | ||
function! lsp#ui#vim#floatwin#nvim#write(floatwin, lines) abort | ||
call nvim_buf_set_lines(a:floatwin.bufnr, 0, -1, v:true, a:lines) | ||
endfunction | ||
|
||
" | ||
" lsp#ui#vim#floatwin#nvim#enter | ||
" | ||
function! lsp#ui#vim#floatwin#nvim#enter(floatwin) abort | ||
if lsp#ui#vim#floatwin#nvim#is_showing(a:floatwin) | ||
execute printf('%swincmd w', win_id2win(lsp#ui#vim#floatwin#nvim#winid(a:floatwin))) | ||
endif | ||
endfunction | ||
|
||
" | ||
" lsp#ui#vim#floatwin#nvim#is_showing | ||
" | ||
function! lsp#ui#vim#floatwin#nvim#is_showing(floatwin) abort | ||
if !has_key(a:floatwin,'nvim_window') || a:floatwin.nvim_window is v:null | ||
return v:false | ||
endif | ||
|
||
try | ||
return nvim_win_get_number(a:floatwin.nvim_window) != -1 | ||
catch /.*/ | ||
let a:floatwin.nvim_window = v:null | ||
endtry | ||
return v:false | ||
endfunction | ||
|
||
" | ||
" lsp#ui#vim#floatwin#nvim#winid | ||
" | ||
function! lsp#ui#vim#floatwin#nvim#winid(floatwin) abort | ||
if lsp#ui#vim#floatwin#nvim#is_showing(a:floatwin) | ||
return win_getid(nvim_win_get_number(a:floatwin.nvim_window)) | ||
endif | ||
return -1 | ||
endfunction | ||
|
||
" | ||
" s:get_config | ||
" | ||
function! s:get_config(floatwin) abort | ||
return { | ||
\ 'relative': 'editor', | ||
\ 'width': a:floatwin.get_width(a:floatwin.contents), | ||
\ 'height': a:floatwin.get_height(a:floatwin.contents), | ||
\ 'row': a:floatwin.screenpos[0], | ||
\ 'col': a:floatwin.screenpos[1], | ||
\ 'focusable': v:true, | ||
\ 'style': 'minimal' | ||
\ } | ||
endfunction | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
" | ||
" lsp#ui#vim#floatwin#vim#show | ||
" | ||
function! lsp#ui#vim#floatwin#vim#show(floatwin) abort | ||
if lsp#ui#vim#floatwin#vim#is_showing(a:floatwin) | ||
call popup_move(a:floatwin.vim_winid, s:get_config(a:floatwin)) | ||
else | ||
let a:floatwin.vim_winid = popup_create(a:floatwin.bufnr, s:get_config(a:floatwin)) | ||
endif | ||
endfunction | ||
|
||
" | ||
" lsp#ui#vim#floatwin#vim#hide | ||
" | ||
function! lsp#ui#vim#floatwin#vim#hide(floatwin) abort | ||
try | ||
call popup_hide(a:floatwin.vim_winid) | ||
catch /.*/ | ||
endtry | ||
let a:floatwin.vim_winid = v:null | ||
endfunction | ||
|
||
" | ||
" lsp#ui#vim#floatwin#vim#write | ||
" | ||
function! lsp#ui#vim#floatwin#vim#write(floatwin, lines) abort | ||
call deletebufline(a:floatwin.bufnr, '^', '$') | ||
for l:line in reverse(a:lines) | ||
call appendbufline(a:floatwin.bufnr, 0, l:line) | ||
endfor | ||
call deletebufline(a:floatwin.bufnr, '$') | ||
endfunction | ||
|
||
" | ||
" lsp#ui#vim#floatwin#vim#enter | ||
" | ||
function! lsp#ui#vim#floatwin#vim#enter(floatwin) abort | ||
" noop | ||
endfunction | ||
|
||
" | ||
" lsp#ui#vim#floatwin#vim#is_showing | ||
" | ||
function! lsp#ui#vim#floatwin#vim#is_showing(floatwin) abort | ||
if !has_key(a:floatwin, 'vim_winid') || a:floatwin.vim_winid is v:null | ||
return v:false | ||
endif | ||
|
||
if win_id2win(a:floatwin.vim_winid) == -1 | ||
let a:floatwin.vim_winid = v:null | ||
return v:false | ||
endif | ||
return v:true | ||
endfunction | ||
|
||
" | ||
" lsp#ui#vim#floatwin#vim#winid | ||
" | ||
function! lsp#ui#vim#floatwin#vim#winid(floatwin) abort | ||
if lsp#ui#vim#floatwin#vim#is_showing(a:floatwin) | ||
return a:floatwin.vim_winid | ||
endif | ||
return -1 | ||
endfunction | ||
|
||
" | ||
" s:get_config | ||
" | ||
function! s:get_config(floatwin) abort | ||
return { | ||
\ 'line': a:floatwin.screenpos[0] + 1, | ||
\ 'col': a:floatwin.screenpos[1] + 1, | ||
\ 'pos': 'topleft', | ||
\ 'moved': [0, 100000], | ||
\ 'scrollbar': 0, | ||
\ 'maxwidth': a:floatwin.get_width(a:floatwin.contents), | ||
\ 'maxheight': a:floatwin.get_height(a:floatwin.contents), | ||
\ 'minwidth': a:floatwin.get_width(a:floatwin.contents), | ||
\ 'minheight': a:floatwin.get_height(a:floatwin.contents), | ||
\ 'tabpage': 0 | ||
\ } | ||
endfunction | ||
|
Oops, something went wrong.