2 Commits

Author SHA1 Message Date
Tim Pope
62c50ff296 Handle .git in file system root
References https://github.com/tpope/vim-fugitive/issues/908
2017-05-07 15:29:01 -04:00
Tim Pope
c2877d0d5c Show commit message in :Gblame statusline
References #405.
2017-05-02 20:52:19 -04:00
5 changed files with 143 additions and 247 deletions

2
.gitattributes vendored
View File

@@ -1,2 +0,0 @@
.git* export-ignore
*.markdown export-ignore

View File

@@ -8,14 +8,8 @@ platform issues, and interactions with other plugins. I end up bisecting a
lot more than other projects, and thus I'm especially meticulous here about
maintaining a clean, readable, history. Squash and force push any requested
changes to a pull request. And if your [commit message
sucks](https://commit.style), I'm not going to accept it. Period.
If your contribution involves adding a configuration option, you are going to
need a very compelling justification for it. Options add a maintenance
burden, support burden, and documentation bloat, and oftentimes can be
achieved much more simply with a custom map or autocommand. If your option
controls an underlying Git command, ask yourself why Git itself does not offer
such configuration.
sucks](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html),
I'm not going to accept it. Period.
Beyond that, don't be shy about asking before patching. What takes you hours
might take me minutes simply because I have both domain knowledge and a

View File

@@ -20,7 +20,7 @@ changed, or `o` to open it in a split. When you're done, use `:Gedit`
in the historic buffer to go back to the work tree version.
`:Gmove` does a `git mv` on a file and simultaneously renames the
buffer. `:Gdelete` does a `git rm` on a file and simultaneously deletes
buffer. `:Gremove` does a `git rm` on a file and simultaneously deletes
the buffer.
Use `:Ggrep` to search the work tree (or any arbitrary commit) with
@@ -66,7 +66,7 @@ If you don't have a preferred installation method, one option is to install
and paste:
cd ~/.vim/bundle
git clone https://github.com/tpope/vim-fugitive.git
git clone git://github.com/tpope/vim-fugitive.git
vim -u NONE -c "helptags vim-fugitive/doc" -c q
If your Vim version is below 7.2, I recommend also installing
@@ -75,11 +75,24 @@ other Git niceties.
## FAQ
> Why don't any of the commands exist?
> I installed the plugin and started Vim. Why don't any of the commands
> exist?
Fugitive cares about the current file, not the current working directory.
Edit a file from the repository. To avoid the blank window problem, favor
commands like `:split` and `:tabedit` over commands like `:new` and `:tabnew`.
Fugitive cares about the current file, not the current working
directory. Edit a file from the repository.
> I opened a new tab. Why don't any of the commands exist?
Fugitive cares about the current file, not the current working
directory. Edit a file from the repository.
> Why is `:Gbrowse` not using the right browser?
`:Gbrowse` delegates to `git web--browse`, which is less than perfect
when it comes to finding the right browser. You can tell it the correct
browser to use with `git config --global web.browser ...`. On OS X, for
example, you might want to set this to `open`. See `git web--browse --help`
for details.
> Here's a patch that automatically opens the quickfix window after
> `:Ggrep`.

View File

