1
0
Fork 0
mirror of synced 2024-11-14 21:18:58 -05:00
ultimate-vim/sources_non_forked/vim-gitgutter/autoload/gitgutter/utility.vim

219 lines
6.4 KiB
VimL
Raw Normal View History

2018-03-31 10:56:26 -04:00
function! gitgutter#utility#supports_overscore_sign()
2018-06-14 06:31:12 -04:00
if gitgutter#utility#windows()
2018-03-31 10:56:26 -04:00
return &encoding ==? 'utf-8'
else
return &termencoding ==? &encoding || &termencoding == ''
endif
endfunction
2017-04-01 07:22:06 -04:00
function! gitgutter#utility#setbufvar(buffer, varname, val)
2018-11-01 06:03:42 -04:00
let buffer = +a:buffer
2018-12-17 06:28:27 -05:00
" Default value for getbufvar() was introduced in Vim 7.3.831.
let bvars = getbufvar(buffer, '')
if empty(bvars)
let bvars = {}
endif
let dict = get(bvars, 'gitgutter', {})
2018-03-31 10:56:26 -04:00
let needs_setting = empty(dict)
2017-04-01 07:22:06 -04:00
let dict[a:varname] = a:val
2018-03-31 10:56:26 -04:00
if needs_setting
2018-11-01 06:03:42 -04:00
call setbufvar(buffer, 'gitgutter', dict)
2018-03-31 10:56:26 -04:00
endif
2017-04-01 07:22:06 -04:00
endfunction
function! gitgutter#utility#getbufvar(buffer, varname, ...)
2019-07-08 12:44:45 -04:00
let bvars = getbufvar(a:buffer, '')
if !empty(bvars)
let dict = get(bvars, 'gitgutter', {})
if has_key(dict, a:varname)
return dict[a:varname]
2017-04-01 07:22:06 -04:00
endif
endif
2019-07-08 12:44:45 -04:00
if a:0
return a:1
endif
2017-04-01 07:22:06 -04:00
endfunction
function! gitgutter#utility#warn(message) abort
echohl WarningMsg
echo 'vim-gitgutter: ' . a:message
echohl None
let v:warningmsg = a:message
endfunction
2018-03-31 10:56:26 -04:00
function! gitgutter#utility#warn_once(bufnr, message, key) abort
if empty(gitgutter#utility#getbufvar(a:bufnr, a:key))
call gitgutter#utility#setbufvar(a:bufnr, a:key, '1')
echohl WarningMsg
2018-03-31 10:56:26 -04:00
redraw | echom 'vim-gitgutter: ' . a:message
echohl None
let v:warningmsg = a:message
endif
endfunction
" Returns truthy when the buffer's file should be processed; and falsey when it shouldn't.
" This function does not and should not make any system calls.
2018-03-31 10:56:26 -04:00
function! gitgutter#utility#is_active(bufnr) abort
return g:gitgutter_enabled &&
2019-03-08 06:04:56 -05:00
\ gitgutter#utility#getbufvar(a:bufnr, 'enabled', 1) &&
\ !pumvisible() &&
2018-03-31 10:56:26 -04:00
\ s:is_file_buffer(a:bufnr) &&
\ s:exists_file(a:bufnr) &&
\ s:not_git_dir(a:bufnr)
endfunction
2018-03-31 10:56:26 -04:00
function! s:not_git_dir(bufnr) abort
return s:dir(a:bufnr) !~ '[/\\]\.git\($\|[/\\]\)'
endfunction
2018-03-31 10:56:26 -04:00
function! s:is_file_buffer(bufnr) abort
return empty(getbufvar(a:bufnr, '&buftype'))
endfunction
2018-03-31 10:56:26 -04:00
" From tpope/vim-fugitive
function! s:winshell()
return &shell =~? 'cmd' || exists('+shellslash') && !&shellslash
endfunction
" From tpope/vim-fugitive
function! gitgutter#utility#shellescape(arg) abort
if a:arg =~ '^[A-Za-z0-9_/.-]\+$'
return a:arg
2018-03-31 10:56:26 -04:00
elseif s:winshell()
return '"' . substitute(substitute(a:arg, '"', '""', 'g'), '%', '"%"', 'g') . '"'
else
return shellescape(a:arg)
endif
endfunction
2018-03-31 10:56:26 -04:00
function! gitgutter#utility#file(bufnr)
return s:abs_path(a:bufnr, 1)
endfunction
2018-03-31 10:56:26 -04:00
" Not shellescaped
function! gitgutter#utility#extension(bufnr) abort
return fnamemodify(s:abs_path(a:bufnr, 0), ':e')
endfunction
2018-03-31 10:56:26 -04:00
function! gitgutter#utility#system(cmd, ...) abort
call gitgutter#debug#log(a:cmd, a:000)
2018-03-31 10:56:26 -04:00
call s:use_known_shell()
silent let output = (a:0 == 0) ? system(a:cmd) : system(a:cmd, a:1)
call s:restore_shell()
2018-03-31 10:56:26 -04:00
return output
endfunction
2018-03-31 10:56:26 -04:00
" Path of file relative to repo root.
"
" * empty string - not set
" * non-empty string - path
" * -1 - pending
" * -2 - not tracked by git
function! gitgutter#utility#repo_path(bufnr, shellesc) abort
let p = gitgutter#utility#getbufvar(a:bufnr, 'path')
return a:shellesc ? gitgutter#utility#shellescape(p) : p
endfunction
let s:set_path_handler = {}
function! s:set_path_handler.out(buffer, path) abort
let path = s:strip_trailing_new_line(a:path)
call gitgutter#utility#setbufvar(a:buffer, 'path', path)
if type(self.continuation) == type(function('tr'))
call self.continuation()
else
call call(self.continuation.function, self.continuation.arguments)
endif
endfunction
function! s:set_path_handler.err(buffer) abort
call gitgutter#utility#setbufvar(a:buffer, 'path', -2)
endfunction
" continuation - a funcref or hash to call after setting the repo path asynchronously.
"
" Returns 'async' if the the path is set asynchronously, 0 otherwise.
function! gitgutter#utility#set_repo_path(bufnr, continuation) abort
2018-03-31 10:56:26 -04:00
" Values of path:
" * non-empty string - path
" * -1 - pending
" * -2 - not tracked by git
call gitgutter#utility#setbufvar(a:bufnr, 'path', -1)
2019-07-08 12:44:45 -04:00
let cmd = gitgutter#utility#cd_cmd(a:bufnr, g:gitgutter_git_executable.' '.g:gitgutter_git_args.' ls-files --error-unmatch --full-name -z -- '.gitgutter#utility#shellescape(s:filename(a:bufnr)))
2018-03-31 10:56:26 -04:00
2019-07-08 12:44:45 -04:00
if g:gitgutter_async && gitgutter#async#available() && !has('vim_starting')
let handler = copy(s:set_path_handler)
let handler.continuation = a:continuation
call gitgutter#async#execute(cmd, a:bufnr, handler)
return 'async'
endif
let path = gitgutter#utility#system(cmd)
if v:shell_error
call gitgutter#utility#setbufvar(a:bufnr, 'path', -2)
else
call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(path))
endif
endfunction
2018-03-31 10:56:26 -04:00
function! gitgutter#utility#cd_cmd(bufnr, cmd) abort
2018-06-14 06:31:12 -04:00
let cd = s:unc_path(a:bufnr) ? 'pushd' : (gitgutter#utility#windows() ? 'cd /d' : 'cd')
2018-03-31 10:56:26 -04:00
return cd.' '.s:dir(a:bufnr).' && '.a:cmd
endfunction
2018-03-31 10:56:26 -04:00
function! s:unc_path(bufnr)
return s:abs_path(a:bufnr, 0) =~ '^\\\\'
endfunction
2018-03-31 10:56:26 -04:00
function! s:use_known_shell() abort
if has('unix') && &shell !=# 'sh'
let [s:shell, s:shellcmdflag, s:shellredir] = [&shell, &shellcmdflag, &shellredir]
let &shell = 'sh'
set shellcmdflag=-c shellredir=>%s\ 2>&1
endif
endfunction
2018-03-31 10:56:26 -04:00
function! s:restore_shell() abort
if has('unix') && exists('s:shell')
let [&shell, &shellcmdflag, &shellredir] = [s:shell, s:shellcmdflag, s:shellredir]
endif
endfunction
2018-03-31 10:56:26 -04:00
function! s:abs_path(bufnr, shellesc)
let p = resolve(expand('#'.a:bufnr.':p'))
return a:shellesc ? gitgutter#utility#shellescape(p) : p
endfunction
2018-03-31 10:56:26 -04:00
function! s:dir(bufnr) abort
return gitgutter#utility#shellescape(fnamemodify(s:abs_path(a:bufnr, 0), ':h'))
endfunction
2018-03-31 10:56:26 -04:00
" Not shellescaped.
function! s:filename(bufnr) abort
return fnamemodify(s:abs_path(a:bufnr, 0), ':t')
endfunction
2018-03-31 10:56:26 -04:00
function! s:exists_file(bufnr) abort
return filereadable(s:abs_path(a:bufnr, 0))
endfunction
2018-12-17 06:28:27 -05:00
" Get rid of any trailing new line or SOH character.
"
" git ls-files -z produces output with null line termination.
" Vim's system() replaces any null characters in the output
" with SOH (start of header), i.e. ^A.
2018-03-31 10:56:26 -04:00
function! s:strip_trailing_new_line(line) abort
2018-12-17 06:28:27 -05:00
return substitute(a:line, '[[:cntrl:]]$', '', '')
2018-03-31 10:56:26 -04:00
endfunction
2018-06-14 06:31:12 -04:00
function! gitgutter#utility#windows()
2018-03-31 10:56:26 -04:00
return has('win64') || has('win32') || has('win16')
endfunction