Support expansion flags
This commit is contained in:
parent
1e3786734b
commit
fd83fcaf90
@ -53,11 +53,12 @@ function! s:shellesc(arg) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:fnameescape = " \t\n*?[{`$\\%#'\"|!<"
|
||||
function! s:fnameescape(file) abort
|
||||
if exists('*fnameescape')
|
||||
return fnameescape(a:file)
|
||||
else
|
||||
return escape(a:file," \t\n*?[{`$\\%#'\"|!<")
|
||||
return escape(a:file, s:fnameescape)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@ -641,18 +642,13 @@ function! s:Generate(rev, ...) abort
|
||||
return fugitive#Route(object, dir)
|
||||
endfunction
|
||||
|
||||
function! s:RemoveDot(path, ...) abort
|
||||
if a:path !~# '^\./'
|
||||
return a:path
|
||||
function! s:DotRelative(path) abort
|
||||
let cwd = getcwd()
|
||||
let path = substitute(a:path, '^[~$]\i*', '\=expand(submatch(0))', '')
|
||||
if s:cpath(cwd . '/', (path . '/')[0 : len(cwd)])
|
||||
return '.' . strpart(path, len(cwd))
|
||||
endif
|
||||
let dir = a:0 ? a:1 : get(b:, 'git_dir', '')
|
||||
let cdir = fugitive#CommonDir(dir)
|
||||
if len(filter(['', '/tags', '/heads', '/remotes'], 'getftime(cdir . "/refs" . v:val . a:path[1:-1]) >= 0')) ||
|
||||
\ a:path =~# 'HEAD$' && filereadable(dir . a:path[1:-1]) ||
|
||||
\ a:path =~# '^\./refs/' && filereadable(cdir . a:path[1:-1])
|
||||
return a:path
|
||||
endif
|
||||
return a:path[2:-1]
|
||||
endfunction
|
||||
|
||||
function! fugitive#Object(...) abort
|
||||
@ -681,6 +677,44 @@ function! fugitive#Object(...) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:var = '\%(%\|#<\=\d\+\|##\=\)'
|
||||
let s:flag = '\%(:[p8~.htre]\|:g\=s\(.\).\{-\}\1.\{-\}\1\)'
|
||||
let s:expand = '\%(\(' . s:var . '\)\(' . s:flag . '*\)\(:S\)\=\)'
|
||||
|
||||
function! s:BufName(var) abort
|
||||
if a:var ==# '%'
|
||||
return bufname(get(b:, 'fugitive_blamed_bufnr', ''))
|
||||
elseif a:var =~# '^#\d*$'
|
||||
let nr = getbufvar(+a:var[1:-1], 'fugitive_blamed_bufnr', '')
|
||||
return bufname(nr ? nr : +a:var[1:-1])
|
||||
else
|
||||
return expand(a:var)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:ExpandVar(other, var, flags, esc) abort
|
||||
if a:other =~# '^\'
|
||||
return a:other[1:-1]
|
||||
elseif a:other =~# '^!'
|
||||
let buffer = s:BufName(len(a:other) > 1 ? '#'. a:other[1:-1] : '%')
|
||||
let owner = s:Owner(buffer)
|
||||
return len(owner) ? owner : '@'
|
||||
endif
|
||||
let flags = a:flags
|
||||
let file = s:DotRelative(fugitive#Real(s:BufName(a:var)))
|
||||
while len(flags)
|
||||
let flag = matchstr(flags, s:flag)
|
||||
let flags = strpart(flags, len(flag))
|
||||
if flag ==# ':.'
|
||||
let file = s:DotRelative(file)
|
||||
else
|
||||
let file = fnamemodify(file, flag)
|
||||
endif
|
||||
endwhile
|
||||
let file = s:Slash(file)
|
||||
return (len(a:esc) ? shellescape(file) : file)
|
||||
endfunction
|
||||
|
||||
function! s:Expand(rev) abort
|
||||
if a:rev =~# '^:[0-3]$'
|
||||
let file = a:rev . s:Relative(':')
|
||||
@ -688,19 +722,26 @@ function! s:Expand(rev) abort
|
||||
let file = 'HEAD^{}' . a:rev[1:-1] . s:Relative(':')
|
||||
elseif a:rev =~# '^@{'
|
||||
let file = 'HEAD' . a:rev. s:Relative(':')
|
||||
elseif a:rev =~# '^[~^]/\@!'
|
||||
elseif a:rev =~# '^\^[0-9~^{]\|^\~[0-9~^]'
|
||||
let commit = substitute(s:DirCommitFile(@%)[1], '^\d\=$', 'HEAD', '')
|
||||
let file = commit . a:rev . s:Relative(':')
|
||||
else
|
||||
let file = a:rev
|
||||
endif
|
||||
return s:sub(substitute(file,
|
||||
\ '\([%#]\)$\|\\\([[:punct:]]\)','\=len(submatch(2)) ? submatch(2) : fugitive#Path(expand(submatch(1)))','g'),
|
||||
\ '\.\@<=/$','')
|
||||
return substitute(file,
|
||||
\ '\(\\[' . s:fnameescape . ']\|^\\[>+-]\|!\d*\)\|' . s:expand,
|
||||
\ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),"")', 'g')
|
||||
endfunction
|
||||
|
||||
function! fugitive#Expand(object) abort
|
||||
return substitute(a:object,
|
||||
\ '\(\\[' . s:fnameescape . ']\|^\\[>+-]\|!\d*\)\|' . s:expand,
|
||||
\ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),submatch(5))', 'g')
|
||||
endfunction
|
||||
|
||||
function! s:ShellExpand(cmd) abort
|
||||
return substitute(a:cmd, '\\\@<![%#]:\@!', '\=s:RemoveDot(fugitive#Path(expand(submatch(0)), "./"))', 'g')
|
||||
return substitute(a:cmd, '\(\\[!#%]\|!\d*\)\|' . s:expand,
|
||||
\ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),submatch(5))', 'g')
|
||||
endfunction
|
||||
|
||||
let s:trees = {}
|
||||
|
@ -312,14 +312,14 @@ a Show the current tag, commit, or tree in an alternate
|
||||
SPECIFYING OBJECTS *fugitive-object* *fugitive-revision*
|
||||
|
||||
Fugitive objects are either work tree files or Git revisions as defined in the
|
||||
"SPECIFYING REVISIONS" section in the git-rev-parse man page, with a few
|
||||
convenience notations thrown in for good measure. For commands that accept an
|
||||
"SPECIFYING REVISIONS" section in the git-rev-parse man page, with expansions
|
||||
inspired by |cmdline-special| layered on top. For commands that accept an
|
||||
optional object, the default is the file in the index for work tree files and
|
||||
the work tree file for everything else. Example objects follow.
|
||||
|
||||
Object Meaning ~
|
||||
HEAD .git/HEAD
|
||||
refs/heads/x .git/refs/heads/x
|
||||
refs/heads/x .git/refs/heads/x (in "common dir" if present)
|
||||
@ The commit referenced by @ aka HEAD
|
||||
master^ The parent of the commit referenced by master
|
||||
master: The tree referenced by master
|
||||
@ -327,15 +327,16 @@ master: The tree referenced by master
|
||||
Makefile The file named Makefile in the work tree
|
||||
@^:Makefile The file named Makefile in the parent of HEAD
|
||||
:Makefile The file named Makefile in the index (writable)
|
||||
@:% The current file in HEAD
|
||||
- The current file in HEAD
|
||||
-^ The current file in the previous commit
|
||||
-~3 The current file 3 commits ago
|
||||
: .git/index (Same as |:Gstatus|)
|
||||
@~2:% The current file in the grandparent of HEAD
|
||||
:% The current file in the index
|
||||
:1:% The current file's common ancestor during a conflict
|
||||
:2:% The current file in the target branch during a conflict
|
||||
:3:% The current file in the merged branch during a conflict
|
||||
:2:# The alternate file in the target branch during a conflict
|
||||
:3:#5 The file from buffer #5 in the merged branch during a conflict
|
||||
! The commit owning the current file
|
||||
!:Makefile The file named Makefile in the commit owning the current file
|
||||
!3^2 The second parent of the commit owning buffer #3
|
||||
.git/config The repo config file
|
||||
: Same as |:Gstatus|
|
||||
|
||||
STATUSLINE *fugitive-statusline*
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user