@@ -40,12 +40,10 @@ that are part of Git repositories).
<CR> |:Gedit|
- |:Git| add
- |:Git| reset (staged files)
a Show alternative format
cA |:Gcommit| --amend --reuse-message=HEAD
ca |:Gcommit| --amend
cc |:Gcommit|
ce |:Gcommit| --amend --no-edit
cw |:Gcommit| --amend --only
cva |:Gcommit| --verbose --amend
cva |:Gcommit| --amend --verbose
cvc |:Gcommit| --verbose
D |:Gdiff|
ds |:Gsdiff|
@@ -78,17 +76,17 @@ that are part of Git repositories).
*fugitive-:Gmerge*
:Gmerge [args] Calls git-merge and loads errors and conflicted files
into the |quickfix| list. Opens a |:Gcommit| style
into the quickfix list. Opens a |:Gcommit| style
split window for the commit message if the merge
succeeds. If called during a merge conflict, the
conflicted files from the current index are loaded
into the |quickfix| list.
into the quickfix list.
*fugitive-:Gpull*
:Gpull [args] Like |:Gmerge|, but for git-pull.
*fugitive-:Gpush*
:Gpush [args] Invoke git-push, load the results into the |quickfix|
:Gpush [args] Invoke git-push, load the results into the quickfix
list, and invoke |:cwindow| to reveal any errors.
|:Dispatch| is used if available for asynchronous
invocation.
@@ -104,20 +102,20 @@ that are part of Git repositories).
*fugitive-:Glog*
:Glog [args] Load all previous revisions of the current file into
the |quickfix| list. Additional git-log arguments can
the quickfix list. Additional git-log arguments can
be given (for example, --reverse). If "--" appears as
an argument, no file specific filtering is done, and
previous commits rather than previous file revisions
are loaded.
:{range}Glog [args] Use git-log -L to load previous revisions of the given
range of the current file into the |quickfix| list.
The cursor is positioned on the first line of the
first diff hunk for each commit.
range of the current file into the quickfix list. The
cursor is positioned on the first line of the first
diff hunk for each commit.
*fugitive-:Gllog*
:Gllog [args] Like |:Glog|, but use the location list instead of the
|quickfix| list.
quickfix list.
*fugitive-:Gedit* *fugitive-:Ge*
:Gedit [revision] |:edit| a |fugitive-revision|.
@@ -197,23 +195,14 @@ that are part of Git repositories).
:Gmove {destination} Wrapper around git-mv that renames the buffer
afterward. The destination is relative to the current
directory except when started with a /, in which case
it is relative to the work tree. (This is a holdover
from before |:Grename| and will be removed.) Add a !
to pass -f.
it is relative to the work tree. Add a ! to pass -f.
*fugitive-:Grename*
:Grename {destination} Like |:Gmove| but operates relative to the parent
directory of the current file.
*fugitive-:Gdelete*
:Gdelete Wrapper around git-rm that deletes the buffer
*fugitive-:Gremove*
:Gremove Wrapper around git-rm that deletes the buffer
afterward. When invoked in an index file, --cached is
passed. Add a ! to pass -f and forcefully discard the
buffer.
*fugitive-:Gremove*
:Gremove Like :Gdelete, but keep the (now empty) buffer around.
*fugitive-:Gblame*
:Gblame [flags] Run git-blame on the file and open the results in a
scroll bound vertical split. You can give any of

View File

