diff --git a/README.markdown b/README.markdown index 83cc075..8c33cc1 100644 --- 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 index 6825835..3e0ae1a 100644 --- 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 index 31df5ad..247ac5f 100644 --- 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 : '', '\\@>>>>>> + 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',)") -call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gedit :execute s:Edit('edit',)") -call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gpedit :execute s:Edit('pedit',)") -call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gsplit :execute s:Edit('split',)") -call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gvsplit :execute s:Edit('vsplit',)") -call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gtabedit :execute s:Edit('tabedit',)") -call s:command("-bar -bang -nargs=? -count -complete=customlist,s:EditComplete Gread :execute s:Edit((! && ? '' : ).'read',)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Ge :execute s:Edit('edit',0,)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gedit :execute s:Edit('edit',0,)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gpedit :execute s:Edit('pedit',0,)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gsplit :execute s:Edit('split',0,)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gvsplit :execute s:Edit('vsplit',0,)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gtabedit :execute s:Edit('tabedit',0,)") +call s:command("-bar -bang -nargs=? -count -complete=customlist,s:EditComplete Gread :execute s:Edit((! && ? '' : ).'read',0,)") " }}}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