Introduce new "popup" match display

Using Neovim's floating window, or Vim 8.x popup.
This commit is contained in:
Rafael Bodill
2019-09-01 21:39:38 +03:00
parent a0691e744a
commit d1ac1d0c5d
2 changed files with 84 additions and 1 deletions

View File

@@ -9,6 +9,8 @@ scriptencoding utf-8
let s:save_cpo = &cpo
set cpo&vim
let s:winid = 0
function! matchup#matchparen#init_module() " {{{1
if !g:matchup_matchparen_enabled | return | endif
@@ -508,6 +510,8 @@ function! s:do_offscreen(current, method) " {{{1
call s:do_offscreen_statusline(l:offscreen, 0)
elseif a:method ==# 'status_manual'
call s:do_offscreen_statusline(l:offscreen, 1)
elseif a:method ==# 'popup'
call s:do_offscreen_popup(l:offscreen)
endif
endfunction
@@ -536,7 +540,84 @@ function! s:do_offscreen_statusline(offscreen, manual) " {{{1
endfunction
" }}}1
function! s:do_offscreen_popup(offscreen) " {{{1
let l:original_filetype = &filetype
if exists('*nvim_open_win')
" neovim floating window
call s:close_floating_win()
" Set default width and height for now.
let buf = nvim_create_buf(v:false, v:false)
let s:winid = nvim_open_win(buf, v:false, {
\ 'relative': 'cursor',
\ 'row': 1,
\ 'col': 0,
\ 'width': 42,
\ 'height': &previewheight,
\ 'style': 'minimal'
\ })
call nvim_buf_set_var(buf, 'cursorword', 0)
call nvim_buf_set_option(buf, 'filetype', l:original_filetype)
call nvim_buf_set_option(buf, 'buftype', 'nofile')
call nvim_buf_set_option(buf, 'bufhidden', 'delete')
call nvim_buf_set_option(buf, 'swapfile', v:false)
" assumes cursor is in original window
autocmd matchup_matchparen CursorMoved <buffer> ++once
\ call s:close_floating_win()
elseif exists('*popup_create')
" vim8 popup
let s:winid = popup_create('', {
\ 'line': 'cursor+1',
\ 'col': 'cursor',
\ 'moved': 'any',
\ })
call setbufvar(winbufnr(s:winid), 'cursorword', 0)
call setbufvar(winbufnr(s:winid), '&filetype', l:original_filetype)
endif
call s:populate_floating_win(a:offscreen)
endfunction
" }}}1
function! s:populate_floating_win(offscreen) " {{{1
let l:adjust = matchup#quirks#status_adjust(a:offscreen)
let l:lnum = a:offscreen.lnum + l:adjust
let l:line = getline(l:lnum)
let l:body = split(l:line, '\n')
let body_length = len(l:body)
let height = min([body_length, &previewheight])
if exists('*nvim_open_win')
" neovim floating win
let width = max(map(copy(l:body), 'strdisplaywidth(v:val)'))
call nvim_win_set_width(s:winid, width)
call nvim_win_set_height(s:winid, height)
call nvim_buf_set_lines(winbufnr(s:winid), 0, -1, v:false, [])
call nvim_buf_set_lines(winbufnr(s:winid), 0, -1, v:false, l:body)
call nvim_win_set_cursor(s:winid, [1,0])
elseif exists('*popup_create')
" vim8 popup
call popup_settext(s:winid, l:body)
endif
endfunction
" }}}1
function! s:close_floating_win() " {{{1
if win_id2win(s:winid) > 0
execute win_id2win(s:winid) . 'wincmd c'
endif
let s:winid = 0
endfunction
" }}}1
function! MatchupStatusOffscreen() " {{{1
return substitute(get(w:, 'matchup_statusline', ''),
\ '%<\|%#\w*#', '', 'g')

View File

@@ -612,7 +612,7 @@ Module matchparen~
Sets the method to use to show off-screen matches.
Possible values are:
`'status' (default): Replace the |status-line| for off-screen matches.
`'status'` (default): Replace the |status-line| for off-screen matches.
If a match is off of the screen, the line belonging to that match will be
displayed syntax-highlighted in the status line along with the line number
@@ -623,6 +623,8 @@ Module matchparen~
`'status_manual'`: Compute the status-line but do not display it (future
extension).
`'popup'`: Use neovim floating window or vim8 popup to show match.
scrolloff~
When enabled, off-screen matches will not be shown in the statusline while
the cursor is at the screen edge (respects the value of 'scrolloff').