Open prabirshrestha opened 4 years ago
Let's definitely have them. And yes let's have both the lower layor one to bridge and the one to orchestrate/coordinate a set of popups.
This one seems interesting since it supports border which I believe neovim doesn't support by default. https://github.com/junegunn/fzf.vim/issues/821#issuecomment-581273191 I have found popup without border very difficult to use since some colorschemes blend together and very difficult to know what the issue is.
I haven't played much with popup apis but would be good to hear thoughts from those who have experience around it.
Just note.
https://github.com/lambdalisue/loupe.vim/blob/master/autoload/loupe/viewer/nvim.vim#L24-L105
To provide borders in Neovim, we need to make the border by ourselves like above.
The feature request has closed in Neovim. https://github.com/neovim/neovim/issues/9718
Here is an api I can think of some would most likely have to be pushed as a higher level api.
let s:Popup = vital#vital#import('UI.Popup')
function! s:demo() abort
let popup = s:Popup.new({
\ 'max_width': 'auto',
\ 'max_height': 'auto',
\ 'min_height': 'auto',
\ 'min_width': 'auto',
\ 'height': 10,
\ 'width': 10,
\ 'border': 1,
\ 'borderchars': '',
\ 'contents': ['hello', 'world'],
\ 'screenpos': [0, 0],
\ 'directionalhint': 'bottomleft|bottomright|topleftedge|topcenter',
\ 'focusable': 0,
\ 'zindex': 0,
\ 'drag': 0,
\ 'scrollbar': 0,
\ 'on_event': function('s:on_event'),
\ })
let winid = popup.get_winid()
let [height, width] = popup.get_dimensions(id)
call popup.set_dimensions(height, width)
" or
let height = popup.get_height()
let width = popup.get_width()
call popup.set_height(height)
call popup.set_width(width)
let isopen = popup.is_open()
call popup.show(id) " open popup
call popup.hide(id) " popup is hidden
" or
call popup.set_visibility(0)
let isvisible = popup.get_visiblity()
let contents = popup.get_contents()
call popup.set_contents(contents)
call popup.focus() " focus cursor
call popup.close(id) " disposes and cleans up the popup
endfunction
function! s:on_event(id, event, data) abort
let l:popup = s:Popup.get(a:id)
let l:bufnr = a:data['bufnr']
let l:popuid = a:id
if a:event == 'open'
" register autocmd for cursor move so can auto close the popup
elseif a:event == 'close'
elseif a:event == 'focus'
elseif a:event == 'blur'
elseif a:event == 'hidden'
elseif a:event == 'scrolldown'
elseif a:event == 'scrollup'
endif
endfunction
Another option is for s:Popup.new()
to return an id
which is a number instead of string so when using different languages such as lua or rpc it is very easy to pass references around. This does mean one would have to use call s:Popup.close(id)
//cc @hrsh7th since he had submitted a similar PR to refactor this for vim-lsp.
sent initial PR at https://github.com/vim-jp/vital.vim/pull/748
Seems like the border in neovim uses two floating window most likely to not have impact on syntax highlighting. In order to make it consistent with vim and have z-index the same might have to use the same trick on vim.
It would be good if vital.vim has a popup api that works in both vim and neovim. There has been some PRs related to this in vim-lsp at https://github.com/prabirshrestha/vim-lsp/pull/510 and https://github.com/prabirshrestha/vim-lsp/pull/567. Another one i found was this https://github.com/ZSaberLv0/ZFVimPopup. Lot of other plugins also has to keep creating wrappers to solve this issue.
Besides just a wrapper around vim and neovim apis there are other high level apis that would be necessary for the popup such as controlling direction and zindex. For example I might want to show LSP hover information above the cursor but diagnostics below the cursor. If autocomplete popup menu is open I might want to show the popup at the right of the complete menu but if it is to the end of the screen i might want to show it to the left instead or if at the bottom of the screen i might want to show at the top. Or might even want to dock it similar as https://github.com/ncm2/float-preview.nvim. Might also want to listen to buffer/window resizes and resize accordingly.
Since some of these are quite complicated specially when dealing with multiple popup at the same time my thought was to have 2 modules.
Popup
: This is a simple wrapper that is just bridges vim popup and neovim floating window apis.PopupManager
: This is the bigger one which does the management of multiple popups.