" Location: autoload/fugitive.vim
" Maintainer: Tim Pope
" The functions contained within this file are for internal use only. For the
" official API, see the commented functions in plugin/fugitive.vim.
if exists('g:autoloaded_fugitive')
finish
endif
let g:autoloaded_fugitive = 1
" Section: Utility
function! s:function(name) abort
return function(substitute(a:name,'^s:',matchstr(expand(''), '.*\zs\d\+_'),''))
endfunction
function! s:sub(str,pat,rep) abort
return substitute(a:str,'\v\C'.a:pat,a:rep,'')
endfunction
function! s:gsub(str,pat,rep) abort
return substitute(a:str,'\v\C'.a:pat,a:rep,'g')
endfunction
function! s:Uniq(list) abort
let i = 0
let seen = {}
while i < len(a:list)
let str = string(a:list[i])
if has_key(seen, str)
call remove(a:list, i)
else
let seen[str] = 1
let i += 1
endif
endwhile
return a:list
endfunction
function! s:JoinChomp(list) abort
if empty(a:list[-1])
return join(a:list[0:-2], "\n")
else
return join(a:list, "\n")
endif
endfunction
function! s:winshell() abort
return has('win32') && &shellcmdflag !~# '^-'
endfunction
function! s:WinShellEsc(arg) abort
if type(a:arg) == type([])
return join(map(copy(a:arg), 's:WinShellEsc(v:val)'))
elseif a:arg =~# '^[A-Za-z0-9_/:.-]\+$'
return a:arg
else
return '"' . s:gsub(s:gsub(a:arg, '"', '""'), '\%', '"%"') . '"'
endif
endfunction
function! s:shellesc(arg) abort
if type(a:arg) == type([])
return join(map(copy(a:arg), 's:shellesc(v:val)'))
elseif a:arg =~# '^[A-Za-z0-9_/:.-]\+$'
return a:arg
elseif s:winshell()
return '"' . s:gsub(s:gsub(a:arg, '"', '""'), '\%', '"%"') . '"'
else
return shellescape(a:arg)
endif
endfunction
function! s:fnameescape(file) abort
if type(a:file) == type([])
return join(map(copy(a:file), 's:fnameescape(v:val)'))
else
return fnameescape(a:file)
endif
endfunction
function! fugitive#UrlDecode(str) abort
return substitute(a:str, '%\(\x\x\)', '\=iconv(nr2char("0x".submatch(1)), "utf-8", "latin1")', 'g')
endfunction
function! s:UrlEncode(str) abort
return substitute(a:str, '[%#?&;+=\<> [:cntrl:]]', '\=printf("%%%02X", char2nr(submatch(0)))', 'g')
endfunction
function! s:PathUrlEncode(str) abort
return substitute(a:str, '[%#?[:cntrl:]]', '\=printf("%%%02X", char2nr(submatch(0)))', 'g')
endfunction
function! s:PathJoin(prefix, str) abort
if a:prefix =~# '://'
return a:prefix . s:PathUrlEncode(a:str)
else
return a:prefix . a:str
endif
endfunction
function! s:throw(string) abort
throw 'fugitive: '.a:string
endfunction
function! s:VersionCheck() abort
if v:version < 704
return 'return ' . string('echoerr "fugitive: Vim 7.4 or newer required"')
elseif empty(fugitive#GitVersion())
let exe = get(s:GitCmd(), 0, '')
if len(exe) && !executable(exe)
return 'return ' . string('echoerr "fugitive: cannot find ' . string(exe) . ' in PATH"')
endif
return 'return ' . string('echoerr "fugitive: cannot execute Git"')
elseif !fugitive#GitVersion(1, 8, 5)
return 'return ' . string('echoerr "fugitive: Git 1.8.5 or newer required"')
else
return ''
endif
endfunction
let s:worktree_error = "core.worktree is required when using an external Git dir"
function! s:DirCheck(...) abort
let vcheck = s:VersionCheck()
if !empty(vcheck)
return vcheck
endif
let dir = call('FugitiveGitDir', a:000)
if !empty(dir) && FugitiveWorkTree(dir, 1) is# 0
return 'return ' . string('echoerr "fugitive: ' . s:worktree_error . '"')
elseif !empty(dir)
return ''
elseif empty(bufname(''))
return 'return ' . string('echoerr "fugitive: working directory does not belong to a Git repository"')
else
return 'return ' . string('echoerr "fugitive: file does not belong to a Git repository"')
endif
endfunction
function! s:Mods(mods, ...) abort
let mods = substitute(a:mods, '\C', '', '')
let mods = mods =~# '\S$' ? mods . ' ' : mods
if a:0 && mods !~# '\<\%(aboveleft\|belowright\|leftabove\|rightbelow\|topleft\|botright\|tab\)\>'
if a:1 ==# 'Edge'
if mods =~# '\' ? &splitright : &splitbelow
let mods = 'botright ' . mods
else
let mods = 'topleft ' . mods
endif
else
let mods = a:1 . ' ' . mods
endif
endif
return substitute(mods, '\s\+', ' ', 'g')
endfunction
if exists('+shellslash')
let s:dir_commit_file = '\c^fugitive://\%(/[^/]\@=\)\=\(.\{-1,\}\)//\%(\(\x\{40,\}\|[0-3]\)\(/.*\)\=\)\=$'
function! s:Slash(path) abort
return tr(a:path, '\', '/')
endfunction
function! s:VimSlash(path) abort
return tr(a:path, '\/', &shellslash ? '//' : '\\')
endfunction
else
let s:dir_commit_file = '\c^fugitive://\(.\{-\}\)//\%(\(\x\{40,\}\|[0-3]\)\(/.*\)\=\)\=$'
function! s:Slash(path) abort
return a:path
endfunction
function! s:VimSlash(path) abort
return a:path
endfunction
endif
function! s:AbsoluteVimPath(...) abort
if a:0 && type(a:1) == type('')
let path = a:1
else
let path = bufname(a:0 && a:1 > 0 ? a:1 : '')
if getbufvar(a:0 && a:1 > 0 ? a:1 : '', '&buftype') !~# '^\%(nowrite\|acwrite\)\=$'
return path
endif
endif
if s:Slash(path) =~# '^/\|^\a\+:'
return path
else
return getcwd() . matchstr(getcwd(), '[\\/]') . path
endif
endfunction
function! s:Resolve(path) abort
let path = resolve(a:path)
if has('win32')
let path = s:VimSlash(fnamemodify(fnamemodify(path, ':h'), ':p') . fnamemodify(path, ':t'))
endif
return path
endfunction
function! s:FileIgnoreCase(for_completion) abort
return (exists('+fileignorecase') && &fileignorecase)
\ || (a:for_completion && exists('+wildignorecase') && &wildignorecase)
endfunction
function! s:cpath(path, ...) abort
if s:FileIgnoreCase(0)
let path = s:VimSlash(tolower(a:path))
else
let path = s:VimSlash(a:path)
endif
return a:0 ? path ==# s:cpath(a:1) : path
endfunction
let s:quote_chars = {
\ "\007": 'a', "\010": 'b', "\011": 't', "\012": 'n', "\013": 'v', "\014": 'f', "\015": 'r',
\ '"': '"', '\': '\'}
let s:unquote_chars = {
\ 'a': "\007", 'b': "\010", 't': "\011", 'n': "\012", 'v': "\013", 'f': "\014", 'r': "\015",
\ '"': '"', '\': '\'}
function! s:Quote(string) abort
let string = substitute(a:string, "[\001-\037\"\\\177]", '\="\\" . get(s:quote_chars, submatch(0), printf("%03o", char2nr(submatch(0))))', 'g')
if string !=# a:string
return '"' . string . '"'
else
return string
endif
endfunction
function! fugitive#Unquote(string) abort
let string = substitute(a:string, "\t*$", '', '')
if string =~# '^".*"$'
return substitute(string[1:-2], '\\\(\o\o\o\|.\)', '\=get(s:unquote_chars, submatch(1), iconv(nr2char("0" . submatch(1)), "utf-8", "latin1"))', 'g')
else
return string
endif
endfunction
let s:executables = {}
function! s:executable(binary) abort
if !has_key(s:executables, a:binary)
let s:executables[a:binary] = executable(a:binary)
endif
return s:executables[a:binary]
endfunction
if !exists('s:temp_scripts')
let s:temp_scripts = {}
endif
function! s:TempScript(...) abort
let body = join(a:000, "\n")
if !has_key(s:temp_scripts, body)
let s:temp_scripts[body] = tempname() . '.sh'
endif
let temp = s:temp_scripts[body]
if !filereadable(temp)
call writefile(['#!/bin/sh'] + a:000, temp)
endif
return FugitiveGitPath(temp)
endfunction
function! s:DoAutocmd(...) abort
return join(map(copy(a:000), "'doautocmd ' . v:val"), '|')
endfunction
function! s:Map(mode, lhs, rhs, ...) abort
let maps = []
let defer = a:0 && a:1 =~# '' || get(g:, 'fugitive_defer_to_existing_maps')
let flags = substitute(a:0 ? a:1 : '', '', '', '') . (a:rhs =~# '' ? '' : '