Support expansion flags
This commit is contained in:
parent
1e3786734b
commit
fd83fcaf90
@ -53,11 +53,12 @@ function! s:shellesc(arg) abort
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
let s:fnameescape = " \t\n*?[{`$\\%#'\"|!<"
|
||||||
function! s:fnameescape(file) abort
|
function! s:fnameescape(file) abort
|
||||||
if exists('*fnameescape')
|
if exists('*fnameescape')
|
||||||
return fnameescape(a:file)
|
return fnameescape(a:file)
|
||||||
else
|
else
|
||||||
return escape(a:file," \t\n*?[{`$\\%#'\"|!<")
|
return escape(a:file, s:fnameescape)
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@ -641,18 +642,13 @@ function! s:Generate(rev, ...) abort
|
|||||||
return fugitive#Route(object, dir)
|
return fugitive#Route(object, dir)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:RemoveDot(path, ...) abort
|
function! s:DotRelative(path) abort
|
||||||
if a:path !~# '^\./'
|
let cwd = getcwd()
|
||||||
return a:path
|
let path = substitute(a:path, '^[~$]\i*', '\=expand(submatch(0))', '')
|
||||||
|
if s:cpath(cwd . '/', (path . '/')[0 : len(cwd)])
|
||||||
|
return '.' . strpart(path, len(cwd))
|
||||||
endif
|
endif
|
||||||
let dir = a:0 ? a:1 : get(b:, 'git_dir', '')
|
return a:path
|
||||||
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
|
endfunction
|
||||||
|
|
||||||
function! fugitive#Object(...) abort
|
function! fugitive#Object(...) abort
|
||||||
@ -681,6 +677,44 @@ function! fugitive#Object(...) abort
|
|||||||
endif
|
endif
|
||||||
endfunction
|
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
|
function! s:Expand(rev) abort
|
||||||
if a:rev =~# '^:[0-3]$'
|
if a:rev =~# '^:[0-3]$'
|
||||||
let file = a:rev . s:Relative(':')
|
let file = a:rev . s:Relative(':')
|
||||||
@ -688,19 +722,26 @@ function! s:Expand(rev) abort
|
|||||||
let file = 'HEAD^{}' . a:rev[1:-1] . s:Relative(':')
|
let file = 'HEAD^{}' . a:rev[1:-1] . s:Relative(':')
|
||||||
elseif a:rev =~# '^@{'
|
elseif a:rev =~# '^@{'
|
||||||
let file = 'HEAD' . a:rev. s:Relative(':')
|
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 commit = substitute(s:DirCommitFile(@%)[1], '^\d\=$', 'HEAD', '')
|
||||||
let file = commit . a:rev . s:Relative(':')
|
let file = commit . a:rev . s:Relative(':')
|
||||||
else
|
else
|
||||||
let file = a:rev
|
let file = a:rev
|
||||||
endif
|
endif
|
||||||
return s:sub(substitute(file,
|
return substitute(file,
|
||||||
\ '\([%#]\)$\|\\\([[:punct:]]\)','\=len(submatch(2)) ? submatch(2) : fugitive#Path(expand(submatch(1)))','g'),
|
\ '\(\\[' . 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
|
endfunction
|
||||||
|
|
||||||
function! s:ShellExpand(cmd) abort
|
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
|
endfunction
|
||||||
|
|
||||||
let s:trees = {}
|
let s:trees = {}
|
||||||
|
@ -312,14 +312,14 @@ a Show the current tag, commit, or tree in an alternate
|
|||||||
SPECIFYING OBJECTS *fugitive-object* *fugitive-revision*
|
SPECIFYING OBJECTS *fugitive-object* *fugitive-revision*
|
||||||
|
|
||||||
Fugitive objects are either work tree files or Git revisions as defined in the
|
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
|
"SPECIFYING REVISIONS" section in the git-rev-parse man page, with expansions
|
||||||
convenience notations thrown in for good measure. For commands that accept an
|
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
|
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.
|
the work tree file for everything else. Example objects follow.
|
||||||
|
|
||||||
Object Meaning ~
|
Object Meaning ~
|
||||||
HEAD .git/HEAD
|
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
|
@ The commit referenced by @ aka HEAD
|
||||||
master^ The parent of the commit referenced by master
|
master^ The parent of the commit referenced by master
|
||||||
master: The tree 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 work tree
|
||||||
@^:Makefile The file named Makefile in the parent of HEAD
|
@^:Makefile The file named Makefile in the parent of HEAD
|
||||||
:Makefile The file named Makefile in the index (writable)
|
:Makefile The file named Makefile in the index (writable)
|
||||||
@:% The current file in HEAD
|
@~2:% The current file in the grandparent of 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|)
|
|
||||||
:% The current file in the index
|
:% The current file in the index
|
||||||
:1:% The current file's common ancestor during a conflict
|
:1:% The current file's common ancestor during a conflict
|
||||||
:2:% The current file in the target branch during a conflict
|
:2:# The alternate file in the target branch during a conflict
|
||||||
:3:% The current file in the merged 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*
|
STATUSLINE *fugitive-statusline*
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user