mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-04 04:00:05 +08:00
98 lines
3.0 KiB
VimL
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
|