2010-02-14 14:16:30 -05:00
|
|
|
" fugitive.vim - A Git wrapper so awesome, it should be illegal
|
2011-08-06 16:55:57 -04:00
|
|
|
" Maintainer: Tim Pope <http://tpo.pe/>
|
2018-05-27 01:02:44 -04:00
|
|
|
" Version: 2.3
|
2010-02-15 14:03:22 -05:00
|
|
|
" GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2010-02-15 14:03:04 -05:00
|
|
|
if exists('g:loaded_fugitive') || &cp
|
2009-10-10 19:47:14 -04:00
|
|
|
finish
|
|
|
|
endif
|
|
|
|
let g:loaded_fugitive = 1
|
|
|
|
|
|
|
|
if !exists('g:fugitive_git_executable')
|
|
|
|
let g:fugitive_git_executable = 'git'
|
|
|
|
endif
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Utility
|
2009-10-10 19:47:14 -04:00
|
|
|
|
|
|
|
function! s:function(name) abort
|
|
|
|
return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '<SNR>\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
|
|
|
|
|
2014-06-21 11:11:17 -04:00
|
|
|
function! s:winshell() abort
|
2014-06-22 13:30:41 -04:00
|
|
|
return &shell =~? 'cmd' || exists('+shellslash') && !&shellslash
|
2014-06-21 11:11:17 -04:00
|
|
|
endfunction
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
function! s:shellesc(arg) abort
|
|
|
|
if a:arg =~ '^[A-Za-z0-9_/.-]\+$'
|
|
|
|
return a:arg
|
2014-06-21 11:11:17 -04:00
|
|
|
elseif s:winshell()
|
2012-04-21 10:11:02 -04:00
|
|
|
return '"'.s:gsub(s:gsub(a:arg, '"', '""'), '\%', '"%"').'"'
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
|
|
|
return shellescape(a:arg)
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:fnameescape(file) abort
|
|
|
|
if exists('*fnameescape')
|
|
|
|
return fnameescape(a:file)
|
|
|
|
else
|
|
|
|
return escape(a:file," \t\n*?[{`$\\%#'\"|!<")
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:throw(string) abort
|
|
|
|
let v:errmsg = 'fugitive: '.a:string
|
|
|
|
throw v:errmsg
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:warn(str) abort
|
2010-01-09 19:12:45 -05:00
|
|
|
echohl WarningMsg
|
|
|
|
echomsg a:str
|
|
|
|
echohl None
|
|
|
|
let v:warningmsg = a:str
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:shellslash(path) abort
|
2014-06-21 11:11:17 -04:00
|
|
|
if s:winshell()
|
2010-03-09 19:03:44 -05:00
|
|
|
return s:gsub(a:path,'\\','/')
|
|
|
|
else
|
|
|
|
return a:path
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2017-05-29 22:41:33 -04:00
|
|
|
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
|
|
|
|
|
2013-10-24 00:15:40 -04:00
|
|
|
let s:git_versions = {}
|
|
|
|
|
2017-04-11 18:54:53 -04:00
|
|
|
function! s:git_command() abort
|
|
|
|
return get(g:, 'fugitive_git_command', g:fugitive_git_executable)
|
|
|
|
endfunction
|
|
|
|
|
2013-10-24 00:15:40 -04:00
|
|
|
function! fugitive#git_version(...) abort
|
|
|
|
if !has_key(s:git_versions, g:fugitive_git_executable)
|
|
|
|
let s:git_versions[g:fugitive_git_executable] = matchstr(system(g:fugitive_git_executable.' --version'), "\\S\\+\n")
|
|
|
|
endif
|
|
|
|
return s:git_versions[g:fugitive_git_executable]
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:recall() abort
|
2012-04-07 15:42:09 -04:00
|
|
|
let rev = s:sub(s:buffer().rev(), '^/', '')
|
2011-08-09 15:15:05 -04:00
|
|
|
if rev ==# ':'
|
2012-07-28 11:54:52 -04:00
|
|
|
return matchstr(getline('.'),'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( ([^()[:digit:]]\+)\)\=$\|^\d\{6} \x\{40\} \d\t\zs.*')
|
2013-03-12 02:15:40 -04:00
|
|
|
elseif s:buffer().type('tree')
|
|
|
|
let file = matchstr(getline('.'), '\t\zs.*')
|
|
|
|
if empty(file) && line('.') > 2
|
|
|
|
let file = s:sub(getline('.'), '/$', '')
|
|
|
|
endif
|
|
|
|
if !empty(file) && rev !~# ':$'
|
|
|
|
return rev . '/' . file
|
|
|
|
else
|
|
|
|
return rev . file
|
|
|
|
endif
|
2011-08-09 15:15:05 -04:00
|
|
|
endif
|
|
|
|
return rev
|
|
|
|
endfunction
|
|
|
|
|
2018-05-06 19:11:34 -04:00
|
|
|
function! s:map(mode, lhs, rhs, ...) abort
|
|
|
|
let flags = (a:0 ? a:1 : '') . (a:rhs =~# '^<Plug>' ? '' : '<script>')
|
|
|
|
let head = a:lhs
|
|
|
|
let tail = ''
|
|
|
|
let keys = get(g:, a:mode.'remap', {})
|
2018-05-15 23:11:13 -04:00
|
|
|
if type(keys) == type([])
|
2018-05-06 19:11:34 -04:00
|
|
|
return
|
|
|
|
endif
|
|
|
|
while !empty(head)
|
|
|
|
if has_key(keys, head)
|
|
|
|
let head = keys[head]
|
|
|
|
if empty(head)
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
break
|
|
|
|
endif
|
|
|
|
let tail = matchstr(head, '<[^<>]*>$\|.$') . tail
|
|
|
|
let head = substitute(head, '<[^<>]*>$\|.$', '', '')
|
|
|
|
endwhile
|
2018-05-06 22:35:44 -04:00
|
|
|
if flags !~# '<unique>' || empty(mapcheck(head.tail, a:mode))
|
|
|
|
exe a:mode.'map <buffer>' flags head.tail a:rhs
|
|
|
|
endif
|
2018-05-06 19:11:34 -04:00
|
|
|
endfunction
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
function! s:add_methods(namespace, method_names) abort
|
|
|
|
for name in a:method_names
|
|
|
|
let s:{a:namespace}_prototype[name] = s:function('s:'.a:namespace.'_'.name)
|
|
|
|
endfor
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
let s:commands = []
|
|
|
|
function! s:command(definition) abort
|
|
|
|
let s:commands += [a:definition]
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:define_commands() abort
|
2009-10-10 19:47:14 -04:00
|
|
|
for command in s:commands
|
|
|
|
exe 'command! -buffer '.command
|
|
|
|
endfor
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
let s:abstract_prototype = {}
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Initialization
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2012-03-18 22:44:04 -04:00
|
|
|
function! fugitive#is_git_dir(path) abort
|
2012-06-04 15:16:48 -04:00
|
|
|
let path = s:sub(a:path, '[\/]$', '') . '/'
|
2016-02-24 16:08:55 -05:00
|
|
|
return getfsize(path.'HEAD') > 10 && (
|
|
|
|
\ isdirectory(path.'objects') && isdirectory(path.'refs') ||
|
|
|
|
\ getftype(path.'commondir') ==# 'file')
|
2012-03-18 22:44:04 -04:00
|
|
|
endfunction
|
|
|
|
|
2018-05-12 19:46:36 -04:00
|
|
|
function! FugitiveIsGitDir(path) abort
|
|
|
|
return fugitive#is_git_dir(a:path)
|
|
|
|
endfunction
|
|
|
|
|
2012-03-18 22:44:04 -04:00
|
|
|
function! fugitive#extract_git_dir(path) abort
|
2012-03-25 22:19:19 -04:00
|
|
|
if s:shellslash(a:path) =~# '^fugitive://.*//'
|
|
|
|
return matchstr(s:shellslash(a:path), '\C^fugitive://\zs.\{-\}\ze//')
|
2012-03-18 22:44:04 -04:00
|
|
|
endif
|
2017-04-29 19:15:00 -04:00
|
|
|
if isdirectory(a:path)
|
|
|
|
let path = fnamemodify(a:path, ':p:s?[\/]$??')
|
|
|
|
else
|
|
|
|
let path = fnamemodify(a:path, ':p:h:s?[\/]$??')
|
|
|
|
endif
|
|
|
|
let root = s:shellslash(resolve(path))
|
2012-03-18 22:44:04 -04:00
|
|
|
let previous = ""
|
|
|
|
while root !=# previous
|
2013-12-17 07:33:07 -05:00
|
|
|
if root =~# '\v^//%([^/]+/?)?$'
|
|
|
|
" This is for accessing network shares from Cygwin Vim. There won't be
|
|
|
|
" any git directory called //.git or //serverName/.git so let's avoid
|
|
|
|
" checking for them since such checks are extremely slow.
|
|
|
|
break
|
|
|
|
endif
|
2014-01-21 18:39:48 -05:00
|
|
|
if index(split($GIT_CEILING_DIRECTORIES, ':'), root) >= 0
|
|
|
|
break
|
|
|
|
endif
|
2014-03-02 21:21:48 -05:00
|
|
|
if root ==# $GIT_WORK_TREE && fugitive#is_git_dir($GIT_DIR)
|
2015-11-03 09:45:03 -05:00
|
|
|
return simplify(fnamemodify(expand($GIT_DIR), ':p:s?[\/]$??'))
|
2014-03-02 21:21:48 -05:00
|
|
|
endif
|
2014-11-06 13:38:07 -05:00
|
|
|
if fugitive#is_git_dir($GIT_DIR)
|
|
|
|
" Ensure that we've cached the worktree
|
2015-11-03 09:45:03 -05:00
|
|
|
call s:configured_tree(simplify(fnamemodify(expand($GIT_DIR), ':p:s?[\/]$??')))
|
2014-11-06 13:38:07 -05:00
|
|
|
if has_key(s:dir_for_worktree, root)
|
|
|
|
return s:dir_for_worktree[root]
|
|
|
|
endif
|
|
|
|
endif
|
2012-03-18 22:44:04 -04:00
|
|
|
let dir = s:sub(root, '[\/]$', '') . '/.git'
|
|
|
|
let type = getftype(dir)
|
|
|
|
if type ==# 'dir' && fugitive#is_git_dir(dir)
|
|
|
|
return dir
|
|
|
|
elseif type ==# 'link' && fugitive#is_git_dir(dir)
|
|
|
|
return resolve(dir)
|
2012-03-20 08:10:46 -04:00
|
|
|
elseif type !=# '' && filereadable(dir)
|
2012-04-03 06:52:48 -04:00
|
|
|
let line = get(readfile(dir, '', 1), 0, '')
|
2012-05-15 21:50:13 -04:00
|
|
|
if line =~# '^gitdir: \.' && fugitive#is_git_dir(root.'/'.line[8:-1])
|
|
|
|
return simplify(root.'/'.line[8:-1])
|
|
|
|
elseif line =~# '^gitdir: ' && fugitive#is_git_dir(line[8:-1])
|
2012-03-14 22:02:20 -04:00
|
|
|
return line[8:-1]
|
|
|
|
endif
|
2012-03-18 22:44:04 -04:00
|
|
|
elseif fugitive#is_git_dir(root)
|
|
|
|
return root
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2012-03-18 22:44:04 -04:00
|
|
|
let previous = root
|
2012-04-10 22:49:31 -04:00
|
|
|
let root = fnamemodify(root, ':h')
|
2009-10-10 19:47:14 -04:00
|
|
|
endwhile
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
|
2018-05-12 19:46:36 -04:00
|
|
|
function! FugitiveExtractGitDir(path) abort
|
|
|
|
return fugitive#extract_git_dir(a:path)
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! fugitive#detect(path) abort
|
2011-08-06 17:05:46 -04:00
|
|
|
if exists('b:git_dir') && (b:git_dir ==# '' || b:git_dir =~# '/$')
|
2010-01-24 22:59:42 -05:00
|
|
|
unlet b:git_dir
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
if !exists('b:git_dir')
|
2012-03-18 22:44:04 -04:00
|
|
|
let dir = fugitive#extract_git_dir(a:path)
|
2012-04-10 22:49:31 -04:00
|
|
|
if dir !=# ''
|
2009-10-10 19:47:14 -04:00
|
|
|
let b:git_dir = dir
|
2017-04-29 19:15:00 -04:00
|
|
|
if empty(fugitive#buffer().path())
|
|
|
|
silent! exe haslocaldir() ? 'lcd .' : 'cd .'
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
if exists('b:git_dir')
|
2014-11-20 15:43:36 -05:00
|
|
|
if exists('#User#FugitiveBoot')
|
|
|
|
try
|
|
|
|
let [save_mls, &modelines] = [&mls, 0]
|
|
|
|
doautocmd User FugitiveBoot
|
|
|
|
finally
|
|
|
|
let &mls = save_mls
|
|
|
|
endtry
|
|
|
|
endif
|
2015-02-11 07:14:53 -05:00
|
|
|
if !exists('g:fugitive_no_maps')
|
2018-05-06 19:11:34 -04:00
|
|
|
call s:map('c', '<C-R><C-G>', 'fnameescape(<SID>recall())', '<expr>')
|
|
|
|
call s:map('n', 'y<C-G>', ':call setreg(v:register, <SID>recall())<CR>', '<silent>')
|
2015-02-11 07:14:53 -05:00
|
|
|
endif
|
2010-07-28 14:41:11 -04:00
|
|
|
let buffer = fugitive#buffer()
|
2017-02-03 11:04:54 -05:00
|
|
|
if expand('%:p') =~# '://'
|
2012-04-10 22:49:31 -04:00
|
|
|
call buffer.setvar('&path', s:sub(buffer.getvar('&path'), '^\.%(,|$)', ''))
|
2009-12-13 19:49:35 -05:00
|
|
|
endif
|
2014-07-06 00:20:19 -04:00
|
|
|
if stridx(buffer.getvar('&tags'), escape(b:git_dir, ', ')) == -1
|
|
|
|
if filereadable(b:git_dir.'/tags')
|
|
|
|
call buffer.setvar('&tags', escape(b:git_dir.'/tags', ', ').','.buffer.getvar('&tags'))
|
|
|
|
endif
|
|
|
|
if &filetype !=# '' && filereadable(b:git_dir.'/'.&filetype.'.tags')
|
2012-12-16 20:23:12 -05:00
|
|
|
call buffer.setvar('&tags', escape(b:git_dir.'/'.&filetype.'.tags', ', ').','.buffer.getvar('&tags'))
|
2011-02-07 15:02:25 -05:00
|
|
|
endif
|
2010-07-28 14:41:11 -04:00
|
|
|
endif
|
2014-11-20 15:43:36 -05:00
|
|
|
try
|
|
|
|
let [save_mls, &modelines] = [&mls, 0]
|
2016-05-11 18:01:39 -04:00
|
|
|
call s:define_commands()
|
2014-11-20 15:43:36 -05:00
|
|
|
doautocmd User Fugitive
|
|
|
|
finally
|
|
|
|
let &mls = save_mls
|
|
|
|
endtry
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2018-05-12 19:46:36 -04:00
|
|
|
function! FugitiveDetect(path) abort
|
|
|
|
return fugitive#detect(a:path)
|
|
|
|
endfunction
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
augroup fugitive
|
|
|
|
autocmd!
|
2014-12-02 18:35:18 -05:00
|
|
|
autocmd BufNewFile,BufReadPost * call fugitive#detect(expand('%:p'))
|
2013-02-23 12:24:24 -05:00
|
|
|
autocmd FileType netrw call fugitive#detect(expand('%:p'))
|
2017-11-14 08:58:31 -05:00
|
|
|
autocmd User NERDTreeInit,NERDTreeNewRoot call fugitive#detect(b:NERDTree.root.path.str())
|
2013-02-23 12:24:24 -05:00
|
|
|
autocmd VimEnter * if expand('<amatch>')==''|call fugitive#detect(getcwd())|endif
|
2014-04-02 02:14:32 -04:00
|
|
|
autocmd CmdWinEnter * call fugitive#detect(expand('#:p'))
|
2011-10-04 03:10:04 -04:00
|
|
|
autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave')
|
2009-10-10 19:47:14 -04:00
|
|
|
augroup END
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Repository
|
2009-10-10 19:47:14 -04:00
|
|
|
|
|
|
|
let s:repo_prototype = {}
|
|
|
|
let s:repos = {}
|
2014-11-06 13:38:07 -05:00
|
|
|
let s:worktree_for_dir = {}
|
|
|
|
let s:dir_for_worktree = {}
|
2009-10-10 19:47:14 -04:00
|
|
|
|
|
|
|
function! s:repo(...) abort
|
2012-03-18 22:44:04 -04:00
|
|
|
let dir = a:0 ? a:1 : (exists('b:git_dir') && b:git_dir !=# '' ? b:git_dir : fugitive#extract_git_dir(expand('%:p')))
|
2009-11-10 21:17:21 -05:00
|
|
|
if dir !=# ''
|
2012-04-10 22:49:31 -04:00
|
|
|
if has_key(s:repos, dir)
|
|
|
|
let repo = get(s:repos, dir)
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
|
|
|
let repo = {'git_dir': dir}
|
|
|
|
let s:repos[dir] = repo
|
|
|
|
endif
|
2012-04-10 22:49:31 -04:00
|
|
|
return extend(extend(repo, s:repo_prototype, 'keep'), s:abstract_prototype, 'keep')
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2009-11-10 21:17:21 -05:00
|
|
|
call s:throw('not a git repository: '.expand('%:p'))
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! fugitive#repo(...) abort
|
2011-10-04 20:25:32 -04:00
|
|
|
return call('s:repo', a:000)
|
|
|
|
endfunction
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
function! s:repo_dir(...) dict abort
|
|
|
|
return join([self.git_dir]+a:000,'/')
|
|
|
|
endfunction
|
|
|
|
|
2014-11-06 13:38:07 -05:00
|
|
|
function! s:configured_tree(git_dir) abort
|
|
|
|
if !has_key(s:worktree_for_dir, a:git_dir)
|
|
|
|
let s:worktree_for_dir[a:git_dir] = ''
|
|
|
|
let config_file = a:git_dir . '/config'
|
|
|
|
if filereadable(config_file)
|
|
|
|
let config = readfile(config_file,'',10)
|
2012-03-18 22:22:28 -04:00
|
|
|
call filter(config,'v:val =~# "^\\s*worktree *="')
|
|
|
|
if len(config) == 1
|
2016-02-24 16:08:55 -05:00
|
|
|
let worktree = matchstr(config[0], '= *\zs.*')
|
2012-03-18 22:22:28 -04:00
|
|
|
endif
|
2016-02-24 16:08:55 -05:00
|
|
|
elseif filereadable(a:git_dir . '/gitdir')
|
|
|
|
let worktree = fnamemodify(readfile(a:git_dir . '/gitdir')[0], ':h')
|
2016-02-24 19:29:27 -05:00
|
|
|
if worktree ==# '.'
|
|
|
|
unlet! worktree
|
|
|
|
endif
|
2016-02-24 16:08:55 -05:00
|
|
|
endif
|
|
|
|
if exists('worktree')
|
|
|
|
let s:worktree_for_dir[a:git_dir] = worktree
|
|
|
|
let s:dir_for_worktree[s:worktree_for_dir[a:git_dir]] = a:git_dir
|
2012-03-14 22:02:20 -04:00
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2014-11-06 13:38:07 -05:00
|
|
|
if s:worktree_for_dir[a:git_dir] =~# '^\.'
|
|
|
|
return simplify(a:git_dir . '/' . s:worktree_for_dir[a:git_dir])
|
2012-05-17 21:42:06 -04:00
|
|
|
else
|
2014-11-06 13:38:07 -05:00
|
|
|
return s:worktree_for_dir[a:git_dir]
|
2012-05-17 21:42:06 -04:00
|
|
|
endif
|
2012-03-18 22:09:46 -04:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:repo_tree(...) dict abort
|
|
|
|
if self.dir() =~# '/\.git$'
|
|
|
|
let dir = self.dir()[0:-6]
|
2017-05-07 15:29:01 -04:00
|
|
|
if dir !~# '/'
|
|
|
|
let dir .= '/'
|
|
|
|
endif
|
2012-03-18 22:09:46 -04:00
|
|
|
else
|
2014-11-06 13:38:07 -05:00
|
|
|
let dir = s:configured_tree(self.git_dir)
|
2012-03-18 22:09:46 -04:00
|
|
|
endif
|
|
|
|
if dir ==# ''
|
|
|
|
call s:throw('no work tree')
|
|
|
|
else
|
|
|
|
return join([dir]+a:000,'/')
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:repo_bare() dict abort
|
2012-03-14 22:02:20 -04:00
|
|
|
if self.dir() =~# '/\.git$'
|
|
|
|
return 0
|
|
|
|
else
|
2014-11-06 13:38:07 -05:00
|
|
|
return s:configured_tree(self.git_dir) ==# ''
|
2013-07-21 21:52:08 -04:00
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:repo_translate(spec) dict abort
|
2016-02-24 15:53:51 -05:00
|
|
|
let refs = self.dir('refs/')
|
2016-02-24 16:08:55 -05:00
|
|
|
if filereadable(self.dir('commondir'))
|
|
|
|
let refs = simplify(self.dir(get(readfile(self.dir('commondir'), 1), 0, ''))) . '/refs/'
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
if a:spec ==# '.' || a:spec ==# '/.'
|
|
|
|
return self.bare() ? self.dir() : self.tree()
|
2012-03-27 13:33:04 -04:00
|
|
|
elseif a:spec =~# '^/\=\.git$' && self.bare()
|
|
|
|
return self.dir()
|
|
|
|
elseif a:spec =~# '^/\=\.git/'
|
|
|
|
return self.dir(s:sub(a:spec, '^/=\.git/', ''))
|
2009-10-10 19:47:14 -04:00
|
|
|
elseif a:spec =~# '^/'
|
2012-03-27 13:33:04 -04:00
|
|
|
return self.tree().a:spec
|
2009-10-10 19:47:14 -04:00
|
|
|
elseif a:spec =~# '^:[0-3]:'
|
|
|
|
return 'fugitive://'.self.dir().'//'.a:spec[1].'/'.a:spec[3:-1]
|
|
|
|
elseif a:spec ==# ':'
|
2012-03-18 21:55:53 -04:00
|
|
|
if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(self.dir())] ==# self.dir('') && filereadable($GIT_INDEX_FILE)
|
2010-01-09 18:19:07 -05:00
|
|
|
return fnamemodify($GIT_INDEX_FILE,':p')
|
|
|
|
else
|
|
|
|
return self.dir('index')
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
elseif a:spec =~# '^:/'
|
|
|
|
let ref = self.rev_parse(matchstr(a:spec,'.[^:]*'))
|
|
|
|
return 'fugitive://'.self.dir().'//'.ref
|
|
|
|
elseif a:spec =~# '^:'
|
|
|
|
return 'fugitive://'.self.dir().'//0/'.a:spec[1:-1]
|
2015-12-01 18:06:38 -05:00
|
|
|
elseif a:spec ==# '@'
|
|
|
|
return self.dir('HEAD')
|
2016-02-24 15:53:51 -05:00
|
|
|
elseif a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(refs . '../' . a:spec)
|
|
|
|
return simplify(refs . '../' . a:spec)
|
|
|
|
elseif filereadable(refs.a:spec)
|
|
|
|
return refs.a:spec
|
|
|
|
elseif filereadable(refs.'tags/'.a:spec)
|
|
|
|
return refs.'tags/'.a:spec
|
|
|
|
elseif filereadable(refs.'heads/'.a:spec)
|
|
|
|
return refs.'heads/'.a:spec
|
|
|
|
elseif filereadable(refs.'remotes/'.a:spec)
|
|
|
|
return refs.'remotes/'.a:spec
|
|
|
|
elseif filereadable(refs.'remotes/'.a:spec.'/HEAD')
|
2016-05-11 17:37:45 -04:00
|
|
|
return refs.'remotes/'.a:spec.'/HEAD'
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
|
|
|
try
|
|
|
|
let ref = self.rev_parse(matchstr(a:spec,'[^:]*'))
|
|
|
|
let path = s:sub(matchstr(a:spec,':.*'),'^:','/')
|
|
|
|
return 'fugitive://'.self.dir().'//'.ref.path
|
|
|
|
catch /^fugitive:/
|
|
|
|
return self.tree(a:spec)
|
|
|
|
endtry
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2012-04-17 15:28:11 -04:00
|
|
|
function! s:repo_head(...) dict abort
|
|
|
|
let head = s:repo().head_ref()
|
|
|
|
|
|
|
|
if head =~# '^ref: '
|
|
|
|
let branch = s:sub(head,'^ref: %(refs/%(heads/|remotes/|tags/)=)=','')
|
|
|
|
elseif head =~# '^\x\{40\}$'
|
|
|
|
" truncate hash to a:1 characters if we're in detached head mode
|
|
|
|
let len = a:0 ? a:1 : 0
|
|
|
|
let branch = len ? head[0:len-1] : ''
|
2014-03-30 13:13:46 -04:00
|
|
|
else
|
|
|
|
return ''
|
2012-04-17 15:28:11 -04:00
|
|
|
endif
|
|
|
|
|
|
|
|
return branch
|
|
|
|
endfunction
|
|
|
|
|
2014-11-06 13:38:07 -05:00
|
|
|
call s:add_methods('repo',['dir','tree','bare','translate','head'])
|
2009-10-10 19:47:14 -04:00
|
|
|
|
|
|
|
function! s:repo_git_command(...) dict abort
|
2017-04-11 18:54:53 -04:00
|
|
|
let git = s:git_command() . ' --git-dir='.s:shellesc(self.git_dir)
|
2009-10-10 19:47:14 -04:00
|
|
|
return git.join(map(copy(a:000),'" ".s:shellesc(v:val)'),'')
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:repo_git_chomp(...) dict abort
|
2017-04-11 18:54:53 -04:00
|
|
|
let git = g:fugitive_git_executable . ' --git-dir='.s:shellesc(self.git_dir)
|
|
|
|
let output = git.join(map(copy(a:000),'" ".s:shellesc(v:val)'),'')
|
|
|
|
return s:sub(system(output),'\n$','')
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:repo_git_chomp_in_tree(...) dict abort
|
2017-05-30 14:10:37 -04:00
|
|
|
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
|
2009-10-10 19:47:14 -04:00
|
|
|
let dir = getcwd()
|
|
|
|
try
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(s:repo().tree())
|
2009-10-10 19:47:14 -04:00
|
|
|
return call(s:repo().git_chomp, a:000, s:repo())
|
|
|
|
finally
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(dir)
|
2009-10-10 19:47:14 -04:00
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:repo_rev_parse(rev) dict abort
|
|
|
|
let hash = self.git_chomp('rev-parse','--verify',a:rev)
|
2011-02-26 13:45:24 -05:00
|
|
|
if hash =~ '\<\x\{40\}$'
|
|
|
|
return matchstr(hash,'\<\x\{40\}$')
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2009-11-10 21:17:21 -05:00
|
|
|
call s:throw('rev-parse '.a:rev.': '.hash)
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
call s:add_methods('repo',['git_command','git_chomp','git_chomp_in_tree','rev_parse'])
|
|
|
|
|
|
|
|
function! s:repo_dirglob(base) dict abort
|
|
|
|
let base = s:sub(a:base,'^/','')
|
|
|
|
let matches = split(glob(self.tree(s:gsub(base,'/','*&').'*/')),"\n")
|
|
|
|
call map(matches,'v:val[ strlen(self.tree())+(a:base !~ "^/") : -1 ]')
|
|
|
|
return matches
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:repo_superglob(base) dict abort
|
|
|
|
if a:base =~# '^/' || a:base !~# ':'
|
|
|
|
let results = []
|
|
|
|
if a:base !~# '^/'
|
|
|
|
let heads = ["HEAD","ORIG_HEAD","FETCH_HEAD","MERGE_HEAD"]
|
|
|
|
let heads += sort(split(s:repo().git_chomp("rev-parse","--symbolic","--branches","--tags","--remotes"),"\n"))
|
2015-08-27 16:18:56 -04:00
|
|
|
" Add any stashes.
|
|
|
|
if filereadable(s:repo().dir('refs/stash'))
|
|
|
|
let heads += ["stash"]
|
|
|
|
let heads += sort(split(s:repo().git_chomp("stash","list","--pretty=format:%gd"),"\n"))
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
call filter(heads,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
|
|
|
|
let results += heads
|
|
|
|
endif
|
|
|
|
if !self.bare()
|
|
|
|
let base = s:sub(a:base,'^/','')
|
|
|
|
let matches = split(glob(self.tree(s:gsub(base,'/','*&').'*')),"\n")
|
2010-03-09 19:03:44 -05:00
|
|
|
call map(matches,'s:shellslash(v:val)')
|
2009-10-10 19:47:14 -04:00
|
|
|
call map(matches,'v:val !~ "/$" && isdirectory(v:val) ? v:val."/" : v:val')
|
|
|
|
call map(matches,'v:val[ strlen(self.tree())+(a:base !~ "^/") : -1 ]')
|
|
|
|
let results += matches
|
|
|
|
endif
|
|
|
|
return results
|
|
|
|
|
|
|
|
elseif a:base =~# '^:'
|
|
|
|
let entries = split(self.git_chomp('ls-files','--stage'),"\n")
|
|
|
|
call map(entries,'s:sub(v:val,".*(\\d)\\t(.*)",":\\1:\\2")')
|
|
|
|
if a:base !~# '^:[0-3]\%(:\|$\)'
|
|
|
|
call filter(entries,'v:val[1] == "0"')
|
|
|
|
call map(entries,'v:val[2:-1]')
|
|
|
|
endif
|
|
|
|
call filter(entries,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
|
|
|
|
return entries
|
|
|
|
|
|
|
|
else
|
|
|
|
let tree = matchstr(a:base,'.*[:/]')
|
|
|
|
let entries = split(self.git_chomp('ls-tree',tree),"\n")
|
|
|
|
call map(entries,'s:sub(v:val,"^04.*\\zs$","/")')
|
|
|
|
call map(entries,'tree.s:sub(v:val,".*\t","")')
|
|
|
|
return filter(entries,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base')
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
call s:add_methods('repo',['dirglob','superglob'])
|
|
|
|
|
2011-08-21 13:52:33 -04:00
|
|
|
function! s:repo_config(conf) dict abort
|
2017-04-11 18:54:53 -04:00
|
|
|
return matchstr(s:repo().git_chomp('config',a:conf),"[^\r\n]*")
|
2011-08-21 13:52:33 -04:00
|
|
|
endfun
|
|
|
|
|
|
|
|
function! s:repo_user() dict abort
|
|
|
|
let username = s:repo().config('user.name')
|
|
|
|
let useremail = s:repo().config('user.email')
|
|
|
|
return username.' <'.useremail.'>'
|
|
|
|
endfun
|
|
|
|
|
|
|
|
function! s:repo_aliases() dict abort
|
|
|
|
if !has_key(self,'_aliases')
|
|
|
|
let self._aliases = {}
|
2016-10-21 16:01:34 -04:00
|
|
|
for line in split(self.git_chomp('config','-z','--get-regexp','^alias[.]'),"\1")
|
|
|
|
let self._aliases[matchstr(line, '\.\zs.\{-}\ze\n')] = matchstr(line, '\n\zs.*')
|
2011-08-21 13:52:33 -04:00
|
|
|
endfor
|
|
|
|
endif
|
|
|
|
return self._aliases
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
call s:add_methods('repo',['config', 'user', 'aliases'])
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
function! s:repo_keywordprg() dict abort
|
2012-10-09 18:35:44 -04:00
|
|
|
let args = ' --git-dir='.escape(self.dir(),"\\\"' ")
|
2010-03-08 22:57:18 -05:00
|
|
|
if has('gui_running') && !has('win32')
|
2017-04-11 18:54:53 -04:00
|
|
|
return s:git_command() . ' --no-pager' . args . ' log -1'
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
2017-04-11 18:54:53 -04:00
|
|
|
return s:git_command() . args . ' show'
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
call s:add_methods('repo',['keywordprg'])
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Buffer
|
2009-10-10 19:47:14 -04:00
|
|
|
|
|
|
|
let s:buffer_prototype = {}
|
|
|
|
|
|
|
|
function! s:buffer(...) abort
|
|
|
|
let buffer = {'#': bufnr(a:0 ? a:1 : '%')}
|
|
|
|
call extend(extend(buffer,s:buffer_prototype,'keep'),s:abstract_prototype,'keep')
|
2009-11-10 21:17:21 -05:00
|
|
|
if buffer.getvar('git_dir') !=# ''
|
|
|
|
return buffer
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2009-11-10 21:17:21 -05:00
|
|
|
call s:throw('not a git repository: '.expand('%:p'))
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! fugitive#buffer(...) abort
|
|
|
|
return s:buffer(a:0 ? a:1 : '%')
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:buffer_getvar(var) dict abort
|
2014-04-01 18:59:01 -04:00
|
|
|
return getbufvar(self['#'],a:var)
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
2009-12-13 19:49:35 -05:00
|
|
|
function! s:buffer_setvar(var,value) dict abort
|
2014-04-01 18:59:01 -04:00
|
|
|
return setbufvar(self['#'],a:var,a:value)
|
2009-12-13 19:49:35 -05:00
|
|
|
endfunction
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
function! s:buffer_getline(lnum) dict abort
|
2014-04-01 18:59:01 -04:00
|
|
|
return get(getbufline(self['#'], a:lnum), 0, '')
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:buffer_repo() dict abort
|
|
|
|
return s:repo(self.getvar('git_dir'))
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:buffer_type(...) dict abort
|
|
|
|
if self.getvar('fugitive_type') != ''
|
|
|
|
let type = self.getvar('fugitive_type')
|
2010-08-03 15:23:25 -04:00
|
|
|
elseif fnamemodify(self.spec(),':p') =~# '.\git/refs/\|\.git/\w*HEAD$'
|
2009-10-10 19:47:14 -04:00
|
|
|
let type = 'head'
|
|
|
|
elseif self.getline(1) =~ '^tree \x\{40\}$' && self.getline(2) == ''
|
|
|
|
let type = 'tree'
|
|
|
|
elseif self.getline(1) =~ '^\d\{6\} \w\{4\} \x\{40\}\>\t'
|
|
|
|
let type = 'tree'
|
|
|
|
elseif self.getline(1) =~ '^\d\{6\} \x\{40\}\> \d\t'
|
|
|
|
let type = 'index'
|
2010-08-03 15:23:25 -04:00
|
|
|
elseif isdirectory(self.spec())
|
2009-10-10 19:47:14 -04:00
|
|
|
let type = 'directory'
|
2010-08-03 15:23:25 -04:00
|
|
|
elseif self.spec() == ''
|
2010-02-07 21:54:07 -05:00
|
|
|
let type = 'null'
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
2011-08-25 20:24:01 -04:00
|
|
|
let type = 'file'
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
if a:0
|
|
|
|
return !empty(filter(copy(a:000),'v:val ==# type'))
|
|
|
|
else
|
|
|
|
return type
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2010-12-03 01:38:26 -05:00
|
|
|
if has('win32')
|
|
|
|
|
|
|
|
function! s:buffer_spec() dict abort
|
|
|
|
let bufname = bufname(self['#'])
|
|
|
|
let retval = ''
|
|
|
|
for i in split(bufname,'[^:]\zs\\')
|
|
|
|
let retval = fnamemodify((retval==''?'':retval.'\').i,':.')
|
|
|
|
endfor
|
|
|
|
return s:shellslash(fnamemodify(retval,':p'))
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
function! s:buffer_spec() dict abort
|
|
|
|
let bufname = bufname(self['#'])
|
|
|
|
return s:shellslash(bufname == '' ? '' : fnamemodify(bufname,':p'))
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2010-08-03 15:23:25 -04:00
|
|
|
function! s:buffer_name() dict abort
|
|
|
|
return self.spec()
|
|
|
|
endfunction
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
function! s:buffer_commit() dict abort
|
2010-08-03 15:23:25 -04:00
|
|
|
return matchstr(self.spec(),'^fugitive://.\{-\}//\zs\w*')
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
2015-06-30 17:42:13 -04:00
|
|
|
function! s:cpath(path) abort
|
2015-07-01 10:55:35 -04:00
|
|
|
if exists('+fileignorecase') && &fileignorecase
|
2015-06-30 17:42:13 -04:00
|
|
|
return tolower(a:path)
|
|
|
|
else
|
|
|
|
return a:path
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
function! s:buffer_path(...) dict abort
|
2010-08-03 15:23:25 -04:00
|
|
|
let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
|
2009-10-10 19:47:14 -04:00
|
|
|
if rev != ''
|
|
|
|
let rev = s:sub(rev,'\w*','')
|
2015-06-30 17:42:13 -04:00
|
|
|
elseif s:cpath(self.spec()[0 : len(self.repo().dir())]) ==#
|
|
|
|
\ s:cpath(self.repo().dir() . '/')
|
2011-10-08 16:03:50 -04:00
|
|
|
let rev = '/.git'.self.spec()[strlen(self.repo().dir()) : -1]
|
2015-06-30 17:42:13 -04:00
|
|
|
elseif !self.repo().bare() &&
|
|
|
|
\ s:cpath(self.spec()[0 : len(self.repo().tree())]) ==#
|
|
|
|
\ s:cpath(self.repo().tree() . '/')
|
2010-08-03 15:23:25 -04:00
|
|
|
let rev = self.spec()[strlen(self.repo().tree()) : -1]
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2010-09-09 11:51:04 -04:00
|
|
|
return s:sub(s:sub(rev,'.\zs/$',''),'^/',a:0 ? a:1 : '')
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:buffer_rev() dict abort
|
2010-08-03 15:23:25 -04:00
|
|
|
let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
|
2009-10-10 19:47:14 -04:00
|
|
|
if rev =~ '^\x/'
|
|
|
|
return ':'.rev[0].':'.rev[2:-1]
|
|
|
|
elseif rev =~ '.'
|
|
|
|
return s:sub(rev,'/',':')
|
2010-08-03 15:23:25 -04:00
|
|
|
elseif self.spec() =~ '\.git/index$'
|
2009-10-10 19:47:14 -04:00
|
|
|
return ':'
|
2010-08-03 15:23:25 -04:00
|
|
|
elseif self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
|
|
|
|
return self.spec()[strlen(self.repo().dir())+1 : -1]
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
2012-04-07 15:42:09 -04:00
|
|
|
return self.path('/')
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:buffer_sha1() dict abort
|
2010-08-03 15:23:25 -04:00
|
|
|
if self.spec() =~ '^fugitive://' || self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
|
2009-10-10 19:47:14 -04:00
|
|
|
return self.repo().rev_parse(self.rev())
|
|
|
|
else
|
|
|
|
return ''
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:buffer_expand(rev) dict abort
|
|
|
|
if a:rev =~# '^:[0-3]$'
|
|
|
|
let file = a:rev.self.path(':')
|
2011-02-26 12:39:13 -05:00
|
|
|
elseif a:rev =~# '^[-:]/$'
|
|
|
|
let file = '/'.self.path()
|
2009-10-10 19:47:14 -04:00
|
|
|
elseif a:rev =~# '^-'
|
|
|
|
let file = 'HEAD^{}'.a:rev[1:-1].self.path(':')
|
|
|
|
elseif a:rev =~# '^@{'
|
|
|
|
let file = 'HEAD'.a:rev.self.path(':')
|
|
|
|
elseif a:rev =~# '^[~^]'
|
|
|
|
let commit = s:sub(self.commit(),'^\d=$','HEAD')
|
|
|
|
let file = commit.a:rev.self.path(':')
|
|
|
|
else
|
|
|
|
let file = a:rev
|
|
|
|
endif
|
2017-11-30 15:00:35 -05:00
|
|
|
return s:sub(substitute(file,
|
|
|
|
\ '%$\|\\\([[:punct:]]\)','\=len(submatch(1)) ? submatch(1) : self.path()','g'),
|
|
|
|
\ '\.\@<=/$','')
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:buffer_containing_commit() dict abort
|
2009-11-11 00:16:02 -05:00
|
|
|
if self.commit() =~# '^\d$'
|
2009-10-10 19:47:14 -04:00
|
|
|
return ':'
|
2009-11-11 00:16:02 -05:00
|
|
|
elseif self.commit() =~# '.'
|
|
|
|
return self.commit()
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
|
|
|
return 'HEAD'
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2012-04-07 16:14:51 -04:00
|
|
|
function! s:buffer_up(...) dict abort
|
|
|
|
let rev = self.rev()
|
|
|
|
let c = a:0 ? a:1 : 1
|
|
|
|
while c
|
|
|
|
if rev =~# '^[/:]$'
|
|
|
|
let rev = 'HEAD'
|
|
|
|
elseif rev =~# '^:'
|
|
|
|
let rev = ':'
|
2012-04-07 16:23:49 -04:00
|
|
|
elseif rev =~# '^refs/[^^~:]*$\|^[^^~:]*HEAD$'
|
2012-04-07 16:14:51 -04:00
|
|
|
let rev .= '^{}'
|
|
|
|
elseif rev =~# '^/\|:.*/'
|
|
|
|
let rev = s:sub(rev, '.*\zs/.*', '')
|
|
|
|
elseif rev =~# ':.'
|
|
|
|
let rev = matchstr(rev, '^[^:]*:')
|
|
|
|
elseif rev =~# ':$'
|
|
|
|
let rev = rev[0:-2]
|
|
|
|
else
|
|
|
|
return rev.'~'.c
|
|
|
|
endif
|
|
|
|
let c -= 1
|
|
|
|
endwhile
|
|
|
|
return rev
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
call s:add_methods('buffer',['getvar','setvar','getline','repo','type','spec','name','commit','path','rev','sha1','expand','containing_commit','up'])
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Git
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2010-03-19 19:59:08 -04:00
|
|
|
call s:command("-bang -nargs=? -complete=customlist,s:GitComplete Git :execute s:Git(<bang>0,<q-args>)")
|
2009-10-10 19:47:14 -04:00
|
|
|
|
|
|
|
function! s:ExecuteInTree(cmd) abort
|
2017-05-30 14:10:37 -04:00
|
|
|
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
|
2009-10-10 19:47:14 -04:00
|
|
|
let dir = getcwd()
|
|
|
|
try
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(s:repo().tree())
|
2009-10-10 19:47:14 -04:00
|
|
|
execute a:cmd
|
|
|
|
finally
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(dir)
|
2009-10-10 19:47:14 -04:00
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
2014-06-11 03:30:27 -04:00
|
|
|
function! s:Git(bang, args) abort
|
2011-08-19 02:43:31 -04:00
|
|
|
if a:bang
|
2014-06-11 03:30:27 -04:00
|
|
|
return s:Edit('edit', 1, a:args)
|
2011-08-19 02:43:31 -04:00
|
|
|
endif
|
2017-04-11 18:54:53 -04:00
|
|
|
let git = s:git_command()
|
2010-03-08 22:57:18 -05:00
|
|
|
if has('gui_running') && !has('win32')
|
2009-10-10 19:47:14 -04:00
|
|
|
let git .= ' --no-pager'
|
|
|
|
endif
|
2014-06-11 03:30:27 -04:00
|
|
|
let args = matchstr(a:args,'\v\C.{-}%($|\\@<!%(\\\\)*\|)@=')
|
2017-07-12 17:33:37 -04:00
|
|
|
if exists(':terminal') && has('nvim')
|
2015-03-28 11:11:07 -04:00
|
|
|
let dir = s:repo().tree()
|
2017-02-10 12:35:36 -05:00
|
|
|
if expand('%') != ''
|
|
|
|
-tabedit %
|
|
|
|
else
|
|
|
|
-tabnew
|
|
|
|
endif
|
2015-03-28 11:11:07 -04:00
|
|
|
execute 'lcd' fnameescape(dir)
|
|
|
|
execute 'terminal' git args
|
|
|
|
else
|
|
|
|
call s:ExecuteInTree('!'.git.' '.args)
|
|
|
|
if has('win32')
|
|
|
|
call fugitive#reload_status()
|
|
|
|
endif
|
|
|
|
endif
|
2014-06-11 03:30:27 -04:00
|
|
|
return matchstr(a:args, '\v\C\\@<!%(\\\\)*\|\zs.*')
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
2014-06-29 10:53:52 -04:00
|
|
|
function! fugitive#git_commands() abort
|
2009-10-10 19:47:14 -04:00
|
|
|
if !exists('s:exec_path')
|
|
|
|
let s:exec_path = s:sub(system(g:fugitive_git_executable.' --exec-path'),'\n$','')
|
|
|
|
endif
|
2014-06-29 10:53:52 -04:00
|
|
|
return map(split(glob(s:exec_path.'/git-*'),"\n"),'s:sub(v:val[strlen(s:exec_path)+5 : -1],"\\.exe$","")')
|
|
|
|
endfunction
|
|
|
|
|
2014-06-29 10:58:41 -04:00
|
|
|
function! s:GitComplete(A, L, P) abort
|
|
|
|
if strpart(a:L, 0, a:P) !~# ' [[:alnum:]-]\+ '
|
|
|
|
let cmds = fugitive#git_commands()
|
2014-06-17 02:30:30 -04:00
|
|
|
return filter(sort(cmds+keys(s:repo().aliases())), 'strpart(v:val, 0, strlen(a:A)) ==# a:A')
|
2014-06-29 10:58:41 -04:00
|
|
|
else
|
|
|
|
return s:repo().superglob(a:A)
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Gcd, Glcd
|
2009-10-10 19:47:14 -04:00
|
|
|
|
|
|
|
function! s:DirComplete(A,L,P) abort
|
|
|
|
let matches = s:repo().dirglob(a:A)
|
|
|
|
return matches
|
|
|
|
endfunction
|
|
|
|
|
2017-05-30 14:10:37 -04:00
|
|
|
call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Gcd :exe 'cd<bang>' s:fnameescape(s:repo().bare() ? s:repo().dir(<q-args>) : s:repo().tree(<q-args>))")
|
|
|
|
call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Glcd :exe 'lcd<bang>' s:fnameescape(s:repo().bare() ? s:repo().dir(<q-args>) : s:repo().tree(<q-args>))")
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Gstatus
|
2009-10-19 22:11:40 -04:00
|
|
|
|
|
|
|
call s:command("-bar Gstatus :execute s:Status()")
|
2013-03-12 02:01:49 -04:00
|
|
|
augroup fugitive_status
|
|
|
|
autocmd!
|
|
|
|
if !has('win32')
|
|
|
|
autocmd FocusGained,ShellCmdPost * call fugitive#reload_status()
|
2015-03-28 11:11:07 -04:00
|
|
|
autocmd BufDelete term://* call fugitive#reload_status()
|
2013-03-12 02:01:49 -04:00
|
|
|
endif
|
|
|
|
augroup END
|
2009-10-19 22:11:40 -04:00
|
|
|
|
2010-01-09 17:01:44 -05:00
|
|
|
function! s:Status() abort
|
2009-10-19 22:11:40 -04:00
|
|
|
try
|
|
|
|
Gpedit :
|
|
|
|
wincmd P
|
2013-09-14 08:37:03 -04:00
|
|
|
setlocal foldmethod=syntax foldlevel=1
|
2011-09-02 15:19:06 -04:00
|
|
|
nnoremap <buffer> <silent> q :<C-U>bdelete<CR>
|
2009-10-19 22:11:40 -04:00
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
|
2010-01-09 17:01:44 -05:00
|
|
|
function! fugitive#reload_status() abort
|
2013-03-12 02:01:49 -04:00
|
|
|
if exists('s:reloading_status')
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
try
|
|
|
|
let s:reloading_status = 1
|
|
|
|
let mytab = tabpagenr()
|
|
|
|
for tab in [mytab] + range(1,tabpagenr('$'))
|
|
|
|
for winnr in range(1,tabpagewinnr(tab,'$'))
|
|
|
|
if getbufvar(tabpagebuflist(tab)[winnr-1],'fugitive_type') ==# 'index'
|
|
|
|
execute 'tabnext '.tab
|
|
|
|
if winnr != winnr()
|
|
|
|
execute winnr.'wincmd w'
|
|
|
|
let restorewinnr = 1
|
2009-10-19 22:11:40 -04:00
|
|
|
endif
|
2013-03-12 02:01:49 -04:00
|
|
|
try
|
|
|
|
if !&modified
|
|
|
|
call s:BufReadIndex()
|
|
|
|
endif
|
|
|
|
finally
|
|
|
|
if exists('restorewinnr')
|
|
|
|
wincmd p
|
|
|
|
endif
|
|
|
|
execute 'tabnext '.mytab
|
|
|
|
endtry
|
|
|
|
endif
|
|
|
|
endfor
|
2009-10-19 22:11:40 -04:00
|
|
|
endfor
|
2013-03-12 02:01:49 -04:00
|
|
|
finally
|
|
|
|
unlet! s:reloading_status
|
|
|
|
endtry
|
2009-10-19 22:11:40 -04:00
|
|
|
endfunction
|
|
|
|
|
2018-05-12 19:46:36 -04:00
|
|
|
function! fugitive#ReloadStatus() abort
|
|
|
|
return fugitive#reload_status()
|
|
|
|
endfunction
|
|
|
|
|
2012-07-16 18:10:27 -04:00
|
|
|
function! s:stage_info(lnum) abort
|
2012-07-28 11:54:52 -04:00
|
|
|
let filename = matchstr(getline(a:lnum),'^#\t\zs.\{-\}\ze\%( ([^()[:digit:]]\+)\)\=$')
|
2012-07-16 11:16:35 -04:00
|
|
|
let lnum = a:lnum
|
2013-02-10 13:01:22 -05:00
|
|
|
if has('multi_byte_encoding')
|
|
|
|
let colon = '\%(:\|\%uff1a\)'
|
|
|
|
else
|
|
|
|
let colon = ':'
|
|
|
|
endif
|
2013-01-09 23:11:30 -05:00
|
|
|
while lnum && getline(lnum) !~# colon.'$'
|
2012-07-16 11:16:35 -04:00
|
|
|
let lnum -= 1
|
|
|
|
endwhile
|
|
|
|
if !lnum
|
2012-07-16 18:10:27 -04:00
|
|
|
return ['', '']
|
2014-03-05 17:57:43 -05:00
|
|
|
elseif (getline(lnum+1) =~# '^# .*\<git \%(reset\|rm --cached\) ' && getline(lnum+2) ==# '#') || getline(lnum) ==# '# Changes to be committed:'
|
2013-01-09 23:11:30 -05:00
|
|
|
return [matchstr(filename, colon.' *\zs.*'), 'staged']
|
2014-06-20 07:52:06 -04:00
|
|
|
elseif (getline(lnum+1) =~# '^# .*\<git add ' && getline(lnum+2) ==# '#' && getline(lnum+3) !~# colon.' ') || getline(lnum) ==# '# Untracked files:'
|
2014-03-05 17:57:43 -05:00
|
|
|
return [filename, 'untracked']
|
2013-06-05 21:35:15 -04:00
|
|
|
elseif getline(lnum+2) =~# '^# .*\<git checkout ' || getline(lnum) ==# '# Changes not staged for commit:'
|
2013-01-09 23:11:30 -05:00
|
|
|
return [matchstr(filename, colon.' *\zs.*'), 'unstaged']
|
2014-03-05 17:57:43 -05:00
|
|
|
elseif getline(lnum+2) =~# '^# .*\<git \%(add\|rm\)' || getline(lnum) ==# '# Unmerged paths:'
|
2013-01-09 23:11:30 -05:00
|
|
|
return [matchstr(filename, colon.' *\zs.*'), 'unmerged']
|
2012-07-28 11:54:52 -04:00
|
|
|
else
|
2014-03-05 17:57:43 -05:00
|
|
|
return ['', 'unknown']
|
2012-07-16 11:16:35 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:StageNext(count) abort
|
2012-09-07 01:07:54 -04:00
|
|
|
for i in range(a:count)
|
|
|
|
call search('^#\t.*','W')
|
|
|
|
endfor
|
|
|
|
return '.'
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:StagePrevious(count) abort
|
2014-04-10 14:53:49 -04:00
|
|
|
if line('.') == 1 && exists(':CtrlP') && get(g:, 'ctrl_p_map') =~? '^<c-p>$'
|
2012-09-07 01:15:48 -04:00
|
|
|
return 'CtrlP '.fnameescape(s:repo().tree())
|
|
|
|
else
|
|
|
|
for i in range(a:count)
|
|
|
|
call search('^#\t.*','Wbe')
|
|
|
|
endfor
|
|
|
|
return '.'
|
|
|
|
endif
|
2012-09-07 01:07:54 -04:00
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:StageReloadSeek(target,lnum1,lnum2) abort
|
2011-08-21 13:45:21 -04:00
|
|
|
let jump = a:target
|
2013-01-09 23:11:30 -05:00
|
|
|
let f = matchstr(getline(a:lnum1-1),'^#\t\%([[:alpha:] ]\+: *\|.*\%uff1a *\)\=\zs.*')
|
2011-08-21 13:45:21 -04:00
|
|
|
if f !=# '' | let jump = f | endif
|
2013-01-09 23:11:30 -05:00
|
|
|
let f = matchstr(getline(a:lnum2+1),'^#\t\%([[:alpha:] ]\+: *\|.*\%uff1a *\)\=\zs.*')
|
2011-08-21 13:45:21 -04:00
|
|
|
if f !=# '' | let jump = f | endif
|
|
|
|
silent! edit!
|
|
|
|
1
|
|
|
|
redraw
|
2013-01-09 23:11:30 -05:00
|
|
|
call search('^#\t\%([[:alpha:] ]\+: *\|.*\%uff1a *\)\=\V'.jump.'\%( ([^()[:digit:]]\+)\)\=\$','W')
|
2011-08-21 13:45:21 -04:00
|
|
|
endfunction
|
|
|
|
|
2014-06-21 10:05:46 -04:00
|
|
|
function! s:StageUndo() abort
|
|
|
|
let [filename, section] = s:stage_info(line('.'))
|
|
|
|
if empty(filename)
|
|
|
|
return ''
|
|
|
|
endif
|
|
|
|
let repo = s:repo()
|
|
|
|
let hash = repo.git_chomp('hash-object', '-w', filename)
|
|
|
|
if !empty(hash)
|
|
|
|
if section ==# 'untracked'
|
2016-08-08 15:18:18 -04:00
|
|
|
call repo.git_chomp_in_tree('clean', '-f', '--', filename)
|
2016-03-09 21:31:25 -05:00
|
|
|
elseif section ==# 'unmerged'
|
|
|
|
call repo.git_chomp_in_tree('rm', '--', filename)
|
2014-06-21 10:05:46 -04:00
|
|
|
elseif section ==# 'unstaged'
|
2014-06-25 10:29:17 -04:00
|
|
|
call repo.git_chomp_in_tree('checkout', '--', filename)
|
2014-06-21 10:05:46 -04:00
|
|
|
else
|
2014-06-25 10:29:17 -04:00
|
|
|
call repo.git_chomp_in_tree('checkout', 'HEAD', '--', filename)
|
2014-06-21 10:05:46 -04:00
|
|
|
endif
|
|
|
|
call s:StageReloadSeek(filename, line('.'), line('.'))
|
|
|
|
let @" = hash
|
|
|
|
return 'checktime|redraw|echomsg ' .
|
|
|
|
\ string('To restore, :Git cat-file blob '.hash[0:6].' > '.filename)
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2011-08-19 15:01:37 -04:00
|
|
|
function! s:StageDiff(diff) abort
|
2012-07-16 18:10:27 -04:00
|
|
|
let [filename, section] = s:stage_info(line('.'))
|
2012-07-16 11:16:35 -04:00
|
|
|
if filename ==# '' && section ==# 'staged'
|
2013-05-17 23:58:10 -04:00
|
|
|
return 'Git! diff --no-ext-diff --cached'
|
2010-03-19 21:48:41 -04:00
|
|
|
elseif filename ==# ''
|
2013-05-17 23:58:10 -04:00
|
|
|
return 'Git! diff --no-ext-diff'
|
2012-07-16 18:10:27 -04:00
|
|
|
elseif filename =~# ' -> '
|
2010-03-19 21:23:41 -04:00
|
|
|
let [old, new] = split(filename,' -> ')
|
|
|
|
execute 'Gedit '.s:fnameescape(':0:'.new)
|
2011-08-19 15:01:37 -04:00
|
|
|
return a:diff.' HEAD:'.s:fnameescape(old)
|
2012-07-16 11:16:35 -04:00
|
|
|
elseif section ==# 'staged'
|
2010-03-19 21:23:41 -04:00
|
|
|
execute 'Gedit '.s:fnameescape(':0:'.filename)
|
2011-08-19 15:01:37 -04:00
|
|
|
return a:diff.' -'
|
2010-03-19 21:23:41 -04:00
|
|
|
else
|
|
|
|
execute 'Gedit '.s:fnameescape('/'.filename)
|
2011-08-19 15:01:37 -04:00
|
|
|
return a:diff
|
2010-03-19 21:23:41 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2011-08-19 15:13:44 -04:00
|
|
|
function! s:StageDiffEdit() abort
|
2012-07-16 18:10:27 -04:00
|
|
|
let [filename, section] = s:stage_info(line('.'))
|
2011-08-21 13:45:21 -04:00
|
|
|
let arg = (filename ==# '' ? '.' : filename)
|
2012-07-16 11:16:35 -04:00
|
|
|
if section ==# 'staged'
|
2013-05-17 23:58:10 -04:00
|
|
|
return 'Git! diff --no-ext-diff --cached '.s:shellesc(arg)
|
2012-07-16 11:16:35 -04:00
|
|
|
elseif section ==# 'untracked'
|
2011-08-21 13:45:21 -04:00
|
|
|
let repo = s:repo()
|
|
|
|
call repo.git_chomp_in_tree('add','--intent-to-add',arg)
|
|
|
|
if arg ==# '.'
|
|
|
|
silent! edit!
|
|
|
|
1
|
2012-08-01 16:00:02 -04:00
|
|
|
if !search('^# .*:\n#.*\n# .*"git checkout \|^# Changes not staged for commit:$','W')
|
2012-07-16 11:16:35 -04:00
|
|
|
call search('^# .*:$','W')
|
2011-08-21 13:45:21 -04:00
|
|
|
endif
|
|
|
|
else
|
|
|
|
call s:StageReloadSeek(arg,line('.'),line('.'))
|
|
|
|
endif
|
|
|
|
return ''
|
2011-08-19 15:13:44 -04:00
|
|
|
else
|
2013-05-17 23:58:10 -04:00
|
|
|
return 'Git! diff --no-ext-diff '.s:shellesc(arg)
|
2011-08-19 15:13:44 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2010-01-09 17:01:44 -05:00
|
|
|
function! s:StageToggle(lnum1,lnum2) abort
|
2013-03-29 22:58:23 -04:00
|
|
|
if a:lnum1 == 1 && a:lnum2 == 1
|
|
|
|
return 'Gedit /.git|call search("^index$", "wc")'
|
|
|
|
endif
|
2009-10-19 22:11:40 -04:00
|
|
|
try
|
2009-10-22 21:54:55 -04:00
|
|
|
let output = ''
|
|
|
|
for lnum in range(a:lnum1,a:lnum2)
|
2012-07-16 18:10:27 -04:00
|
|
|
let [filename, section] = s:stage_info(lnum)
|
2011-04-26 08:35:02 -04:00
|
|
|
let repo = s:repo()
|
2012-07-16 18:10:27 -04:00
|
|
|
if getline('.') =~# '^# .*:$'
|
2012-07-16 11:16:35 -04:00
|
|
|
if section ==# 'staged'
|
|
|
|
call repo.git_chomp_in_tree('reset','-q')
|
|
|
|
silent! edit!
|
|
|
|
1
|
2012-08-01 16:00:02 -04:00
|
|
|
if !search('^# .*:\n# .*"git add .*\n#\n\|^# Untracked files:$','W')
|
2012-07-16 11:16:35 -04:00
|
|
|
call search('^# .*:$','W')
|
|
|
|
endif
|
|
|
|
return ''
|
|
|
|
elseif section ==# 'unstaged'
|
|
|
|
call repo.git_chomp_in_tree('add','-u')
|
|
|
|
silent! edit!
|
|
|
|
1
|
2012-08-01 16:00:02 -04:00
|
|
|
if !search('^# .*:\n# .*"git add .*\n#\n\|^# Untracked files:$','W')
|
2012-07-16 11:16:35 -04:00
|
|
|
call search('^# .*:$','W')
|
|
|
|
endif
|
|
|
|
return ''
|
|
|
|
else
|
|
|
|
call repo.git_chomp_in_tree('add','.')
|
|
|
|
silent! edit!
|
|
|
|
1
|
|
|
|
call search('^# .*:$','W')
|
|
|
|
return ''
|
2011-04-23 22:15:28 -04:00
|
|
|
endif
|
2010-01-09 23:31:22 -05:00
|
|
|
endif
|
2009-10-22 21:54:55 -04:00
|
|
|
if filename ==# ''
|
|
|
|
continue
|
|
|
|
endif
|
|
|
|
execute lnum
|
2017-05-14 06:48:03 -04:00
|
|
|
if section ==# 'staged'
|
|
|
|
if filename =~ ' -> '
|
|
|
|
let files_to_unstage = split(filename,' -> ')
|
|
|
|
else
|
|
|
|
let files_to_unstage = [filename]
|
|
|
|
endif
|
|
|
|
let filename = files_to_unstage[-1]
|
|
|
|
let cmd = ['reset','-q','--'] + files_to_unstage
|
2012-07-16 18:10:27 -04:00
|
|
|
elseif getline(lnum) =~# '^#\tdeleted:'
|
2009-10-22 21:54:55 -04:00
|
|
|
let cmd = ['rm','--',filename]
|
2012-07-28 11:54:52 -04:00
|
|
|
elseif getline(lnum) =~# '^#\tmodified:'
|
2009-10-22 21:54:55 -04:00
|
|
|
let cmd = ['add','--',filename]
|
2012-07-28 11:54:52 -04:00
|
|
|
else
|
|
|
|
let cmd = ['add','-A','--',filename]
|
2009-10-22 21:54:55 -04:00
|
|
|
endif
|
2014-06-21 11:28:33 -04:00
|
|
|
if !exists('first_filename')
|
|
|
|
let first_filename = filename
|
|
|
|
endif
|
2011-04-26 08:35:02 -04:00
|
|
|
let output .= call(repo.git_chomp_in_tree,cmd,s:repo())."\n"
|
2009-10-22 21:54:55 -04:00
|
|
|
endfor
|
|
|
|
if exists('first_filename')
|
2011-08-21 13:45:21 -04:00
|
|
|
call s:StageReloadSeek(first_filename,a:lnum1,a:lnum2)
|
2009-10-19 22:11:40 -04:00
|
|
|
endif
|
2009-10-22 21:54:55 -04:00
|
|
|
echo s:sub(s:gsub(output,'\n+','\n'),'\n$','')
|
2009-10-19 22:11:40 -04:00
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
|
|
|
return 'checktime'
|
|
|
|
endfunction
|
|
|
|
|
2010-01-11 22:51:54 -05:00
|
|
|
function! s:StagePatch(lnum1,lnum2) abort
|
|
|
|
let add = []
|
|
|
|
let reset = []
|
|
|
|
|
|
|
|
for lnum in range(a:lnum1,a:lnum2)
|
2012-07-16 18:10:27 -04:00
|
|
|
let [filename, section] = s:stage_info(lnum)
|
|
|
|
if getline('.') =~# '^# .*:$' && section ==# 'staged'
|
2010-01-11 22:51:54 -05:00
|
|
|
return 'Git reset --patch'
|
2012-07-16 18:10:27 -04:00
|
|
|
elseif getline('.') =~# '^# .*:$' && section ==# 'unstaged'
|
2010-01-11 22:51:54 -05:00
|
|
|
return 'Git add --patch'
|
2012-07-16 18:10:27 -04:00
|
|
|
elseif getline('.') =~# '^# .*:$' && section ==# 'untracked'
|
|
|
|
return 'Git add -N .'
|
|
|
|
elseif filename ==# ''
|
2010-01-11 22:51:54 -05:00
|
|
|
continue
|
|
|
|
endif
|
|
|
|
if !exists('first_filename')
|
|
|
|
let first_filename = filename
|
|
|
|
endif
|
|
|
|
execute lnum
|
2012-07-16 18:10:27 -04:00
|
|
|
if filename =~ ' -> '
|
2010-01-11 22:51:54 -05:00
|
|
|
let reset += [split(filename,' -> ')[1]]
|
2012-07-16 11:16:35 -04:00
|
|
|
elseif section ==# 'staged'
|
2010-01-11 22:51:54 -05:00
|
|
|
let reset += [filename]
|
2012-07-16 18:10:27 -04:00
|
|
|
elseif getline(lnum) !~# '^#\tdeleted:'
|
2010-01-11 22:51:54 -05:00
|
|
|
let add += [filename]
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
try
|
|
|
|
if !empty(add)
|
|
|
|
execute "Git add --patch -- ".join(map(add,'s:shellesc(v:val)'))
|
|
|
|
endif
|
|
|
|
if !empty(reset)
|
2015-03-29 16:29:18 -04:00
|
|
|
execute "Git reset --patch -- ".join(map(reset,'s:shellesc(v:val)'))
|
2010-01-11 22:51:54 -05:00
|
|
|
endif
|
|
|
|
if exists('first_filename')
|
|
|
|
silent! edit!
|
|
|
|
1
|
|
|
|
redraw
|
2012-07-28 11:54:52 -04:00
|
|
|
call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.first_filename.'\%( ([^()[:digit:]]\+)\)\=\$','W')
|
2010-01-11 22:51:54 -05:00
|
|
|
endif
|
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
|
|
|
return 'checktime'
|
|
|
|
endfunction
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Gcommit
|
2010-01-09 23:31:22 -05:00
|
|
|
|
2018-04-06 14:52:53 -04:00
|
|
|
call s:command("-nargs=? -complete=customlist,s:CommitComplete Gcommit :execute s:Commit('<mods>', <q-args>)")
|
2010-01-09 23:31:22 -05:00
|
|
|
|
2018-04-06 14:52:53 -04:00
|
|
|
function! s:Commit(mods, args, ...) abort
|
|
|
|
let mods = s:gsub(a:mods ==# '<mods>' ? '' : a:mods, '<tab>', '-tab')
|
2014-06-30 14:02:53 -04:00
|
|
|
let repo = a:0 ? a:1 : s:repo()
|
2017-05-30 14:10:37 -04:00
|
|
|
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
|
2012-03-03 10:08:00 -05:00
|
|
|
let dir = getcwd()
|
2014-06-30 14:02:53 -04:00
|
|
|
let msgfile = repo.dir('COMMIT_EDITMSG')
|
2010-01-09 23:31:22 -05:00
|
|
|
let outfile = tempname()
|
|
|
|
let errorfile = tempname()
|
|
|
|
try
|
2012-03-03 03:22:48 -05:00
|
|
|
try
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(repo.tree())
|
2014-06-21 11:11:17 -04:00
|
|
|
if s:winshell()
|
2012-03-03 03:22:48 -05:00
|
|
|
let command = ''
|
|
|
|
let old_editor = $GIT_EDITOR
|
|
|
|
let $GIT_EDITOR = 'false'
|
|
|
|
else
|
|
|
|
let command = 'env GIT_EDITOR=false '
|
|
|
|
endif
|
2014-06-30 14:02:53 -04:00
|
|
|
let command .= repo.git_command('commit').' '.a:args
|
2012-03-03 03:22:48 -05:00
|
|
|
if &shell =~# 'csh'
|
2013-03-12 02:32:13 -04:00
|
|
|
noautocmd silent execute '!('.command.' > '.outfile.') >& '.errorfile
|
2014-03-20 13:21:19 -04:00
|
|
|
elseif a:args =~# '\%(^\| \)-\%(-interactive\|p\|-patch\)\>'
|
2013-03-12 02:32:13 -04:00
|
|
|
noautocmd execute '!'.command.' 2> '.errorfile
|
2012-03-03 03:22:48 -05:00
|
|
|
else
|
2013-03-12 02:32:13 -04:00
|
|
|
noautocmd silent execute '!'.command.' > '.outfile.' 2> '.errorfile
|
2012-03-03 03:22:48 -05:00
|
|
|
endif
|
2017-02-25 17:05:12 -05:00
|
|
|
let error = v:shell_error
|
2012-03-03 03:22:48 -05:00
|
|
|
finally
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(dir)
|
2012-03-03 03:22:48 -05:00
|
|
|
endtry
|
2011-05-09 20:05:50 -04:00
|
|
|
if !has('gui_running')
|
|
|
|
redraw!
|
2010-01-13 22:01:43 -05:00
|
|
|
endif
|
2017-02-25 17:05:12 -05:00
|
|
|
if !error
|
2010-01-09 23:31:22 -05:00
|
|
|
if filereadable(outfile)
|
|
|
|
for line in readfile(outfile)
|
|
|
|
echo line
|
|
|
|
endfor
|
|
|
|
endif
|
|
|
|
return ''
|
|
|
|
else
|
2010-10-24 13:40:07 -04:00
|
|
|
let errors = readfile(errorfile)
|
|
|
|
let error = get(errors,-2,get(errors,-1,'!'))
|
2013-04-18 12:53:19 -04:00
|
|
|
if error =~# 'false''\=\.$'
|
2010-01-09 23:31:22 -05:00
|
|
|
let args = a:args
|
2014-07-05 18:58:18 -04:00
|
|
|
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-[esp]|--edit|--interactive|--patch|--signoff)%($| )','')
|
2014-06-21 11:19:59 -04:00
|
|
|
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-c|--reedit-message|--reuse-message|-F|--file|-m|--message)%(\s+|\=)%(''[^'']*''|"%(\\.|[^"])*"|\\.|\S)*','')
|
2010-01-09 23:31:22 -05:00
|
|
|
let args = s:gsub(args,'%(^| )@<=[%#]%(:\w)*','\=expand(submatch(0))')
|
2014-07-05 18:58:18 -04:00
|
|
|
let args = s:sub(args, '\ze -- |$', ' --no-edit --no-interactive --no-signoff')
|
2010-01-09 23:31:22 -05:00
|
|
|
let args = '-F '.s:shellesc(msgfile).' '.args
|
|
|
|
if args !~# '\%(^\| \)--cleanup\>'
|
|
|
|
let args = '--cleanup=strip '.args
|
|
|
|
endif
|
2010-02-07 21:54:07 -05:00
|
|
|
if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&mod
|
2018-04-06 14:52:53 -04:00
|
|
|
execute mods 'keepalt edit' s:fnameescape(msgfile)
|
2018-04-06 14:57:29 -04:00
|
|
|
elseif a:args =~# '\%(^\| \)-\w*v' || mods =~# '\<tab\>'
|
2018-04-06 14:52:53 -04:00
|
|
|
execute mods 'keepalt -tabedit' s:fnameescape(msgfile)
|
2011-09-05 20:46:52 -04:00
|
|
|
elseif s:buffer().type() ==# 'index'
|
2018-04-06 14:52:53 -04:00
|
|
|
execute mods 'keepalt edit' s:fnameescape(msgfile)
|
2011-09-05 20:46:52 -04:00
|
|
|
execute (search('^#','n')+1).'wincmd+'
|
|
|
|
setlocal nopreviewwindow
|
2010-02-07 21:54:07 -05:00
|
|
|
else
|
2018-04-06 14:52:53 -04:00
|
|
|
execute mods 'keepalt split' s:fnameescape(msgfile)
|
2010-02-07 21:54:07 -05:00
|
|
|
endif
|
2010-01-09 23:31:22 -05:00
|
|
|
let b:fugitive_commit_arguments = args
|
2012-03-03 03:22:48 -05:00
|
|
|
setlocal bufhidden=wipe filetype=gitcommit
|
2010-01-09 23:31:22 -05:00
|
|
|
return '1'
|
|
|
|
elseif error ==# '!'
|
|
|
|
return s:Status()
|
|
|
|
else
|
2017-05-07 19:51:45 -04:00
|
|
|
call s:throw(empty(error)?join(errors, ' '):error)
|
2010-01-09 23:31:22 -05:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
finally
|
2010-01-13 22:01:43 -05:00
|
|
|
if exists('old_editor')
|
|
|
|
let $GIT_EDITOR = old_editor
|
|
|
|
endif
|
2010-01-09 23:31:22 -05:00
|
|
|
call delete(outfile)
|
|
|
|
call delete(errorfile)
|
|
|
|
call fugitive#reload_status()
|
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:CommitComplete(A,L,P) abort
|
|
|
|
if a:A =~ '^-' || type(a:A) == type(0) " a:A is 0 on :Gcommit -<Tab>
|
2016-06-24 13:45:00 -04:00
|
|
|
let args = ['-C', '-F', '-a', '-c', '-e', '-i', '-m', '-n', '-o', '-q', '-s', '-t', '-u', '-v', '--all', '--allow-empty', '--amend', '--author=', '--cleanup=', '--dry-run', '--edit', '--file=', '--fixup=', '--include', '--interactive', '--message=', '--no-verify', '--only', '--quiet', '--reedit-message=', '--reuse-message=', '--signoff', '--squash=', '--template=', '--untracked-files', '--verbose']
|
2010-01-09 23:31:22 -05:00
|
|
|
return filter(args,'v:val[0 : strlen(a:A)-1] ==# a:A')
|
|
|
|
else
|
|
|
|
return s:repo().superglob(a:A)
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:FinishCommit() abort
|
2010-01-09 23:31:22 -05:00
|
|
|
let args = getbufvar(+expand('<abuf>'),'fugitive_commit_arguments')
|
|
|
|
if !empty(args)
|
|
|
|
call setbufvar(+expand('<abuf>'),'fugitive_commit_arguments','')
|
2018-04-06 14:52:53 -04:00
|
|
|
return s:Commit('', args, s:repo(getbufvar(+expand('<abuf>'),'git_dir')))
|
2010-01-09 23:31:22 -05:00
|
|
|
endif
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
|
2014-06-25 13:05:14 -04:00
|
|
|
" Section: Gmerge, Gpull
|
|
|
|
|
|
|
|
call s:command("-nargs=? -bang -complete=custom,s:RevisionComplete Gmerge " .
|
|
|
|
\ "execute s:Merge('merge', <bang>0, <q-args>)")
|
|
|
|
call s:command("-nargs=? -bang -complete=custom,s:RemoteComplete Gpull " .
|
|
|
|
\ "execute s:Merge('pull --progress', <bang>0, <q-args>)")
|
|
|
|
|
|
|
|
function! s:RevisionComplete(A, L, P) abort
|
|
|
|
return s:repo().git_chomp('rev-parse', '--symbolic', '--branches', '--tags', '--remotes')
|
|
|
|
\ . "\nHEAD\nFETCH_HEAD\nORIG_HEAD"
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:RemoteComplete(A, L, P) abort
|
|
|
|
let remote = matchstr(a:L, ' \zs\S\+\ze ')
|
|
|
|
if !empty(remote)
|
|
|
|
let matches = split(s:repo().git_chomp('ls-remote', remote), "\n")
|
|
|
|
call filter(matches, 'v:val =~# "\t" && v:val !~# "{"')
|
|
|
|
call map(matches, 's:sub(v:val, "^.*\t%(refs/%(heads/|tags/)=)=", "")')
|
|
|
|
else
|
|
|
|
let matches = split(s:repo().git_chomp('remote'), "\n")
|
|
|
|
endif
|
|
|
|
return join(matches, "\n")
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! fugitive#cwindow() abort
|
|
|
|
if &buftype == 'quickfix'
|
|
|
|
cwindow
|
|
|
|
else
|
|
|
|
botright cwindow
|
|
|
|
if &buftype == 'quickfix'
|
|
|
|
wincmd p
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
let s:common_efm = ''
|
|
|
|
\ . '%+Egit:%.%#,'
|
|
|
|
\ . '%+Eusage:%.%#,'
|
|
|
|
\ . '%+Eerror:%.%#,'
|
|
|
|
\ . '%+Efatal:%.%#,'
|
2014-06-29 14:46:16 -04:00
|
|
|
\ . '%-G%.%#%\e[K%.%#,'
|
2014-06-25 13:05:14 -04:00
|
|
|
\ . '%-G%.%#%\r%.%\+'
|
|
|
|
|
|
|
|
function! s:Merge(cmd, bang, args) abort
|
|
|
|
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
|
|
|
|
let cwd = getcwd()
|
|
|
|
let [mp, efm] = [&l:mp, &l:efm]
|
|
|
|
let had_merge_msg = filereadable(s:repo().dir('MERGE_MSG'))
|
|
|
|
try
|
|
|
|
let &l:errorformat = ''
|
|
|
|
\ . '%-Gerror:%.%#false''.,'
|
|
|
|
\ . '%-G%.%# ''git commit'' %.%#,'
|
|
|
|
\ . '%+Emerge:%.%#,'
|
|
|
|
\ . s:common_efm . ','
|
|
|
|
\ . '%+ECannot %.%#: You have unstaged changes.,'
|
|
|
|
\ . '%+ECannot %.%#: Your index contains uncommitted changes.,'
|
|
|
|
\ . '%+EThere is no tracking information for the current branch.,'
|
|
|
|
\ . '%+EYou are not currently on a branch. Please specify which,'
|
|
|
|
\ . 'CONFLICT (%m): %f deleted in %.%#,'
|
|
|
|
\ . 'CONFLICT (%m): Merge conflict in %f,'
|
|
|
|
\ . 'CONFLICT (%m): Rename \"%f\"->%.%#,'
|
|
|
|
\ . 'CONFLICT (%m): Rename %.%#->%f %.%#,'
|
|
|
|
\ . 'CONFLICT (%m): There is a directory with name %f in %.%#,'
|
|
|
|
\ . '%+ECONFLICT %.%#,'
|
|
|
|
\ . '%+EKONFLIKT %.%#,'
|
|
|
|
\ . '%+ECONFLIT %.%#,'
|
|
|
|
\ . "%+EXUNG \u0110\u1ed8T %.%#,"
|
|
|
|
\ . "%+E\u51b2\u7a81 %.%#,"
|
|
|
|
\ . 'U%\t%f'
|
|
|
|
if a:cmd =~# '^merge' && empty(a:args) &&
|
|
|
|
\ (had_merge_msg || isdirectory(s:repo().dir('rebase-apply')) ||
|
|
|
|
\ !empty(s:repo().git_chomp('diff-files', '--diff-filter=U')))
|
|
|
|
let &l:makeprg = g:fugitive_git_executable.' diff-files --name-status --diff-filter=U'
|
|
|
|
else
|
2017-04-11 18:54:53 -04:00
|
|
|
let &l:makeprg = s:sub(s:git_command() . ' ' . a:cmd .
|
2015-05-19 11:12:13 -04:00
|
|
|
\ (a:args =~# ' \%(--no-edit\|--abort\|-m\)\>' ? '' : ' --edit') .
|
|
|
|
\ ' ' . a:args, ' *$', '')
|
2014-06-25 13:05:14 -04:00
|
|
|
endif
|
2015-05-19 11:12:13 -04:00
|
|
|
if !empty($GIT_EDITOR) || has('win32')
|
2014-06-25 13:05:14 -04:00
|
|
|
let old_editor = $GIT_EDITOR
|
|
|
|
let $GIT_EDITOR = 'false'
|
2015-05-19 11:12:13 -04:00
|
|
|
else
|
|
|
|
let &l:makeprg = 'env GIT_EDITOR=false ' . &l:makeprg
|
2014-06-25 13:05:14 -04:00
|
|
|
endif
|
|
|
|
execute cd fnameescape(s:repo().tree())
|
|
|
|
silent noautocmd make!
|
|
|
|
catch /^Vim\%((\a\+)\)\=:E211/
|
|
|
|
let err = v:exception
|
|
|
|
finally
|
|
|
|
redraw!
|
|
|
|
let [&l:mp, &l:efm] = [mp, efm]
|
|
|
|
if exists('old_editor')
|
|
|
|
let $GIT_EDITOR = old_editor
|
|
|
|
endif
|
|
|
|
execute cd fnameescape(cwd)
|
|
|
|
endtry
|
|
|
|
call fugitive#reload_status()
|
|
|
|
if empty(filter(getqflist(),'v:val.valid'))
|
|
|
|
if !had_merge_msg && filereadable(s:repo().dir('MERGE_MSG'))
|
|
|
|
cclose
|
2014-07-07 21:23:22 -04:00
|
|
|
return 'Gcommit --no-status -n -t '.s:shellesc(s:repo().dir('MERGE_MSG'))
|
2014-06-25 13:05:14 -04:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
let qflist = getqflist()
|
|
|
|
let found = 0
|
|
|
|
for e in qflist
|
|
|
|
if !empty(e.bufnr)
|
|
|
|
let found = 1
|
|
|
|
let e.pattern = '^<<<<<<<'
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
call fugitive#cwindow()
|
|
|
|
if found
|
|
|
|
call setqflist(qflist, 'r')
|
|
|
|
if !a:bang
|
|
|
|
return 'cfirst'
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
return exists('err') ? 'echoerr '.string(err) : ''
|
|
|
|
endfunction
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Ggrep, Glog
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2009-12-14 00:00:03 -05:00
|
|
|
if !exists('g:fugitive_summary_format')
|
|
|
|
let g:fugitive_summary_format = '%s'
|
|
|
|
endif
|
|
|
|
|
2012-04-05 12:25:24 -04:00
|
|
|
call s:command("-bang -nargs=? -complete=customlist,s:EditComplete Ggrep :execute s:Grep('grep',<bang>0,<q-args>)")
|
|
|
|
call s:command("-bang -nargs=? -complete=customlist,s:EditComplete Glgrep :execute s:Grep('lgrep',<bang>0,<q-args>)")
|
2014-06-24 13:02:04 -04:00
|
|
|
call s:command("-bar -bang -nargs=* -range=0 -complete=customlist,s:EditComplete Glog :call s:Log('grep<bang>',<line1>,<count>,<f-args>)")
|
2014-09-02 12:05:34 -04:00
|
|
|
call s:command("-bar -bang -nargs=* -range=0 -complete=customlist,s:EditComplete Gllog :call s:Log('lgrep<bang>',<line1>,<count>,<f-args>)")
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2012-04-05 12:25:24 -04:00
|
|
|
function! s:Grep(cmd,bang,arg) abort
|
2009-10-10 19:47:14 -04:00
|
|
|
let grepprg = &grepprg
|
|
|
|
let grepformat = &grepformat
|
2017-05-30 14:10:37 -04:00
|
|
|
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
|
2010-01-13 17:50:18 -05:00
|
|
|
let dir = getcwd()
|
2009-10-10 19:47:14 -04:00
|
|
|
try
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(s:repo().tree())
|
2015-05-16 08:27:44 -04:00
|
|
|
let &grepprg = s:repo().git_command('--no-pager', 'grep', '-n', '--no-color')
|
2015-12-15 19:01:40 -05:00
|
|
|
let &grepformat = '%f:%l:%m,%m %f match%ts,%f'
|
2012-04-05 12:25:24 -04:00
|
|
|
exe a:cmd.'! '.escape(matchstr(a:arg,'\v\C.{-}%($|[''" ]\@=\|)@='),'|')
|
|
|
|
let list = a:cmd =~# '^l' ? getloclist(0) : getqflist()
|
2009-10-10 19:47:14 -04:00
|
|
|
for entry in list
|
|
|
|
if bufname(entry.bufnr) =~ ':'
|
|
|
|
let entry.filename = s:repo().translate(bufname(entry.bufnr))
|
|
|
|
unlet! entry.bufnr
|
2014-06-19 16:40:26 -04:00
|
|
|
let changed = 1
|
2009-10-10 19:47:14 -04:00
|
|
|
elseif a:arg =~# '\%(^\| \)--cached\>'
|
|
|
|
let entry.filename = s:repo().translate(':0:'.bufname(entry.bufnr))
|
|
|
|
unlet! entry.bufnr
|
2014-06-19 16:40:26 -04:00
|
|
|
let changed = 1
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
endfor
|
2014-06-19 16:40:26 -04:00
|
|
|
if a:cmd =~# '^l' && exists('changed')
|
2012-04-05 12:25:24 -04:00
|
|
|
call setloclist(0, list, 'r')
|
2014-06-19 16:40:26 -04:00
|
|
|
elseif exists('changed')
|
2012-04-07 18:16:54 -04:00
|
|
|
call setqflist(list, 'r')
|
2012-04-05 12:25:24 -04:00
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
if !a:bang && !empty(list)
|
2012-04-05 12:25:24 -04:00
|
|
|
return (a:cmd =~# '^l' ? 'l' : 'c').'first'.matchstr(a:arg,'\v\C[''" ]\zs\|.*')
|
2009-10-14 18:57:11 -04:00
|
|
|
else
|
2010-03-19 19:59:08 -04:00
|
|
|
return matchstr(a:arg,'\v\C[''" ]\|\zs.*')
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
finally
|
|
|
|
let &grepprg = grepprg
|
|
|
|
let &grepformat = grepformat
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(dir)
|
2009-10-10 19:47:14 -04:00
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
2014-06-24 13:02:04 -04:00
|
|
|
function! s:Log(cmd, line1, line2, ...) abort
|
2009-11-10 22:26:08 -05:00
|
|
|
let path = s:buffer().path('/')
|
2009-11-14 23:47:17 -05:00
|
|
|
if path =~# '^/\.git\%(/\|$\)' || index(a:000,'--') != -1
|
2009-11-10 22:26:08 -05:00
|
|
|
let path = ''
|
|
|
|
endif
|
2009-11-14 23:47:17 -05:00
|
|
|
let cmd = ['--no-pager', 'log', '--no-color']
|
2014-06-24 13:02:04 -04:00
|
|
|
let cmd += ['--pretty=format:fugitive://'.s:repo().dir().'//%H'.path.'::'.g:fugitive_summary_format]
|
2009-11-14 23:47:17 -05:00
|
|
|
if empty(filter(a:000[0 : index(a:000,'--')],'v:val !~# "^-"'))
|
|
|
|
if s:buffer().commit() =~# '\x\{40\}'
|
|
|
|
let cmd += [s:buffer().commit()]
|
|
|
|
elseif s:buffer().path() =~# '^\.git/refs/\|^\.git/.*HEAD$'
|
|
|
|
let cmd += [s:buffer().path()[5:-1]]
|
|
|
|
endif
|
|
|
|
end
|
|
|
|
let cmd += map(copy(a:000),'s:sub(v:val,"^\\%(%(:\\w)*)","\\=fnamemodify(s:buffer().path(),submatch(1))")')
|
2009-11-10 22:26:08 -05:00
|
|
|
if path =~# '/.'
|
2014-06-24 13:02:04 -04:00
|
|
|
if a:line2
|
|
|
|
let cmd += ['-L', a:line1 . ',' . a:line2 . ':' . path[1:-1]]
|
|
|
|
else
|
|
|
|
let cmd += ['--', path[1:-1]]
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
let grepformat = &grepformat
|
|
|
|
let grepprg = &grepprg
|
2017-05-30 14:10:37 -04:00
|
|
|
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
|
2010-01-13 17:50:18 -05:00
|
|
|
let dir = getcwd()
|
2009-10-10 19:47:14 -04:00
|
|
|
try
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(s:repo().tree())
|
2012-11-04 17:28:25 -05:00
|
|
|
let &grepprg = escape(call(s:repo().git_command,cmd,s:repo()),'%#')
|
2014-06-24 13:02:04 -04:00
|
|
|
let &grepformat = '%Cdiff %.%#,%C--- %.%#,%C+++ %.%#,%Z@@ -%\d%\+\,%\d%\+ +%l\,%\d%\+ @@,%-G-%.%#,%-G+%.%#,%-G %.%#,%A%f::%m,%-G%.%#'
|
2009-10-10 19:47:14 -04:00
|
|
|
exe a:cmd
|
|
|
|
finally
|
|
|
|
let &grepformat = grepformat
|
|
|
|
let &grepprg = grepprg
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(dir)
|
2009-10-10 19:47:14 -04:00
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Gedit, Gpedit, Gsplit, Gvsplit, Gtabedit, Gread
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2018-05-27 01:02:44 -04:00
|
|
|
function! s:UsableWin(nr) abort
|
|
|
|
return a:nr && !getwinvar(a:nr, '&previewwindow') &&
|
|
|
|
\ index(['nofile','help','quickfix'], getbufvar(winbufnr(a:nr), '&buftype')) < 0
|
|
|
|
endfunction
|
|
|
|
|
2011-08-19 02:43:31 -04:00
|
|
|
function! s:Edit(cmd,bang,...) abort
|
2012-09-21 12:30:28 -04:00
|
|
|
let buffer = s:buffer()
|
2011-08-19 02:40:34 -04:00
|
|
|
if a:cmd !~# 'read'
|
|
|
|
if &previewwindow && getbufvar('','fugitive_type') ==# 'index'
|
2018-05-27 01:02:44 -04:00
|
|
|
let winnrs = filter([winnr('#')] + range(1, winnr('$')), 's:UsableWin(v:val)')
|
|
|
|
if len(winnrs)
|
|
|
|
exe winnrs[1].'wincmd w'
|
|
|
|
elseif winnr('$') == 1
|
2015-10-06 23:57:56 -04:00
|
|
|
let tabs = (&go =~# 'e' || !has('gui_running')) && &stal && (tabpagenr('$') >= &stal)
|
|
|
|
execute 'rightbelow' (&lines - &previewheight - &cmdheight - tabs - 1 - !!&laststatus).'new'
|
2015-10-16 18:43:12 -04:00
|
|
|
else
|
2018-05-27 01:02:44 -04:00
|
|
|
rightbelow new
|
2015-10-06 23:57:56 -04:00
|
|
|
endif
|
2011-08-19 02:40:34 -04:00
|
|
|
if &diff
|
|
|
|
let mywinnr = winnr()
|
|
|
|
for winnr in range(winnr('$'),1,-1)
|
|
|
|
if winnr != mywinnr && getwinvar(winnr,'&diff')
|
|
|
|
execute winnr.'wincmd w'
|
|
|
|
close
|
2014-06-21 14:19:13 -04:00
|
|
|
if winnr('$') > 1
|
|
|
|
wincmd p
|
|
|
|
endif
|
2011-08-19 02:40:34 -04:00
|
|
|
endif
|
|
|
|
endfor
|
2017-05-19 18:14:55 -04:00
|
|
|
diffoff!
|
2011-08-19 02:40:34 -04:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
2011-08-19 02:43:31 -04:00
|
|
|
if a:bang
|
2014-02-28 21:48:21 -05:00
|
|
|
let arglist = map(copy(a:000), 's:gsub(v:val, ''\\@<!%(\\\\)*\zs[%#]'', ''\=s:buffer().expand(submatch(0))'')')
|
|
|
|
let args = join(arglist, ' ')
|
2011-08-19 02:43:31 -04:00
|
|
|
if a:cmd =~# 'read'
|
2012-09-21 12:30:28 -04:00
|
|
|
let git = buffer.repo().git_command()
|
2011-08-19 02:43:31 -04:00
|
|
|
let last = line('$')
|
|
|
|
silent call s:ExecuteInTree((a:cmd ==# 'read' ? '$read' : a:cmd).'!'.git.' --no-pager '.args)
|
|
|
|
if a:cmd ==# 'read'
|
|
|
|
silent execute '1,'.last.'delete_'
|
|
|
|
endif
|
|
|
|
call fugitive#reload_status()
|
|
|
|
diffupdate
|
|
|
|
return 'redraw|echo '.string(':!'.git.' '.args)
|
|
|
|
else
|
2011-10-07 01:32:46 -04:00
|
|
|
let temp = resolve(tempname())
|
2017-04-05 14:58:03 -04:00
|
|
|
if has('win32')
|
|
|
|
let temp = fnamemodify(fnamemodify(temp, ':h'), ':p').fnamemodify(temp, ':t')
|
|
|
|
endif
|
2015-06-30 17:42:13 -04:00
|
|
|
let s:temp_files[s:cpath(temp)] = { 'dir': buffer.repo().dir(), 'args': arglist }
|
2011-08-19 02:43:31 -04:00
|
|
|
silent execute a:cmd.' '.temp
|
|
|
|
if a:cmd =~# 'pedit'
|
|
|
|
wincmd P
|
|
|
|
endif
|
|
|
|
let echo = s:Edit('read',1,args)
|
|
|
|
silent write!
|
2011-09-08 17:12:41 -04:00
|
|
|
setlocal buftype=nowrite nomodified filetype=git foldmarker=<<<<<<<,>>>>>>>
|
|
|
|
if getline(1) !~# '^diff '
|
|
|
|
setlocal readonly nomodifiable
|
|
|
|
endif
|
2011-08-19 02:43:31 -04:00
|
|
|
if a:cmd =~# 'pedit'
|
|
|
|
wincmd p
|
|
|
|
endif
|
|
|
|
return echo
|
|
|
|
endif
|
|
|
|
return ''
|
|
|
|
endif
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
if a:0 && a:1 == ''
|
|
|
|
return ''
|
|
|
|
elseif a:0
|
2013-02-10 12:57:37 -05:00
|
|
|
let file = buffer.expand(join(a:000, ' '))
|
2011-08-25 19:08:23 -04:00
|
|
|
elseif expand('%') ==# ''
|
|
|
|
let file = ':'
|
2012-09-21 12:30:28 -04:00
|
|
|
elseif buffer.commit() ==# '' && buffer.path('/') !~# '^/.git\>'
|
|
|
|
let file = buffer.path(':')
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
2012-09-21 12:30:28 -04:00
|
|
|
let file = buffer.path('/')
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2009-10-15 18:47:03 -04:00
|
|
|
try
|
2012-09-21 12:30:28 -04:00
|
|
|
let file = buffer.repo().translate(file)
|
2009-10-15 18:47:03 -04:00
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
2015-12-23 21:27:43 -05:00
|
|
|
if file !~# '^fugitive:'
|
|
|
|
let file = s:sub(file, '/$', '')
|
|
|
|
endif
|
2011-02-27 10:47:28 -05:00
|
|
|
if a:cmd ==# 'read'
|
2010-12-27 23:50:32 -05:00
|
|
|
return 'silent %delete_|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.')
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
|
|
|
return a:cmd.' '.s:fnameescape(file)
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:EditComplete(A,L,P) abort
|
2013-02-10 12:57:37 -05:00
|
|
|
return map(s:repo().superglob(a:A), 'fnameescape(v:val)')
|
2011-09-12 17:02:07 -04:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:EditRunComplete(A,L,P) abort
|
2011-08-19 02:43:31 -04:00
|
|
|
if a:L =~# '^\w\+!'
|
|
|
|
return s:GitComplete(a:A,a:L,a:P)
|
|
|
|
else
|
|
|
|
return s:repo().superglob(a:A)
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
2013-02-10 12:57:37 -05:00
|
|
|
call s:command("-bar -bang -nargs=* -complete=customlist,s:EditComplete Ge :execute s:Edit('edit<bang>',0,<f-args>)")
|
|
|
|
call s:command("-bar -bang -nargs=* -complete=customlist,s:EditComplete Gedit :execute s:Edit('edit<bang>',0,<f-args>)")
|
|
|
|
call s:command("-bar -bang -nargs=* -complete=customlist,s:EditRunComplete Gpedit :execute s:Edit('pedit',<bang>0,<f-args>)")
|
|
|
|
call s:command("-bar -bang -nargs=* -complete=customlist,s:EditRunComplete Gsplit :execute s:Edit('split',<bang>0,<f-args>)")
|
|
|
|
call s:command("-bar -bang -nargs=* -complete=customlist,s:EditRunComplete Gvsplit :execute s:Edit('vsplit',<bang>0,<f-args>)")
|
|
|
|
call s:command("-bar -bang -nargs=* -complete=customlist,s:EditRunComplete Gtabedit :execute s:Edit('tabedit',<bang>0,<f-args>)")
|
2017-10-09 08:02:16 -04:00
|
|
|
call s:command("-bar -bang -nargs=* -range=-1 -complete=customlist,s:EditRunComplete Gread :execute s:Edit((<count> == -1 ? '' : <count>).'read',<bang>0,<f-args>)")
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Gwrite, Gwq
|
2009-10-14 23:15:03 -04:00
|
|
|
|
2013-02-10 12:57:37 -05:00
|
|
|
call s:command("-bar -bang -nargs=* -complete=customlist,s:EditComplete Gwrite :execute s:Write(<bang>0,<f-args>)")
|
|
|
|
call s:command("-bar -bang -nargs=* -complete=customlist,s:EditComplete Gw :execute s:Write(<bang>0,<f-args>)")
|
|
|
|
call s:command("-bar -bang -nargs=* -complete=customlist,s:EditComplete Gwq :execute s:Wq(<bang>0,<f-args>)")
|
2009-10-14 23:15:03 -04:00
|
|
|
|
|
|
|
function! s:Write(force,...) abort
|
2010-01-09 23:31:22 -05:00
|
|
|
if exists('b:fugitive_commit_arguments')
|
|
|
|
return 'write|bdelete'
|
|
|
|
elseif expand('%:t') == 'COMMIT_EDITMSG' && $GIT_INDEX_FILE != ''
|
|
|
|
return 'wq'
|
2010-01-10 00:04:58 -05:00
|
|
|
elseif s:buffer().type() == 'index'
|
|
|
|
return 'Gcommit'
|
2011-09-08 17:12:41 -04:00
|
|
|
elseif s:buffer().path() ==# '' && getline(4) =~# '^+++ '
|
|
|
|
let filename = getline(4)[6:-1]
|
|
|
|
setlocal buftype=
|
|
|
|
silent write
|
|
|
|
setlocal buftype=nowrite
|
|
|
|
if matchstr(getline(2),'index [[:xdigit:]]\+\.\.\zs[[:xdigit:]]\{7\}') ==# s:repo().rev_parse(':0:'.filename)[0:6]
|
|
|
|
let err = s:repo().git_chomp('apply','--cached','--reverse',s:buffer().spec())
|
|
|
|
else
|
|
|
|
let err = s:repo().git_chomp('apply','--cached',s:buffer().spec())
|
|
|
|
endif
|
|
|
|
if err !=# ''
|
|
|
|
let v:errmsg = split(err,"\n")[0]
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
elseif a:force
|
|
|
|
return 'bdelete'
|
|
|
|
else
|
|
|
|
return 'Gedit '.fnameescape(filename)
|
|
|
|
endif
|
2010-01-09 23:31:22 -05:00
|
|
|
endif
|
2009-10-14 23:15:03 -04:00
|
|
|
let mytab = tabpagenr()
|
|
|
|
let mybufnr = bufnr('')
|
2013-02-10 12:57:37 -05:00
|
|
|
let path = a:0 ? join(a:000, ' ') : s:buffer().path()
|
2015-10-06 20:33:41 -04:00
|
|
|
if empty(path)
|
|
|
|
return 'echoerr '.string('fugitive: cannot determine file path')
|
|
|
|
endif
|
2009-10-14 23:15:03 -04:00
|
|
|
if path =~# '^:\d\>'
|
|
|
|
return 'write'.(a:force ? '! ' : ' ').s:fnameescape(s:repo().translate(s:buffer().expand(path)))
|
|
|
|
endif
|
|
|
|
let always_permitted = (s:buffer().path() ==# path && s:buffer().commit() =~# '^0\=$')
|
|
|
|
if !always_permitted && !a:force && s:repo().git_chomp_in_tree('diff','--name-status','HEAD','--',path) . s:repo().git_chomp_in_tree('ls-files','--others','--',path) !=# ''
|
|
|
|
let v:errmsg = 'fugitive: file has uncommitted changes (use ! to override)'
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endif
|
|
|
|
let file = s:repo().translate(path)
|
|
|
|
let treebufnr = 0
|
|
|
|
for nr in range(1,bufnr('$'))
|
2010-01-09 17:35:27 -05:00
|
|
|
if fnamemodify(bufname(nr),':p') ==# file
|
2009-10-14 23:15:03 -04:00
|
|
|
let treebufnr = nr
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
|
|
|
|
if treebufnr > 0 && treebufnr != bufnr('')
|
|
|
|
let temp = tempname()
|
|
|
|
silent execute '%write '.temp
|
|
|
|
for tab in [mytab] + range(1,tabpagenr('$'))
|
|
|
|
for winnr in range(1,tabpagewinnr(tab,'$'))
|
|
|
|
if tabpagebuflist(tab)[winnr-1] == treebufnr
|
|
|
|
execute 'tabnext '.tab
|
2009-10-19 21:42:48 -04:00
|
|
|
if winnr != winnr()
|
|
|
|
execute winnr.'wincmd w'
|
|
|
|
let restorewinnr = 1
|
|
|
|
endif
|
2009-10-14 23:15:03 -04:00
|
|
|
try
|
|
|
|
let lnum = line('.')
|
|
|
|
let last = line('$')
|
|
|
|
silent execute '$read '.temp
|
|
|
|
silent execute '1,'.last.'delete_'
|
|
|
|
silent write!
|
|
|
|
silent execute lnum
|
|
|
|
let did = 1
|
|
|
|
finally
|
2009-10-19 21:42:48 -04:00
|
|
|
if exists('restorewinnr')
|
|
|
|
wincmd p
|
|
|
|
endif
|
2009-10-18 19:54:30 -04:00
|
|
|
execute 'tabnext '.mytab
|
2009-10-14 23:15:03 -04:00
|
|
|
endtry
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
endfor
|
|
|
|
if !exists('did')
|
|
|
|
call writefile(readfile(temp,'b'),file,'b')
|
|
|
|
endif
|
|
|
|
else
|
|
|
|
execute 'write! '.s:fnameescape(s:repo().translate(path))
|
|
|
|
endif
|
|
|
|
|
2010-08-21 22:52:02 -04:00
|
|
|
if a:force
|
2014-06-22 12:27:26 -04:00
|
|
|
let error = s:repo().git_chomp_in_tree('add', '--force', '--', path)
|
2010-08-21 22:52:02 -04:00
|
|
|
else
|
2014-06-22 12:27:26 -04:00
|
|
|
let error = s:repo().git_chomp_in_tree('add', '--', path)
|
2010-08-21 22:52:02 -04:00
|
|
|
endif
|
2009-10-14 23:15:03 -04:00
|
|
|
if v:shell_error
|
|
|
|
let v:errmsg = 'fugitive: '.error
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endif
|
2010-01-09 17:35:27 -05:00
|
|
|
if s:buffer().path() ==# path && s:buffer().commit() =~# '^\d$'
|
2009-10-14 23:15:03 -04:00
|
|
|
set nomodified
|
|
|
|
endif
|
|
|
|
|
|
|
|
let one = s:repo().translate(':1:'.path)
|
|
|
|
let two = s:repo().translate(':2:'.path)
|
|
|
|
let three = s:repo().translate(':3:'.path)
|
|
|
|
for nr in range(1,bufnr('$'))
|
2012-04-01 22:04:10 -04:00
|
|
|
let name = fnamemodify(bufname(nr), ':p')
|
|
|
|
if bufloaded(nr) && !getbufvar(nr,'&modified') && (name ==# one || name ==# two || name ==# three)
|
2009-10-14 23:15:03 -04:00
|
|
|
execute nr.'bdelete'
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
|
2009-10-19 21:42:48 -04:00
|
|
|
unlet! restorewinnr
|
2009-10-14 23:15:03 -04:00
|
|
|
let zero = s:repo().translate(':0:'.path)
|
2016-03-23 10:27:54 -04:00
|
|
|
silent execute 'doautocmd BufWritePost' s:fnameescape(zero)
|
2009-10-14 23:15:03 -04:00
|
|
|
for tab in range(1,tabpagenr('$'))
|
|
|
|
for winnr in range(1,tabpagewinnr(tab,'$'))
|
|
|
|
let bufnr = tabpagebuflist(tab)[winnr-1]
|
2012-04-01 22:04:10 -04:00
|
|
|
let bufname = fnamemodify(bufname(bufnr), ':p')
|
2009-10-14 23:15:03 -04:00
|
|
|
if bufname ==# zero && bufnr != mybufnr
|
|
|
|
execute 'tabnext '.tab
|
2009-10-19 21:42:48 -04:00
|
|
|
if winnr != winnr()
|
|
|
|
execute winnr.'wincmd w'
|
|
|
|
let restorewinnr = 1
|
|
|
|
endif
|
2009-10-14 23:15:03 -04:00
|
|
|
try
|
|
|
|
let lnum = line('.')
|
|
|
|
let last = line('$')
|
2012-04-03 18:42:58 -04:00
|
|
|
silent execute '$read '.s:fnameescape(file)
|
2009-10-14 23:15:03 -04:00
|
|
|
silent execute '1,'.last.'delete_'
|
|
|
|
silent execute lnum
|
|
|
|
set nomodified
|
|
|
|
diffupdate
|
|
|
|
finally
|
2009-10-19 21:42:48 -04:00
|
|
|
if exists('restorewinnr')
|
|
|
|
wincmd p
|
|
|
|
endif
|
2009-10-14 23:15:03 -04:00
|
|
|
execute 'tabnext '.mytab
|
|
|
|
endtry
|
|
|
|
break
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
endfor
|
2009-11-03 22:23:58 -05:00
|
|
|
call fugitive#reload_status()
|
2009-10-14 23:15:03 -04:00
|
|
|
return 'checktime'
|
|
|
|
endfunction
|
|
|
|
|
2011-02-27 13:58:05 -05:00
|
|
|
function! s:Wq(force,...) abort
|
|
|
|
let bang = a:force ? '!' : ''
|
|
|
|
if exists('b:fugitive_commit_arguments')
|
|
|
|
return 'wq'.bang
|
|
|
|
endif
|
|
|
|
let result = call(s:function('s:Write'),[a:force]+a:000)
|
|
|
|
if result =~# '^\%(write\|wq\|echoerr\)'
|
|
|
|
return s:sub(result,'^write','wq')
|
|
|
|
else
|
|
|
|
return result.'|quit'.bang
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2014-06-22 12:46:16 -04:00
|
|
|
augroup fugitive_commit
|
|
|
|
autocmd!
|
|
|
|
autocmd VimLeavePre,BufDelete COMMIT_EDITMSG execute s:sub(s:FinishCommit(), '^echoerr (.*)', 'echohl ErrorMsg|echo \1|echohl NONE')
|
|
|
|
augroup END
|
|
|
|
|
2014-06-30 14:30:44 -04:00
|
|
|
" Section: Gpush, Gfetch
|
|
|
|
|
|
|
|
call s:command("-nargs=? -bang -complete=custom,s:RemoteComplete Gpush execute s:Dispatch('<bang>', 'push '.<q-args>)")
|
|
|
|
call s:command("-nargs=? -bang -complete=custom,s:RemoteComplete Gfetch execute s:Dispatch('<bang>', 'fetch '.<q-args>)")
|
|
|
|
|
|
|
|
function! s:Dispatch(bang, args)
|
|
|
|
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
|
|
|
|
let cwd = getcwd()
|
|
|
|
let [mp, efm, cc] = [&l:mp, &l:efm, get(b:, 'current_compiler', '')]
|
|
|
|
try
|
|
|
|
let b:current_compiler = 'git'
|
|
|
|
let &l:errorformat = s:common_efm
|
2017-04-23 22:34:41 -04:00
|
|
|
let &l:makeprg = substitute(s:git_command() . ' ' . a:args, '\s\+$', '', '')
|
2014-06-30 14:30:44 -04:00
|
|
|
execute cd fnameescape(s:repo().tree())
|
|
|
|
if exists(':Make') == 2
|
|
|
|
noautocmd Make
|
|
|
|
else
|
|
|
|
silent noautocmd make!
|
|
|
|
redraw!
|
|
|
|
return 'call fugitive#cwindow()'
|
|
|
|
endif
|
|
|
|
return ''
|
|
|
|
finally
|
|
|
|
let [&l:mp, &l:efm, b:current_compiler] = [mp, efm, cc]
|
|
|
|
if empty(cc) | unlet! b:current_compiler | endif
|
|
|
|
execute cd fnameescape(cwd)
|
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Gdiff
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2015-10-06 23:24:34 -04:00
|
|
|
call s:command("-bang -bar -nargs=* -complete=customlist,s:EditComplete Gdiff :execute s:Diff('',<bang>0,<f-args>)")
|
|
|
|
call s:command("-bang -bar -nargs=* -complete=customlist,s:EditComplete Gvdiff :execute s:Diff('keepalt vert ',<bang>0,<f-args>)")
|
|
|
|
call s:command("-bang -bar -nargs=* -complete=customlist,s:EditComplete Gsdiff :execute s:Diff('keepalt ',<bang>0,<f-args>)")
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2009-10-14 23:26:10 -04:00
|
|
|
augroup fugitive_diff
|
2010-05-25 15:32:35 -04:00
|
|
|
autocmd!
|
2014-05-30 14:26:40 -04:00
|
|
|
autocmd BufWinLeave *
|
2014-06-21 13:44:44 -04:00
|
|
|
\ if s:can_diffoff(+expand('<abuf>')) && s:diff_window_count() == 2 |
|
2014-05-30 14:26:40 -04:00
|
|
|
\ call s:diffoff_all(getbufvar(+expand('<abuf>'), 'git_dir')) |
|
|
|
|
\ endif
|
|
|
|
autocmd BufWinEnter *
|
2014-06-21 13:44:44 -04:00
|
|
|
\ if s:can_diffoff(+expand('<abuf>')) && s:diff_window_count() == 1 |
|
2014-05-30 14:26:40 -04:00
|
|
|
\ call s:diffoff() |
|
|
|
|
\ endif
|
2009-10-14 23:26:10 -04:00
|
|
|
augroup END
|
|
|
|
|
2014-06-21 13:44:44 -04:00
|
|
|
function! s:can_diffoff(buf) abort
|
|
|
|
return getwinvar(bufwinnr(a:buf), '&diff') &&
|
|
|
|
\ !empty(getbufvar(a:buf, 'git_dir')) &&
|
|
|
|
\ !empty(getwinvar(bufwinnr(a:buf), 'fugitive_diff_restore'))
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! fugitive#can_diffoff(buf) abort
|
|
|
|
return s:can_diffoff(a:buf)
|
|
|
|
endfunction
|
|
|
|
|
2014-06-23 20:06:24 -04:00
|
|
|
function! s:diff_modifier(count) abort
|
2014-06-21 11:17:59 -04:00
|
|
|
let fdc = matchstr(&diffopt, 'foldcolumn:\zs\d\+')
|
2014-06-21 08:18:46 -04:00
|
|
|
if &diffopt =~# 'horizontal' && &diffopt !~# 'vertical'
|
2014-06-21 11:17:59 -04:00
|
|
|
return 'keepalt '
|
2014-06-23 20:06:24 -04:00
|
|
|
elseif &diffopt =~# 'vertical'
|
|
|
|
return 'keepalt vert '
|
2014-06-21 11:17:59 -04:00
|
|
|
elseif winwidth(0) <= a:count * ((&tw ? &tw : 80) + (empty(fdc) ? 2 : fdc))
|
|
|
|
return 'keepalt '
|
2014-06-21 08:18:46 -04:00
|
|
|
else
|
2014-06-21 11:17:59 -04:00
|
|
|
return 'keepalt vert '
|
2014-06-21 08:18:46 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:diff_window_count() abort
|
2010-04-14 11:05:53 -04:00
|
|
|
let c = 0
|
|
|
|
for nr in range(1,winnr('$'))
|
|
|
|
let c += getwinvar(nr,'&diff')
|
|
|
|
endfor
|
|
|
|
return c
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:diff_restore() abort
|
2013-04-19 15:53:02 -04:00
|
|
|
let restore = 'setlocal nodiff noscrollbind'
|
|
|
|
\ . ' scrollopt=' . &l:scrollopt
|
|
|
|
\ . (&l:wrap ? ' wrap' : ' nowrap')
|
2013-12-30 10:38:53 -05:00
|
|
|
\ . ' foldlevel=999'
|
2013-04-19 15:53:02 -04:00
|
|
|
\ . ' foldmethod=' . &l:foldmethod
|
|
|
|
\ . ' foldcolumn=' . &l:foldcolumn
|
|
|
|
\ . ' foldlevel=' . &l:foldlevel
|
2014-06-04 06:27:12 -04:00
|
|
|
\ . (&l:foldenable ? ' foldenable' : ' nofoldenable')
|
2013-04-19 15:53:02 -04:00
|
|
|
if has('cursorbind')
|
|
|
|
let restore .= (&l:cursorbind ? ' ' : ' no') . 'cursorbind'
|
|
|
|
endif
|
|
|
|
return restore
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:diffthis() abort
|
2011-08-07 19:53:03 -04:00
|
|
|
if !&diff
|
2013-04-19 15:53:02 -04:00
|
|
|
let w:fugitive_diff_restore = s:diff_restore()
|
2011-08-07 19:53:03 -04:00
|
|
|
diffthis
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:diffoff() abort
|
2011-08-07 19:53:03 -04:00
|
|
|
if exists('w:fugitive_diff_restore')
|
|
|
|
execute w:fugitive_diff_restore
|
|
|
|
unlet w:fugitive_diff_restore
|
|
|
|
else
|
|
|
|
diffoff
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:diffoff_all(dir) abort
|
2014-12-10 22:03:08 -05:00
|
|
|
let curwin = winnr()
|
2010-11-13 20:04:34 -05:00
|
|
|
for nr in range(1,winnr('$'))
|
|
|
|
if getwinvar(nr,'&diff')
|
2010-11-13 20:15:26 -05:00
|
|
|
if nr != winnr()
|
|
|
|
execute nr.'wincmd w'
|
2010-11-13 20:04:34 -05:00
|
|
|
let restorewinnr = 1
|
|
|
|
endif
|
2010-11-13 20:26:53 -05:00
|
|
|
if exists('b:git_dir') && b:git_dir ==# a:dir
|
2011-08-07 19:53:03 -04:00
|
|
|
call s:diffoff()
|
2010-11-13 20:26:53 -05:00
|
|
|
endif
|
2010-11-13 20:04:34 -05:00
|
|
|
endif
|
|
|
|
endfor
|
2014-12-10 22:03:08 -05:00
|
|
|
execute curwin.'wincmd w'
|
2010-05-25 16:48:34 -04:00
|
|
|
endfunction
|
|
|
|
|
2010-01-30 00:31:10 -05:00
|
|
|
function! s:buffer_compare_age(commit) dict abort
|
|
|
|
let scores = {':0': 1, ':1': 2, ':2': 3, ':': 4, ':3': 5}
|
|
|
|
let my_score = get(scores,':'.self.commit(),0)
|
|
|
|
let their_score = get(scores,':'.a:commit,0)
|
|
|
|
if my_score || their_score
|
|
|
|
return my_score < their_score ? -1 : my_score != their_score
|
|
|
|
elseif self.commit() ==# a:commit
|
|
|
|
return 0
|
|
|
|
endif
|
|
|
|
let base = self.repo().git_chomp('merge-base',self.commit(),a:commit)
|
|
|
|
if base ==# self.commit()
|
|
|
|
return -1
|
|
|
|
elseif base ==# a:commit
|
|
|
|
return 1
|
|
|
|
endif
|
2010-01-30 00:38:00 -05:00
|
|
|
let my_time = +self.repo().git_chomp('log','--max-count=1','--pretty=format:%at',self.commit())
|
|
|
|
let their_time = +self.repo().git_chomp('log','--max-count=1','--pretty=format:%at',a:commit)
|
2010-01-30 00:31:10 -05:00
|
|
|
return my_time < their_time ? -1 : my_time != their_time
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
call s:add_methods('buffer',['compare_age'])
|
|
|
|
|
2015-10-06 23:24:34 -04:00
|
|
|
function! s:Diff(vert,keepfocus,...) abort
|
2015-10-06 23:21:41 -04:00
|
|
|
let args = copy(a:000)
|
|
|
|
let post = ''
|
|
|
|
if get(args, 0) =~# '^+'
|
|
|
|
let post = remove(args, 0)[1:-1]
|
|
|
|
endif
|
2014-06-23 20:06:24 -04:00
|
|
|
let vert = empty(a:vert) ? s:diff_modifier(2) : a:vert
|
2009-10-10 19:47:14 -04:00
|
|
|
if exists(':DiffGitCached')
|
|
|
|
return 'DiffGitCached'
|
2015-10-06 23:21:41 -04:00
|
|
|
elseif (empty(args) || args[0] == ':') && s:buffer().commit() =~# '^[0-1]\=$' && s:repo().git_chomp_in_tree('ls-files', '--unmerged', '--', s:buffer().path()) !=# ''
|
2014-06-23 20:06:24 -04:00
|
|
|
let vert = empty(a:vert) ? s:diff_modifier(3) : a:vert
|
2011-04-25 11:50:19 -04:00
|
|
|
let nr = bufnr('')
|
2017-06-07 19:32:02 -04:00
|
|
|
execute 'leftabove '.vert.'split' s:fnameescape(fugitive#repo().translate(s:buffer().expand(':2')))
|
2011-04-25 14:31:59 -04:00
|
|
|
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
|
2016-11-05 12:20:24 -04:00
|
|
|
let nr2 = bufnr('')
|
2011-08-07 19:53:03 -04:00
|
|
|
call s:diffthis()
|
2010-05-25 16:32:09 -04:00
|
|
|
wincmd p
|
2017-06-07 19:32:02 -04:00
|
|
|
execute 'rightbelow '.vert.'split' s:fnameescape(fugitive#repo().translate(s:buffer().expand(':3')))
|
2011-04-25 14:31:59 -04:00
|
|
|
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
|
2016-11-05 12:20:24 -04:00
|
|
|
let nr3 = bufnr('')
|
2011-08-07 19:53:03 -04:00
|
|
|
call s:diffthis()
|
2010-05-25 16:32:09 -04:00
|
|
|
wincmd p
|
2011-08-07 19:53:03 -04:00
|
|
|
call s:diffthis()
|
2016-11-05 12:20:24 -04:00
|
|
|
execute 'nnoremap <buffer> <silent> d2o :diffget '.nr2.'<Bar>diffupdate<CR>'
|
|
|
|
execute 'nnoremap <buffer> <silent> d3o :diffget '.nr3.'<Bar>diffupdate<CR>'
|
2015-10-06 23:21:41 -04:00
|
|
|
return post
|
|
|
|
elseif len(args)
|
|
|
|
let arg = join(args, ' ')
|
2013-02-10 12:57:37 -05:00
|
|
|
if arg ==# ''
|
2015-10-06 23:21:41 -04:00
|
|
|
return post
|
2013-02-10 12:57:37 -05:00
|
|
|
elseif arg ==# '/'
|
2009-10-14 23:26:10 -04:00
|
|
|
let file = s:buffer().path('/')
|
2013-02-10 12:57:37 -05:00
|
|
|
elseif arg ==# ':'
|
2009-10-14 23:26:10 -04:00
|
|
|
let file = s:buffer().path(':0:')
|
2013-02-10 12:57:37 -05:00
|
|
|
elseif arg =~# '^:/.'
|
2009-10-15 18:47:03 -04:00
|
|
|
try
|
2013-02-10 12:57:37 -05:00
|
|
|
let file = s:repo().rev_parse(arg).s:buffer().path(':')
|
2009-10-15 18:47:03 -04:00
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
2013-02-10 12:57:37 -05:00
|
|
|
let file = s:buffer().expand(arg)
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2010-02-14 15:55:09 -05:00
|
|
|
if file !~# ':' && file !~# '^/' && s:repo().git_chomp('cat-file','-t',file) =~# '^\%(tag\|commit\)$'
|
2009-10-15 18:33:08 -04:00
|
|
|
let file = file.s:buffer().path(':')
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
else
|
2009-10-14 23:26:10 -04:00
|
|
|
let file = s:buffer().path(s:buffer().commit() == '' ? ':0:' : '/')
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
try
|
2010-01-30 00:31:10 -05:00
|
|
|
let spec = s:repo().translate(file)
|
|
|
|
let commit = matchstr(spec,'\C[^:/]//\zs\x\+')
|
2013-12-30 10:45:54 -05:00
|
|
|
let restore = s:diff_restore()
|
2014-04-14 13:33:12 -04:00
|
|
|
if exists('+cursorbind')
|
|
|
|
setlocal cursorbind
|
|
|
|
endif
|
2013-12-30 10:45:54 -05:00
|
|
|
let w:fugitive_diff_restore = restore
|
2010-01-30 00:31:10 -05:00
|
|
|
if s:buffer().compare_age(commit) < 0
|
2013-12-30 10:45:54 -05:00
|
|
|
execute 'rightbelow '.vert.'diffsplit '.s:fnameescape(spec)
|
2010-01-30 00:31:10 -05:00
|
|
|
else
|
2013-12-30 10:45:54 -05:00
|
|
|
execute 'leftabove '.vert.'diffsplit '.s:fnameescape(spec)
|
2010-01-30 00:31:10 -05:00
|
|
|
endif
|
2015-10-06 23:24:34 -04:00
|
|
|
let &l:readonly = &l:readonly
|
|
|
|
redraw
|
2013-12-30 10:45:54 -05:00
|
|
|
let w:fugitive_diff_restore = restore
|
2014-04-14 13:33:12 -04:00
|
|
|
let winnr = winnr()
|
|
|
|
if getwinvar('#', '&diff')
|
|
|
|
wincmd p
|
2015-10-06 23:24:34 -04:00
|
|
|
if !a:keepfocus
|
|
|
|
call feedkeys(winnr."\<C-W>w", 'n')
|
|
|
|
endif
|
2014-04-14 13:33:12 -04:00
|
|
|
endif
|
2015-10-06 23:21:41 -04:00
|
|
|
return post
|
2009-10-10 19:47:14 -04:00
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Gmove, Gremove
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2018-05-04 21:39:38 -04:00
|
|
|
function! s:Move(force, rename, destination) abort
|
2009-10-10 19:47:14 -04:00
|
|
|
if a:destination =~# '^/'
|
|
|
|
let destination = a:destination[1:-1]
|
2018-05-04 21:39:38 -04:00
|
|
|
elseif a:rename
|
|
|
|
let destination = fnamemodify(s:buffer().path(), ':h') . '/' . a:destination
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
2013-06-23 03:59:13 -04:00
|
|
|
let destination = s:shellslash(fnamemodify(s:sub(a:destination,'[%#]%(:\w)*','\=expand(submatch(0))'),':p'))
|
2010-01-09 17:35:27 -05:00
|
|
|
if destination[0:strlen(s:repo().tree())] ==# s:repo().tree('')
|
2009-10-10 19:47:14 -04:00
|
|
|
let destination = destination[strlen(s:repo().tree('')):-1]
|
|
|
|
endif
|
|
|
|
endif
|
2012-04-03 07:33:18 -04:00
|
|
|
if isdirectory(s:buffer().spec())
|
2011-01-04 15:04:47 -05:00
|
|
|
" Work around Vim parser idiosyncrasy
|
2011-04-25 15:14:32 -04:00
|
|
|
let discarded = s:buffer().setvar('&swapfile',0)
|
2010-12-27 23:27:03 -05:00
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
let message = call(s:repo().git_chomp_in_tree,['mv']+(a:force ? ['-f'] : [])+['--', s:buffer().path(), destination], s:repo())
|
|
|
|
if v:shell_error
|
|
|
|
let v:errmsg = 'fugitive: '.message
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endif
|
|
|
|
let destination = s:repo().tree(destination)
|
|
|
|
if isdirectory(destination)
|
|
|
|
let destination = fnamemodify(s:sub(destination,'/$','').'/'.expand('%:t'),':.')
|
|
|
|
endif
|
2009-11-03 22:23:58 -05:00
|
|
|
call fugitive#reload_status()
|
2018-05-04 21:39:38 -04:00
|
|
|
if empty(s:buffer().commit())
|
2010-12-27 23:27:03 -05:00
|
|
|
if isdirectory(destination)
|
2012-03-13 20:58:59 -04:00
|
|
|
return 'keepalt edit '.s:fnameescape(destination)
|
2010-12-27 23:27:03 -05:00
|
|
|
else
|
2012-03-13 20:58:59 -04:00
|
|
|
return 'keepalt saveas! '.s:fnameescape(destination)
|
2010-12-27 23:27:03 -05:00
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
2013-10-22 11:18:35 -04:00
|
|
|
return 'file '.s:fnameescape(s:repo().translate(':0:'.destination))
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:MoveComplete(A,L,P) abort
|
2018-05-04 21:39:38 -04:00
|
|
|
if a:A =~# '^/'
|
2009-10-10 19:47:14 -04:00
|
|
|
return s:repo().superglob(a:A)
|
|
|
|
else
|
2010-01-31 16:04:10 -05:00
|
|
|
let matches = split(glob(a:A.'*'),"\n")
|
2018-05-04 21:39:38 -04:00
|
|
|
call map(matches,'v:val !~# "/$" && isdirectory(v:val) ? v:val."/" : v:val')
|
2010-01-31 16:04:10 -05:00
|
|
|
return matches
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2018-05-04 21:39:38 -04:00
|
|
|
function! s:RenameComplete(A,L,P) abort
|
|
|
|
if a:A =~# '^/'
|
|
|
|
return s:repo().superglob(a:A)
|
|
|
|
else
|
|
|
|
let pre = '/'. fnamemodify(s:buffer().path(), ':h') . '/'
|
|
|
|
return map(s:repo().superglob(pre.a:A), 'strpart(v:val, len(pre))')
|
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2017-06-08 01:20:21 -04:00
|
|
|
function! s:Remove(after, force) abort
|
2009-10-10 19:47:14 -04:00
|
|
|
if s:buffer().commit() ==# ''
|
|
|
|
let cmd = ['rm']
|
|
|
|
elseif s:buffer().commit() ==# '0'
|
|
|
|
let cmd = ['rm','--cached']
|
|
|
|
else
|
|
|
|
let v:errmsg = 'fugitive: rm not supported here'
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endif
|
|
|
|
if a:force
|
|
|
|
let cmd += ['--force']
|
|
|
|
endif
|
|
|
|
let message = call(s:repo().git_chomp_in_tree,cmd+['--',s:buffer().path()],s:repo())
|
|
|
|
if v:shell_error
|
|
|
|
let v:errmsg = 'fugitive: '.s:sub(message,'error:.*\zs\n\(.*-f.*',' (add ! to force)')
|
|
|
|
return 'echoerr '.string(v:errmsg)
|
|
|
|
else
|
2009-11-03 22:23:58 -05:00
|
|
|
call fugitive#reload_status()
|
2017-06-08 01:20:21 -04:00
|
|
|
return a:after . (a:force ? '!' : '')
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
augroup fugitive_remove
|
|
|
|
autocmd!
|
|
|
|
autocmd User Fugitive if s:buffer().commit() =~# '^0\=$' |
|
2018-05-04 21:39:38 -04:00
|
|
|
\ exe "command! -buffer -bar -bang -nargs=1 -complete=customlist,s:MoveComplete Gmove :execute s:Move(<bang>0,0,<q-args>)" |
|
|
|
|
\ exe "command! -buffer -bar -bang -nargs=1 -complete=customlist,s:RenameComplete Grename :execute s:Move(<bang>0,1,<q-args>)" |
|
2017-06-08 01:20:21 -04:00
|
|
|
\ exe "command! -buffer -bar -bang Gremove :execute s:Remove('edit',<bang>0)" |
|
|
|
|
\ exe "command! -buffer -bar -bang Gdelete :execute s:Remove('bdelete',<bang>0)" |
|
2009-10-10 19:47:14 -04:00
|
|
|
\ endif
|
|
|
|
augroup END
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Gblame
|
2009-10-10 19:47:14 -04:00
|
|
|
|
|
|
|
augroup fugitive_blame
|
|
|
|
autocmd!
|
|
|
|
autocmd BufReadPost *.fugitiveblame setfiletype fugitiveblame
|
|
|
|
autocmd FileType fugitiveblame setlocal nomodeline | if exists('b:git_dir') | let &l:keywordprg = s:repo().keywordprg() | endif
|
|
|
|
autocmd Syntax fugitiveblame call s:BlameSyntax()
|
2010-03-05 22:28:53 -05:00
|
|
|
autocmd User Fugitive if s:buffer().type('file', 'blob') | exe "command! -buffer -bar -bang -range=0 -nargs=* Gblame :execute s:Blame(<bang>0,<line1>,<line2>,<count>,[<f-args>])" | endif
|
2012-07-07 17:30:08 -04:00
|
|
|
autocmd ColorScheme,GUIEnter * call s:RehighlightBlame()
|
2009-10-10 19:47:14 -04:00
|
|
|
augroup END
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:linechars(pattern) abort
|
2012-10-09 14:33:06 -04:00
|
|
|
let chars = strlen(s:gsub(matchstr(getline('.'), a:pattern), '.', '.'))
|
|
|
|
if exists('*synconcealed') && &conceallevel > 1
|
|
|
|
for col in range(1, chars)
|
|
|
|
let chars -= synconcealed(line('.'), col)[0]
|
|
|
|
endfor
|
|
|
|
endif
|
|
|
|
return chars
|
2012-06-22 19:44:26 -04:00
|
|
|
endfunction
|
|
|
|
|
2010-03-05 22:28:53 -05:00
|
|
|
function! s:Blame(bang,line1,line2,count,args) abort
|
2014-06-26 14:40:09 -04:00
|
|
|
if exists('b:fugitive_blamed_bufnr')
|
|
|
|
return 'bdelete'
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
try
|
|
|
|
if s:buffer().path() == ''
|
|
|
|
call s:throw('file or blob required')
|
|
|
|
endif
|
2012-10-09 16:24:31 -04:00
|
|
|
if filter(copy(a:args),'v:val !~# "^\\%(--root\|--show-name\\|-\\=\\%([ltfnsew]\\|[MC]\\d*\\)\\+\\)$"') != []
|
2010-03-05 22:28:53 -05:00
|
|
|
call s:throw('unsupported option')
|
|
|
|
endif
|
|
|
|
call map(a:args,'s:sub(v:val,"^\\ze[^-]","-")')
|
|
|
|
let cmd = ['--no-pager', 'blame', '--show-number'] + a:args
|
2009-11-11 00:16:02 -05:00
|
|
|
if s:buffer().commit() =~# '\D\|..'
|
2009-10-10 19:47:14 -04:00
|
|
|
let cmd += [s:buffer().commit()]
|
|
|
|
else
|
2009-10-12 21:48:16 -04:00
|
|
|
let cmd += ['--contents', '-']
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2014-02-28 21:48:21 -05:00
|
|
|
let cmd += ['--', s:buffer().path()]
|
2017-10-21 18:06:41 -04:00
|
|
|
let basecmd = escape(call(s:repo().git_command,cmd,s:repo()),'!%#')
|
2009-10-12 21:48:16 -04:00
|
|
|
try
|
2017-05-30 14:10:37 -04:00
|
|
|
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
|
2009-10-12 21:48:16 -04:00
|
|
|
if !s:repo().bare()
|
|
|
|
let dir = getcwd()
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(s:repo().tree())
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2009-10-12 21:48:16 -04:00
|
|
|
if a:count
|
|
|
|
execute 'write !'.substitute(basecmd,' blame ',' blame -L '.a:line1.','.a:line2.' ','g')
|
|
|
|
else
|
2011-10-07 01:32:46 -04:00
|
|
|
let error = resolve(tempname())
|
2010-03-09 08:43:57 -05:00
|
|
|
let temp = error.'.fugitiveblame'
|
2010-06-08 11:08:05 -04:00
|
|
|
if &shell =~# 'csh'
|
|
|
|
silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
|
|
|
|
else
|
|
|
|
silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
|
|
|
|
endif
|
2010-11-05 18:17:09 -04:00
|
|
|
if exists('l:dir')
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(dir)
|
2010-11-05 18:17:09 -04:00
|
|
|
unlet dir
|
|
|
|
endif
|
2009-10-12 21:48:16 -04:00
|
|
|
if v:shell_error
|
2010-03-09 08:43:57 -05:00
|
|
|
call s:throw(join(readfile(error),"\n"))
|
2009-10-12 21:48:16 -04:00
|
|
|
endif
|
2011-10-04 03:13:46 -04:00
|
|
|
for winnr in range(winnr('$'),1,-1)
|
|
|
|
call setwinvar(winnr, '&scrollbind', 0)
|
2014-06-24 23:10:57 -04:00
|
|
|
if exists('+cursorbind')
|
|
|
|
call setwinvar(winnr, '&cursorbind', 0)
|
|
|
|
endif
|
2011-10-04 03:13:46 -04:00
|
|
|
if getbufvar(winbufnr(winnr), 'fugitive_blamed_bufnr')
|
|
|
|
execute winbufnr(winnr).'bdelete'
|
|
|
|
endif
|
|
|
|
endfor
|
2009-10-12 21:48:16 -04:00
|
|
|
let bufnr = bufnr('')
|
2010-05-25 15:34:53 -04:00
|
|
|
let restore = 'call setwinvar(bufwinnr('.bufnr.'),"&scrollbind",0)'
|
2014-06-24 23:10:57 -04:00
|
|
|
if exists('+cursorbind')
|
|
|
|
let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&cursorbind",0)'
|
|
|
|
endif
|
2009-10-12 21:48:16 -04:00
|
|
|
if &l:wrap
|
2010-05-25 15:34:53 -04:00
|
|
|
let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&wrap",1)'
|
2009-10-12 21:48:16 -04:00
|
|
|
endif
|
|
|
|
if &l:foldenable
|
2010-05-25 15:34:53 -04:00
|
|
|
let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&foldenable",1)'
|
2009-10-12 21:48:16 -04:00
|
|
|
endif
|
|
|
|
setlocal scrollbind nowrap nofoldenable
|
2014-06-24 23:10:57 -04:00
|
|
|
if exists('+cursorbind')
|
|
|
|
setlocal cursorbind
|
|
|
|
endif
|
2009-10-12 21:48:16 -04:00
|
|
|
let top = line('w0') + &scrolloff
|
|
|
|
let current = line('.')
|
2017-04-05 14:58:03 -04:00
|
|
|
if has('win32')
|
|
|
|
let temp = fnamemodify(fnamemodify(temp, ':h'), ':p').fnamemodify(temp, ':t')
|
|
|
|
endif
|
2015-06-30 17:42:13 -04:00
|
|
|
let s:temp_files[s:cpath(temp)] = { 'dir': s:repo().dir(), 'args': cmd }
|
2012-01-24 11:45:36 -05:00
|
|
|
exe 'keepalt leftabove vsplit '.temp
|
2009-10-12 21:48:16 -04:00
|
|
|
let b:fugitive_blamed_bufnr = bufnr
|
2011-08-07 19:51:45 -04:00
|
|
|
let w:fugitive_leave = restore
|
2010-03-05 22:28:53 -05:00
|
|
|
let b:fugitive_blame_arguments = join(a:args,' ')
|
2009-10-12 21:48:16 -04:00
|
|
|
execute top
|
|
|
|
normal! zt
|
|
|
|
execute current
|
2014-06-24 23:10:57 -04:00
|
|
|
if exists('+cursorbind')
|
|
|
|
setlocal cursorbind
|
|
|
|
endif
|
2014-03-25 13:37:57 -04:00
|
|
|
setlocal nomodified nomodifiable nonumber scrollbind nowrap foldcolumn=0 nofoldenable winfixwidth filetype=fugitiveblame
|
2012-10-09 14:33:06 -04:00
|
|
|
if exists('+concealcursor')
|
|
|
|
setlocal concealcursor=nc conceallevel=2
|
|
|
|
endif
|
2011-08-25 14:51:48 -04:00
|
|
|
if exists('+relativenumber')
|
|
|
|
setlocal norelativenumber
|
|
|
|
endif
|
2012-10-09 14:33:06 -04:00
|
|
|
execute "vertical resize ".(s:linechars('.\{-\}\ze\s\+\d\+)')+1)
|
2014-04-07 05:00:22 -04:00
|
|
|
nnoremap <buffer> <silent> <F1> :help fugitive-:Gblame<CR>
|
|
|
|
nnoremap <buffer> <silent> g? :help fugitive-:Gblame<CR>
|
Return to correct window when closing Gblame window
Vim does not guarantee persistent window numbers. Instead, windows are
numbered according to their position on the screen, with the topmost,
leftmost window always having number 1, and the bottommost, rightmost
window always having a number equal to the total number of windows
currently visible. Crucially, this means that, when a window is closed,
windows which come "after" it in the positional order will be
renumbered.
When fugitive's Gblame window is closed, e.g. by pressing `q`, it
attempts to return focus to the window of the blamed buffer. Previously,
the number of the window to return to was computed before closing the
Gblame window, then the Gblame window was closed, then the blamed
buffer's window was focused. However, since windows were often
renumbered as soon as the Gblame window was closed, this would
frequently cause focus to jump to the window *after* the blamed buffer's
window, rather than the intended behavior.
This corrects the issue by jumping to the proper return window prior to
deleting the Gblame buffer, ensuring that the computed window number is
in fact correct at the moment when the focus change occurs.
2012-08-29 12:20:39 -04:00
|
|
|
nnoremap <buffer> <silent> q :exe substitute(bufwinnr(b:fugitive_blamed_bufnr).' wincmd w<Bar>'.bufnr('').'bdelete','^-1','','')<CR>
|
|
|
|
nnoremap <buffer> <silent> gq :exe substitute(bufwinnr(b:fugitive_blamed_bufnr).' wincmd w<Bar>'.bufnr('').'bdelete<Bar>if expand("%:p") =~# "^fugitive:[\\/][\\/]"<Bar>Gedit<Bar>endif','^-1','','')<CR>
|
2013-01-30 16:00:41 -05:00
|
|
|
nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>BlameCommit("exe 'norm q'<Bar>edit")<CR>
|
2012-03-28 20:35:47 -04:00
|
|
|
nnoremap <buffer> <silent> - :<C-U>exe <SID>BlameJump('')<CR>
|
2010-01-15 13:37:00 -05:00
|
|
|
nnoremap <buffer> <silent> P :<C-U>exe <SID>BlameJump('^'.v:count1)<CR>
|
|
|
|
nnoremap <buffer> <silent> ~ :<C-U>exe <SID>BlameJump('~'.v:count1)<CR>
|
2011-10-01 17:25:18 -04:00
|
|
|
nnoremap <buffer> <silent> i :<C-U>exe <SID>BlameCommit("exe 'norm q'<Bar>edit")<CR>
|
|
|
|
nnoremap <buffer> <silent> o :<C-U>exe <SID>BlameCommit((&splitbelow ? "botright" : "topleft")." split")<CR>
|
|
|
|
nnoremap <buffer> <silent> O :<C-U>exe <SID>BlameCommit("tabedit")<CR>
|
2012-10-09 16:02:54 -04:00
|
|
|
nnoremap <buffer> <silent> A :<C-u>exe "vertical resize ".(<SID>linechars('.\{-\}\ze [0-9:/+-][0-9:/+ -]* \d\+)')+1+v:count)<CR>
|
|
|
|
nnoremap <buffer> <silent> C :<C-u>exe "vertical resize ".(<SID>linechars('^\S\+')+1+v:count)<CR>
|
|
|
|
nnoremap <buffer> <silent> D :<C-u>exe "vertical resize ".(<SID>linechars('.\{-\}\ze\d\ze\s\+\d\+)')+1-v:count)<CR>
|
2011-10-01 15:52:44 -04:00
|
|
|
redraw
|
2009-10-12 21:48:16 -04:00
|
|
|
syncbind
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2009-10-12 21:48:16 -04:00
|
|
|
finally
|
|
|
|
if exists('l:dir')
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(dir)
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2009-10-12 21:48:16 -04:00
|
|
|
endtry
|
2009-10-10 19:47:14 -04:00
|
|
|
return ''
|
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
2011-10-01 17:25:18 -04:00
|
|
|
function! s:BlameCommit(cmd) abort
|
|
|
|
let cmd = s:Edit(a:cmd, 0, matchstr(getline('.'),'\x\+'))
|
|
|
|
if cmd =~# '^echoerr'
|
|
|
|
return cmd
|
|
|
|
endif
|
|
|
|
let lnum = matchstr(getline('.'),' \zs\d\+\ze\s\+[([:digit:]]')
|
|
|
|
let path = matchstr(getline('.'),'^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
|
|
|
|
if path ==# ''
|
|
|
|
let path = s:buffer(b:fugitive_blamed_bufnr).path()
|
|
|
|
endif
|
|
|
|
execute cmd
|
|
|
|
if search('^diff .* b/\M'.escape(path,'\').'$','W')
|
|
|
|
call search('^+++')
|
|
|
|
let head = line('.')
|
|
|
|
while search('^@@ \|^diff ') && getline('.') =~# '^@@ '
|
|
|
|
let top = +matchstr(getline('.'),' +\zs\d\+')
|
|
|
|
let len = +matchstr(getline('.'),' +\d\+,\zs\d\+')
|
|
|
|
if lnum >= top && lnum <= top + len
|
|
|
|
let offset = lnum - top
|
|
|
|
if &scrolloff
|
|
|
|
+
|
|
|
|
normal! zt
|
|
|
|
else
|
|
|
|
normal! zt
|
|
|
|
+
|
|
|
|
endif
|
|
|
|
while offset > 0 && line('.') < line('$')
|
|
|
|
+
|
|
|
|
if getline('.') =~# '^[ +]'
|
|
|
|
let offset -= 1
|
|
|
|
endif
|
|
|
|
endwhile
|
2014-06-10 18:46:04 -04:00
|
|
|
return 'normal! zv'
|
2011-10-01 17:25:18 -04:00
|
|
|
endif
|
|
|
|
endwhile
|
|
|
|
execute head
|
|
|
|
normal! zt
|
|
|
|
endif
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
|
2010-01-15 13:37:00 -05:00
|
|
|
function! s:BlameJump(suffix) abort
|
2009-10-10 19:47:14 -04:00
|
|
|
let commit = matchstr(getline('.'),'^\^\=\zs\x\+')
|
|
|
|
if commit =~# '^0\+$'
|
|
|
|
let commit = ':0'
|
|
|
|
endif
|
2011-10-01 02:26:26 -04:00
|
|
|
let lnum = matchstr(getline('.'),' \zs\d\+\ze\s\+[([:digit:]]')
|
|
|
|
let path = matchstr(getline('.'),'^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
|
2009-10-10 19:47:14 -04:00
|
|
|
if path ==# ''
|
|
|
|
let path = s:buffer(b:fugitive_blamed_bufnr).path()
|
|
|
|
endif
|
2010-03-05 22:28:53 -05:00
|
|
|
let args = b:fugitive_blame_arguments
|
2009-10-10 19:47:14 -04:00
|
|
|
let offset = line('.') - line('w0')
|
|
|
|
let bufnr = bufnr('%')
|
|
|
|
let winnr = bufwinnr(b:fugitive_blamed_bufnr)
|
|
|
|
if winnr > 0
|
|
|
|
exe winnr.'wincmd w'
|
|
|
|
endif
|
2011-08-21 15:53:12 -04:00
|
|
|
execute s:Edit('edit', 0, commit.a:suffix.':'.path)
|
2011-10-01 02:26:26 -04:00
|
|
|
execute lnum
|
2009-10-10 19:47:14 -04:00
|
|
|
if winnr > 0
|
|
|
|
exe bufnr.'bdelete'
|
|
|
|
endif
|
2015-09-30 18:49:29 -04:00
|
|
|
if exists(':Gblame')
|
|
|
|
execute 'Gblame '.args
|
|
|
|
execute lnum
|
|
|
|
let delta = line('.') - line('w0') - offset
|
|
|
|
if delta > 0
|
|
|
|
execute 'normal! '.delta."\<C-E>"
|
|
|
|
elseif delta < 0
|
|
|
|
execute 'normal! '.(-delta)."\<C-Y>"
|
|
|
|
endif
|
|
|
|
syncbind
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
return ''
|
|
|
|
endfunction
|
|
|
|
|
2012-07-07 17:30:08 -04:00
|
|
|
let s:hash_colors = {}
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
function! s:BlameSyntax() abort
|
|
|
|
let b:current_syntax = 'fugitiveblame'
|
2012-10-09 14:33:06 -04:00
|
|
|
let conceal = has('conceal') ? ' conceal' : ''
|
|
|
|
let arg = exists('b:fugitive_blame_arguments') ? b:fugitive_blame_arguments : ''
|
2009-10-10 19:47:14 -04:00
|
|
|
syn match FugitiveblameBoundary "^\^"
|
2010-03-05 22:28:53 -05:00
|
|
|
syn match FugitiveblameBlank "^\s\+\s\@=" nextgroup=FugitiveblameAnnotation,fugitiveblameOriginalFile,FugitiveblameOriginalLineNumber skipwhite
|
2017-06-07 13:34:15 -04:00
|
|
|
syn match FugitiveblameHash "\%(^\^\=\)\@<=\<\x\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
|
|
|
|
syn match FugitiveblameUncommitted "\%(^\^\=\)\@<=\<0\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
|
2009-10-10 19:47:14 -04:00
|
|
|
syn region FugitiveblameAnnotation matchgroup=FugitiveblameDelimiter start="(" end="\%( \d\+\)\@<=)" contained keepend oneline
|
|
|
|
syn match FugitiveblameTime "[0-9:/+-][0-9:/+ -]*[0-9:/+-]\%( \+\d\+)\)\@=" contained containedin=FugitiveblameAnnotation
|
2012-10-09 14:33:06 -04:00
|
|
|
exec 'syn match FugitiveblameLineNumber " *\d\+)\@=" contained containedin=FugitiveblameAnnotation'.conceal
|
|
|
|
exec 'syn match FugitiveblameOriginalFile " \%(\f\+\D\@<=\|\D\@=\f\+\)\%(\%(\s\+\d\+\)\=\s\%((\|\s*\d\+)\)\)\@=" contained nextgroup=FugitiveblameOriginalLineNumber,FugitiveblameAnnotation skipwhite'.(arg =~# 'f' ? '' : conceal)
|
|
|
|
exec 'syn match FugitiveblameOriginalLineNumber " *\d\+\%(\s(\)\@=" contained nextgroup=FugitiveblameAnnotation skipwhite'.(arg =~# 'n' ? '' : conceal)
|
|
|
|
exec 'syn match FugitiveblameOriginalLineNumber " *\d\+\%(\s\+\d\+)\)\@=" contained nextgroup=FugitiveblameShort skipwhite'.(arg =~# 'n' ? '' : conceal)
|
|
|
|
syn match FugitiveblameShort " \d\+)" contained contains=FugitiveblameLineNumber
|
2009-10-10 19:47:14 -04:00
|
|
|
syn match FugitiveblameNotCommittedYet "(\@<=Not Committed Yet\>" contained containedin=FugitiveblameAnnotation
|
|
|
|
hi def link FugitiveblameBoundary Keyword
|
|
|
|
hi def link FugitiveblameHash Identifier
|
2012-07-07 17:30:08 -04:00
|
|
|
hi def link FugitiveblameUncommitted Ignore
|
2009-10-10 19:47:14 -04:00
|
|
|
hi def link FugitiveblameTime PreProc
|
|
|
|
hi def link FugitiveblameLineNumber Number
|
|
|
|
hi def link FugitiveblameOriginalFile String
|
|
|
|
hi def link FugitiveblameOriginalLineNumber Float
|
2010-03-05 22:28:53 -05:00
|
|
|
hi def link FugitiveblameShort FugitiveblameDelimiter
|
2009-10-10 19:47:14 -04:00
|
|
|
hi def link FugitiveblameDelimiter Delimiter
|
|
|
|
hi def link FugitiveblameNotCommittedYet Comment
|
2012-07-07 17:30:08 -04:00
|
|
|
let seen = {}
|
|
|
|
for lnum in range(1, line('$'))
|
|
|
|
let hash = matchstr(getline(lnum), '^\^\=\zs\x\{6\}')
|
|
|
|
if hash ==# '' || hash ==# '000000' || has_key(seen, hash)
|
|
|
|
continue
|
|
|
|
endif
|
|
|
|
let seen[hash] = 1
|
2017-05-26 19:34:15 -04:00
|
|
|
if &t_Co > 16 && get(g:, 'CSApprox_loaded') && !empty(findfile('autoload/csapprox/per_component.vim', escape(&rtp, ' ')))
|
2012-07-07 17:30:08 -04:00
|
|
|
\ && empty(get(s:hash_colors, hash))
|
|
|
|
let [s, r, g, b; __] = map(matchlist(hash, '\(\x\x\)\(\x\x\)\(\x\x\)'), 'str2nr(v:val,16)')
|
|
|
|
let color = csapprox#per_component#Approximate(r, g, b)
|
|
|
|
if color == 16 && &background ==# 'dark'
|
|
|
|
let color = 8
|
|
|
|
endif
|
|
|
|
let s:hash_colors[hash] = ' ctermfg='.color
|
|
|
|
else
|
|
|
|
let s:hash_colors[hash] = ''
|
|
|
|
endif
|
|
|
|
exe 'syn match FugitiveblameHash'.hash.' "\%(^\^\=\)\@<='.hash.'\x\{1,34\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite'
|
|
|
|
endfor
|
|
|
|
call s:RehighlightBlame()
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:RehighlightBlame() abort
|
|
|
|
for [hash, cterm] in items(s:hash_colors)
|
2017-04-27 21:18:37 -04:00
|
|
|
if !empty(cterm) || has('gui_running') || has('termguicolors') && &termguicolors
|
2012-07-07 17:30:08 -04:00
|
|
|
exe 'hi FugitiveblameHash'.hash.' guifg=#'.hash.get(s:hash_colors, hash, '')
|
|
|
|
else
|
|
|
|
exe 'hi link FugitiveblameHash'.hash.' Identifier'
|
|
|
|
endif
|
|
|
|
endfor
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Gbrowse
|
2011-02-21 00:11:47 -05:00
|
|
|
|
2015-12-26 19:53:07 -05:00
|
|
|
call s:command("-bar -bang -range=0 -nargs=* -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(<bang>0,<line1>,<count>,<f-args>)")
|
2011-02-21 00:11:47 -05:00
|
|
|
|
2017-05-29 22:41:33 -04:00
|
|
|
let s:redirects = {}
|
|
|
|
|
2011-02-21 00:11:47 -05:00
|
|
|
function! s:Browse(bang,line1,count,...) abort
|
|
|
|
try
|
2016-01-08 17:05:54 -05:00
|
|
|
let validremote = '\.\|\.\=/.*\|[[:alnum:]_-]\+\%(://.\{-\}\)\='
|
2015-12-26 19:53:07 -05:00
|
|
|
if a:0
|
|
|
|
let remote = matchstr(join(a:000, ' '),'@\zs\%('.validremote.'\)$')
|
|
|
|
let rev = substitute(join(a:000, ' '),'@\%('.validremote.'\)$','','')
|
|
|
|
else
|
|
|
|
let remote = ''
|
|
|
|
let rev = ''
|
|
|
|
endif
|
2011-02-26 15:40:59 -05:00
|
|
|
if rev ==# ''
|
|
|
|
let expanded = s:buffer().rev()
|
|
|
|
elseif rev ==# ':'
|
|
|
|
let expanded = s:buffer().path('/')
|
|
|
|
else
|
|
|
|
let expanded = s:buffer().expand(rev)
|
|
|
|
endif
|
|
|
|
let full = s:repo().translate(expanded)
|
|
|
|
let commit = ''
|
|
|
|
if full =~# '^fugitive://'
|
2015-12-26 14:18:00 -05:00
|
|
|
let commit = matchstr(full,'://.*//\zs\w\w\+')
|
2011-02-26 15:40:59 -05:00
|
|
|
let path = matchstr(full,'://.*//\w\+\zs/.*')
|
|
|
|
if commit =~ '..'
|
|
|
|
let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':'))
|
2015-12-26 19:53:07 -05:00
|
|
|
let branch = matchstr(expanded, '^[^:]*')
|
2011-02-26 15:40:59 -05:00
|
|
|
else
|
|
|
|
let type = 'blob'
|
|
|
|
endif
|
|
|
|
let path = path[1:-1]
|
|
|
|
elseif s:repo().bare()
|
|
|
|
let path = '.git/' . full[strlen(s:repo().dir())+1:-1]
|
|
|
|
let type = ''
|
|
|
|
else
|
|
|
|
let path = full[strlen(s:repo().tree())+1:-1]
|
|
|
|
if path =~# '^\.git/'
|
|
|
|
let type = ''
|
|
|
|
elseif isdirectory(full)
|
|
|
|
let type = 'tree'
|
|
|
|
else
|
|
|
|
let type = 'blob'
|
|
|
|
endif
|
|
|
|
endif
|
2015-12-26 14:36:06 -05:00
|
|
|
if type ==# 'tree' && !empty(path)
|
|
|
|
let path = s:sub(path, '/\=$', '/')
|
|
|
|
endif
|
2011-02-26 20:55:04 -05:00
|
|
|
if path =~# '^\.git/.*HEAD' && filereadable(s:repo().dir(path[5:-1]))
|
|
|
|
let body = readfile(s:repo().dir(path[5:-1]))[0]
|
|
|
|
if body =~# '^\x\{40\}$'
|
|
|
|
let commit = body
|
|
|
|
let type = 'commit'
|
|
|
|
let path = ''
|
|
|
|
elseif body =~# '^ref: refs/'
|
|
|
|
let path = '.git/' . matchstr(body,'ref: \zs.*')
|
|
|
|
endif
|
|
|
|
endif
|
2011-02-26 15:40:59 -05:00
|
|
|
|
2015-12-26 19:53:07 -05:00
|
|
|
let merge = ''
|
|
|
|
if path =~# '^\.git/refs/remotes/.'
|
|
|
|
if empty(remote)
|
|
|
|
let remote = matchstr(path, '^\.git/refs/remotes/\zs[^/]\+')
|
2017-04-03 17:18:20 -04:00
|
|
|
let branch = matchstr(path, '^\.git/refs/remotes/[^/]\+/\zs.\+')
|
|
|
|
else
|
|
|
|
let merge = matchstr(path, '^\.git/refs/remotes/[^/]\+/\zs.\+')
|
|
|
|
let path = '.git/refs/heads/'.merge
|
2011-02-26 15:40:59 -05:00
|
|
|
endif
|
2015-12-26 19:53:07 -05:00
|
|
|
elseif path =~# '^\.git/refs/heads/.'
|
|
|
|
let branch = path[16:-1]
|
|
|
|
elseif !exists('branch')
|
|
|
|
let branch = s:repo().head()
|
|
|
|
endif
|
|
|
|
if !empty(branch)
|
|
|
|
let r = s:repo().git_chomp('config','branch.'.branch.'.remote')
|
|
|
|
let m = s:repo().git_chomp('config','branch.'.branch.'.merge')[11:-1]
|
|
|
|
if r ==# '.' && !empty(m)
|
|
|
|
let r2 = s:repo().git_chomp('config','branch.'.m.'.remote')
|
|
|
|
if r2 !~# '^\.\=$'
|
|
|
|
let r = r2
|
|
|
|
let m = s:repo().git_chomp('config','branch.'.m.'.merge')[11:-1]
|
2011-02-26 15:40:59 -05:00
|
|
|
endif
|
2015-12-26 19:53:07 -05:00
|
|
|
endif
|
|
|
|
if empty(remote)
|
|
|
|
let remote = r
|
|
|
|
endif
|
|
|
|
if r ==# '.' || r ==# remote
|
|
|
|
let merge = m
|
|
|
|
if path =~# '^\.git/refs/heads/.'
|
|
|
|
let path = '.git/refs/heads/'.merge
|
2011-02-21 00:11:47 -05:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
endif
|
2011-02-26 15:40:59 -05:00
|
|
|
|
2015-12-26 19:53:07 -05:00
|
|
|
if empty(commit) && path !~# '^\.git/'
|
|
|
|
if a:line1 && !a:count && !empty(merge)
|
|
|
|
let commit = merge
|
|
|
|
else
|
|
|
|
let commit = s:repo().rev_parse('HEAD')
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
|
|
|
if empty(remote)
|
|
|
|
let remote = '.'
|
2017-04-26 13:05:13 -04:00
|
|
|
let remote_for_url = 'origin'
|
2015-12-26 19:53:07 -05:00
|
|
|
else
|
2017-04-26 13:05:13 -04:00
|
|
|
let remote_for_url = remote
|
|
|
|
endif
|
2017-05-29 21:17:20 -04:00
|
|
|
if fugitive#git_version() =~# '^[01]\.\|^2\.[0-6]\.'
|
2017-04-26 13:05:13 -04:00
|
|
|
let raw = s:repo().git_chomp('config','remote.'.remote_for_url.'.url')
|
|
|
|
else
|
|
|
|
let raw = s:repo().git_chomp('remote','get-url',remote_for_url)
|
2015-12-26 19:53:07 -05:00
|
|
|
endif
|
2011-02-24 15:51:51 -05:00
|
|
|
if raw ==# ''
|
|
|
|
let raw = remote
|
|
|
|
endif
|
2011-02-26 15:40:59 -05:00
|
|
|
|
2017-05-29 22:41:33 -04:00
|
|
|
if raw =~# '^https\=://' && s:executable('curl')
|
|
|
|
if !has_key(s:redirects, raw)
|
|
|
|
let s:redirects[raw] = matchstr(system('curl -I ' .
|
|
|
|
\ s:shellesc(raw . '/info/refs?service=git-upload-pack')),
|
|
|
|
\ 'Location: \zs\S\+\ze/info/refs?')
|
|
|
|
endif
|
|
|
|
if len(s:redirects[raw])
|
|
|
|
let raw = s:redirects[raw]
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
2014-07-22 00:17:43 -04:00
|
|
|
for Handler in g:fugitive_browse_handlers
|
2014-07-22 20:45:54 -04:00
|
|
|
let url = call(Handler, [{
|
|
|
|
\ 'repo': s:repo(),
|
2014-07-22 00:17:43 -04:00
|
|
|
\ 'remote': raw,
|
2015-12-26 19:53:07 -05:00
|
|
|
\ 'revision': 'No longer provided',
|
2014-07-22 00:17:43 -04:00
|
|
|
\ 'commit': commit,
|
|
|
|
\ 'path': path,
|
|
|
|
\ 'type': type,
|
2014-07-27 12:14:42 -04:00
|
|
|
\ 'line1': a:count > 0 ? a:line1 : 0,
|
|
|
|
\ 'line2': a:count > 0 ? a:count : 0}])
|
2014-07-17 20:16:28 -04:00
|
|
|
if !empty(url)
|
|
|
|
break
|
|
|
|
endif
|
|
|
|
endfor
|
2011-02-26 15:40:59 -05:00
|
|
|
|
2015-12-26 19:53:07 -05:00
|
|
|
if empty(url) && raw ==# '.'
|
|
|
|
call s:throw("Instaweb failed to start")
|
|
|
|
elseif empty(url)
|
2016-11-13 19:02:27 -05:00
|
|
|
call s:throw("'".remote."' is not a supported remote")
|
2011-02-21 00:11:47 -05:00
|
|
|
endif
|
2011-02-26 15:40:59 -05:00
|
|
|
|
2015-12-26 14:11:54 -05:00
|
|
|
let url = s:gsub(url, '[ <>]', '\="%".printf("%02X",char2nr(submatch(0)))')
|
2011-02-21 00:11:47 -05:00
|
|
|
if a:bang
|
2014-07-23 07:42:26 -04:00
|
|
|
if has('clipboard')
|
2016-04-06 14:57:40 -04:00
|
|
|
let @+ = url
|
2014-07-23 07:42:26 -04:00
|
|
|
endif
|
2011-02-21 00:11:47 -05:00
|
|
|
return 'echomsg '.string(url)
|
2014-06-26 17:07:07 -04:00
|
|
|
elseif exists(':Browse') == 2
|
2014-06-26 17:08:59 -04:00
|
|
|
return 'echomsg '.string(url).'|Browse '.url
|
2011-02-21 00:11:47 -05:00
|
|
|
else
|
2015-02-20 15:47:08 -05:00
|
|
|
if !exists('g:loaded_netrw')
|
|
|
|
runtime! autoload/netrw.vim
|
|
|
|
endif
|
|
|
|
if exists('*netrw#BrowseX')
|
2015-02-08 22:31:37 -05:00
|
|
|
return 'echomsg '.string(url).'|call netrw#BrowseX('.string(url).', 0)'
|
|
|
|
else
|
|
|
|
return 'echomsg '.string(url).'|call netrw#NetrwBrowseX('.string(url).', 0)'
|
|
|
|
endif
|
2011-02-21 00:11:47 -05:00
|
|
|
endif
|
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
2014-07-22 20:45:54 -04:00
|
|
|
function! s:github_url(opts, ...) abort
|
2014-07-22 00:17:43 -04:00
|
|
|
if a:0 || type(a:opts) != type({})
|
|
|
|
return ''
|
|
|
|
endif
|
2012-03-14 16:27:46 -04:00
|
|
|
let domain_pattern = 'github\.com'
|
2012-11-18 22:43:04 -05:00
|
|
|
let domains = exists('g:fugitive_github_domains') ? g:fugitive_github_domains : []
|
|
|
|
for domain in domains
|
|
|
|
let domain_pattern .= '\|' . escape(split(domain, '://')[-1], '.')
|
2012-03-14 16:27:46 -04:00
|
|
|
endfor
|
2014-07-22 00:17:43 -04:00
|
|
|
let repo = matchstr(get(a:opts, 'remote'), '^\%(https\=://\|git://\|git@\)\=\zs\('.domain_pattern.'\)[/:].\{-\}\ze\%(\.git\)\=$')
|
2012-03-14 16:27:46 -04:00
|
|
|
if repo ==# ''
|
2011-02-21 00:11:47 -05:00
|
|
|
return ''
|
|
|
|
endif
|
2017-04-11 17:58:44 -04:00
|
|
|
call s:warn('Install rhubarb.vim for GitHub support')
|
|
|
|
return 'https://github.com/tpope/vim-rhubarb'
|
2011-02-21 00:11:47 -05:00
|
|
|
endfunction
|
|
|
|
|
2014-07-22 20:45:54 -04:00
|
|
|
function! s:instaweb_url(opts) abort
|
2015-12-26 19:53:07 -05:00
|
|
|
if a:opts.remote !=# '.'
|
|
|
|
return ''
|
|
|
|
endif
|
2014-07-22 20:45:54 -04:00
|
|
|
let output = a:opts.repo.git_chomp('instaweb','-b','unknown')
|
2011-02-21 00:11:47 -05:00
|
|
|
if output =~# 'http://'
|
2014-11-06 13:47:26 -05:00
|
|
|
let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:opts.repo.dir(),':t')
|
2011-02-21 00:11:47 -05:00
|
|
|
else
|
|
|
|
return ''
|
|
|
|
endif
|
2014-07-22 00:17:43 -04:00
|
|
|
if a:opts.path =~# '^\.git/refs/.'
|
|
|
|
return root . ';a=shortlog;h=' . matchstr(a:opts.path,'^\.git/\zs.*')
|
|
|
|
elseif a:opts.path =~# '^\.git\>'
|
2011-02-21 00:11:47 -05:00
|
|
|
return root
|
|
|
|
endif
|
|
|
|
let url = root
|
2014-07-22 00:17:43 -04:00
|
|
|
if a:opts.commit =~# '^\x\{40\}$'
|
|
|
|
if a:opts.type ==# 'commit'
|
2011-02-26 15:40:59 -05:00
|
|
|
let url .= ';a=commit'
|
|
|
|
endif
|
2014-07-22 20:45:54 -04:00
|
|
|
let url .= ';h=' . a:opts.repo.rev_parse(a:opts.commit . (a:opts.path == '' ? '' : ':' . a:opts.path))
|
2011-02-21 00:11:47 -05:00
|
|
|
else
|
2015-12-01 18:41:29 -05:00
|
|
|
if a:opts.type ==# 'blob' && empty(a:opts.commit)
|
|
|
|
let url .= ';h='.a:opts.repo.git_chomp('hash-object', '-w', a:opts.path)
|
2011-02-21 00:11:47 -05:00
|
|
|
else
|
|
|
|
try
|
2014-07-22 20:45:54 -04:00
|
|
|
let url .= ';h=' . a:opts.repo.rev_parse((a:opts.commit == '' ? 'HEAD' : ':' . a:opts.commit) . ':' . a:opts.path)
|
2011-02-21 00:11:47 -05:00
|
|
|
catch /^fugitive:/
|
2011-02-26 20:12:34 -05:00
|
|
|
call s:throw('fugitive: cannot browse uncommitted file')
|
2011-02-21 00:11:47 -05:00
|
|
|
endtry
|
|
|
|
endif
|
2014-07-22 20:45:54 -04:00
|
|
|
let root .= ';hb=' . matchstr(a:opts.repo.head_ref(),'[^ ]\+$')
|
2011-02-21 00:11:47 -05:00
|
|
|
endif
|
2014-07-22 00:17:43 -04:00
|
|
|
if a:opts.path !=# ''
|
|
|
|
let url .= ';f=' . a:opts.path
|
2011-02-21 00:11:47 -05:00
|
|
|
endif
|
2014-07-22 00:17:43 -04:00
|
|
|
if get(a:opts, 'line1')
|
|
|
|
let url .= '#l' . a:opts.line1
|
2011-02-21 00:11:47 -05:00
|
|
|
endif
|
|
|
|
return url
|
|
|
|
endfunction
|
|
|
|
|
2014-07-22 00:17:43 -04:00
|
|
|
if !exists('g:fugitive_browse_handlers')
|
|
|
|
let g:fugitive_browse_handlers = []
|
2014-07-17 21:05:03 -04:00
|
|
|
endif
|
|
|
|
|
2014-07-22 00:17:43 -04:00
|
|
|
call extend(g:fugitive_browse_handlers,
|
2014-07-17 21:05:03 -04:00
|
|
|
\ [s:function('s:github_url'), s:function('s:instaweb_url')])
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: File access
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2010-01-13 22:01:43 -05:00
|
|
|
function! s:ReplaceCmd(cmd,...) abort
|
2012-04-01 22:04:10 -04:00
|
|
|
let fn = expand('%:p')
|
2009-10-10 19:47:14 -04:00
|
|
|
let tmp = tempname()
|
2010-01-13 22:01:43 -05:00
|
|
|
let prefix = ''
|
2009-10-10 19:47:14 -04:00
|
|
|
try
|
2010-01-13 22:01:43 -05:00
|
|
|
if a:0 && a:1 != ''
|
2014-06-21 11:11:17 -04:00
|
|
|
if s:winshell()
|
2010-01-13 22:01:43 -05:00
|
|
|
let old_index = $GIT_INDEX_FILE
|
|
|
|
let $GIT_INDEX_FILE = a:1
|
|
|
|
else
|
2011-04-03 14:43:16 -04:00
|
|
|
let prefix = 'env GIT_INDEX_FILE='.s:shellesc(a:1).' '
|
2010-01-13 22:01:43 -05:00
|
|
|
endif
|
|
|
|
endif
|
2015-07-10 06:39:36 -04:00
|
|
|
let redir = ' > '.tmp
|
|
|
|
if &shellpipe =~ '2>&1'
|
|
|
|
let redir .= ' 2>&1'
|
|
|
|
endif
|
2014-06-21 11:11:17 -04:00
|
|
|
if s:winshell()
|
2012-05-03 08:00:33 -04:00
|
|
|
let cmd_escape_char = &shellxquote == '(' ? '^' : '^^^'
|
2015-07-10 06:39:36 -04:00
|
|
|
call system('cmd /c "'.prefix.s:gsub(a:cmd,'[<>]', cmd_escape_char.'&').redir.'"')
|
2015-10-10 20:38:33 -04:00
|
|
|
elseif &shell =~# 'fish'
|
|
|
|
call system(' begin;'.prefix.a:cmd.redir.';end ')
|
2011-08-09 00:59:38 -04:00
|
|
|
else
|
2015-07-10 06:39:36 -04:00
|
|
|
call system(' ('.prefix.a:cmd.redir.') ')
|
2011-08-09 00:59:38 -04:00
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
finally
|
2010-01-13 22:01:43 -05:00
|
|
|
if exists('old_index')
|
2010-03-09 19:13:28 -05:00
|
|
|
let $GIT_INDEX_FILE = old_index
|
2010-01-13 22:01:43 -05:00
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
endtry
|
2018-05-22 22:02:13 -04:00
|
|
|
silent exe 'doau BufReadPre '.s:fnameescape(fn)
|
2014-06-22 19:36:43 -04:00
|
|
|
silent exe 'keepalt file '.tmp
|
2012-03-05 07:11:13 -05:00
|
|
|
try
|
2018-05-22 22:01:19 -04:00
|
|
|
silent noautocmd edit!
|
2012-03-05 07:11:13 -05:00
|
|
|
finally
|
2014-04-09 22:55:34 -04:00
|
|
|
try
|
|
|
|
silent exe 'keepalt file '.s:fnameescape(fn)
|
|
|
|
catch /^Vim\%((\a\+)\)\=:E302/
|
|
|
|
endtry
|
2012-03-05 07:11:13 -05:00
|
|
|
call delete(tmp)
|
2012-04-01 22:04:10 -04:00
|
|
|
if fnamemodify(bufname('$'), ':p') ==# tmp
|
2012-03-05 07:11:13 -05:00
|
|
|
silent execute 'bwipeout '.bufnr('$')
|
|
|
|
endif
|
|
|
|
silent exe 'doau BufReadPost '.s:fnameescape(fn)
|
|
|
|
endtry
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:BufReadIndex() abort
|
2009-10-19 22:11:40 -04:00
|
|
|
if !exists('b:fugitive_display_format')
|
2010-01-09 19:17:43 -05:00
|
|
|
let b:fugitive_display_format = filereadable(expand('%').'.lock')
|
2009-10-19 22:11:40 -04:00
|
|
|
endif
|
|
|
|
let b:fugitive_display_format = b:fugitive_display_format % 2
|
|
|
|
let b:fugitive_type = 'index'
|
2009-10-10 19:47:14 -04:00
|
|
|
try
|
|
|
|
let b:git_dir = s:repo().dir()
|
2012-03-05 06:58:00 -05:00
|
|
|
setlocal noro ma nomodeline
|
2010-01-09 19:17:43 -05:00
|
|
|
if fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : b:git_dir . '/index', ':p') ==# expand('%:p')
|
2010-01-13 22:01:43 -05:00
|
|
|
let index = ''
|
2010-01-09 18:19:07 -05:00
|
|
|
else
|
2010-08-18 22:14:50 -04:00
|
|
|
let index = expand('%:p')
|
2010-01-09 18:19:07 -05:00
|
|
|
endif
|
2009-10-19 22:11:40 -04:00
|
|
|
if b:fugitive_display_format
|
2010-01-13 22:01:43 -05:00
|
|
|
call s:ReplaceCmd(s:repo().git_command('ls-files','--stage'),index)
|
2009-10-19 22:11:40 -04:00
|
|
|
set ft=git nospell
|
|
|
|
else
|
2017-05-30 14:10:37 -04:00
|
|
|
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
|
2009-10-19 22:11:40 -04:00
|
|
|
let dir = getcwd()
|
2015-11-30 19:38:48 -05:00
|
|
|
if fugitive#git_version() =~# '^0\|^1\.[1-7]\.'
|
2013-10-24 00:16:15 -04:00
|
|
|
let cmd = s:repo().git_command('status')
|
|
|
|
else
|
|
|
|
let cmd = s:repo().git_command(
|
|
|
|
\ '-c', 'status.displayCommentPrefix=true',
|
|
|
|
\ '-c', 'color.status=false',
|
2014-06-03 15:47:05 -04:00
|
|
|
\ '-c', 'status.short=false',
|
2013-10-24 00:16:15 -04:00
|
|
|
\ 'status')
|
|
|
|
endif
|
2009-10-19 22:11:40 -04:00
|
|
|
try
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(s:repo().tree())
|
2013-10-24 00:16:15 -04:00
|
|
|
call s:ReplaceCmd(cmd, index)
|
2009-10-19 22:11:40 -04:00
|
|
|
finally
|
2017-05-30 14:10:37 -04:00
|
|
|
execute cd s:fnameescape(dir)
|
2009-10-19 22:11:40 -04:00
|
|
|
endtry
|
|
|
|
set ft=gitcommit
|
2013-01-13 16:01:17 -05:00
|
|
|
set foldtext=fugitive#foldtext()
|
2009-10-19 22:11:40 -04:00
|
|
|
endif
|
2012-03-12 18:36:16 -04:00
|
|
|
setlocal ro noma nomod noswapfile
|
|
|
|
if &bufhidden ==# ''
|
|
|
|
setlocal bufhidden=delete
|
|
|
|
endif
|
2011-08-19 15:01:37 -04:00
|
|
|
call s:JumpInit()
|
|
|
|
nunmap <buffer> P
|
|
|
|
nunmap <buffer> ~
|
2012-09-07 01:07:54 -04:00
|
|
|
nnoremap <buffer> <silent> <C-N> :<C-U>execute <SID>StageNext(v:count1)<CR>
|
|
|
|
nnoremap <buffer> <silent> <C-P> :<C-U>execute <SID>StagePrevious(v:count1)<CR>
|
2012-12-31 22:32:53 -05:00
|
|
|
nnoremap <buffer> <silent> - :<C-U>silent execute <SID>StageToggle(line('.'),line('.')+v:count1-1)<CR>
|
|
|
|
xnoremap <buffer> <silent> - :<C-U>silent execute <SID>StageToggle(line("'<"),line("'>"))<CR>
|
2009-10-19 22:11:40 -04:00
|
|
|
nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += 1<Bar>exe <SID>BufReadIndex()<CR>
|
|
|
|
nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= 1<Bar>exe <SID>BufReadIndex()<CR>
|
2018-05-16 00:28:17 -04:00
|
|
|
nnoremap <buffer> <silent> C :<C-U>Gcommit<CR>:echohl WarningMsg<Bar>echo ':Gstatus C is deprecated in favor of cc'<Bar>echohl NONE<CR>
|
2018-05-19 15:41:12 -04:00
|
|
|
nnoremap <buffer> <silent> cA :<C-U>Gcommit --amend --reuse-message=HEAD<CR>:echohl WarningMsg<Bar>echo ':Gstatus cA is deprecated in favor of ce'<CR>
|
2011-08-25 15:45:00 -04:00
|
|
|
nnoremap <buffer> <silent> ca :<C-U>Gcommit --amend<CR>
|
2011-08-29 20:50:05 -04:00
|
|
|
nnoremap <buffer> <silent> cc :<C-U>Gcommit<CR>
|
2018-05-11 17:12:18 -04:00
|
|
|
nnoremap <buffer> <silent> ce :<C-U>Gcommit --amend --no-edit<CR>
|
|
|
|
nnoremap <buffer> <silent> cw :<C-U>Gcommit --amend --only<CR>
|
|
|
|
nnoremap <buffer> <silent> cva :<C-U>Gcommit -v --amend<CR>
|
|
|
|
nnoremap <buffer> <silent> cvc :<C-U>Gcommit -v<CR>
|
2014-06-21 09:37:51 -04:00
|
|
|
nnoremap <buffer> <silent> D :<C-U>execute <SID>StageDiff('Gdiff')<CR>
|
|
|
|
nnoremap <buffer> <silent> dd :<C-U>execute <SID>StageDiff('Gdiff')<CR>
|
2011-02-27 13:14:58 -05:00
|
|
|
nnoremap <buffer> <silent> dh :<C-U>execute <SID>StageDiff('Gsdiff')<CR>
|
|
|
|
nnoremap <buffer> <silent> ds :<C-U>execute <SID>StageDiff('Gsdiff')<CR>
|
2011-08-19 15:13:44 -04:00
|
|
|
nnoremap <buffer> <silent> dp :<C-U>execute <SID>StageDiffEdit()<CR>
|
2011-08-19 15:01:37 -04:00
|
|
|
nnoremap <buffer> <silent> dv :<C-U>execute <SID>StageDiff('Gvdiff')<CR>
|
2010-01-11 22:51:54 -05:00
|
|
|
nnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR>
|
|
|
|
xnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line("'<"),line("'>"))<CR>
|
2016-01-01 16:55:17 -05:00
|
|
|
nnoremap <buffer> <silent> P :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR>
|
|
|
|
xnoremap <buffer> <silent> P :<C-U>execute <SID>StagePatch(line("'<"),line("'>"))<CR>
|
2011-09-02 15:19:06 -04:00
|
|
|
nnoremap <buffer> <silent> q :<C-U>if bufnr('$') == 1<Bar>quit<Bar>else<Bar>bdelete<Bar>endif<CR>
|
2014-06-21 09:33:59 -04:00
|
|
|
nnoremap <buffer> <silent> r :<C-U>edit<CR>
|
2011-08-19 15:01:37 -04:00
|
|
|
nnoremap <buffer> <silent> R :<C-U>edit<CR>
|
2014-06-21 10:05:46 -04:00
|
|
|
nnoremap <buffer> <silent> U :<C-U>execute <SID>StageUndo()<CR>
|
2014-04-07 05:00:22 -04:00
|
|
|
nnoremap <buffer> <silent> g? :help fugitive-:Gstatus<CR>
|
2014-03-30 13:13:46 -04:00
|
|
|
nnoremap <buffer> <silent> <F1> :help fugitive-:Gstatus<CR>
|
2009-10-10 19:47:14 -04:00
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:FileRead() abort
|
2009-10-10 19:47:14 -04:00
|
|
|
try
|
2012-03-18 22:44:04 -04:00
|
|
|
let repo = s:repo(fugitive#extract_git_dir(expand('<amatch>')))
|
2009-10-10 19:47:14 -04:00
|
|
|
let path = s:sub(s:sub(matchstr(expand('<amatch>'),'fugitive://.\{-\}//\zs.*'),'/',':'),'^\d:',':&')
|
|
|
|
let hash = repo.rev_parse(path)
|
|
|
|
if path =~ '^:'
|
|
|
|
let type = 'blob'
|
|
|
|
else
|
|
|
|
let type = repo.git_chomp('cat-file','-t',hash)
|
|
|
|
endif
|
|
|
|
" TODO: use count, if possible
|
|
|
|
return "read !".escape(repo.git_command('cat-file',type,hash),'%#\')
|
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:BufReadIndexFile() abort
|
2009-10-10 19:47:14 -04:00
|
|
|
try
|
|
|
|
let b:fugitive_type = 'blob'
|
|
|
|
let b:git_dir = s:repo().dir()
|
2012-03-05 07:19:31 -05:00
|
|
|
try
|
|
|
|
call s:ReplaceCmd(s:repo().git_command('cat-file','blob',s:buffer().sha1()))
|
|
|
|
finally
|
|
|
|
if &bufhidden ==# ''
|
|
|
|
setlocal bufhidden=delete
|
|
|
|
endif
|
2014-03-19 00:53:05 -04:00
|
|
|
setlocal noswapfile
|
2012-03-05 07:19:31 -05:00
|
|
|
endtry
|
2009-10-10 19:47:14 -04:00
|
|
|
return ''
|
|
|
|
catch /^fugitive: rev-parse/
|
2012-04-01 22:04:10 -04:00
|
|
|
silent exe 'doau BufNewFile '.s:fnameescape(expand('%:p'))
|
2009-10-10 19:47:14 -04:00
|
|
|
return ''
|
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:BufWriteIndexFile() abort
|
2009-10-10 19:47:14 -04:00
|
|
|
let tmp = tempname()
|
|
|
|
try
|
2009-10-14 22:30:36 -04:00
|
|
|
let path = matchstr(expand('<amatch>'),'//\d/\zs.*')
|
|
|
|
let stage = matchstr(expand('<amatch>'),'//\zs\d')
|
2009-10-10 19:47:14 -04:00
|
|
|
silent execute 'write !'.s:repo().git_command('hash-object','-w','--stdin').' > '.tmp
|
|
|
|
let sha1 = readfile(tmp)[0]
|
2009-10-14 22:30:36 -04:00
|
|
|
let old_mode = matchstr(s:repo().git_chomp('ls-files','--stage',path),'^\d\+')
|
2009-10-10 19:47:14 -04:00
|
|
|
if old_mode == ''
|
2009-10-14 22:30:36 -04:00
|
|
|
let old_mode = executable(s:repo().tree(path)) ? '100755' : '100644'
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2009-10-14 22:30:36 -04:00
|
|
|
let info = old_mode.' '.sha1.' '.stage."\t".path
|
2009-10-10 19:47:14 -04:00
|
|
|
call writefile([info],tmp)
|
2014-06-21 11:11:17 -04:00
|
|
|
if s:winshell()
|
2012-06-07 22:05:06 -04:00
|
|
|
let error = system('type '.s:gsub(tmp,'/','\\').'|'.s:repo().git_command('update-index','--index-info'))
|
2010-06-02 22:42:41 -04:00
|
|
|
else
|
|
|
|
let error = system(s:repo().git_command('update-index','--index-info').' < '.tmp)
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
if v:shell_error == 0
|
|
|
|
setlocal nomodified
|
2014-11-20 15:43:36 -05:00
|
|
|
if exists('#BufWritePost')
|
|
|
|
execute 'doautocmd BufWritePost '.s:fnameescape(expand('%:p'))
|
|
|
|
endif
|
2009-11-03 22:23:58 -05:00
|
|
|
call fugitive#reload_status()
|
2009-10-10 19:47:14 -04:00
|
|
|
return ''
|
|
|
|
else
|
|
|
|
return 'echoerr '.string('fugitive: '.error)
|
|
|
|
endif
|
|
|
|
finally
|
|
|
|
call delete(tmp)
|
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! s:BufReadObject() abort
|
2009-10-10 19:47:14 -04:00
|
|
|
try
|
|
|
|
setlocal noro ma
|
|
|
|
let b:git_dir = s:repo().dir()
|
|
|
|
let hash = s:buffer().sha1()
|
|
|
|
if !exists("b:fugitive_type")
|
|
|
|
let b:fugitive_type = s:repo().git_chomp('cat-file','-t',hash)
|
|
|
|
endif
|
|
|
|
if b:fugitive_type !~# '^\%(tag\|commit\|tree\|blob\)$'
|
2017-04-02 17:04:02 -04:00
|
|
|
return "echoerr ".string("fugitive: unrecognized git type '".b:fugitive_type."'")
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
if !exists('b:fugitive_display_format') && b:fugitive_type != 'blob'
|
|
|
|
let b:fugitive_display_format = +getbufvar('#','fugitive_display_format')
|
|
|
|
endif
|
|
|
|
|
2012-03-05 06:58:00 -05:00
|
|
|
if b:fugitive_type !=# 'blob'
|
|
|
|
setlocal nomodeline
|
|
|
|
endif
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
let pos = getpos('.')
|
2014-03-19 23:36:20 -04:00
|
|
|
silent keepjumps %delete_
|
2009-10-10 19:47:14 -04:00
|
|
|
setlocal endofline
|
|
|
|
|
2012-03-05 07:19:31 -05:00
|
|
|
try
|
2012-03-05 07:32:01 -05:00
|
|
|
if b:fugitive_type ==# 'tree'
|
2012-03-05 07:19:31 -05:00
|
|
|
let b:fugitive_display_format = b:fugitive_display_format % 2
|
|
|
|
if b:fugitive_display_format
|
|
|
|
call s:ReplaceCmd(s:repo().git_command('ls-tree',hash))
|
|
|
|
else
|
|
|
|
call s:ReplaceCmd(s:repo().git_command('show','--no-color',hash))
|
|
|
|
endif
|
2012-03-05 07:32:01 -05:00
|
|
|
elseif b:fugitive_type ==# 'tag'
|
2012-03-05 07:19:31 -05:00
|
|
|
let b:fugitive_display_format = b:fugitive_display_format % 2
|
|
|
|
if b:fugitive_display_format
|
|
|
|
call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
|
|
|
|
else
|
|
|
|
call s:ReplaceCmd(s:repo().git_command('cat-file','-p',hash))
|
|
|
|
endif
|
2012-03-05 07:32:01 -05:00
|
|
|
elseif b:fugitive_type ==# 'commit'
|
2012-03-05 07:19:31 -05:00
|
|
|
let b:fugitive_display_format = b:fugitive_display_format % 2
|
|
|
|
if b:fugitive_display_format
|
|
|
|
call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
|
|
|
|
else
|
2016-03-05 13:37:40 -05:00
|
|
|
call s:ReplaceCmd(s:repo().git_command('show','--no-color','--pretty=format:tree%x20%T%nparent%x20%P%nauthor%x20%an%x20<%ae>%x20%ad%ncommitter%x20%cn%x20<%ce>%x20%cd%nencoding%x20%e%n%n%s%n%n%b',hash))
|
2014-03-19 23:36:20 -04:00
|
|
|
keepjumps call search('^parent ')
|
2012-03-05 07:19:31 -05:00
|
|
|
if getline('.') ==# 'parent '
|
2014-03-19 23:36:20 -04:00
|
|
|
silent keepjumps delete_
|
2012-03-05 07:19:31 -05:00
|
|
|
else
|
2018-05-06 19:10:51 -04:00
|
|
|
silent exe 'keepjumps s/\m\C\%(^parent\)\@<! /\rparent /e' . (&gdefault ? '' : 'g')
|
2012-03-05 07:19:31 -05:00
|
|
|
endif
|
2014-03-19 23:36:20 -04:00
|
|
|
keepjumps let lnum = search('^encoding \%(<unknown>\)\=$','W',line('.')+3)
|
|
|
|
if lnum
|
|
|
|
silent keepjumps delete_
|
2012-03-05 07:19:31 -05:00
|
|
|
end
|
2018-04-04 15:03:56 -04:00
|
|
|
silent keepjumps 1,/^diff --git\|\%$/g/\r$/s///
|
2014-03-19 23:36:20 -04:00
|
|
|
keepjumps 1
|
2012-03-05 07:19:31 -05:00
|
|
|
endif
|
|
|
|
elseif b:fugitive_type ==# 'blob'
|
2009-10-10 19:47:14 -04:00
|
|
|
call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
|
2014-04-02 02:32:20 -04:00
|
|
|
setlocal nomodeline
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2012-03-05 07:19:31 -05:00
|
|
|
finally
|
2014-03-19 23:36:20 -04:00
|
|
|
keepjumps call setpos('.',pos)
|
2014-03-19 00:53:05 -04:00
|
|
|
setlocal ro noma nomod noswapfile
|
2012-03-05 07:19:31 -05:00
|
|
|
if &bufhidden ==# ''
|
|
|
|
setlocal bufhidden=delete
|
|
|
|
endif
|
|
|
|
if b:fugitive_type !=# 'blob'
|
2014-06-21 10:25:30 -04:00
|
|
|
setlocal filetype=git foldmethod=syntax
|
2012-03-05 07:19:31 -05:00
|
|
|
nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += v:count1<Bar>exe <SID>BufReadObject()<CR>
|
|
|
|
nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= v:count1<Bar>exe <SID>BufReadObject()<CR>
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
2012-03-05 07:19:31 -05:00
|
|
|
call s:JumpInit()
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
2012-03-05 07:19:31 -05:00
|
|
|
endtry
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2017-10-30 17:15:41 -04:00
|
|
|
return ''
|
|
|
|
catch /^fugitive: rev-parse/
|
2009-10-10 19:47:14 -04:00
|
|
|
return ''
|
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
augroup fugitive_files
|
|
|
|
autocmd!
|
2012-03-16 22:27:45 -04:00
|
|
|
autocmd BufReadCmd index{,.lock}
|
2012-03-18 22:44:04 -04:00
|
|
|
\ if fugitive#is_git_dir(expand('<amatch>:p:h')) |
|
2012-03-16 22:27:45 -04:00
|
|
|
\ exe s:BufReadIndex() |
|
2012-08-01 10:35:52 -04:00
|
|
|
\ elseif filereadable(expand('<amatch>')) |
|
2012-07-08 01:11:12 -04:00
|
|
|
\ read <amatch> |
|
|
|
|
\ 1delete |
|
2012-03-16 22:27:45 -04:00
|
|
|
\ endif
|
2009-10-10 19:47:14 -04:00
|
|
|
autocmd FileReadCmd fugitive://**//[0-3]/** exe s:FileRead()
|
|
|
|
autocmd BufReadCmd fugitive://**//[0-3]/** exe s:BufReadIndexFile()
|
|
|
|
autocmd BufWriteCmd fugitive://**//[0-3]/** exe s:BufWriteIndexFile()
|
|
|
|
autocmd BufReadCmd fugitive://**//[0-9a-f][0-9a-f]* exe s:BufReadObject()
|
|
|
|
autocmd FileReadCmd fugitive://**//[0-9a-f][0-9a-f]* exe s:FileRead()
|
2012-07-15 13:33:36 -04:00
|
|
|
autocmd FileType git
|
|
|
|
\ if exists('b:git_dir') |
|
|
|
|
\ call s:JumpInit() |
|
|
|
|
\ endif
|
2015-10-07 00:03:06 -04:00
|
|
|
autocmd FileType git,gitcommit,gitrebase
|
|
|
|
\ if exists('b:git_dir') |
|
|
|
|
\ call s:GFInit() |
|
|
|
|
\ endif
|
2009-10-10 19:47:14 -04:00
|
|
|
augroup END
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Temp files
|
2011-08-19 02:21:33 -04:00
|
|
|
|
2011-10-07 01:32:46 -04:00
|
|
|
if !exists('s:temp_files')
|
|
|
|
let s:temp_files = {}
|
|
|
|
endif
|
2011-08-19 02:21:33 -04:00
|
|
|
|
|
|
|
augroup fugitive_temp
|
|
|
|
autocmd!
|
|
|
|
autocmd BufNewFile,BufReadPost *
|
2015-06-30 17:42:13 -04:00
|
|
|
\ if has_key(s:temp_files,s:cpath(expand('<afile>:p'))) |
|
|
|
|
\ let b:git_dir = s:temp_files[s:cpath(expand('<afile>:p'))].dir |
|
2011-08-19 02:21:33 -04:00
|
|
|
\ let b:git_type = 'temp' |
|
2015-06-30 17:42:13 -04:00
|
|
|
\ let b:git_args = s:temp_files[s:cpath(expand('<afile>:p'))].args |
|
2013-02-23 12:24:24 -05:00
|
|
|
\ call fugitive#detect(expand('<afile>:p')) |
|
2014-07-23 17:55:15 -04:00
|
|
|
\ setlocal bufhidden=delete nobuflisted |
|
2011-10-01 03:54:58 -04:00
|
|
|
\ nnoremap <buffer> <silent> q :<C-U>bdelete<CR>|
|
2011-08-19 02:21:33 -04:00
|
|
|
\ endif
|
|
|
|
augroup END
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Go to file
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2015-10-07 00:03:06 -04:00
|
|
|
nnoremap <SID>: :<C-U><C-R>=v:count ? v:count : ''<CR>
|
|
|
|
function! s:GFInit(...) abort
|
|
|
|
cnoremap <buffer> <expr> <Plug><cfile> fugitive#cfile()
|
2018-05-06 19:11:34 -04:00
|
|
|
if !exists('g:fugitive_no_maps')
|
|
|
|
call s:map('n', 'gf', '<SID>:find <Plug><cfile><CR>', '<silent><unique>')
|
|
|
|
call s:map('n', '<C-W>f', '<SID>:sfind <Plug><cfile><CR>', '<silent><unique>')
|
|
|
|
call s:map('n', '<C-W><C-F>', '<SID>:sfind <Plug><cfile><CR>', '<silent><unique>')
|
|
|
|
call s:map('n', '<C-W>gf', '<SID>:tabfind <Plug><cfile><CR>', '<silent><unique>')
|
|
|
|
call s:map('c', '<C-R><C-F>', '<Plug><cfile>', '<silent><unique>')
|
2015-10-07 00:03:06 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:JumpInit(...) abort
|
2009-10-10 19:47:14 -04:00
|
|
|
nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>GF("edit")<CR>
|
|
|
|
if !&modifiable
|
|
|
|
nnoremap <buffer> <silent> o :<C-U>exe <SID>GF("split")<CR>
|
2012-03-26 00:02:08 -04:00
|
|
|
nnoremap <buffer> <silent> S :<C-U>exe <SID>GF("vsplit")<CR>
|
2009-10-10 19:47:14 -04:00
|
|
|
nnoremap <buffer> <silent> O :<C-U>exe <SID>GF("tabedit")<CR>
|
2013-03-12 02:01:49 -04:00
|
|
|
nnoremap <buffer> <silent> - :<C-U>exe <SID>Edit('edit',0,<SID>buffer().up(v:count1))<Bar> if fugitive#buffer().type('tree')<Bar>call search('^'.escape(expand('#:t'),'.*[]~\').'/\=$','wc')<Bar>endif<CR>
|
2011-08-21 15:53:12 -04:00
|
|
|
nnoremap <buffer> <silent> P :<C-U>exe <SID>Edit('edit',0,<SID>buffer().commit().'^'.v:count1.<SID>buffer().path(':'))<CR>
|
|
|
|
nnoremap <buffer> <silent> ~ :<C-U>exe <SID>Edit('edit',0,<SID>buffer().commit().'~'.v:count1.<SID>buffer().path(':'))<CR>
|
|
|
|
nnoremap <buffer> <silent> C :<C-U>exe <SID>Edit('edit',0,<SID>buffer().containing_commit())<CR>
|
|
|
|
nnoremap <buffer> <silent> cc :<C-U>exe <SID>Edit('edit',0,<SID>buffer().containing_commit())<CR>
|
|
|
|
nnoremap <buffer> <silent> co :<C-U>exe <SID>Edit('split',0,<SID>buffer().containing_commit())<CR>
|
2012-03-26 00:02:08 -04:00
|
|
|
nnoremap <buffer> <silent> cS :<C-U>exe <SID>Edit('vsplit',0,<SID>buffer().containing_commit())<CR>
|
2011-08-21 15:53:12 -04:00
|
|
|
nnoremap <buffer> <silent> cO :<C-U>exe <SID>Edit('tabedit',0,<SID>buffer().containing_commit())<CR>
|
2013-03-12 02:24:45 -04:00
|
|
|
nnoremap <buffer> <silent> cP :<C-U>exe <SID>Edit('pedit',0,<SID>buffer().containing_commit())<CR>
|
2013-03-12 02:22:02 -04:00
|
|
|
nnoremap <buffer> . : <C-R>=fnameescape(<SID>recall())<CR><Home>
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
endfunction
|
|
|
|
|
2015-10-06 21:45:40 -04:00
|
|
|
function! s:cfile() abort
|
2009-10-10 19:47:14 -04:00
|
|
|
try
|
|
|
|
let buffer = s:buffer()
|
|
|
|
let myhash = buffer.sha1()
|
2011-08-19 02:43:31 -04:00
|
|
|
if myhash ==# '' && getline(1) =~# '^\%(commit\|tag\) \w'
|
|
|
|
let myhash = matchstr(getline(1),'^\w\+ \zs\S\+')
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
|
2009-10-19 22:11:40 -04:00
|
|
|
if buffer.type('tree')
|
2009-10-10 19:47:14 -04:00
|
|
|
let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
|
2015-10-06 21:45:40 -04:00
|
|
|
if showtree && line('.') > 2
|
|
|
|
return [buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(getline('.'),'/$','')]
|
2009-10-10 19:47:14 -04:00
|
|
|
elseif getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
|
2015-10-06 21:45:40 -04:00
|
|
|
return [buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$','')]
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
|
|
|
|
elseif buffer.type('blob')
|
|
|
|
let ref = expand("<cfile>")
|
|
|
|
try
|
|
|
|
let sha1 = buffer.repo().rev_parse(ref)
|
|
|
|
catch /^fugitive:/
|
|
|
|
endtry
|
|
|
|
if exists('sha1')
|
2015-10-06 21:45:40 -04:00
|
|
|
return [ref]
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
|
|
|
|
else
|
2009-10-19 22:11:40 -04:00
|
|
|
|
2015-10-06 23:03:21 -04:00
|
|
|
let dcmds = []
|
|
|
|
|
2009-10-19 22:11:40 -04:00
|
|
|
" Index
|
|
|
|
if getline('.') =~# '^\d\{6\} \x\{40\} \d\t'
|
|
|
|
let ref = matchstr(getline('.'),'\x\{40\}')
|
|
|
|
let file = ':'.s:sub(matchstr(getline('.'),'\d\t.*'),'\t',':')
|
2015-10-06 21:45:40 -04:00
|
|
|
return [file]
|
2009-10-19 22:11:40 -04:00
|
|
|
|
|
|
|
elseif getline('.') =~# '^#\trenamed:.* -> '
|
|
|
|
let file = '/'.matchstr(getline('.'),' -> \zs.*')
|
2015-10-06 21:45:40 -04:00
|
|
|
return [file]
|
2016-07-06 17:50:38 -04:00
|
|
|
elseif getline('.') =~# '^#\t\(\k\| \)\+\p\?: *.'
|
2012-07-28 11:54:52 -04:00
|
|
|
let file = '/'.matchstr(getline('.'),': *\zs.\{-\}\ze\%( ([^()[:digit:]]\+)\)\=$')
|
2015-10-06 21:45:40 -04:00
|
|
|
return [file]
|
2009-10-19 22:11:40 -04:00
|
|
|
elseif getline('.') =~# '^#\t.'
|
|
|
|
let file = '/'.matchstr(getline('.'),'#\t\zs.*')
|
2015-10-06 21:45:40 -04:00
|
|
|
return [file]
|
2009-10-19 22:11:40 -04:00
|
|
|
elseif getline('.') =~# ': needs merge$'
|
|
|
|
let file = '/'.matchstr(getline('.'),'.*\ze: needs merge$')
|
2015-10-06 23:24:34 -04:00
|
|
|
return [file, 'Gdiff!']
|
2009-10-19 22:11:40 -04:00
|
|
|
|
|
|
|
elseif getline('.') ==# '# Not currently on any branch.'
|
2015-10-06 21:45:40 -04:00
|
|
|
return ['HEAD']
|
2009-10-19 22:11:40 -04:00
|
|
|
elseif getline('.') =~# '^# On branch '
|
|
|
|
let file = 'refs/heads/'.getline('.')[12:]
|
2015-10-06 21:45:40 -04:00
|
|
|
return [file]
|
2009-10-19 22:11:40 -04:00
|
|
|
elseif getline('.') =~# "^# Your branch .*'"
|
2010-01-09 23:20:30 -05:00
|
|
|
let file = matchstr(getline('.'),"'\\zs\\S\\+\\ze'")
|
2015-10-06 21:45:40 -04:00
|
|
|
return [file]
|
2009-10-19 22:11:40 -04:00
|
|
|
endif
|
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
|
|
|
|
|
|
|
|
if getline('.') =~# '^ref: '
|
|
|
|
let ref = strpart(getline('.'),5)
|
|
|
|
|
2011-08-19 02:43:31 -04:00
|
|
|
elseif getline('.') =~# '^commit \x\{40\}\>'
|
|
|
|
let ref = matchstr(getline('.'),'\x\{40\}')
|
2015-10-06 21:45:40 -04:00
|
|
|
return [ref]
|
2011-08-19 02:43:31 -04:00
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
elseif getline('.') =~# '^parent \x\{40\}\>'
|
|
|
|
let ref = matchstr(getline('.'),'\x\{40\}')
|
|
|
|
let line = line('.')
|
|
|
|
let parent = 0
|
|
|
|
while getline(line) =~# '^parent '
|
|
|
|
let parent += 1
|
|
|
|
let line -= 1
|
|
|
|
endwhile
|
2015-10-06 21:45:40 -04:00
|
|
|
return [ref]
|
2009-10-10 19:47:14 -04:00
|
|
|
|
|
|
|
elseif getline('.') =~ '^tree \x\{40\}$'
|
|
|
|
let ref = matchstr(getline('.'),'\x\{40\}')
|
|
|
|
if s:repo().rev_parse(myhash.':') == ref
|
|
|
|
let ref = myhash.':'
|
|
|
|
endif
|
2015-10-06 21:45:40 -04:00
|
|
|
return [ref]
|
2009-10-10 19:47:14 -04:00
|
|
|
|
|
|
|
elseif getline('.') =~# '^object \x\{40\}$' && getline(line('.')+1) =~ '^type \%(commit\|tree\|blob\)$'
|
|
|
|
let ref = matchstr(getline('.'),'\x\{40\}')
|
|
|
|
let type = matchstr(getline(line('.')+1),'type \zs.*')
|
|
|
|
|
|
|
|
elseif getline('.') =~# '^\l\{3,8\} '.myhash.'$'
|
2015-10-06 21:45:40 -04:00
|
|
|
let ref = buffer.rev()
|
2009-10-10 19:47:14 -04:00
|
|
|
|
|
|
|
elseif getline('.') =~# '^\l\{3,8\} \x\{40\}\>'
|
|
|
|
let ref = matchstr(getline('.'),'\x\{40\}')
|
|
|
|
echoerr "warning: unknown context ".matchstr(getline('.'),'^\l*')
|
|
|
|
|
2017-05-02 19:31:07 -04:00
|
|
|
elseif getline('.') =~# '^[+-]\{3\} [abciow12]\=/'
|
2009-10-10 19:47:14 -04:00
|
|
|
let ref = getline('.')[4:]
|
|
|
|
|
2011-10-01 16:48:39 -04:00
|
|
|
elseif getline('.') =~# '^[+-]' && search('^@@ -\d\+,\d\+ +\d\+,','bnW')
|
|
|
|
let type = getline('.')[0]
|
|
|
|
let lnum = line('.') - 1
|
2015-12-15 21:19:33 -05:00
|
|
|
let offset = 0
|
2011-10-01 16:48:39 -04:00
|
|
|
while getline(lnum) !~# '^@@ -\d\+,\d\+ +\d\+,'
|
|
|
|
if getline(lnum) =~# '^[ '.type.']'
|
|
|
|
let offset += 1
|
|
|
|
endif
|
|
|
|
let lnum -= 1
|
|
|
|
endwhile
|
|
|
|
let offset += matchstr(getline(lnum), type.'\zs\d\+')
|
2017-05-02 19:31:07 -04:00
|
|
|
let ref = getline(search('^'.type.'\{3\} [abciow12]/','bnW'))[4:-1]
|
2015-10-06 23:03:21 -04:00
|
|
|
let dcmds = [offset, 'normal!zv']
|
2011-10-01 16:48:39 -04:00
|
|
|
|
2009-10-18 18:12:36 -04:00
|
|
|
elseif getline('.') =~# '^rename from '
|
|
|
|
let ref = 'a/'.getline('.')[12:]
|
|
|
|
elseif getline('.') =~# '^rename to '
|
|
|
|
let ref = 'b/'.getline('.')[10:]
|
|
|
|
|
2015-10-06 23:03:21 -04:00
|
|
|
elseif getline('.') =~# '^@@ -\d\+,\d\+ +\d\+,'
|
2017-05-02 19:31:07 -04:00
|
|
|
let diff = getline(search('^diff --git \%([abciow12]/.*\|/dev/null\) \%([abciow12]/.*\|/dev/null\)', 'bcnW'))
|
2015-10-06 23:03:21 -04:00
|
|
|
let offset = matchstr(getline('.'), '+\zs\d\+')
|
|
|
|
|
2017-05-02 19:31:07 -04:00
|
|
|
let dref = matchstr(diff, '\Cdiff --git \zs\%([abciow12]/.*\|/dev/null\)\ze \%([abciow12]/.*\|/dev/null\)')
|
|
|
|
let ref = matchstr(diff, '\Cdiff --git \%([abciow12]/.*\|/dev/null\) \zs\%([abciow12]/.*\|/dev/null\)')
|
2015-10-06 23:03:21 -04:00
|
|
|
let dcmd = 'Gdiff! +'.offset
|
|
|
|
|
2017-05-02 19:31:07 -04:00
|
|
|
elseif getline('.') =~# '^diff --git \%([abciow12]/.*\|/dev/null\) \%([abciow12]/.*\|/dev/null\)'
|
|
|
|
let dref = matchstr(getline('.'),'\Cdiff --git \zs\%([abciow12]/.*\|/dev/null\)\ze \%([abciow12]/.*\|/dev/null\)')
|
|
|
|
let ref = matchstr(getline('.'),'\Cdiff --git \%([abciow12]/.*\|/dev/null\) \zs\%([abciow12]/.*\|/dev/null\)')
|
2015-10-06 23:24:34 -04:00
|
|
|
let dcmd = 'Gdiff!'
|
2010-06-28 11:50:44 -04:00
|
|
|
|
2017-05-02 19:31:07 -04:00
|
|
|
elseif getline('.') =~# '^index ' && getline(line('.')-1) =~# '^diff --git \%([abciow12]/.*\|/dev/null\) \%([abciow12]/.*\|/dev/null\)'
|
2010-06-28 11:50:44 -04:00
|
|
|
let line = getline(line('.')-1)
|
2017-05-02 19:31:07 -04:00
|
|
|
let dref = matchstr(line,'\Cdiff --git \zs\%([abciow12]/.*\|/dev/null\)\ze \%([abciow12]/.*\|/dev/null\)')
|
|
|
|
let ref = matchstr(line,'\Cdiff --git \%([abciow12]/.*\|/dev/null\) \zs\%([abciow12]/.*\|/dev/null\)')
|
2010-06-28 11:50:44 -04:00
|
|
|
let dcmd = 'Gdiff!'
|
2009-10-18 18:12:36 -04:00
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
elseif line('$') == 1 && getline('.') =~ '^\x\{40\}$'
|
|
|
|
let ref = getline('.')
|
2013-05-03 19:28:50 -04:00
|
|
|
|
|
|
|
elseif expand('<cword>') =~# '^\x\{7,40\}\>'
|
2015-10-06 21:45:40 -04:00
|
|
|
return [expand('<cword>')]
|
2013-05-03 19:28:50 -04:00
|
|
|
|
2009-10-10 19:47:14 -04:00
|
|
|
else
|
|
|
|
let ref = ''
|
|
|
|
endif
|
|
|
|
|
2017-05-01 14:45:25 -04:00
|
|
|
let prefixes = {
|
|
|
|
\ '1': '',
|
|
|
|
\ '2': '',
|
|
|
|
\ 'b': ':0:',
|
|
|
|
\ 'i': ':0:',
|
|
|
|
\ 'o': '',
|
|
|
|
\ 'w': ''}
|
|
|
|
|
|
|
|
if len(myhash)
|
|
|
|
let prefixes.a = myhash.'^:'
|
|
|
|
let prefixes.b = myhash.':'
|
|
|
|
endif
|
2017-05-02 19:34:47 -04:00
|
|
|
let ref = substitute(ref, '^\(\w\)/', '\=get(prefixes, submatch(1), "HEAD:")', '')
|
2017-05-01 14:45:25 -04:00
|
|
|
if exists('dref')
|
2017-05-02 19:34:47 -04:00
|
|
|
let dref = substitute(dref, '^\(\w\)/', '\=get(prefixes, submatch(1), "HEAD:")', '')
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
|
2010-01-09 17:35:27 -05:00
|
|
|
if ref ==# '/dev/null'
|
2009-10-10 19:47:14 -04:00
|
|
|
" Empty blob
|
|
|
|
let ref = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'
|
|
|
|
endif
|
|
|
|
|
2009-10-18 18:12:36 -04:00
|
|
|
if exists('dref')
|
2015-10-06 23:03:21 -04:00
|
|
|
return [ref, dcmd . ' ' . s:fnameescape(dref)] + dcmds
|
2009-10-18 18:12:36 -04:00
|
|
|
elseif ref != ""
|
2015-10-06 23:03:21 -04:00
|
|
|
return [ref] + dcmds
|
2009-10-10 19:47:14 -04:00
|
|
|
endif
|
|
|
|
|
|
|
|
endif
|
2015-10-06 21:45:40 -04:00
|
|
|
return []
|
|
|
|
endtry
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! s:GF(mode) abort
|
|
|
|
try
|
|
|
|
let results = s:cfile()
|
2009-10-10 19:47:14 -04:00
|
|
|
catch /^fugitive:/
|
|
|
|
return 'echoerr v:errmsg'
|
|
|
|
endtry
|
2015-10-06 23:03:21 -04:00
|
|
|
if len(results)
|
|
|
|
return s:Edit(a:mode, 0, results[0]).join(map(results[1:-1], '"|".v:val'), '')
|
2015-10-06 21:45:40 -04:00
|
|
|
else
|
|
|
|
return ''
|
|
|
|
endif
|
2009-10-10 19:47:14 -04:00
|
|
|
endfunction
|
|
|
|
|
2015-10-07 00:03:06 -04:00
|
|
|
function! fugitive#cfile() abort
|
|
|
|
let pre = ''
|
|
|
|
let results = s:cfile()
|
|
|
|
if empty(results)
|
2016-01-22 20:03:58 -05:00
|
|
|
let cfile = expand('<cfile>')
|
|
|
|
if &includeexpr =~# '\<v:fname\>'
|
|
|
|
sandbox let cfile = eval(substitute(&includeexpr, '\C\<v:fname\>', '\=string(cfile)', 'g'))
|
|
|
|
endif
|
|
|
|
return cfile
|
2015-10-07 00:03:06 -04:00
|
|
|
elseif len(results) > 1
|
|
|
|
let pre = '+' . join(map(results[1:-1], 'escape(v:val, " ")'), '\|') . ' '
|
|
|
|
endif
|
|
|
|
return pre . s:fnameescape(fugitive#repo().translate(results[0]))
|
|
|
|
endfunction
|
|
|
|
|
2018-05-12 19:46:36 -04:00
|
|
|
function! fugitive#Cfile() abort
|
|
|
|
return fugitive#cfile()
|
|
|
|
endfunction
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Statusline
|
2010-02-02 23:46:04 -05:00
|
|
|
|
|
|
|
function! s:repo_head_ref() dict abort
|
2014-03-30 13:13:46 -04:00
|
|
|
if !filereadable(self.dir('HEAD'))
|
|
|
|
return ''
|
|
|
|
endif
|
2012-03-18 21:55:53 -04:00
|
|
|
return readfile(self.dir('HEAD'))[0]
|
2010-02-02 23:46:04 -05:00
|
|
|
endfunction
|
|
|
|
|
|
|
|
call s:add_methods('repo',['head_ref'])
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! fugitive#statusline(...) abort
|
2010-02-02 23:46:04 -05:00
|
|
|
if !exists('b:git_dir')
|
|
|
|
return ''
|
|
|
|
endif
|
2010-02-10 10:07:56 -05:00
|
|
|
let status = ''
|
2010-02-02 23:46:04 -05:00
|
|
|
if s:buffer().commit() != ''
|
|
|
|
let status .= ':' . s:buffer().commit()[0:7]
|
|
|
|
endif
|
2012-05-07 11:41:25 -04:00
|
|
|
let status .= '('.fugitive#head(7).')'
|
2010-02-10 10:07:56 -05:00
|
|
|
if &statusline =~# '%[MRHWY]' && &statusline !~# '%[mrhwy]'
|
|
|
|
return ',GIT'.status
|
|
|
|
else
|
|
|
|
return '[Git'.status.']'
|
|
|
|
endif
|
2010-02-02 23:46:04 -05:00
|
|
|
endfunction
|
|
|
|
|
2018-05-12 19:46:36 -04:00
|
|
|
function! fugitive#Statusline(...) abort
|
|
|
|
return fugitive#statusline()
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! FugitiveStatusline(...) abort
|
|
|
|
return fugitive#statusline()
|
|
|
|
endfunction
|
|
|
|
|
2014-03-27 17:22:35 -04:00
|
|
|
function! fugitive#head(...) abort
|
2012-04-17 15:28:11 -04:00
|
|
|
if !exists('b:git_dir')
|
|
|
|
return ''
|
|
|
|
endif
|
|
|
|
|
|
|
|
return s:repo().head(a:0 ? a:1 : 0)
|
|
|
|
endfunction
|
|
|
|
|
2018-05-12 19:46:36 -04:00
|
|
|
function! FugitiveHead(...) abort
|
|
|
|
return fugitive#head(a:0 ? a:1 : 0)
|
|
|
|
endfunction
|
|
|
|
|
2015-06-14 20:06:38 -04:00
|
|
|
augroup fugitive_statusline
|
|
|
|
autocmd!
|
|
|
|
autocmd User Flags call Hoist('buffer', function('fugitive#statusline'))
|
|
|
|
augroup END
|
|
|
|
|
2014-06-21 08:48:11 -04:00
|
|
|
" Section: Folding
|
2011-11-20 15:32:32 -05:00
|
|
|
|
|
|
|
function! fugitive#foldtext() abort
|
|
|
|
if &foldmethod !=# 'syntax'
|
|
|
|
return foldtext()
|
2018-04-02 15:58:45 -04:00
|
|
|
endif
|
|
|
|
|
|
|
|
let line_foldstart = getline(v:foldstart)
|
|
|
|
if line_foldstart =~# '^diff '
|
2011-11-20 15:32:32 -05:00
|
|
|
let [add, remove] = [-1, -1]
|
|
|
|
let filename = ''
|
|
|
|
for lnum in range(v:foldstart, v:foldend)
|
2018-04-02 15:58:45 -04:00
|
|
|
let line = getline(lnum)
|
|
|
|
if filename ==# '' && line =~# '^[+-]\{3\} [abciow12]/'
|
|
|
|
let filename = line[6:-1]
|
2011-11-20 15:32:32 -05:00
|
|
|
endif
|
2018-04-02 15:58:45 -04:00
|
|
|
if line =~# '^+'
|
2011-11-20 15:32:32 -05:00
|
|
|
let add += 1
|
2018-04-02 15:58:45 -04:00
|
|
|
elseif line =~# '^-'
|
2011-11-20 15:32:32 -05:00
|
|
|
let remove += 1
|
2018-04-02 15:58:45 -04:00
|
|
|
elseif line =~# '^Binary '
|
2011-11-20 15:32:32 -05:00
|
|
|
let binary = 1
|
|
|
|
endif
|
|
|
|
endfor
|
|
|
|
if filename ==# ''
|
2018-04-02 15:58:45 -04:00
|
|
|
let filename = matchstr(line_foldstart, '^diff .\{-\} [abciow12]/\zs.*\ze [abciow12]/')
|
2011-11-20 15:32:32 -05:00
|
|
|
endif
|
2012-10-21 23:21:12 -04:00
|
|
|
if filename ==# ''
|
2018-04-02 15:58:45 -04:00
|
|
|
let filename = line_foldstart[5:-1]
|
2012-10-21 23:21:12 -04:00
|
|
|
endif
|
2011-11-20 15:32:32 -05:00
|
|
|
if exists('binary')
|
|
|
|
return 'Binary: '.filename
|
|
|
|
else
|
|
|
|
return (add<10&&remove<100?' ':'') . add . '+ ' . (remove<10&&add<100?' ':'') . remove . '- ' . filename
|
|
|
|
endif
|
2018-04-02 15:58:45 -04:00
|
|
|
elseif line_foldstart =~# '^# .*:$'
|
2011-11-20 15:32:32 -05:00
|
|
|
let lines = getline(v:foldstart, v:foldend)
|
|
|
|
call filter(lines, 'v:val =~# "^#\t"')
|
2018-04-02 15:58:45 -04:00
|
|
|
cal map(lines, "s:sub(v:val, '^#\t%(modified: +|renamed: +)=', '')")
|
|
|
|
cal map(lines, "s:sub(v:val, '^([[:alpha:] ]+): +(.*)', '\\2 (\\1)')")
|
|
|
|
return line_foldstart.' '.join(lines, ', ')
|
2011-11-20 15:32:32 -05:00
|
|
|
endif
|
|
|
|
return foldtext()
|
|
|
|
endfunction
|
|
|
|
|
2018-05-12 19:46:36 -04:00
|
|
|
function! fugitive#Foldtext() abort
|
|
|
|
return fugitive#foldtext()
|
|
|
|
endfunction
|
|
|
|
|
2011-11-20 15:32:32 -05:00
|
|
|
augroup fugitive_foldtext
|
|
|
|
autocmd!
|
|
|
|
autocmd User Fugitive
|
|
|
|
\ if &filetype =~# '^git\%(commit\)\=$' && &foldtext ==# 'foldtext()' |
|
2018-05-12 19:46:36 -04:00
|
|
|
\ set foldtext=fugitive#Foldtext() |
|
2011-11-20 15:32:32 -05:00
|
|
|
\ endif
|
|
|
|
augroup END
|