1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 20:00:06 +08:00
SpaceVim/bundle/gina.vim/autoload/vital/_gina/Vim/Buffer/Group.vim

98 lines
3.0 KiB
VimL

" ___vital___
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
" Do not modify the code nor insert new lines before '" ___vital___'
function! s:_SID() abort
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
endfunction
execute join(['function! vital#_gina#Vim#Buffer#Group#import() abort', printf("return map({'new': ''}, \"vital#_gina#function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
delfunction s:_SID
" ___vital___
let s:groups = {}
function! s:new(...) abort
let options = extend({
\ 'on_close_fail': v:null,
\}, get(a:000, 0, {})
\)
let hash = sha256(reltimestr(reltime()))
let s:groups[hash] = {
\ 'add': function('s:_group_add'),
\ 'close': function('s:_group_close'),
\}
let s:groups[hash].__hash = hash
let s:groups[hash].__tabnr = v:null
let s:groups[hash].__members = []
let s:groups[hash].__on_close_fail = options.on_close_fail
return s:groups[hash]
endfunction
function! s:_group_add(...) abort dict
let options = extend({
\ 'keep': 0,
\ 'expr': '%',
\}, get(a:000, 0, {})
\)
let bufnr = bufnr(options.expr)
let winid = bufwinid(options.expr)
let tabnr = tabpagenr()
if self.__tabnr is# v:null
let self.__tabnr = tabnr
elseif tabnr != self.__tabnr
throw printf(
\ 'vital: Vim.Buffer.Group: %s',
\ 'A buffer on a different tabpage cannot be added.'
\)
endif
call add(self.__members, {
\ 'bufnr': bufnr,
\ 'winid': winid,
\ 'options': options,
\})
execute printf('augroup vital_vim_buffer_group_%s', self.__hash)
execute printf('autocmd! * <buffer=%d>', bufnr)
execute printf('autocmd WinLeave <buffer=%d> call s:_on_WinLeave(''%s'')', bufnr, self.__hash)
execute 'augroup END'
endfunction
function! s:_group_close() abort dict
for member in self.__members
if member.options.keep
continue
endif
let winnr = win_id2win(member.winid)
if winnr == 0 || getbufvar(member.bufnr, '&modified') || bufwinid(member.bufnr) != member.winid
continue
endif
try
execute printf('%dclose', winnr)
catch /^Vim\%((\a\+)\)\=:E444/
" E444: Cannot close last window may thrown but ignore that
" Vim.Buffer.Group should NOT close the last window so ignore
" this exception silently.
if self.__on_close_fail isnot# v:null
call call(self.__on_close_fail, [winnr, member], self)
endif
endtry
endfor
endfunction
function! s:_on_WinLeave(hash) abort
execute 'augroup vital_vim_buffer_group_temporal_' . a:hash
execute 'autocmd! *'
execute printf(
\ 'autocmd WinEnter * nested call s:_on_WinEnter(''%s'', %d)',
\ a:hash, winnr('$'),
\)
execute 'augroup END'
endfunction
function! s:_on_WinEnter(hash, nwin) abort
execute 'augroup vital_vim_buffer_group_temporal_' . a:hash
execute 'autocmd! *'
execute 'augroup END'
if winnr('$') < a:nwin
call s:groups[a:hash].close()
endif
endfunction