" 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 =~# '' ? '' : '