mirror of
https://github.com/chenasraf/vim-matchup.git
synced 2026-05-18 01:38:57 +00:00
Merge pull request #71 from andymass/feature-offscreen-popup-both
Feature - offscreen popup
This commit is contained in:
@@ -45,10 +45,12 @@ function! matchup#matchparen#enable() " {{{1
|
||||
endif
|
||||
autocmd BufReadPost * call s:matchparen.transmute_reset()
|
||||
autocmd WinLeave,BufLeave * call s:matchparen.clear()
|
||||
autocmd InsertEnter,Insertchange * call s:matchparen.highlight(1, 1)
|
||||
autocmd InsertEnter,InsertChange * call s:matchparen.highlight(1, 1)
|
||||
autocmd InsertLeave * call s:matchparen.highlight(1)
|
||||
augroup END
|
||||
|
||||
call s:init_match_popup()
|
||||
|
||||
if has('vim_starting')
|
||||
" prevent this from autoloading during timer callback at startup
|
||||
if g:matchup_matchparen_deferred
|
||||
@@ -136,6 +138,10 @@ function! s:matchparen.clear() abort dict " {{{1
|
||||
unlet! w:matchup_match_id_list
|
||||
endif
|
||||
|
||||
if exists('s:match_popup')
|
||||
call popup_hide(s:match_popup)
|
||||
endif
|
||||
|
||||
if exists('w:matchup_oldstatus')
|
||||
let &l:statusline = w:matchup_oldstatus
|
||||
unlet w:matchup_oldstatus
|
||||
@@ -508,6 +514,12 @@ 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'
|
||||
if has('nvim')
|
||||
call s:do_offscreen_popup_nvim(l:offscreen)
|
||||
else
|
||||
call s:do_offscreen_popup(l:offscreen)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@@ -535,6 +547,118 @@ function! s:do_offscreen_statusline(offscreen, manual) " {{{1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:init_match_popup() abort " {{{1
|
||||
if !exists('*popup_create') || exists('s:match_popup')
|
||||
return
|
||||
endif
|
||||
|
||||
" create a popup and store its winid
|
||||
let s:match_popup = popup_create('', {
|
||||
\ 'hidden': v:true,
|
||||
\})
|
||||
|
||||
" in case 'hidden' in popup_create-usage is unimplemented
|
||||
call popup_hide(s:match_popup)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:do_offscreen_popup(offscreen) " {{{1
|
||||
" screen position of top-left corner of current window
|
||||
let [l:row, l:col] = win_screenpos(winnr())
|
||||
let l:height = winheight(0) " height of current window
|
||||
let l:adjust = matchup#quirks#status_adjust(a:offscreen)
|
||||
let l:lnum = a:offscreen.lnum + l:adjust
|
||||
let l:line = l:lnum < line('.') ? l:row : l:row + l:height - 1
|
||||
|
||||
" if popup would overlap with cursor
|
||||
if l:line == winline() | return | endif
|
||||
|
||||
call popup_move(s:match_popup, {
|
||||
\ 'line': l:line,
|
||||
\ 'col': l:col,
|
||||
\ 'maxheight': 1,
|
||||
\})
|
||||
|
||||
" set popup text
|
||||
let l:text = ''
|
||||
if &number || &relativenumber
|
||||
let l:text = printf('%*S ', wincol()-virtcol('.')-1, l:lnum)
|
||||
endif
|
||||
let l:text .= getline(l:lnum) . ' '
|
||||
if l:adjust
|
||||
let l:text .= '… ' . a:offscreen.match . ' '
|
||||
endif
|
||||
call setbufline(winbufnr(s:match_popup), 1, l:text)
|
||||
call popup_show(s:match_popup)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:do_offscreen_popup_nvim(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()
|
||||
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:float_id, width)
|
||||
call nvim_win_set_height(s:float_id, height)
|
||||
|
||||
call nvim_buf_set_lines(winbufnr(s:float_id), 0, -1, v:false, [])
|
||||
call nvim_buf_set_lines(winbufnr(s:float_id), 0, -1, v:false, l:body)
|
||||
call nvim_win_set_cursor(s:float_id, [1,0])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:close_floating_win() " {{{1
|
||||
if !exists('s:float_id')
|
||||
return
|
||||
endif
|
||||
if win_id2win(s:float_id) > 0
|
||||
execute win_id2win(s:float_id) . 'wincmd c'
|
||||
endif
|
||||
let s:float_id = 0
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! MatchupStatusOffscreen() " {{{1
|
||||
|
||||
@@ -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,9 @@ Module matchparen~
|
||||
`'status_manual'`: Compute the status-line but do not display it (future
|
||||
extension).
|
||||
|
||||
`'popup'`: Use a popup window (requires at least vim 8.1.1406) or
|
||||
a floating window (in neovim) to show the off-screen 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').
|
||||
|
||||
Reference in New Issue
Block a user