commit 7005789427d98909bd41b2fda2365a235512f5bc (tree)
parent dd52642d13f603289aa742d29f9a4bfb3a259edb
Author: Tim Pope <code@tpope.net>
Date: Fri, 19 Aug 2011 02:43:31 -0400
Add :Git! et al. for loading output into a buffer
Diffstat:
3 files changed, 87 insertions(+), 27 deletions(-)
diff --git a/README.markdown b/README.markdown
@@ -43,7 +43,8 @@ GitHub, `git instaweb` will be spun up instead.
Add `%{fugitive#statusline()}` to `'statusline'` to get an indicator
with the current branch in (surprise!) your statusline.
-Oh, and of course there's `:Git` for running any arbitrary command.
+Last but not least, there's `:Git` for running any arbitrary command,
+and `Git!` to open the output of a command in a temp file.
Screencasts
-----------
diff --git a/doc/fugitive.txt b/doc/fugitive.txt
@@ -19,6 +19,10 @@ that are part of Git repositories).
:Git [args] Run an arbitrary git command. Similar to :!git [args]
but chdir to the repository tree first.
+ *fugitive-:Git!*
+:Git! [args] Like |:Git|, but capture the output into a temp file,
+ and edit that temp file.
+
*fugitive-:Gcd*
:Gcd [directory] |:cd| relative to the repository.
@@ -78,10 +82,15 @@ that are part of Git repositories).
:Gvsplit [revision] |:vsplit| a |fugitive-revision|.
*fugitive-:Gtabedit*
-:Gtabedit [revision] |:tabedit| a |fugitive-revision|
+:Gtabedit [revision] |:tabedit| a |fugitive-revision|.
*fugitive-:Gpedit*
-:Gpedit [revision] |:pedit| a |fugitive-revision|
+:Gpedit [revision] |:pedit| a |fugitive-revision|.
+
+:Gsplit! [args] *fugitive-:Gsplit!* *fugitive-:Gvsplit!*
+:Gvsplit! [args] *fugitive-:Gtabedit!* *fugitive-:Gpedit!*
+:Gtabedit! [args] Like |:Git!|, but open the resulting temp file in a
+:Gpedit! [args] split, tab, or preview window.
*fugitive-:Gread*
:Gread [revision] Empty the buffer and |:read| a |fugitive-revision|.
@@ -92,6 +101,12 @@ that are part of Git repositories).
:{range}Gread [revision]
|:read| in a |fugitive-revision| after {range}.
+ *fugitive-:Gread!*
+:Gread! [args] Empty the buffer and |:read| the output of a Git
+ command. For example, :Gread! show HEAD:%.
+
+:{range}Gread! [args] |:read| the output of a Git command after {range}.
+
*fugitive-:Gwrite*
:Gwrite Write to the current file's path and stage the results.
When run in a work tree file, it is effectively git
diff --git a/plugin/fugitive.vim b/plugin/fugitive.vim
@@ -497,6 +497,9 @@ function! s:ExecuteInTree(cmd) abort
endfunction
function! s:Git(bang,cmd) abort
+ if a:bang
+ return s:Edit('edit',1,a:cmd)
+ endif
let git = s:repo().git_command()
if has('gui_running') && !has('win32')
let git .= ' --no-pager'
@@ -897,7 +900,7 @@ endfunction
" }}}1
" Gedit, Gpedit, Gsplit, Gvsplit, Gtabedit, Gread {{{1
-function! s:Edit(cmd,...) abort
+function! s:Edit(cmd,bang,...) abort
if a:cmd !~# 'read'
if &previewwindow && getbufvar('','fugitive_type') ==# 'index'
wincmd p
@@ -914,6 +917,36 @@ function! s:Edit(cmd,...) abort
endif
endif
+ if a:bang
+ let args = s:gsub(a:0 ? a:1 : '', '\\@<!%(\\\\)*\zs[%#]', '\=s:buffer().expand(submatch(0))')
+ if a:cmd =~# 'read'
+ let git = s:repo().git_command()
+ 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
+ let temp = tempname()
+ let s:temp_files[temp] = s:repo().dir()
+ silent execute a:cmd.' '.temp
+ if a:cmd =~# 'pedit'
+ wincmd P
+ endif
+ let echo = s:Edit('read',1,args)
+ silent write!
+ setlocal readonly nomodified nomodifiable filetype=git foldmarker=<<<<<<<,>>>>>>>
+ if a:cmd =~# 'pedit'
+ wincmd p
+ endif
+ return echo
+ endif
+ return ''
+ endif
+
if a:0 && a:1 == ''
return ''
elseif a:0
@@ -936,16 +969,20 @@ function! s:Edit(cmd,...) abort
endfunction
function! s:EditComplete(A,L,P) abort
- return s:repo().superglob(a:A)
+ if a:L =~# '^\w\+!'
+ return s:GitComplete(a:A,a:L,a:P)
+ else
+ return s:repo().superglob(a:A)
+ endif
endfunction
-call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Ge :execute s:Edit('edit<bang>',<f-args>)")
-call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gedit :execute s:Edit('edit<bang>',<f-args>)")
-call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gpedit :execute s:Edit('pedit<bang>',<f-args>)")
-call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gsplit :execute s:Edit('split<bang>',<f-args>)")
-call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gvsplit :execute s:Edit('vsplit<bang>',<f-args>)")
-call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gtabedit :execute s:Edit('tabedit<bang>',<f-args>)")
-call s:command("-bar -bang -nargs=? -count -complete=customlist,s:EditComplete Gread :execute s:Edit((!<count> && <line1> ? '' : <count>).'read<bang>',<f-args>)")
+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:EditComplete Gpedit :execute s:Edit('pedit',<bang>0,<f-args>)")
+call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gsplit :execute s:Edit('split',<bang>0,<f-args>)")
+call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gvsplit :execute s:Edit('vsplit',<bang>0,<f-args>)")
+call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gtabedit :execute s:Edit('tabedit',<bang>0,<f-args>)")
+call s:command("-bar -bang -nargs=? -count -complete=customlist,s:EditComplete Gread :execute s:Edit((!<count> && <line1> ? '' : <count>).'read',<bang>0,<f-args>)")
" }}}1
" Gwrite, Gwq {{{1
@@ -1917,15 +1954,18 @@ function! s:GF(mode) abort
try
let buffer = s:buffer()
let myhash = buffer.sha1()
+ if myhash ==# '' && getline(1) =~# '^\%(commit\|tag\) \w'
+ let myhash = matchstr(getline(1),'^\w\+ \zs\S\+')
+ endif
if buffer.type('tree')
let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
if showtree && line('.') == 1
return ""
elseif showtree && line('.') > 2
- return s:Edit(a:mode,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(getline('.'),'/$',''))
+ return s:Edit(a:mode,0,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(getline('.'),'/$',''))
elseif getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
- return s:Edit(a:mode,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$',''))
+ return s:Edit(a:mode,0,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$',''))
endif
elseif buffer.type('blob')
@@ -1935,7 +1975,7 @@ function! s:GF(mode) abort
catch /^fugitive:/
endtry
if exists('sha1')
- return s:Edit(a:mode,ref)
+ return s:Edit(a:mode,0,ref)
endif
else
@@ -1944,29 +1984,29 @@ function! s:GF(mode) abort
if getline('.') =~# '^\d\{6\} \x\{40\} \d\t'
let ref = matchstr(getline('.'),'\x\{40\}')
let file = ':'.s:sub(matchstr(getline('.'),'\d\t.*'),'\t',':')
- return s:Edit(a:mode,file)
+ return s:Edit(a:mode,0,file)
elseif getline('.') =~# '^#\trenamed:.* -> '
let file = '/'.matchstr(getline('.'),' -> \zs.*')
- return s:Edit(a:mode,file)
+ return s:Edit(a:mode,0,file)
elseif getline('.') =~# '^#\t[[:alpha:] ]\+: *.'
let file = '/'.matchstr(getline('.'),': *\zs.\{-\}\ze\%( (new commits)\)\=$')
- return s:Edit(a:mode,file)
+ return s:Edit(a:mode,0,file)
elseif getline('.') =~# '^#\t.'
let file = '/'.matchstr(getline('.'),'#\t\zs.*')
- return s:Edit(a:mode,file)
+ return s:Edit(a:mode,0,file)
elseif getline('.') =~# ': needs merge$'
let file = '/'.matchstr(getline('.'),'.*\ze: needs merge$')
- return s:Edit(a:mode,file).'|Gdiff'
+ return s:Edit(a:mode,0,file).'|Gdiff'
elseif getline('.') ==# '# Not currently on any branch.'
- return s:Edit(a:mode,'HEAD')
+ return s:Edit(a:mode,0,'HEAD')
elseif getline('.') =~# '^# On branch '
let file = 'refs/heads/'.getline('.')[12:]
- return s:Edit(a:mode,file)
+ return s:Edit(a:mode,0,file)
elseif getline('.') =~# "^# Your branch .*'"
let file = matchstr(getline('.'),"'\\zs\\S\\+\\ze'")
- return s:Edit(a:mode,file)
+ return s:Edit(a:mode,0,file)
endif
let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
@@ -1974,6 +2014,10 @@ function! s:GF(mode) abort
if getline('.') =~# '^ref: '
let ref = strpart(getline('.'),5)
+ elseif getline('.') =~# '^commit \x\{40\}\>'
+ let ref = matchstr(getline('.'),'\x\{40\}')
+ return s:Edit(a:mode,0,ref)
+
elseif getline('.') =~# '^parent \x\{40\}\>'
let ref = matchstr(getline('.'),'\x\{40\}')
let line = line('.')
@@ -1982,14 +2026,14 @@ function! s:GF(mode) abort
let parent += 1
let line -= 1
endwhile
- return s:Edit(a:mode,ref)
+ return s:Edit(a:mode,0,ref)
elseif getline('.') =~ '^tree \x\{40\}$'
let ref = matchstr(getline('.'),'\x\{40\}')
if s:repo().rev_parse(myhash.':') == ref
let ref = myhash.':'
endif
- return s:Edit(a:mode,ref)
+ return s:Edit(a:mode,0,ref)
elseif getline('.') =~# '^object \x\{40\}$' && getline(line('.')+1) =~ '^type \%(commit\|tree\|blob\)$'
let ref = matchstr(getline('.'),'\x\{40\}')
@@ -2047,9 +2091,9 @@ function! s:GF(mode) abort
endif
if exists('dref')
- return s:Edit(a:mode,ref) . '|'.dcmd.' '.s:fnameescape(dref)
+ return s:Edit(a:mode,0,ref) . '|'.dcmd.' '.s:fnameescape(dref)
elseif ref != ""
- return s:Edit(a:mode,ref)
+ return s:Edit(a:mode,0,ref)
endif
endif