Enhance fugitive#Prepare()

This commit is contained in:
Tim Pope
2018-08-30 16:25:06 -04:00
parent 8b4a1017b6
commit 0fe0964385

View File

@@ -204,17 +204,23 @@ function! s:Tree(...) abort
return FugitiveTreeForGitDir(a:0 ? a:1 : get(b:, 'git_dir', ''))
endfunction
function! s:PreparePathArgs(cmd, dir) abort
if fugitive#GitVersion() !~# '^[01]\.'
function! s:PreparePathArgs(cmd, dir, literal) abort
let literal_supported = fugitive#GitVersion() !~# '^0\|^1\.[1-8]\.'
if a:literal && literal_supported
call insert(a:cmd, '--literal-pathspecs')
endif
let split = index(a:cmd, '--')
let tree = s:Tree(a:dir)
if empty(tree) || split < 0
if split < 0
return a:cmd
endif
for i in range(split + 1, len(a:cmd) - 1)
let a:cmd[i] = fugitive#Path(a:cmd[i], './', a:dir)
if type(a:cmd[i]) == type(0)
let a:cmd[i] = fugitive#Path(bufname(a:cmd[i]), './', a:dir)
elseif a:literal
let a:cmd[i] = fugitive#Path(a:cmd[i], './', a:dir)
elseif !literal_supported
let a:cmd[i] = substitute(a:cmd[i], '^:\%(/\|([^)]*)\)\=:\=', './', '')
endif
endfor
return a:cmd
endfunction
@@ -222,7 +228,7 @@ endfunction
function! s:TreeChomp(...) abort
let args = copy(type(a:1) == type([]) ? a:1 : a:000)
let dir = a:0 > 1 && type(a:1) == type([]) ? a:2 : b:git_dir
call s:PreparePathArgs(args, dir)
call s:PreparePathArgs(args, dir, 1)
let tree = s:Tree(dir)
let pre = ''
if empty(tree)
@@ -238,15 +244,66 @@ function! s:TreeChomp(...) abort
\ join(map(args, 's:shellesc(v:val)'))), '\n$', '')
endfunction
function! fugitive#Prepare(cmd, ...) abort
let dir = a:0 ? a:1 : get(b:, 'git_dir', '')
let tree = s:Tree(dir)
let args = type(a:cmd) == type([]) ? join(map(s:PreparePathArgs(copy(a:cmd), dir), 's:shellesc(v:val)')) : a:cmd
let s:prepare_env = {
\ 'sequence.editor': 'GIT_SEQUENCE_EDITOR',
\ 'core.editor': 'GIT_EDITOR',
\ 'core.askpass': 'GIT_ASKPASS',
\ }
function! fugitive#Prepare(...) abort
if !a:0
return g:fugitive_git_executable
endif
if type(a:1) ==# type([])
let cmd = a:000[1:-1] + a:1
else
let cmd = copy(a:000)
endif
let pre = ''
if empty(tree) || (type(a:cmd) == type([]) && index(a:cmd, '--') == len(a:cmd) - 1)
let i = 0
while i < len(cmd)
if cmd[i] =~# '^$\|[\/.]' && cmd[i] !~# '^-'
let dir = remove(cmd, 0)
elseif type(cmd[i]) ==# type(0)
let dir = getbufvar(remove(cmd, i), 'git_dir')
elseif cmd[i] ==# '-c' && len(cmd) > i + 1
let key = matchstr(cmd[i+1], '^[^=]*')
if has_key(s:prepare_env, tolower(key)) || key !~# '\.'
let var = get(s:prepare_env, tolower(key), key)
let val = matchstr(cmd[i+1], '=\zs.*')
if s:winshell()
let pre .= 'set ' . var . '=' . s:shellesc(val) . ' & '
else
let pre = (len(pre) ? pre : 'env ') . var . '=' . s:shellesc(val) . ' '
endif
endif
if fugitive#GitVersion() =~# '^0\|^1\.[1-7]\.' || cmd[i+1] !~# '\.'
call remove(cmd, i, i + 1)
else
let i += 2
endif
elseif cmd[i] =~# '^--.*pathspecs$'
let explicit_pathspec_option = 1
if fugitive#GitVersion() =~# '^0\|^1\.[1-8]\.'
call remove(cmd, i)
else
let i += 1
endif
elseif cmd[i] !~# '^-'
break
else
let i += 1
endif
endwhile
if !exists('dir')
let dir = get(b:, 'git_dir', '')
endif
let tree = s:Tree(dir)
call s:PreparePathArgs(cmd, dir, !exists('explicit_pathspec_option'))
let args = join(map(copy(cmd), 's:shellesc(v:val)'))
if empty(tree) || index(cmd, '--') == len(cmd) - 1
let args = s:shellesc('--git-dir=' . dir) . ' ' . args
elseif fugitive#GitVersion() =~# '^[01]\.'
let pre = 'cd ' . s:shellesc(tree) . (s:winshell() ? ' & ' : '; ')
elseif fugitive#GitVersion() =~# '^0\|^1\.[1-8]\.'
let pre = 'cd ' . s:shellesc(tree) . (s:winshell() ? ' & ' : '; ') . pre
else
let args = '-C ' . s:shellesc(tree) . ' ' . args
endif
@@ -377,6 +434,10 @@ endfunction
call s:add_methods('repo',['dir','tree','bare','route','translate','head'])
function! s:repo_prepare(...) dict abort
return call('fugitive#Prepare', [self.git_dir] + a:000)
endfunction
function! s:repo_git_command(...) dict abort
let git = s:UserCommand() . ' --git-dir='.s:shellesc(self.git_dir)
return git.join(map(copy(a:000),'" ".s:shellesc(v:val)'),'')
@@ -401,7 +462,7 @@ function! s:repo_rev_parse(rev) dict abort
return fugitive#RevParse(a:rev, self.git_dir)
endfunction
call s:add_methods('repo',['git_command','git_chomp','git_chomp_in_tree','rev_parse'])
call s:add_methods('repo',['prepare','git_command','git_chomp','git_chomp_in_tree','rev_parse'])
function! s:repo_superglob(base) dict abort
return map(fugitive#Complete(a:base, self.git_dir), 'substitute(v:val, ''\\\(.\)'', ''\1'', "g")')