mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 18:00:05 +08:00
252 lines
6.5 KiB
VimL
252 lines
6.5 KiB
VimL
let s:Dict = vital#gina#import('Data.Dict')
|
|
let s:File = vital#gina#import('System.File')
|
|
let s:String = vital#gina#import('Data.String')
|
|
let s:DIRECTION_PATTERN = printf('\<\%%(%s\)\>', join([
|
|
\ 'lefta\%[bove]',
|
|
\ 'abo\%[veleft]',
|
|
\ 'rightb\%[elow]',
|
|
\ 'bel\%[owright]',
|
|
\ 'to\%[pleft]',
|
|
\ 'bo\%[tright]',
|
|
\], '\|')
|
|
\)
|
|
let s:t_list = type([])
|
|
let s:timer_syncbind = v:null
|
|
let s:timer_diffupdate = v:null
|
|
|
|
|
|
function! gina#util#contain_direction(mods) abort
|
|
return a:mods =~# s:DIRECTION_PATTERN
|
|
endfunction
|
|
|
|
function! gina#util#get(obj, key, ...) abort
|
|
let val = get(a:obj, a:key, v:null)
|
|
return val is# v:null ? get(a:000, 0, '') : val
|
|
endfunction
|
|
|
|
function! gina#util#map(lhs, rhs, ...) abort
|
|
let options = extend({
|
|
\ 'mode': '',
|
|
\ 'noremap': 0,
|
|
\ 'buffer': 1,
|
|
\ 'nowait': 0,
|
|
\ 'silent': 0,
|
|
\ 'special': 0,
|
|
\ 'script': 0,
|
|
\ 'unique': 0,
|
|
\ 'expr': 0,
|
|
\}, get(a:000, 0, {})
|
|
\)
|
|
let command = join([
|
|
\ options.mode . (options.noremap ? 'noremap' : 'map'),
|
|
\ options.buffer ? '<buffer>' : '',
|
|
\ options.nowait ? '<nowait>' : '',
|
|
\ options.silent ? '<silent>' : '',
|
|
\ options.special ? '<special>' : '',
|
|
\ options.script ? '<script>' : '',
|
|
\ options.unique ? '<unique>' : '',
|
|
\ options.expr ? '<expr>' : '',
|
|
\ a:lhs, a:rhs
|
|
\])
|
|
execute command
|
|
endfunction
|
|
|
|
function! gina#util#yank(value) abort
|
|
call setreg(v:register, a:value)
|
|
endfunction
|
|
|
|
function! gina#util#open(uri) abort
|
|
call s:File.open(a:uri)
|
|
endfunction
|
|
|
|
function! gina#util#filter(arglead, candidates, ...) abort
|
|
let hidden_pattern = get(a:000, 0, '')
|
|
let pattern = '^' . s:String.escape_pattern(a:arglead)
|
|
let candidates = copy(a:candidates)
|
|
if empty(a:arglead) && !empty(hidden_pattern)
|
|
call filter(candidates, 'v:val !~# hidden_pattern')
|
|
endif
|
|
call filter(candidates, 'v:val =~# pattern')
|
|
return candidates
|
|
endfunction
|
|
|
|
function! gina#util#shellescape(value, ...) abort
|
|
if empty(a:value)
|
|
return ''
|
|
endif
|
|
let value = type(a:value) == s:t_list
|
|
\ ? join(map(copy(a:value), 'shellescape(v:val)'))
|
|
\ : shellescape(a:value)
|
|
let prefix = get(a:000, 0, '')
|
|
return prefix . value
|
|
endfunction
|
|
|
|
function! gina#util#fnameescape(value, ...) abort
|
|
if empty(a:value)
|
|
return ''
|
|
endif
|
|
let value = type(a:value) == s:t_list
|
|
\ ? join(map(copy(a:value), 'fnameescape(v:val)'))
|
|
\ : fnameescape(a:value)
|
|
let prefix = get(a:000, 0, '')
|
|
return prefix . value
|
|
endfunction
|
|
|
|
function! gina#util#windo(expr) abort
|
|
let winid = win_getid()
|
|
try
|
|
execute printf('windo %s', a:expr)
|
|
finally
|
|
call win_gotoid(winid)
|
|
endtry
|
|
endfunction
|
|
|
|
function! gina#util#bufdo(expr, ...) abort
|
|
let bang = a:0 ? '!' : ''
|
|
let winid = win_getid()
|
|
try
|
|
execute printf('bufdo%s %s', bang, a:expr)
|
|
finally
|
|
call win_gotoid(winid)
|
|
endtry
|
|
endfunction
|
|
|
|
function! gina#util#doautocmd(name, ...) abort
|
|
let pattern = get(a:000, 0, '')
|
|
let expr = '#' . a:name
|
|
let eis = split(&eventignore, ',')
|
|
if index(eis, a:name) != -1 || index(eis, 'all') != -1 || !exists(expr)
|
|
" the specified event is ignored or does not exists
|
|
return
|
|
endif
|
|
let is_pseudo_required = empty(pattern) && !exists('#' . a:name . '#*')
|
|
if is_pseudo_required
|
|
" NOTE:
|
|
" autocmd XXXXX <pattern> exists but not sure if the current buffer name
|
|
" match with the <pattern> so register an empty autocmd to prevent
|
|
" 'No matching autocommands' warning
|
|
augroup gina_internal_util_doautocmd
|
|
autocmd! *
|
|
execute printf('autocmd %s * :', a:name)
|
|
augroup END
|
|
endif
|
|
let nomodeline = has('patch-7.4.438') && a:name ==# 'User'
|
|
\ ? '<nomodeline> '
|
|
\ : ''
|
|
try
|
|
execute printf('doautocmd %s %s %s', nomodeline, a:name, pattern)
|
|
finally
|
|
if is_pseudo_required
|
|
augroup gina_internal_util_doautocmd
|
|
autocmd! *
|
|
augroup END
|
|
endif
|
|
endtry
|
|
endfunction
|
|
|
|
function! gina#util#winwidth(winnr) abort
|
|
let width = winwidth(a:winnr)
|
|
let width -= &foldcolumn
|
|
let width -= s:is_sign_visible(winbufnr(a:winnr)) ? 2 : 0
|
|
let width -= (&number || &relativenumber)
|
|
\ ? len(string(line('$'))) + 1
|
|
\ : 0
|
|
return width
|
|
endfunction
|
|
|
|
function! gina#util#syncbind() abort
|
|
" NOTE:
|
|
" 'syncbind' does not work just after a buffer has opened
|
|
" so use timer to delay the command.
|
|
silent! call timer_stop(s:timer_syncbind)
|
|
let s:timer_syncbind = timer_start(50, function('s:syncbind'))
|
|
endfunction
|
|
|
|
function! gina#util#diffthis() abort
|
|
diffthis
|
|
augroup gina_internal_util_diffthis_local
|
|
autocmd! * <buffer>
|
|
autocmd BufReadPost <buffer>
|
|
\ if &diff && &foldmethod !=# 'diff' |
|
|
\ setlocal foldmethod=diff |
|
|
\ endif
|
|
augroup END
|
|
endfunction
|
|
|
|
function! gina#util#diffupdate() abort
|
|
" NOTE:
|
|
" 'diffupdate' does not work just after a buffer has opened
|
|
" so use timer to delay the command.
|
|
silent! call timer_stop(s:timer_diffupdate)
|
|
let s:timer_diffupdate = timer_start(100, function('s:diffupdate', [bufnr('%')]))
|
|
endfunction
|
|
|
|
|
|
|
|
" Private --------------------------------------------------------------------
|
|
function! s:syncbind(...) abort
|
|
syncbind
|
|
silent! wincmd p
|
|
silent! wincmd p
|
|
endfunction
|
|
|
|
function! s:diffoff(update) abort
|
|
augroup gina_internal_util_diffthis
|
|
autocmd! * <buffer>
|
|
augroup END
|
|
diffoff
|
|
if a:update
|
|
call s:diffupdate(bufnr('%'))
|
|
endif
|
|
endfunction
|
|
|
|
function! s:diffoff_all() abort
|
|
let winid = win_getid()
|
|
for winnr in range(1, winnr('$'))
|
|
if getwinvar(winnr, '&diff')
|
|
call win_gotoid(win_getid(winnr))
|
|
call s:diffoff(0)
|
|
endif
|
|
endfor
|
|
call win_gotoid(winid)
|
|
call s:diffupdate(bufnr('%'))
|
|
endfunction
|
|
|
|
function! s:diffupdate(bufnr, ...) abort
|
|
let winid = bufwinid(a:bufnr)
|
|
if winid == -1
|
|
return
|
|
endif
|
|
let winid_saved = win_getid()
|
|
try
|
|
if winid != winid_saved
|
|
call win_gotoid(winid)
|
|
endif
|
|
diffupdate
|
|
syncbind
|
|
finally
|
|
call win_gotoid(winid_saved)
|
|
endtry
|
|
endfunction
|
|
|
|
function! s:diffcount() abort
|
|
let indicators = map(
|
|
\ range(1, winnr('$')),
|
|
\ 'getwinvar(v:val, ''&diff'')'
|
|
\)
|
|
let indicators = filter(indicators, 'v:val')
|
|
return len(indicators)
|
|
endfunction
|
|
|
|
function! s:call_super(cls, method, ...) abort dict
|
|
return call(a:cls.__super[a:method], a:000, self)
|
|
endfunction
|
|
|
|
function! s:is_sign_visible(bufnr) abort
|
|
if !exists('&signcolumn') || &signcolumn ==# 'auto'
|
|
return len(split(execute('sign place buffer=' . a:bufnr), '\r\?\n')) > 1
|
|
else
|
|
return &signcolumn ==# 'yes'
|
|
endif
|
|
endfunction
|