@@ -1,6 +1,6 @@
" fugitive.vim - A Git wrapper so awesome, it should be illegal
" Maintainer: Tim Pope <http://tpo.pe/>
" Version: 2.3
" Version: 2.2
" GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim
if exists('g:loaded_fugitive') || &cp
@@ -68,15 +68,6 @@ function! s:shellslash(path) abort
endif
endfunction
let s:executables = {}
function! s:executable(binary) abort
if !has_key(s:executables, a:binary)
let s:executables[a:binary] = executable(a:binary)
endif
return s:executables[a:binary]
endfunction
let s:git_versions = {}
function! s:git_command() abort
@@ -108,30 +99,6 @@ function! s:recall() abort
return rev
endfunction
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', {})
if type(keys) == type([])
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
if flags !~# '<unique>' || empty(mapcheck(head.tail, a:mode))
exe a:mode.'map <buffer>' flags head.tail a:rhs
endif
endfunction
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)
@@ -160,10 +127,6 @@ function! fugitive#is_git_dir(path) abort
\ getftype(path.'commondir') ==# 'file')
endfunction
function! FugitiveIsGitDir(path) abort
return fugitive#is_git_dir(a:path)
endfunction
function! fugitive#extract_git_dir(path) abort
if s:shellslash(a:path) =~# '^fugitive://.*//'
return matchstr(s:shellslash(a:path), '\C^fugitive://\zs.\{-\}\ze//')
@@ -217,10 +180,6 @@ function! fugitive#extract_git_dir(path) abort
return ''
endfunction
function! FugitiveExtractGitDir(path) abort
return fugitive#extract_git_dir(a:path)
endfunction
function! fugitive#detect(path) abort
if exists('b:git_dir') && (b:git_dir ==# '' || b:git_dir =~# '/$')
unlet b:git_dir
@@ -244,8 +203,8 @@ function! fugitive#detect(path) abort
endtry
endif
if !exists('g:fugitive_no_maps')
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>')
cnoremap <buffer> <expr> <C-R><C-G> fnameescape(<SID>recall())
nnoremap <buffer> <silent> y<C-G> :call setreg(v:register, <SID>recall())<CR>
endif
let buffer = fugitive#buffer()
if expand('%:p') =~# '://'
@@ -269,15 +228,11 @@ function! fugitive#detect(path) abort
endif
endfunction
function! FugitiveDetect(path) abort
return fugitive#detect(a:path)
endfunction
augroup fugitive
autocmd!
autocmd BufNewFile,BufReadPost * call fugitive#detect(expand('%:p'))
autocmd FileType netrw call fugitive#detect(expand('%:p'))
autocmd User NERDTreeInit,NERDTreeNewRoot call fugitive#detect(b:NERDTree.root.path.str())
autocmd User NERDTreeInit,NERDTreeNewRoot call fugitive#detect(b:NERDTreeRoot.path.str())
autocmd VimEnter * if expand('<amatch>')==''|call fugitive#detect(getcwd())|endif
autocmd CmdWinEnter * call fugitive#detect(expand('#:p'))
autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave')
@@ -445,13 +400,13 @@ function! s:repo_git_chomp(...) dict abort
endfunction
function! s:repo_git_chomp_in_tree(...) dict abort
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
try
execute cd s:fnameescape(s:repo().tree())
execute cd.'`=s:repo().tree()`'
return call(s:repo().git_chomp, a:000, s:repo())
finally
execute cd s:fnameescape(dir)
execute cd.'`=dir`'
endtry
endfunction
@@ -697,9 +652,7 @@ function! s:buffer_expand(rev) dict abort
else
let file = a:rev
endif
return s:sub(substitute(file,
\ '%$\|\\\([[:punct:]]\)','\=len(submatch(1)) ? submatch(1) : self.path()','g'),
\ '\.\@<=/$','')
return s:sub(s:sub(file,'\%$',self.path()),'\.\@<=/$','')
endfunction
function! s:buffer_containing_commit() dict abort
@@ -743,13 +696,13 @@ call s:add_methods('buffer',['getvar','setvar','getline','repo','type','spec','n
call s:command("-bang -nargs=? -complete=customlist,s:GitComplete Git :execute s:Git(<bang>0,<q-args>)")
function! s:ExecuteInTree(cmd) abort
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
try
execute cd s:fnameescape(s:repo().tree())
execute cd.'`=s:repo().tree()`'
execute a:cmd
finally
execute cd s:fnameescape(dir)
execute cd.'`=dir`'
endtry
endfunction
@@ -762,7 +715,7 @@ function! s:Git(bang, args) abort
let git .= ' --no-pager'
endif
let args = matchstr(a:args,'\v\C.{-}%($|\\@<!%(\\\\)*\|)@=')
if exists(':terminal') && has('nvim')
if exists(':terminal')
let dir = s:repo().tree()
if expand('%') != ''
-tabedit %
@@ -803,8 +756,8 @@ function! s:DirComplete(A,L,P) abort
return matches
endfunction
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>))")
call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Gcd :cd<bang> `=s:repo().bare() ? s:repo().dir(<q-args>) : s:repo().tree(<q-args>)`")
call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Glcd :lcd<bang> `=s:repo().bare() ? s:repo().dir(<q-args>) : s:repo().tree(<q-args>)`")
" Section: Gstatus
@@ -862,10 +815,6 @@ function! fugitive#reload_status() abort
endtry
endfunction
function! fugitive#ReloadStatus() abort
return fugitive#reload_status()
endfunction
function! s:stage_info(lnum) abort
let filename = matchstr(getline(a:lnum),'^#\t\zs.\{-\}\ze\%( ([^()[:digit:]]\+)\)\=$')
let lnum = a:lnum
@@ -1026,14 +975,11 @@ function! s:StageToggle(lnum1,lnum2) abort
continue
endif
execute lnum
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
let cmd = ['mv','--'] + reverse(split(filename,' -> '))
let filename = cmd[-1]
elseif section ==# 'staged'
let cmd = ['reset','-q','--',filename]
elseif getline(lnum) =~# '^#\tdeleted:'
let cmd = ['rm','--',filename]
elseif getline(lnum) =~# '^#\tmodified:'
@@ -1104,19 +1050,18 @@ endfunction
" Section: Gcommit
call s:command("-nargs=? -complete=customlist,s:CommitComplete Gcommit :execute s:Commit('<mods>', <q-args>)")
call s:command("-nargs=? -complete=customlist,s:CommitComplete Gcommit :execute s:Commit(<q-args>)")
function! s:Commit(mods, args, ...) abort
let mods = s:gsub(a:mods ==# '<mods>' ? '' : a:mods, '<tab>', '-tab')
function! s:Commit(args, ...) abort
let repo = a:0 ? a:1 : s:repo()
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
let msgfile = repo.dir('COMMIT_EDITMSG')
let outfile = tempname()
let errorfile = tempname()
try
try
execute cd s:fnameescape(repo.tree())
execute cd.s:fnameescape(repo.tree())
if s:winshell()
let command = ''
let old_editor = $GIT_EDITOR
@@ -1134,7 +1079,7 @@ function! s:Commit(mods, args, ...) abort
endif
let error = v:shell_error
finally
execute cd s:fnameescape(dir)
execute cd.'`=dir`'
endtry
if !has('gui_running')
redraw!
@@ -1160,15 +1105,15 @@ function! s:Commit(mods, args, ...) abort
let args = '--cleanup=strip '.args
endif
if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&mod
execute mods 'keepalt edit' s:fnameescape(msgfile)
elseif a:args =~# '\%(^\| \)-\w*v' || mods =~# '\<tab\>'
execute mods 'keepalt -tabedit' s:fnameescape(msgfile)
execute 'keepalt edit '.s:fnameescape(msgfile)
elseif a:args =~# '\%(^\| \)-\%(-verbose\|\w*v\)\>'
execute 'keepalt -tabedit '.s:fnameescape(msgfile)
elseif s:buffer().type() ==# 'index'
execute mods 'keepalt edit' s:fnameescape(msgfile)
execute 'keepalt edit '.s:fnameescape(msgfile)
execute (search('^#','n')+1).'wincmd+'
setlocal nopreviewwindow
else
execute mods 'keepalt split' s:fnameescape(msgfile)
execute 'keepalt split '.s:fnameescape(msgfile)
endif
let b:fugitive_commit_arguments = args
setlocal bufhidden=wipe filetype=gitcommit
@@ -1176,7 +1121,7 @@ function! s:Commit(mods, args, ...) abort
elseif error ==# '!'
return s:Status()
else
call s:throw(empty(error)?join(errors, ' '):error)
call s:throw(error)
endif
endif
catch /^fugitive:/
@@ -1204,7 +1149,7 @@ function! s:FinishCommit() abort
let args = getbufvar(+expand('<abuf>'),'fugitive_commit_arguments')
if !empty(args)
call setbufvar(+expand('<abuf>'),'fugitive_commit_arguments','')
return s:Commit('', args, s:repo(getbufvar(+expand('<abuf>'),'git_dir')))
return s:Commit(args, s:repo(getbufvar(+expand('<abuf>'),'git_dir')))
endif
return ''
endfunction
@@ -1344,10 +1289,10 @@ call s:command("-bar -bang -nargs=* -range=0 -complete=customlist,s:EditComplete
function! s:Grep(cmd,bang,arg) abort
let grepprg = &grepprg
let grepformat = &grepformat
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
try
execute cd s:fnameescape(s:repo().tree())
execute cd.'`=s:repo().tree()`'
let &grepprg = s:repo().git_command('--no-pager', 'grep', '-n', '--no-color')
let &grepformat = '%f:%l:%m,%m %f match%ts,%f'
exe a:cmd.'! '.escape(matchstr(a:arg,'\v\C.{-}%($|[''" ]\@=\|)@='),'|')
@@ -1376,7 +1321,7 @@ function! s:Grep(cmd,bang,arg) abort
finally
let &grepprg = grepprg
let &grepformat = grepformat
execute cd s:fnameescape(dir)
execute cd.'`=dir`'
endtry
endfunction
@@ -1404,39 +1349,33 @@ function! s:Log(cmd, line1, line2, ...) abort
endif
let grepformat = &grepformat
let grepprg = &grepprg
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
try
execute cd s:fnameescape(s:repo().tree())
execute cd.'`=s:repo().tree()`'
let &grepprg = escape(call(s:repo().git_command,cmd,s:repo()),'%#')
let &grepformat = '%Cdiff %.%#,%C--- %.%#,%C+++ %.%#,%Z@@ -%\d%\+\,%\d%\+ +%l\,%\d%\+ @@,%-G-%.%#,%-G+%.%#,%-G %.%#,%A%f::%m,%-G%.%#'
exe a:cmd
finally
let &grepformat = grepformat
let &grepprg = grepprg
execute cd s:fnameescape(dir)
execute cd.'`=dir`'
endtry
endfunction
" Section: Gedit, Gpedit, Gsplit, Gvsplit, Gtabedit, Gread
function! s:UsableWin(nr) abort
return a:nr && !getwinvar(a:nr, '&previewwindow') &&
\ index(['nofile','help','quickfix'], getbufvar(winbufnr(a:nr), '&buftype')) < 0
endfunction
function! s:Edit(cmd,bang,...) abort
let buffer = s:buffer()
if a:cmd !~# 'read'
if &previewwindow && getbufvar('','fugitive_type') ==# 'index'
let winnrs = filter([winnr('#')] + range(1, winnr('$')), 's:UsableWin(v:val)')
if len(winnrs)
exe winnrs[0].'wincmd w'
elseif winnr('$') == 1
if winnr('$') == 1
let tabs = (&go =~# 'e' || !has('gui_running')) && &stal && (tabpagenr('$') >= &stal)
execute 'rightbelow' (&lines - &previewheight - &cmdheight - tabs - 1 - !!&laststatus).'new'
elseif winnr('#')
wincmd p
else
rightbelow new
wincmd w
endif
if &diff
let mywinnr = winnr()
@@ -1449,7 +1388,6 @@ function! s:Edit(cmd,bang,...) abort
endif
endif
endfor
diffoff!
endif
endif
endif
@@ -1535,7 +1473,7 @@ call s:command("-bar -bang -nargs=* -complete=customlist,s:EditRunComplete Gpedi
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>)")
call s:command("-bar -bang -nargs=* -range=-1 -complete=customlist,s:EditRunComplete Gread :execute s:Edit((<count> == -1 ? '' : <count>).'read',<bang>0,<f-args>)")
call s:command("-bar -bang -nargs=* -count -complete=customlist,s:EditRunComplete Gread :execute s:Edit((!<count> && <line1> ? '' : <count>).'read',<bang>0,<f-args>)")
" Section: Gwrite, Gwq
@@ -1861,12 +1799,12 @@ function! s:Diff(vert,keepfocus,...) abort
elseif (empty(args) || args[0] == ':') && s:buffer().commit() =~# '^[0-1]\=$' && s:repo().git_chomp_in_tree('ls-files', '--unmerged', '--', s:buffer().path()) !=# ''
let vert = empty(a:vert) ? s:diff_modifier(3) : a:vert
let nr = bufnr('')
execute 'leftabove '.vert.'split' s:fnameescape(fugitive#repo().translate(s:buffer().expand(':2')))
execute 'leftabove '.vert.'split `=fugitive#buffer().repo().translate(s:buffer().expand('':2''))`'
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
let nr2 = bufnr('')
call s:diffthis()
wincmd p
execute 'rightbelow '.vert.'split' s:fnameescape(fugitive#repo().translate(s:buffer().expand(':3')))
execute 'rightbelow '.vert.'split `=fugitive#buffer().repo().translate(s:buffer().expand('':3''))`'
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
let nr3 = bufnr('')
call s:diffthis()
@@ -1929,11 +1867,9 @@ endfunction
" Section: Gmove, Gremove
function! s:Move(force, rename, destination) abort
function! s:Move(force,destination) abort
if a:destination =~# '^/'
let destination = a:destination[1:-1]
elseif a:rename
let destination = fnamemodify(s:buffer().path(), ':h') . '/' . a:destination
else
let destination = s:shellslash(fnamemodify(s:sub(a:destination,'[%#]%(:\w)*','\=expand(submatch(0))'),':p'))
if destination[0:strlen(s:repo().tree())] ==# s:repo().tree('')
@@ -1954,7 +1890,7 @@ function! s:Move(force, rename, destination) abort
let destination = fnamemodify(s:sub(destination,'/$','').'/'.expand('%:t'),':.')
endif
call fugitive#reload_status()
if empty(s:buffer().commit())
if s:buffer().commit() == ''
if isdirectory(destination)
return 'keepalt edit '.s:fnameescape(destination)
else
@@ -1966,25 +1902,16 @@ function! s:Move(force, rename, destination) abort
endfunction
function! s:MoveComplete(A,L,P) abort
if a:A =~# '^/'
if a:A =~ '^/'
return s:repo().superglob(a:A)
else
let matches = split(glob(a:A.'*'),"\n")
call map(matches,'v:val !~# "/$" && isdirectory(v:val) ? v:val."/" : v:val')
call map(matches,'v:val !~ "/$" && isdirectory(v:val) ? v:val."/" : v:val')
return matches
endif
endfunction
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
function! s:Remove(after, force) abort
function! s:Remove(force) abort
if s:buffer().commit() ==# ''
let cmd = ['rm']
elseif s:buffer().commit() ==# '0'
@@ -2002,17 +1929,15 @@ function! s:Remove(after, force) abort
return 'echoerr '.string(v:errmsg)
else
call fugitive#reload_status()
return a:after . (a:force ? '!' : '')
return 'edit'.(a:force ? '!' : '')
endif
endfunction
augroup fugitive_remove
autocmd!
autocmd User Fugitive if s:buffer().commit() =~# '^0\=$' |
\ 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>)" |
\ exe "command! -buffer -bar -bang Gremove :execute s:Remove('edit',<bang>0)" |
\ exe "command! -buffer -bar -bang Gdelete :execute s:Remove('bdelete',<bang>0)" |
\ exe "command! -buffer -bar -bang -nargs=1 -complete=customlist,s:MoveComplete Gmove :execute s:Move(<bang>0,<q-args>)" |
\ exe "command! -buffer -bar -bang Gremove :execute s:Remove(<bang>0)" |
\ endif
augroup END
@@ -2056,12 +1981,12 @@ function! s:Blame(bang,line1,line2,count,args) abort
let cmd += ['--contents', '-']
endif
let cmd += ['--', s:buffer().path()]
let basecmd = escape(call(s:repo().git_command,cmd,s:repo()),'!%#')
let basecmd = escape(call(s:repo().git_command,cmd,s:repo()),'!')
try
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
if !s:repo().bare()
let dir = getcwd()
execute cd s:fnameescape(s:repo().tree())
execute cd.'`=s:repo().tree()`'
endif
if a:count
execute 'write !'.substitute(basecmd,' blame ',' blame -L '.a:line1.','.a:line2.' ','g')
@@ -2074,7 +1999,7 @@ function! s:Blame(bang,line1,line2,count,args) abort
silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
endif
if exists('l:dir')
execute cd s:fnameescape(dir)
execute cd.'`=dir`'
unlet dir
endif
if v:shell_error
@@ -2127,6 +2052,7 @@ function! s:Blame(bang,line1,line2,count,args) abort
if exists('+relativenumber')
setlocal norelativenumber
endif
let &l:statusline = '%{fugitive#blame_statusline('.bufnr('').')}%<'
execute "vertical resize ".(s:linechars('.\{-\}\ze\s\+\d\+)')+1)
nnoremap <buffer> <silent> <F1> :help fugitive-:Gblame<CR>
nnoremap <buffer> <silent> g? :help fugitive-:Gblame<CR>
@@ -2147,7 +2073,7 @@ function! s:Blame(bang,line1,line2,count,args) abort
endif
finally
if exists('l:dir')
execute cd s:fnameescape(dir)
execute cd.'`=dir`'
endif
endtry
return ''
@@ -2241,8 +2167,8 @@ function! s:BlameSyntax() abort
let arg = exists('b:fugitive_blame_arguments') ? b:fugitive_blame_arguments : ''
syn match FugitiveblameBoundary "^\^"
syn match FugitiveblameBlank "^\s\+\s\@=" nextgroup=FugitiveblameAnnotation,fugitiveblameOriginalFile,FugitiveblameOriginalLineNumber skipwhite
syn match FugitiveblameHash "\%(^\^\=\)\@<=\<\x\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
syn match FugitiveblameUncommitted "\%(^\^\=\)\@<=\<0\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
syn match FugitiveblameHash "\%(^\^\=\)\@<=\x\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
syn match FugitiveblameUncommitted "\%(^\^\=\)\@<=0\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite
syn region FugitiveblameAnnotation matchgroup=FugitiveblameDelimiter start="(" end="\%( \d\+\)\@<=)" contained keepend oneline
syn match FugitiveblameTime "[0-9:/+-][0-9:/+ -]*[0-9:/+-]\%( \+\d\+)\)\@=" contained containedin=FugitiveblameAnnotation
exec 'syn match FugitiveblameLineNumber " *\d\+)\@=" contained containedin=FugitiveblameAnnotation'.conceal
@@ -2268,7 +2194,7 @@ function! s:BlameSyntax() abort
continue
endif
let seen[hash] = 1
if &t_Co > 16 && get(g:, 'CSApprox_loaded') && !empty(findfile('autoload/csapprox/per_component.vim', escape(&rtp, ' ')))
if &t_Co > 16 && exists('g:CSApprox_loaded')
\ && 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)
@@ -2294,12 +2220,29 @@ function! s:RehighlightBlame() abort
endfor
endfunction
function! fugitive#blame_statusline(nr) abort
if bufnr('%') != a:nr && !getwinvar(0, '&cursorbind')
return ''
endif
let line = getbufline(a:nr, line('.'))[0]
let hash = matchstr(line, '^\^\=\zs\x\{7}')
if hash =~# '^0*$'
return ''
endif
if type(getbufvar(a:nr, 'fugitive_blame_lookup')) != type({})
call setbufvar(a:nr, 'fugitive_blame_lookup', {})
endif
let lookup = getbufvar(a:nr, 'fugitive_blame_lookup')
if !has_key(lookup, hash)
let lookup[hash] = s:repo().git_chomp('log', '-1', hash, '--pretty=format:'.g:fugitive_summary_format)
endif
return get(lookup, hash, '')
endfunction
" Section: Gbrowse
call s:command("-bar -bang -range=0 -nargs=* -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(<bang>0,<line1>,<count>,<f-args>)")
let s:redirects = {}
function! s:Browse(bang,line1,count,...) abort
try
let validremote = '\.\|\.\=/.*\|[[:alnum:]_-]\+\%(://.\{-\}\)\='
@@ -2405,7 +2348,7 @@ function! s:Browse(bang,line1,count,...) abort
else
let remote_for_url = remote
endif
if fugitive#git_version() =~# '^[01]\.\|^2\.[0-6]\.'
if fugitive#git_version() =~# '^[01]\.|^2\.[0-6]\.'
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)
@@ -2414,17 +2357,6 @@ function! s:Browse(bang,line1,count,...) abort
let raw = remote
endif
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
for Handler in g:fugitive_browse_handlers
let url = call(Handler, [{
\ 'repo': s:repo(),
@@ -2567,10 +2499,9 @@ function! s:ReplaceCmd(cmd,...) abort
let $GIT_INDEX_FILE = old_index
endif
endtry
silent exe 'doau BufReadPre '.s:fnameescape(fn)
silent exe 'keepalt file '.tmp
try
silent noautocmd edit!
silent edit!
finally
try
silent exe 'keepalt file '.s:fnameescape(fn)
@@ -2602,7 +2533,7 @@ function! s:BufReadIndex() abort
call s:ReplaceCmd(s:repo().git_command('ls-files','--stage'),index)
set ft=git nospell
else
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
if fugitive#git_version() =~# '^0\|^1\.[1-7]\.'
let cmd = s:repo().git_command('status')
@@ -2614,10 +2545,10 @@ function! s:BufReadIndex() abort
\ 'status')
endif
try
execute cd s:fnameescape(s:repo().tree())
execute cd.'`=s:repo().tree()`'
call s:ReplaceCmd(cmd, index)
finally
execute cd s:fnameescape(dir)
execute cd.'`=dir`'
endtry
set ft=gitcommit
set foldtext=fugitive#foldtext()
@@ -2635,14 +2566,12 @@ function! s:BufReadIndex() abort
xnoremap <buffer> <silent> - :<C-U>silent execute <SID>StageToggle(line("'<"),line("'>"))<CR>
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>
nnoremap <buffer> <silent> C :<C-U>Gcommit<CR>:echohl WarningMsg<Bar>echo ':Gstatus C is deprecated in favor of cc'<Bar>echohl NONE<CR>
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>
nnoremap <buffer> <silent> C :<C-U>Gcommit<CR>
nnoremap <buffer> <silent> cA :<C-U>Gcommit --amend --reuse-message=HEAD<CR>
nnoremap <buffer> <silent> ca :<C-U>Gcommit --amend<CR>
nnoremap <buffer> <silent> cc :<C-U>Gcommit<CR>
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>
nnoremap <buffer> <silent> cva :<C-U>Gcommit --amend --verbose<CR>
nnoremap <buffer> <silent> cvc :<C-U>Gcommit --verbose<CR>
nnoremap <buffer> <silent> D :<C-U>execute <SID>StageDiff('Gdiff')<CR>
nnoremap <buffer> <silent> dd :<C-U>execute <SID>StageDiff('Gdiff')<CR>
nnoremap <buffer> <silent> dh :<C-U>execute <SID>StageDiff('Gsdiff')<CR>
@@ -2746,6 +2675,7 @@ function! s:BufReadObject() abort
if b:fugitive_type !~# '^\%(tag\|commit\|tree\|blob\)$'
return "echoerr ".string("fugitive: unrecognized git type '".b:fugitive_type."'")
endif
let firstline = getline('.')
if !exists('b:fugitive_display_format') && b:fugitive_type != 'blob'
let b:fugitive_display_format = +getbufvar('#','fugitive_display_format')
endif
@@ -2783,13 +2713,12 @@ function! s:BufReadObject() abort
if getline('.') ==# 'parent '
silent keepjumps delete_
else
silent exe 'keepjumps s/\m\C\%(^parent\)\@<! /\rparent /e' . (&gdefault ? '' : 'g')
silent keepjumps s/\%(^parent\)\@<! /\rparent /ge
endif
keepjumps let lnum = search('^encoding \%(<unknown>\)\=$','W',line('.')+3)
if lnum
silent keepjumps delete_
end
silent keepjumps 1,/^diff --git\|\%$/g/\r$/s///
keepjumps 1
endif
elseif b:fugitive_type ==# 'blob'
@@ -2811,8 +2740,6 @@ function! s:BufReadObject() abort
endif
endtry
return ''
catch /^fugitive: rev-parse/
return ''
catch /^fugitive:/
return 'echoerr v:errmsg'
@@ -2867,12 +2794,11 @@ augroup END
nnoremap <SID>: :<C-U><C-R>=v:count ? v:count : ''<CR>
function! s:GFInit(...) abort
cnoremap <buffer> <expr> <Plug><cfile> fugitive#cfile()
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>')
if !exists('g:fugitive_no_maps') && empty(mapcheck('gf', 'n'))
nmap <buffer> <silent> gf <SID>:find <Plug><cfile><CR>
nmap <buffer> <silent> <C-W>f <SID>:sfind <Plug><cfile><CR>
nmap <buffer> <silent> <C-W><C-F> <SID>:sfind <Plug><cfile><CR>
nmap <buffer> <silent> <C-W>gf <SID>:tabfind <Plug><cfile><CR>
endif
endfunction
@@ -3103,10 +3029,6 @@ function! fugitive#cfile() abort
return pre . s:fnameescape(fugitive#repo().translate(results[0]))
endfunction
function! fugitive#Cfile() abort
return fugitive#cfile()
endfunction
" Section: Statusline
function! s:repo_head_ref() dict abort
@@ -3134,14 +3056,6 @@ function! fugitive#statusline(...) abort
endif
endfunction
function! fugitive#Statusline(...) abort
return fugitive#statusline()
endfunction
function! FugitiveStatusline(...) abort
return fugitive#statusline()
endfunction
function! fugitive#head(...) abort
if !exists('b:git_dir')
return ''
@@ -3150,10 +3064,6 @@ function! fugitive#head(...) abort
return s:repo().head(a:0 ? a:1 : 0)
endfunction
function! FugitiveHead(...) abort
return fugitive#head(a:0 ? a:1 : 0)
endfunction
augroup fugitive_statusline
autocmd!
autocmd User Flags call Hoist('buffer', function('fugitive#statusline'))
@@ -3164,54 +3074,46 @@ augroup END
function! fugitive#foldtext() abort
if &foldmethod !=# 'syntax'
return foldtext()
endif
let line_foldstart = getline(v:foldstart)
if line_foldstart =~# '^diff '
elseif getline(v:foldstart) =~# '^diff '
let [add, remove] = [-1, -1]
let filename = ''
for lnum in range(v:foldstart, v:foldend)
let line = getline(lnum)
if filename ==# '' && line =~# '^[+-]\{3\} [abciow12]/'
let filename = line[6:-1]
if filename ==# '' && getline(lnum) =~# '^[+-]\{3\} [abciow12]/'
let filename = getline(lnum)[6:-1]
endif
if line =~# '^+'
if getline(lnum) =~# '^+'
let add += 1
elseif line =~# '^-'
elseif getline(lnum) =~# '^-'
let remove += 1
elseif line =~# '^Binary '
elseif getline(lnum) =~# '^Binary '
let binary = 1
endif
endfor
if filename ==# ''
let filename = matchstr(line_foldstart, '^diff .\{-\} [abciow12]/\zs.*\ze [abciow12]/')
let filename = matchstr(getline(v:foldstart), '^diff .\{-\} [abciow12]/\zs.*\ze [abciow12]/')
endif
if filename ==# ''
let filename = line_foldstart[5:-1]
let filename = getline(v:foldstart)[5:-1]
endif
if exists('binary')
return 'Binary: '.filename
else
return (add<10&&remove<100?' ':'') . add . '+ ' . (remove<10&&add<100?' ':'') . remove . '- ' . filename
endif
elseif line_foldstart =~# '^# .*:$'
elseif getline(v:foldstart) =~# '^# .*:$'
let lines = getline(v:foldstart, v:foldend)
call filter(lines, 'v:val =~# "^#\t"')
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, ', ')
cal map(lines,'s:sub(v:val, "^#\t%(modified: +|renamed: +)=", "")')
cal map(lines,'s:sub(v:val, "^([[:alpha:] ]+): +(.*)", "\\2 (\\1)")')
return getline(v:foldstart).' '.join(lines, ', ')
endif
return foldtext()
endfunction
function! fugitive#Foldtext() abort
return fugitive#foldtext()
endfunction
augroup fugitive_foldtext
autocmd!
autocmd User Fugitive
\ if &filetype =~# '^git\%(commit\)\=$' && &foldtext ==# 'foldtext()' |
\ set foldtext=fugitive#Foldtext() |
\ set foldtext=fugitive#foldtext() |
\ endif
augroup END