59 Commits
v3.4 ... v3.5

Author SHA1 Message Date
Tim Pope
cd67d087df fugitive.vim 3.5
* Lazy initialization.
* Make status buffer diff retrieval asynchronous.
* Support jump to diff from :Git log --name-status.
* Use smudge filters when viewing blobs.
* Provide User FugitiveEditor event.
* Provide FugitiveRemote() API function.
2021-11-15 00:17:52 -05:00
Tim Pope
b736e457b3 Provide FugitiveRemote() 2021-11-13 16:25:36 -05:00
Tim Pope
2e4ee0b5d6 Don't scroll :Git! window for paginated commands
References: https://github.com/tpope/vim-fugitive/issues/1832
2021-11-11 00:44:14 -05:00
Tim Pope
a6b823b8d0 Fix race condition on nvim 0.4
I could have sworn this wasn't necessary on 0.4, which is why I added
the extra clause, but I can consistently reproduce E716 now.

Resolves: https://github.com/tpope/vim-fugitive/issues/1881
2021-11-02 14:07:58 -04:00
Tim Pope
174fd6a39b Revert "Use :redrawstatus rather than &ro = &ro"
Turns out :redrawstatus is a lot more aggressive and can prevent seeing
Fugitive output.

This reverts commit 6ad15506cc.

References: https://github.com/tpope/vim-fugitive/issues/1180
2021-10-27 03:17:44 -04:00
Tim Pope
6ad15506cc Use :redrawstatus rather than &ro = &ro
References: https://github.com/tpope/vim-fugitive/issues/1180
2021-10-26 09:22:33 -04:00
Tim Pope
30933405bb Support blame maps without filetype plugin on
References: https://github.com/tpope/vim-fugitive/issues/1745
2021-10-19 11:44:22 -04:00
Tim Pope
4d29c1d6a0 Provide for retrieving parsed remote URL
The plan is to expose this as FugitiveRemote(), but let's give it some
bake time before making it official.
2021-10-17 20:25:23 -04:00
Tim Pope
93f41ace7d Move to beginning of line in "(" map
Resolves: https://github.com/tpope/vim-fugitive/issues/1867
2021-10-17 11:22:10 -04:00
Tim Pope
d5a6419fcf Guard against parallel status reload
Resolves: https://github.com/tpope/vim-fugitive/issues/1863
2021-10-17 11:22:10 -04:00
Tim Pope
88c7f867cf Further decouple #BufReadStatus() from v:cmdbang 2021-10-16 12:58:13 -04:00
Tim Pope
0615cd2baf Ignore v:cmdbang when not in autocommand 2021-10-16 10:57:04 -04:00
Tim Pope
ca61174e9d Remove leading slash when parsing scpremote:/~user 2021-10-16 10:43:42 -04:00
Tim Pope
a4c6fb74ee Help file formatting fix 2021-10-16 10:43:42 -04:00
Tim Pope
2e66b3ad05 Don't show diff on root commits
The diff on a root commit is often large and seldom helpful, so let's
get rid of it.  This will also be one less thing to worry about when
changing to a fugitive file type.
2021-10-12 12:34:43 -04:00
Tim Pope
e38d029500 Adjust encapsulation of escaped completion handling
Most calls to s:FilterEscape() pass the original escaped argument, so
we should fix the callers that don't.
2021-10-11 00:38:57 -04:00
Tim Pope
69f5fcbd45 Allow escaped characters in tab complete
Resolves: https://github.com/tpope/vim-fugitive/issues/1859
2021-10-10 13:24:20 -04:00
Tim Pope
b540332a3e Improve parallelism of status buffer with earlier diff
This is a trivial gain, but also trivial to implement.
2021-10-08 19:05:18 -04:00
Tim Pope
ae93dbea2e Ensure jobstart on_exit runs when waiting
Resolves: https://github.com/tpope/vim-fugitive/issues/1857
2021-10-08 19:05:18 -04:00
Tim Pope
bcf7478e6b Make status buffer diff retrieval asynchronous
Resolves: https://github.com/tpope/vim-fugitive/issues/1856
2021-10-06 14:45:36 -04:00
Tim Pope
a67854368e Collapse all status buffer diffs on :edit!
References: https://github.com/tpope/vim-fugitive/issues/1563
2021-10-01 14:28:13 -04:00
Tim Pope
e2883a5426 Support reload on custom chmod and unlink events
These were recently added to eunuch.vim, but other plugins may use them
as well.
2021-09-30 12:43:23 -04:00
Tim Pope
194d63da4f Restore laziness of status reload after write
This got lost in a refactor.
2021-09-30 12:43:23 -04:00
Tim Pope
dd39902e3d Minor performance improvement to global map definition 2021-09-30 12:43:23 -04:00
Tim Pope
7e483dc60d Show overflow sections as 255+ not 256
Resolves: https://github.com/tpope/vim-fugitive/issues/1853
2021-09-29 16:59:38 -04:00
Steven Humphrey
1213953abf Fix default remote in fugitive#RemoteUrl
A previous refactor resulted in fugitive#RemoteUrl() with no arguments
returning the string 'origin' instead of git@github.com....
2021-09-28 10:49:14 -04:00
Tim Pope
7b05afd548 Add experimental behavior for X on commit line
Resolves: https://github.com/tpope/vim-fugitive/issues/1847
2021-09-25 10:21:58 -04:00
Tim Pope
915c050724 Fix :GBrowse - destination 2021-09-25 10:20:09 -04:00
Tim Pope
142a0dc0c4 Fix wrong variable name in fugitive#RemoteUrl()
Resolves: https://github.com/tpope/vim-fugitive/pull/1843
2021-09-23 04:39:47 -04:00
Tim Pope
1352646890 Extract helper to parse fugitive#RemoteUrl() arguments 2021-09-19 14:44:42 -04:00
Tim Pope
e1d382b3e7 Fix resolution of scp style URLs 2021-09-19 14:44:42 -04:00
Tim Pope
3d67d23f47 Normalize path when parsing remote URL
Change an empty path to "/" as is the standard interpretation.  And for
git:// and ssh:// URLs, change a leading "/~" to "~", like Git itself
does.
2021-09-19 12:26:14 -04:00
Tim Pope
f02217b776 Avoid repeat config retrieval in :GBrowse 2021-09-19 12:26:12 -04:00
Tim Pope
12c40427a0 Separate remote resolution from URL reassembly 2021-09-19 08:29:40 -04:00
Tim Pope
bb89a7a497 Invert flag for lazy initialization
I think this second argument might become an optional buffer number at
some point, so change the special value for lazy to an invalid buffer
number.
2021-09-19 07:54:03 -04:00
Tim Pope
a67e1f8189 Try to avoid interference by $GIT_DIR and $GIT_WORK_TREE
Resolves: https://github.com/tpope/vim-fugitive/issues/1841
2021-09-17 06:16:58 -04:00
Tim Pope
27abc3f1bd Respect 'splitright' instead of 'splitbelow' for :vertical
Resolves: https://github.com/tpope/vim-fugitive/issues/1839
2021-09-16 08:13:00 -04:00
Tim Pope
67c4c031fa Support jump to diff from :Git log --name-status
Resolves: https://github.com/tpope/vim-fugitive/issues/1838
2021-09-14 18:19:16 -04:00
Tim Pope
79a6a1941d Fix typo 2021-09-14 14:04:42 -04:00
Tim Pope
ba52c2b446 Make RemoteUrl() option parsing a bit less convoluted 2021-09-14 03:38:26 -04:00
Tim Pope
529311cec7 Fix check for wrong executable 2021-09-14 02:12:50 -04:00
Tim Pope
5f387d4783 Fix FugitiveRemoteUrl('origin', FugitiveConfig()) 2021-09-14 00:06:58 -04:00
Tim Pope
5be8263f16 Override GPG_TTY to prevent terminal garbling
Resolves: https://github.com/tpope/vim-fugitive/issues/1836
2021-09-13 21:05:03 -04:00
Tim Pope
1651cd7f20 Extract helper to determine PTY availability
I constantly have to ask about this to troubleshoot bug reports, so make
it easier to determine.

Also rename g:fugitive_pty to make it clearer that it's not a preference
but a debugging tool.
2021-09-13 16:58:42 -04:00
Yuriy Taraday
630ecc8c3a Use --filters in cat-file whenever possible
Starting with Git 2.11 cat-file provides --filters option that can be
specified instead of "blob" type. This option tells Git to use all
filters specified in .gitattributes.

This enables diffs for files with filters, for example, git-crypt.

Closes #1509
2021-09-13 16:16:32 -04:00
Tim Pope
e2927fb467 Force current buffer number for FugitiveStatusline()
This is normally the default, but might be different during an event
like FugitiveChanged.
2021-09-10 16:13:51 -04:00
Tim Pope
1a652c0cdf Tab complete :Git ++options and --options
Resolves: https://github.com/tpope/vim-fugitive/issues/1833
2021-09-10 16:11:39 -04:00
Tim Pope
6b1d90251e Support lazy initialization in statusline indicator
Resolves: https://github.com/tpope/vim-fugitive/issues/1834
2021-09-10 15:51:47 -04:00
Tim Pope
bb4d1dd9a8 Eliminate internal use of FugitiveCommonDir()
Lead by example.
2021-09-10 15:51:41 -04:00
Tim Pope
b6545ad389 Fix inconsistency when scrolling :Git! preview window
Scrolling with win_execute() works fine while the command is running,
but once the job has finished, it fails to update the viewport until the
window is focused.  I don't get it.  It's not like the window knows a
job is running.  The only obvious trigger I could find is that
'nobuflisted' is set once once the job completes, but even disabling
that behavior fails to rectify the problem.  Screw it, manual focus
bouncing for everyone.

References: https://github.com/tpope/vim-fugitive/issues/1832
2021-09-10 02:47:21 -04:00
Tim Pope
be0abe0b21 Standardize <mods> handling for quickfix commands
Use <mods> for :copen rather than :cfirst, as that seems to be the more
useful of the two.

When I call :vertical copen, I get a window that is initially 10
columns wide, but which resizes to 20 columns upon blurring and
refocusing. Not sure what's up with that, but 10 columns is comically
narrow, so let's go ahead and open at 20 columns to begin with.

Resolves: https://github.com/tpope/vim-fugitive/issues/1831
2021-09-08 16:04:35 -04:00
Tim Pope
02eb2e871c Fix typo in error message 2021-09-07 14:16:27 -04:00
Tim Pope
404c3c24e1 Use new tab for --patch maps
References: https://github.com/tpope/vim-fugitive/discussions/1830
2021-09-07 13:59:52 -04:00
Tim Pope
ed6b45a81a Drop unused args parameter from :Gcommand implementations
We stopped using this in 6356bbc4a7.
2021-09-07 13:56:14 -04:00
Tim Pope
6f07d7e6cd Make initialization lazy 2021-09-06 19:03:55 -04:00
Tim Pope
8c243a7f0d Provide User FugitiveEditor event
I'm not sure if this should trigger every time the buffer is loaded, or
only on the initial split.  Arbitrarily pick the latter for now.

References: https://github.com/tpope/vim-fugitive/issues/1828
2021-09-06 15:54:37 -04:00
Tim Pope
0840f001fe Avoid error when mapcheck() and <unique> semantics differ
References: https://github.com/tpope/vim-fugitive/issues/1826
2021-09-05 10:00:39 -04:00
Tim Pope
8d25dd777c Fix pedit map in :Git -p grep
Resolves: https://github.com/tpope/vim-fugitive/issues/1825
2021-09-04 00:13:35 -04:00
Tim Pope
d488a7090f Add >/ and >:/ as work-tree version expansions
Not sure I want to waste the easy to type ">" on the work tree version,
so adding some alternatives.
2021-09-04 00:13:00 -04:00
4 changed files with 407 additions and 214 deletions

View File

@@ -125,7 +125,15 @@ function! s:Mods(mods, ...) abort
let mods = substitute(a:mods, '\C<mods>', '', '')
let mods = mods =~# '\S$' ? mods . ' ' : mods
if a:0 && mods !~# '\<\%(aboveleft\|belowright\|leftabove\|rightbelow\|topleft\|botright\|tab\)\>'
let mods = a:1 . ' ' . mods
if a:1 ==# 'Edge'
if mods =~# '\<vertical\>' ? &splitright : &splitbelow
let mods = 'botright ' . mods
else
let mods = 'topleft ' . mods
endif
else
let mods = a:1 . ' ' . mods
endif
endif
return substitute(mods, '\s\+', ' ', 'g')
endfunction
@@ -219,8 +227,8 @@ function! s:Map(mode, lhs, rhs, ...) abort
let head = substitute(head, '<[^<>]*>$\|.$', '', '')
endwhile
if !skip && (flags !~# '<unique>' || empty(mapcheck(head.tail, mode)))
call add(maps, mode.'map <buffer>' . s:nowait . flags . ' ' . head.tail . ' ' . a:rhs)
if a:0 > 1
call add(maps, mode.'map <buffer>' . s:nowait . substitute(flags, '<unique>', '', '') . ' ' . head.tail . ' ' . a:rhs)
if a:0 > 1 && a:2
let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'exe') .
\ '|sil! exe "' . mode . 'unmap <buffer> ' . head.tail . '"'
endif
@@ -255,6 +263,9 @@ function! fugitive#Wait(job_or_jobs, ...) abort
if exists('*jobwait')
call map(copy(jobs), 'chanclose(v:val, "stdin")')
call jobwait(jobs, timeout_ms)
if len(jobs)
sleep 1m
endif
else
let sleep = has('patch-8.2.2366') ? 'sleep! 1m' : 'sleep 1m'
for job in jobs
@@ -420,7 +431,7 @@ function! s:UserCommandList(...) abort
if empty(tree)
call add(git, '--git-dir=' . FugitiveGitPath(dir))
else
if !s:cpath(tree . '/.git', dir)
if !s:cpath(tree . '/.git', dir) || len($GIT_DIR)
call add(git, '--git-dir=' . FugitiveGitPath(dir))
endif
if !s:cpath(tree, getcwd())
@@ -547,6 +558,9 @@ function! s:PrepareEnv(env, dir) abort
let a:env['GIT_INDEX_FILE'] = FugitiveGitPath(fugitive#Find('.git/index', a:dir))
endif
endif
if len($GIT_WORK_TREE)
let a:env['GIT_WORK_TREE'] = '.'
endif
endfunction
let s:prepare_env = {
@@ -626,8 +640,10 @@ function! fugitive#PrepareDirEnvGitFlagsArgs(...) abort
if !exists('dir')
let dir = s:Dir()
endif
if !has_key(env, 'GIT_INDEX_FILE')
call s:PrepareEnv(autoenv, dir)
call extend(autoenv, env)
call s:PrepareEnv(autoenv, dir)
if len($GPG_TTY) && !has_key(autoenv, 'GPG_TTY')
let autoenv.GPG_TTY = ''
endif
call s:PreparePathArgs(cmd, dir, literal_pathspecs, explicit_pathspec_option)
return [s:GitDir(dir), env, extend(autoenv, env), git, cmd[0 : -arg_count-1], arg_count ? cmd[-arg_count : -1] : []]
@@ -702,7 +718,7 @@ function! fugitive#PrepareJob(...) abort
else
let dict.cwd = FugitiveVimPath(tree)
call extend(cmd, ['-C', FugitiveGitPath(tree)], 'keep')
if !s:cpath(tree . '/.git', dir)
if !s:cpath(tree . '/.git', dir) || len($GIT_DIR)
call extend(cmd, ['--git-dir=' . FugitiveGitPath(dir)], 'keep')
endif
endif
@@ -740,7 +756,7 @@ function! s:BuildShell(dir, env, git, args) abort
call insert(cmd, '--git-dir=' . FugitiveGitPath(a:dir))
else
call extend(cmd, ['-C', FugitiveGitPath(tree)], 'keep')
if !s:cpath(tree . '/.git', a:dir)
if !s:cpath(tree . '/.git', a:dir) || len($GIT_DIR)
call extend(cmd, ['--git-dir=' . FugitiveGitPath(a:dir)], 'keep')
endif
endif
@@ -1108,7 +1124,7 @@ endfunction
call s:add_methods('config', ['GetAll', 'Get', 'GetRegexp'])
function! s:Remote(dir) abort
function! s:RemoteDefault(dir) abort
let head = FugitiveHead(0, a:dir)
let remote = len(head) ? FugitiveConfigGet('branch.' . head . '.remote', a:dir) : ''
let i = 10
@@ -1220,7 +1236,7 @@ let s:remote_headers = {}
function! fugitive#RemoteHttpHeaders(remote) abort
let remote = type(a:remote) ==# type({}) ? get(a:remote, 'remote', '') : a:remote
if type(remote) !=# type('') || remote !~# '^https\=://.' || !s:executable('cremote')
if type(remote) !=# type('') || remote !~# '^https\=://.' || !s:executable('curl')
return {}
endif
if !has_key(s:remote_headers, remote)
@@ -1234,65 +1250,61 @@ function! fugitive#RemoteHttpHeaders(remote) abort
return s:remote_headers[remote]
endfunction
function! fugitive#ResolveRemote(remote) abort
let scp_authority = matchstr(a:remote, '^[^:/]\+\ze:\%(//\)\@!')
function! s:UrlParse(url) abort
let scp_authority = matchstr(a:url, '^[^:/]\+\ze:\%(//\)\@!')
if len(scp_authority) && !(has('win32') && scp_authority =~# '^\a:[\/]')
let path = strpart(a:remote, len(scp_authority) + 1)
let authority = fugitive#SshHostAlias(scp_authority)
if path =~# '^/'
return 'ssh://' . authority . path
elseif path =~# '^\~'
return 'ssh://' . authority . '/' . path
elseif authority !~# ':'
return authority . ':' . path
let url = {'scheme': 'ssh', 'authority': scp_authority,
\ 'path': strpart(a:url, len(scp_authority) + 1)}
elseif empty(a:url)
let url = {'scheme': '', 'authority': '', 'path': ''}
else
let match = matchlist(a:url, '^\([[:alnum:].+-]\+\)://\([^/]*\)\(/.*\)\=\%(#\|$\)')
if empty(match)
let url = {'scheme': 'file', 'authority': '', 'path': a:url}
else
let url = {'scheme': match[1], 'authority': match[2]}
let url.path = empty(match[3]) ? '/' : match[3]
endif
elseif a:remote =~# '^https\=://'
let headers = fugitive#RemoteHttpHeaders(a:remote)
endif
if (url.scheme ==# 'ssh' || url.scheme ==# 'git') && url.path[0:1] ==# '/~'
let url.path = strpart(url.path, 1)
endif
return url
endfunction
function! s:RemoteResolve(url, flags) abort
let remote = s:UrlParse(a:url)
if remote.scheme =~# '^https\=$' && index(a:flags, ':nohttp') < 0
let headers = fugitive#RemoteHttpHeaders(remote.scheme . '://' . remote.authority . remote.path)
let loc = matchstr(get(headers, 'location', ''), '^https\=://.\{-\}\ze/info/refs?')
if len(loc)
return loc
let remote = s:UrlParse(loc)
else
let remote.headers = headers
endif
elseif a:remote =~# '^ssh://'
let authority = matchstr(a:remote, '[^/?#]*', 6)
return 'ssh://' . fugitive#SshHostAlias(authority) . strpart(a:remote, 6 + len(authority))
elseif remote.scheme ==# 'ssh'
let remote.authority = fugitive#SshHostAlias(remote.authority)
endif
return a:remote
return remote
endfunction
function! s:ConfigLengthSort(i1, i2) abort
return len(a:i2[0]) - len(a:i1[0])
endfunction
function! fugitive#RemoteUrl(...) abort
let args = a:000
if a:0 && (type(a:1) !=# type('') || a:1 =~# '^/\|^\a:[\\/]' && get(a:, 2, '') !~# '^/\|^\a:[\\/]')
let config = fugitive#Config(a:1)
let args = a:000[1:-1]
if type(a:1) ==# type({}) && has_key(a:1, 'remote_name') && (type(get(args, 0, 0)) !=# type('') || args[0] =~# '^:')
call insert(args, a:1.remote_name)
endif
elseif a:0 > 1 && a:2 !~# '^:'
let config = fugitive#Config(a:2)
let args = [a:1] + a:000[2:-1]
else
let config = fugitive#Config()
let args = copy(a:000)
endif
if empty(args) || args[0] =~# '^:'
let url = s:Remote(config)
elseif args[0] =~# '^\.\=$'
call remove(args, 0)
let url = s:Remote(config)
else
let url = remove(args, 0)
function! s:RemoteCallback(config, into, flags, cb) abort
if a:into.remote_name =~# '^\.\=$'
let a:into.remote_name = s:RemoteDefault(a:config)
endif
let url = a:into.remote_name
if url ==# '.git'
let url = s:GitDir(config)
elseif url !~# ':\|^/\|^\.\.\=/'
let url = FugitiveConfigGet('remote.' . url . '.url', config)
let url = s:GitDir(a:config)
elseif url !~# ':\|^/\|^\a:[\/]\|^\.\.\=/'
let url = FugitiveConfigGet('remote.' . url . '.url', a:config)
endif
let instead_of = []
for [k, vs] in items(fugitive#ConfigGetRegexp('^url\.\zs.\{-\}\ze\.insteadof$', config))
for [k, vs] in items(fugitive#ConfigGetRegexp('^url\.\zs.\{-\}\ze\.insteadof$', a:config))
for v in vs
call add(instead_of, [v, k])
endfor
@@ -1304,10 +1316,93 @@ function! fugitive#RemoteUrl(...) abort
break
endif
endfor
if index(args, 1) < 0 && index(args, get(v:, 'true', 1)) < 0 && index(args, ':noresolve') < 0
let url = fugitive#ResolveRemote(url)
if index(a:flags, ':noresolve') < 0
call extend(a:into, s:RemoteResolve(url, a:flags))
else
call extend(a:into, s:UrlParse(url))
endif
return url
let a:into.user = matchstr(a:into.authority, '.\{-\}\ze@', '', '')
let a:into.host = substitute(a:into.authority, '.\{-\}@', '', '')
let a:into.hostname = substitute(a:into.host, ':\d\+$', '', '')
let a:into.port = matchstr(a:into.host, ':\zs\d\+$', '', '')
if a:into.path =~# '^/'
let a:into.url = a:into.scheme . '://' . a:into.authority . a:into.path
elseif a:into.path =~# '^\~'
let a:into.url = a:into.scheme . '://' . a:into.authority . '/' . a:into.path
elseif a:into.scheme ==# 'ssh' && a:into.authority !~# ':'
let a:into.url = a:into.authority . ':' . a:into.path
else
let a:into.url = url
endif
if len(a:cb)
call call(a:cb[0], [a:into] + a:cb[1:-1])
endif
endfunction
function! s:Remote(dir, remote, flags, cb) abort
let into = {'remote_name': a:remote, 'git_dir': s:GitDir(a:dir)}
let config = fugitive#Config(a:dir, function('s:RemoteCallback'), into, a:flags, a:cb)
if len(a:cb)
return config
else
call fugitive#Wait(config)
return into
endif
endfunction
function! s:RemoteParseArgs(args) abort
" Extract ':noresolve' style flags and an optional callback
let args = []
let flags = []
let cb = copy(a:args)
while len(cb)
if type(cb[0]) ==# type(function('tr'))
break
elseif len(args) > 1 || type(cb[0]) ==# type('') && cb[0] =~# '^:'
call add(flags, remove(cb, 0))
else
call add(args, remove(cb, 0))
endif
endwhile
" From the remaining 0-2 arguments, extract the remote and Git config
let remote = ''
if empty(args)
let dir_or_config = s:Dir()
elseif len(args) == 1 && type(args[0]) ==# type('') && args[0] !~# '^/\|^\a:[\\/]'
let dir_or_config = s:Dir()
let remote = args[0]
elseif len(args) == 1
let dir_or_config = args[0]
if type(args[0]) ==# type({}) && has_key(args[0], 'remote_name')
let remote = args[0].remote_name
endif
elseif type(args[1]) !=# type('') || args[1] =~# '^/\|^\a:[\\/]'
let dir_or_config = args[1]
let remote = args[0]
else
let dir_or_config = args[0]
let remote = args[1]
endif
return [dir_or_config, remote, flags, cb]
endfunction
function! fugitive#Remote(...) abort
let [dir_or_config, remote, flags, cb] = s:RemoteParseArgs(a:000)
return s:Remote(dir_or_config, remote, flags, cb)
endfunction
function! s:RemoteUrlCallback(remote, callback) abort
return call(a:callback[0], [a:remote.url] + a:callback[1:-1])
endfunction
function! fugitive#RemoteUrl(...) abort
let [dir_or_config, remote, flags, cb] = s:RemoteParseArgs(a:000)
if len(cb)
let cb = [function('s:RemoteUrlCallback'), cb]
endif
let remote = s:Remote(dir_or_config, remote, flags, cb)
return get(remote, 'url', remote)
endfunction
" Section: Quickfix
@@ -1336,15 +1431,19 @@ function! s:QuickfixCreate(nr, opts) abort
endif
endfunction
function! s:QuickfixOpen(nr, mods) abort
let mods = substitute(s:Mods(a:mods), '\<tab\>', '', '')
return mods . (a:nr < 0 ? 'c' : 'l').'open' . (mods =~# '\<vertical\>' ? ' 20' : '')
endfunction
function! s:QuickfixStream(nr, event, title, cmd, first, mods, callback, ...) abort
call s:BlurStatus()
let mods = s:Mods(a:mods)
let opts = {'title': a:title, 'context': {'items': []}}
call s:QuickfixCreate(a:nr, opts)
let event = (a:nr < 0 ? 'c' : 'l') . 'fugitive-' . a:event
silent exe s:DoAutocmd('QuickFixCmdPre ' . event)
let winnr = winnr()
exe a:nr < 0 ? 'copen' : 'lopen'
exe s:QuickfixOpen(a:nr, a:mods)
if winnr != winnr()
wincmd p
endif
@@ -1359,7 +1458,7 @@ function! s:QuickfixStream(nr, event, title, cmd, first, mods, callback, ...) ab
call extend(opts.context.items, contexts)
unlet contexts
call s:QuickfixSet(a:nr, remove(buffer, 0, -1), 'a')
if mods !~# '\<silent\>'
if a:mods !~# '\<silent\>'
redraw
endif
endif
@@ -1371,7 +1470,7 @@ function! s:QuickfixStream(nr, event, title, cmd, first, mods, callback, ...) ab
silent exe s:DoAutocmd('QuickFixCmdPost ' . event)
if a:first && len(s:QuickfixGet(a:nr))
return mods . (a:nr < 0 ? 'cfirst' : 'lfirst')
return (a:nr < 0 ? 'cfirst' : 'lfirst')
else
return 'exe'
endif
@@ -1868,7 +1967,7 @@ endfunction
function! s:Expand(rev, ...) abort
if a:rev =~# '^>\=:[0-3]$'
let file = len(expand('%')) ? a:rev[-2:-1] . ':%' : '%'
elseif a:rev ==# '>'
elseif a:rev =~# '^>\%(:\=/\)\=$'
let file = '%'
elseif a:rev ==# '>:'
let file = empty(s:DirCommitFile(@%)[0]) ? ':0:%' : '%'
@@ -2105,7 +2204,8 @@ function! s:BlobTemp(url) abort
endif
if commit =~# '^\d$' || !filereadable(tempfile)
let rev = s:DirRev(a:url)[1]
let exec_error = s:StdoutToFile(tempfile, [dir, 'cat-file', 'blob', rev])[1]
let blob_or_filters = fugitive#GitVersion(2, 11) ? '--filters' : 'blob'
let exec_error = s:StdoutToFile(tempfile, [dir, 'cat-file', blob_or_filters, rev])[1]
if exec_error
call delete(tempfile)
return ''
@@ -2318,7 +2418,7 @@ function! fugitive#CompleteObject(base, ...) abort
let heads += ["stash"]
let heads += sort(s:LinesError(["stash","list","--pretty=format:%gd"], dir)[0])
endif
let results += s:FilterEscape(heads, base)
let results += s:FilterEscape(heads, fnameescape(base))
endif
let results += a:0 == 1 || a:0 >= 3 ? fugitive#CompletePath(base, 0, '', dir, a:0 >= 4 ? a:4 : tree) : fugitive#CompletePath(base)
return results
@@ -2340,7 +2440,7 @@ function! fugitive#CompleteObject(base, ...) abort
call map(entries,'s:sub(v:val,"^04.*\\zs$","/")')
call map(entries,'parent.s:sub(v:val,".*\t","")')
endif
return s:FilterEscape(entries, base)
return s:FilterEscape(entries, fnameescape(base))
endfunction
function! s:CompleteSub(subcommand, A, L, P, ...) abort
@@ -2403,8 +2503,8 @@ function! s:ReplaceCmd(cmd) abort
endif
endfunction
function! s:QueryLog(refspec) abort
let lines = s:LinesError(['log', '-n', '256', '--pretty=format:%h%x09%s', a:refspec, '--'])[0]
function! s:QueryLog(refspec, limit) abort
let lines = s:LinesError(['log', '-n', '' . a:limit, '--pretty=format:%h%x09%s', a:refspec, '--'])[0]
call map(lines, 'split(v:val, "\t", 1)')
call map(lines, '{"type": "Log", "commit": v:val[0], "subject": join(v:val[1 : -1], "\t")}')
return lines
@@ -2454,6 +2554,20 @@ function! s:AddSection(label, lines, ...) abort
call append(line('$'), ['', a:label . (len(note) ? ': ' . note : ' (' . len(a:lines) . ')')] + s:Format(a:lines))
endfunction
function! s:AddLogSection(label, a, b) abort
let limit = 256
let log = s:QueryLog(a:a . '..' . a:b, limit)
if empty(log)
return
elseif len(log) == limit
call remove(log, -1)
let label = a:label . ' (' . (limit - 1). '+)'
else
let label = a:label . ' (' . len(log) . ')'
endif
call append(line('$'), ['', label] + s:Format(log))
endfunction
let s:rebase_abbrevs = {
\ 'p': 'pick',
\ 'r': 'reword',
@@ -2468,16 +2582,15 @@ let s:rebase_abbrevs = {
\ 'b': 'break',
\ }
function! fugitive#BufReadStatus() abort
function! fugitive#BufReadStatus(...) abort
let amatch = s:Slash(expand('%:p'))
let b:fugitive_type = 'index'
unlet! b:fugitive_reltime
unlet! b:fugitive_reltime b:fugitive_type
try
silent doautocmd BufReadPre
let config = fugitive#Config()
let cmd = [fnamemodify(amatch, ':h')]
setlocal noro ma nomodeline buftype=nowrite
setlocal noreadonly modifiable nomodeline buftype=nowrite
if s:cpath(fnamemodify($GIT_INDEX_FILE !=# '' ? FugitiveVimPath($GIT_INDEX_FILE) : fugitive#Find('.git/index'), ':p')) !=# s:cpath(amatch)
let cmd += [{'env': {'GIT_INDEX_FILE': FugitiveGitPath(amatch)}}]
endif
@@ -2590,6 +2703,16 @@ function! fugitive#BufReadStatus() abort
endwhile
endif
let diff = {'Staged': {'stdout': ['']}, 'Unstaged': {'stdout': ['']}}
if len(staged)
let diff['Staged'] =
\ fugitive#Execute(['diff', '--color=never', '--no-ext-diff', '--no-prefix', '--cached'], function('len'))
endif
if len(unstaged)
let diff['Unstaged'] =
\ fugitive#Execute(['diff', '--color=never', '--no-ext-diff', '--no-prefix'], function('len'))
endif
for dict in staged
let b:fugitive_files['Staged'][dict.filename] = dict
endfor
@@ -2666,16 +2789,10 @@ function! fugitive#BufReadStatus() abort
endfor
endif
let diff = {'Staged': [], 'Unstaged': []}
if len(staged)
let diff['Staged'] =
\ s:LinesError(['diff', '--color=never', '--no-ext-diff', '--no-prefix', '--cached'])[0]
endif
if len(unstaged)
let diff['Unstaged'] =
\ s:LinesError(['diff', '--color=never', '--no-ext-diff', '--no-prefix'])[0]
endif
let b:fugitive_diff = diff
if get(a:, 1, v:cmdbang)
unlet! b:fugitive_expanded
endif
let expanded = get(b:, 'fugitive_expanded', {'Staged': {}, 'Unstaged': {}})
let b:fugitive_expanded = {'Staged': {}, 'Unstaged': {}}
@@ -2705,16 +2822,16 @@ function! fugitive#BufReadStatus() abort
let staged_end = len(staged) ? line('$') : 0
if len(pull) && get(props, 'branch.ab') !~# ' -0$'
call s:AddSection('Unpulled from ' . pull, s:QueryLog(head . '..' . pull))
call s:AddLogSection('Unpulled from ' . pull, head, pull)
endif
if len(push) && push !=# pull
call s:AddSection('Unpulled from ' . push, s:QueryLog(head . '..' . push))
call s:AddLogSection('Unpulled from ' . push, head, push)
endif
if len(pull) && push !=# pull
call s:AddSection('Unpushed to ' . pull, s:QueryLog(pull . '..' . head))
call s:AddLogSection('Unpushed to ' . pull, pull, head)
endif
if len(push) && !(push ==# pull && get(props, 'branch.ab') =~# '^+0 ')
call s:AddSection('Unpushed to ' . push, s:QueryLog(push . '..' . head))
call s:AddLogSection('Unpushed to ' . push, push, head)
endif
setlocal nomodified readonly noswapfile
@@ -2791,6 +2908,8 @@ function! fugitive#BufReadStatus() abort
return s:DoAutocmd('User FugitiveIndex')
catch /^fugitive:/
return 'echoerr ' . string(v:exception)
finally
let b:fugitive_type = 'index'
endtry
endfunction
@@ -2930,7 +3049,7 @@ function! fugitive#BufReadCmd(...) abort
if b:fugitive_display_format
call s:ReplaceCmd([dir, 'cat-file', b:fugitive_type, rev])
else
call s:ReplaceCmd([dir, '-c', 'diff.noprefix=false', 'show', '--no-color', '-m', '--first-parent', '--pretty=format:tree%x20%T%nparent%x20%P%nauthor%x20%an%x20<%ae>%x20%ad%ncommitter%x20%cn%x20<%ce>%x20%cd%nencoding%x20%e%n%n%s%n%n%b', rev])
call s:ReplaceCmd([dir, '-c', 'diff.noprefix=false', '-c', 'log.showRoot=false', 'show', '--no-color', '-m', '--first-parent', '--pretty=format:tree%x20%T%nparent%x20%P%nauthor%x20%an%x20<%ae>%x20%ad%ncommitter%x20%cn%x20<%ce>%x20%cd%nencoding%x20%e%n%n%s%n%n%b', rev])
keepjumps 1
keepjumps call search('^parent ')
if getline('.') ==# 'parent '
@@ -2948,7 +3067,8 @@ function! fugitive#BufReadCmd(...) abort
elseif b:fugitive_type ==# 'stage'
call s:ReplaceCmd([dir, 'ls-files', '--stage'])
elseif b:fugitive_type ==# 'blob'
call s:ReplaceCmd([dir, 'cat-file', b:fugitive_type, rev])
let blob_or_filters = rev =~# ':' && fugitive#GitVersion(2, 11) ? '--filters' : 'blob'
call s:ReplaceCmd([dir, 'cat-file', blob_or_filters, rev])
endif
finally
keepjumps call setpos('.',pos)
@@ -3074,6 +3194,9 @@ function! s:TempReadPost(file) abort
if dict.filetype ==# 'man' && has('nvim')
let b:man_sect = matchstr(getline(1), '^\w\+(\zs\d\+\ze)')
endif
if !get(g:, 'did_load_ftplugin') && dict.filetype ==# 'fugitiveblame'
call s:BlameMaps(0)
endif
let &l:filetype = dict.filetype
endif
setlocal foldmarker=<<<<<<<<,>>>>>>>>
@@ -3145,8 +3268,18 @@ function! s:RunEdit(state, tmp, job) abort
let file = FugitiveVimPath(readfile(sentinel, '', 1)[0])
exe substitute(a:state.mods, '\<tab\>', '-tab', 'g') 'keepalt split' s:fnameescape(file)
set bufhidden=wipe
let s:edit_jobs[bufnr('')] = [a:state, a:tmp, a:job, sentinel]
let bufnr = bufnr('')
let s:edit_jobs[bufnr] = [a:state, a:tmp, a:job, sentinel]
call fugitive#DidChange(a:state.git_dir)
if bufnr == bufnr('') && !exists('g:fugitive_event')
try
let g:fugitive_event = a:state.git_dir
let g:fugitive_result = a:state
exe s:DoAutocmd('User FugitiveEditor')
finally
unlet! g:fugitive_event g:fugitive_result
endtry
endif
return 1
endfunction
@@ -3200,11 +3333,7 @@ function! s:RunReceive(state, tmp, type, job, data, ...) abort
call setbufline(a:state.capture_bufnr, line_count + 1, lines)
endif
call setbufvar(a:state.capture_bufnr, '&modifiable', 0)
if !getwinvar(bufwinid(a:state.capture_bufnr), '&previewwindow')
" no-op
elseif exists('*win_execute')
call win_execute(bufwinid(a:state.capture_bufnr), '$')
else
if !a:state.pager && getwinvar(bufwinid(a:state.capture_bufnr), '&previewwindow')
let winnr = bufwinnr(a:state.capture_bufnr)
if winnr > 0
let old_winnr = winnr()
@@ -3421,6 +3550,11 @@ augroup fugitive_job
\ endfor
augroup END
function! fugitive#CanPty() abort
return get(g:, 'fugitive_pty_debug_override',
\ has('unix') && !has('win32unix') && (has('patch-8.0.0744') || has('nvim')) && fugitive#GitVersion() !~# '\.windows\>')
endfunction
function! fugitive#PagerFor(argv, ...) abort
let args = a:argv
if empty(args)
@@ -3578,9 +3712,10 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
let after_edit = ''
let stream = 0
if a:bang && pager isnot# 2
let state.pager = pager
let pager = 1
let stream = exists('*setbufline')
let do_edit = substitute(s:Mods(a:mods, &splitbelow ? 'botright' : 'topleft'), '\<tab\>', '-tab', 'g') . 'pedit!'
let do_edit = substitute(s:Mods(a:mods, 'Edge'), '\<tab\>', '-tab', 'g') . 'pedit!'
elseif pager
let allow_pty = 0
if pager is# 2 && a:bang && a:line2 >= 0
@@ -3597,7 +3732,7 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
endif
if s:run_jobs
call extend(env, {'COLUMNS': '' . (&columns - 1)}, 'keep')
let state.pty = allow_pty && get(g:, 'fugitive_pty', has('unix') && !has('win32unix') && (has('patch-8.0.0744') || has('nvim')) && fugitive#GitVersion() !~# '\.windows\>')
let state.pty = allow_pty && fugitive#CanPty()
if !state.pty
let args = s:AskPassArgs(dir) + args
endif
@@ -3620,6 +3755,10 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
\ 'GIT_SEQUENCE_EDITOR': editor,
\ 'GIT_PAGER': 'cat',
\ 'PAGER': 'cat'}, 'keep')
if len($GPG_TTY) && !has_key(env, 'GPG_TTY')
let env.GPG_TTY = ''
let did_override_gpg_tty = 1
endif
if stream
call writefile(['fugitive: aborting edit due to background operation.'], state.file . '.exit')
elseif pager
@@ -3700,6 +3839,9 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
if !explicit_pathspec_option && get(options.flags, 0, '') ==# '--no-literal-pathspecs'
call remove(options.flags, 0)
endif
if exists('l:did_override_gpg_tty')
call remove(env, 'GPG_TTY')
endif
let cmd = s:BuildEnvPrefix(env) . s:shellesc(s:UserCommandList(options) + args)
let after = '|call fugitive#DidChange(' . string(dir) . ')' . after
if !wants_terminal && (no_pager || index(['add', 'clean', 'reset', 'restore', 'stage'], get(args, 0, '')) >= 0 || s:HasOpt(args, ['checkout'], '-q', '--quiet', '--no-progress'))
@@ -3801,8 +3943,12 @@ function! fugitive#Complete(lead, ...) abort
let dir = a:0 == 1 ? a:1 : a:0 >= 3 ? s:Dir(a:3) : s:Dir()
let root = a:0 >= 4 ? a:4 : s:Tree(s:Dir())
let pre = a:0 > 1 ? strpart(a:1, 0, a:2) : ''
let subcmd = matchstr(pre, '\u\w*[! ] *\zs[[:alnum:]-]\+\ze ')
if empty(subcmd)
let subcmd = matchstr(pre, '\u\w*[! ] *\%(\%(++\S\+\|--\S\+-pathspecs\|-c\s\+\S\+\)\s\+\)*\zs[[:alnum:]][[:alnum:]-]*\ze ')
if empty(subcmd) && a:lead =~# '^+'
let results = ['++curwin']
elseif empty(subcmd) && a:lead =~# '^-'
let results = ['--literal-pathspecs', '--no-literal-pathspecs', '--glob-pathspecs', '--noglob-pathspecs', '--icase-pathspecs', '--no-optional-locks']
elseif empty(subcmd)
let results = s:CompletableSubcommands(dir)
elseif a:0 ==# 2 && subcmd =~# '^\%(commit\|revert\|push\|fetch\|pull\|merge\|rebase\)$'
let cmdline = substitute(a:1, '\u\w*\([! ] *\)' . subcmd, 'G' . subcmd, '')
@@ -3845,7 +3991,7 @@ function! s:StatusCommand(line1, line2, range, count, bang, mods, reg, arg, args
let dir = a:0 ? s:Dir(a:1) : s:Dir()
exe s:DirCheck(dir)
try
let mods = s:Mods(a:mods, &splitbelow ? 'botright' : 'topleft')
let mods = s:Mods(a:mods, 'Edge')
let file = fugitive#Find(':', dir)
let arg = ' +setl\ foldmarker=<<<<<<<<,>>>>>>>>\|let\ w:fugitive_status=FugitiveGitDir() ' .
\ s:fnameescape(file)
@@ -3910,7 +4056,7 @@ function! s:StageSeek(info, fallback) abort
if empty(info.heading)
return a:fallback
endif
let line = search('^' . escape(info.heading, '^$.*[]~\') . ' (\d\+)$', 'wn')
let line = search('^' . escape(info.heading, '^$.*[]~\') . ' (\d\++\=)$', 'wn')
if !line
for section in get({'Staged': ['Unstaged', 'Untracked'], 'Unstaged': ['Untracked', 'Staged'], 'Untracked': ['Unstaged', 'Staged']}, info.section, [])
let line = search('^' . section, 'wn')
@@ -3978,7 +4124,7 @@ function! s:DoAutocmdChanged(dir) abort
finally
unlet! g:fugitive_event g:fugitive_result
" Force statusline reload with the buffer's Git dir
let &ro = &ro
let &l:ro = &l:ro
endtry
return ''
endfunction
@@ -3989,7 +4135,7 @@ function! s:ReloadStatusBuffer(...) abort
endif
let original_lnum = a:0 ? a:1 : line('.')
let info = s:StageInfo(original_lnum)
call fugitive#BufReadStatus()
call fugitive#BufReadStatus(0)
call setpos('.', [0, s:StageSeek(info, original_lnum), 1, 0])
return ''
endfunction
@@ -4093,7 +4239,8 @@ endfunction
augroup fugitive_status
autocmd!
autocmd BufWritePost * call fugitive#DidChange(+expand('<abuf>'))
autocmd BufWritePost * call fugitive#DidChange(+expand('<abuf>'), 0)
autocmd User FileChmodPost,FileUnlinkPost call fugitive#DidChange(+expand('<abuf>'), 0)
autocmd ShellCmdPost,ShellFilterPost * nested call fugitive#DidChange(0)
autocmd BufDelete * nested
\ if getbufvar(+expand('<abuf>'), 'buftype') ==# 'terminal' |
@@ -4139,7 +4286,7 @@ function! s:StageInfo(...) abort
let index = 0
while len(getline(slnum - 1)) && empty(heading)
let slnum -= 1
let heading = matchstr(getline(slnum), '^\u\l\+.\{-\}\ze (\d\+)$')
let heading = matchstr(getline(slnum), '^\u\l\+.\{-\}\ze (\d\++\=)$')
if empty(heading) && getline(slnum) !~# '^[ @\+-]'
let index += 1
endif
@@ -4194,7 +4341,7 @@ function! s:Selection(arg1, ...) abort
let index = 0
while empty(heading)
let slnum -= 1
let heading = matchstr(getline(slnum), '^\u\l\+.\{-\}\ze (\d\+)$')
let heading = matchstr(getline(slnum), '^\u\l\+.\{-\}\ze (\d\++\=)$')
if empty(heading) && getline(slnum) !~# '^[ @\+-]'
let index += 1
endif
@@ -4214,7 +4361,7 @@ function! s:Selection(arg1, ...) abort
let lnum = first - (arg1 == flnum ? 0 : 1)
let root = s:Tree() . '/'
while lnum <= last
let heading = matchstr(line, '^\u\l\+\ze.\{-\}\ze (\d\+)$')
let heading = matchstr(line, '^\u\l\+\ze.\{-\}\ze (\d\++\=)$')
if len(heading)
let template.heading = heading
let template.section = matchstr(heading, '^\u\l\+')
@@ -4428,8 +4575,8 @@ endfunction
function! s:PreviousItem(count) abort
for i in range(a:count)
if !search(s:item_pattern, 'Wbe') && getline('.') !~# s:item_pattern
call search('^commit ', 'Wbe')
if !search(s:item_pattern, 'Wb') && getline('.') !~# s:item_pattern
call search('^commit ', 'Wb')
endif
endfor
call s:StageReveal()
@@ -4568,7 +4715,7 @@ function! s:StageInline(mode, ...) abort
let diff = []
let index = 0
let start = -1
for line in b:fugitive_diff[info.section]
for line in fugitive#Wait(b:fugitive_diff[info.section]).stdout
if mode ==# 'await' && line[0] ==# '@'
let mode = 'capture'
endif
@@ -4692,10 +4839,11 @@ function! s:StageApply(info, reverse, extra) abort
endif
let i = b:fugitive_expanded[info.section][info.filename][0]
let head = []
while get(b:fugitive_diff[info.section], i, '@') !~# '^@'
let line = b:fugitive_diff[info.section][i]
let diff_lines = fugitive#Wait(b:fugitive_diff[info.section]).stdout
while get(diff_lines, i, '@') !~# '^@'
let line = diff_lines[i]
if line ==# '--- /dev/null'
call add(head, '--- ' . get(b:fugitive_diff[info.section], i + 1, '')[4:-1])
call add(head, '--- ' . get(diff_lines, i + 1, '')[4:-1])
elseif line !~# '^new file '
call add(head, line)
endif
@@ -4720,9 +4868,13 @@ function! s:StageDelete(lnum1, lnum2, count) abort
let err = ''
let did_conflict_err = 0
let reset_commit = matchstr(getline(a:lnum1), '^Un\w\+ \%(to\| from\) \zs\S\+')
try
for info in s:Selection(a:lnum1, a:lnum2)
if empty(info.paths)
if len(info.commit)
let reset_commit = info.commit . '^'
endif
continue
endif
let sub = get(get(get(b:fugitive_files, info.section, {}), info.filename, {}), 'submodule')
@@ -4788,15 +4940,14 @@ function! s:StageDelete(lnum1, lnum2, count) abort
let err .= '|echoerr ' . string(v:exception)
endtry
if empty(restore)
if len(reset_commit) && empty(err)
call feedkeys(':Git reset ' . reset_commit)
endif
return err[1:-1]
endif
exe s:ReloadStatus()
call s:StageReveal()
if len(restore)
return 'checktime|redraw|echomsg ' . string('To restore, ' . join(restore, '|')) . err
else
return 'checktime|redraw' . err
endif
return 'checktime|redraw|echomsg ' . string('To restore, ' . join(restore, '|')) . err
endfunction
function! s:StageIgnore(lnum1, lnum2, count) abort
@@ -4972,11 +5123,11 @@ function! s:StagePatch(lnum1,lnum2) abort
for lnum in range(a:lnum1,a:lnum2)
let info = s:StageInfo(lnum)
if empty(info.paths) && info.section ==# 'Staged'
return 'Git reset --patch'
return 'tab Git reset --patch'
elseif empty(info.paths) && info.section ==# 'Unstaged'
return 'Git add --patch'
return 'tab Git add --patch'
elseif empty(info.paths) && info.section ==# 'Untracked'
return 'Git add --interactive'
return 'tab Git add --interactive'
elseif empty(info.paths)
continue
endif
@@ -4994,10 +5145,10 @@ function! s:StagePatch(lnum1,lnum2) abort
call s:TreeChomp(['add', '--intent-to-add', '--'] + intend)
endif
if !empty(add)
execute "Git add --patch -- ".join(map(add,'s:fnameescape(v:val)'))
execute "tab Git add --patch -- ".join(map(add,'fnameescape(v:val)'))
endif
if !empty(reset)
execute "Git reset --patch -- ".join(map(reset,'s:fnameescape(v:val)'))
execute "tab Git reset --patch -- ".join(map(reset,'fnameescape(v:val)'))
endif
catch /^fugitive:/
return 'echoerr ' . string(v:exception)
@@ -5082,7 +5233,7 @@ function! s:MergeSubcommand(line1, line2, range, bang, mods, options) abort
\ filereadable(fugitive#Find('.git/MERGE_MSG', a:options)) ||
\ isdirectory(fugitive#Find('.git/rebase-apply', a:options)) ||
\ !empty(s:TreeChomp([a:options.git_dir, 'diff-files', '--diff-filter=U'])))
return 'echoerr ":Git merge for loading conflicts hase been removed in favor of :Git mergetool"'
return 'echoerr ":Git merge for loading conflicts has been removed in favor of :Git mergetool"'
endif
return {}
endfunction
@@ -5531,7 +5682,7 @@ function! s:GrepSubcommand(line1, line2, range, bang, mods, options) abort
silent exe s:DoAutocmd('QuickFixCmdPost ' . event)
if quiet
let bufnr = bufnr('')
silent exe substitute(s:Mods(a:mods), '\<tab\>', '', '') (listnr < 0 ? 'c' : 'l').'open'
exe s:QuickfixOpen(listnr, a:mods)
if bufnr != bufnr('') && !a:bang
wincmd p
endif
@@ -5851,7 +6002,7 @@ function! s:BlurStatus() abort
endfunction
let s:bang_edits = {'split': 'Git', 'vsplit': 'vertical Git', 'tabedit': 'tab Git', 'pedit': 'Git!'}
function! fugitive#Open(cmd, bang, mods, arg, args) abort
function! fugitive#Open(cmd, bang, mods, arg, ...) abort
exe s:VersionCheck()
if a:bang
return 'echoerr ' . string(':G' . a:cmd . '! for temp buffer output has been replaced by :' . get(s:bang_edits, a:cmd, 'Git') . ' --paginate')
@@ -5891,7 +6042,7 @@ function! s:ReadPrepare(line1, count, range, mods) abort
return [pre . 'keepalt ' . mods . after . 'read', '|' . delete . 'diffupdate' . (a:count < 0 ? '|' . line('.') : '')]
endfunction
function! fugitive#ReadCommand(line1, count, range, bang, mods, arg, args) abort
function! fugitive#ReadCommand(line1, count, range, bang, mods, arg, ...) abort
exe s:VersionCheck()
if a:bang
return 'echoerr ' . string(':Gread! for temp buffer output has been replaced by :{range}Git! --paginate')
@@ -5926,7 +6077,7 @@ endfunction
" Section: :Gwrite, :Gwq
function! fugitive#WriteCommand(line1, line2, range, bang, mods, arg, args) abort
function! fugitive#WriteCommand(line1, line2, range, bang, mods, arg, ...) abort
exe s:VersionCheck()
if s:cpath(expand('%:p'), fugitive#Find('.git/COMMIT_EDITMSG')) && empty(a:arg)
return (empty($GIT_INDEX_FILE) ? 'write|bdelete' : 'wq') . (a:bang ? '!' : '')
@@ -6203,7 +6354,7 @@ function! s:IsConflicted() abort
return len(@%) && !empty(s:ChompDefault('', ['ls-files', '--unmerged', '--', expand('%:p')]))
endfunction
function! fugitive#Diffsplit(autodir, keepfocus, mods, arg, args) abort
function! fugitive#Diffsplit(autodir, keepfocus, mods, arg, ...) abort
exe s:VersionCheck()
let args = s:ArgSplit(a:arg)
let post = ''
@@ -6414,11 +6565,11 @@ function! fugitive#RenameComplete(A,L,P) abort
endif
endfunction
function! fugitive#MoveCommand(line1, line2, range, bang, mods, arg, args) abort
function! fugitive#MoveCommand(line1, line2, range, bang, mods, arg, ...) abort
return s:Move(a:bang, 0, a:arg)
endfunction
function! fugitive#RenameCommand(line1, line2, range, bang, mods, arg, args) abort
function! fugitive#RenameCommand(line1, line2, range, bang, mods, arg, ...) abort
return s:Move(a:bang, 1, a:arg)
endfunction
@@ -6444,11 +6595,11 @@ function! s:Remove(after, force) abort
endif
endfunction
function! fugitive#RemoveCommand(line1, line2, range, bang, mods, arg, args) abort
function! fugitive#RemoveCommand(line1, line2, range, bang, mods, arg, ...) abort
return s:Remove('edit', a:bang)
endfunction
function! fugitive#DeleteCommand(line1, line2, range, bang, mods, arg, args) abort
function! fugitive#DeleteCommand(line1, line2, range, bang, mods, arg, ...) abort
return s:Remove('bdelete', a:bang)
endfunction
@@ -6947,6 +7098,33 @@ function! s:BlameRehighlight() abort
endfor
endfunction
function! s:BlameMaps(is_ftplugin) abort
let ft = a:is_ftplugin
call s:Map('n', '<F1>', ':help :Git_blame<CR>', '<silent>', ft)
call s:Map('n', 'g?', ':help :Git_blame<CR>', '<silent>', ft)
if empty(mapcheck('q', 'n'))
nnoremap <buffer> <silent> q :<C-U>echoerr "fugitive: q removed in favor of gq (or :q)"<CR>
endif
call s:Map('n', 'gq', ':exe <SID>BlameQuit()<CR>', '<silent>', ft)
call s:Map('n', '<2-LeftMouse>', ':<C-U>exe <SID>BlameCommit("exe <SID>BlameLeave()<Bar>edit")<CR>', '<silent>', ft)
call s:Map('n', '<CR>', ':<C-U>exe <SID>BlameCommit("exe <SID>BlameLeave()<Bar>edit")<CR>', '<silent>', ft)
call s:Map('n', '-', ':<C-U>exe <SID>BlameJump("")<CR>', '<silent>', ft)
call s:Map('n', 's', ':<C-U>exe <SID>BlameJump("")<CR>', '<silent>', ft)
call s:Map('n', 'u', ':<C-U>exe <SID>BlameJump("")<CR>', '<silent>', ft)
call s:Map('n', 'P', ':<C-U>exe <SID>BlameJump("^".v:count1)<CR>', '<silent>', ft)
call s:Map('n', '~', ':<C-U>exe <SID>BlameJump("~".v:count1)<CR>', '<silent>', ft)
call s:Map('n', 'i', ':<C-U>exe <SID>BlameCommit("exe <SID>BlameLeave()<Bar>edit")<CR>', '<silent>', ft)
call s:Map('n', 'o', ':<C-U>exe <SID>BlameCommit("split")<CR>', '<silent>', ft)
call s:Map('n', 'O', ':<C-U>exe <SID>BlameCommit("tabedit")<CR>', '<silent>', ft)
call s:Map('n', 'p', ':<C-U>exe <SID>BlameCommit("pedit")<CR>', '<silent>', ft)
call s:Map('n', '.', ":<C-U> <C-R>=substitute(<SID>BlameCommitFileLnum()[0],'^$','@','')<CR><Home>", ft)
call s:Map('n', '(', "-", ft)
call s:Map('n', ')', "+", ft)
call s:Map('n', 'A', ":<C-u>exe 'vertical resize '.(<SID>linechars('.\\{-\\}\\ze [0-9:/+-][0-9:/+ -]* \\d\\+)')+1+v:count)<CR>", '<silent>', ft)
call s:Map('n', 'C', ":<C-u>exe 'vertical resize '.(<SID>linechars('^\\S\\+')+1+v:count)<CR>", '<silent>', ft)
call s:Map('n', 'D', ":<C-u>exe 'vertical resize '.(<SID>linechars('.\\{-\\}\\ze\\d\\ze\\s\\+\\d\\+)')+1-v:count)<CR>", '<silent>', ft)
endfunction
function! fugitive#BlameFileType() abort
setlocal nomodeline
setlocal foldmethod=manual
@@ -6961,29 +7139,7 @@ function! fugitive#BlameFileType() abort
if &modifiable
return ''
endif
call s:Map('n', '<F1>', ':help :Git_blame<CR>', '<silent>')
call s:Map('n', 'g?', ':help :Git_blame<CR>', '<silent>')
if empty(mapcheck('q', 'n'))
nnoremap <buffer> <silent> q :<C-U>echoerr "fugitive: q removed in favor of gq (or :q)"<CR>
endif
call s:Map('n', 'gq', ':exe <SID>BlameQuit()<CR>', '<silent>')
call s:Map('n', '<2-LeftMouse>', ':<C-U>exe <SID>BlameCommit("exe <SID>BlameLeave()<Bar>edit")<CR>', '<silent>')
call s:Map('n', '<CR>', ':<C-U>exe <SID>BlameCommit("exe <SID>BlameLeave()<Bar>edit")<CR>', '<silent>')
call s:Map('n', '-', ':<C-U>exe <SID>BlameJump("")<CR>', '<silent>')
call s:Map('n', 's', ':<C-U>exe <SID>BlameJump("")<CR>', '<silent>')
call s:Map('n', 'u', ':<C-U>exe <SID>BlameJump("")<CR>', '<silent>')
call s:Map('n', 'P', ':<C-U>exe <SID>BlameJump("^".v:count1)<CR>', '<silent>')
call s:Map('n', '~', ':<C-U>exe <SID>BlameJump("~".v:count1)<CR>', '<silent>')
call s:Map('n', 'i', ':<C-U>exe <SID>BlameCommit("exe <SID>BlameLeave()<Bar>edit")<CR>', '<silent>')
call s:Map('n', 'o', ':<C-U>exe <SID>BlameCommit("split")<CR>', '<silent>')
call s:Map('n', 'O', ':<C-U>exe <SID>BlameCommit("tabedit")<CR>', '<silent>')
call s:Map('n', 'p', ':<C-U>exe <SID>BlameCommit("pedit")<CR>', '<silent>')
call s:Map('n', '.', ":<C-U> <C-R>=substitute(<SID>BlameCommitFileLnum()[0],'^$','@','')<CR><Home>")
call s:Map('n', '(', "-")
call s:Map('n', ')', "+")
call s:Map('n', 'A', ":<C-u>exe 'vertical resize '.(<SID>linechars('.\\{-\\}\\ze [0-9:/+-][0-9:/+ -]* \\d\\+)')+1+v:count)<CR>", '<silent>')
call s:Map('n', 'C', ":<C-u>exe 'vertical resize '.(<SID>linechars('^\\S\\+')+1+v:count)<CR>", '<silent>')
call s:Map('n', 'D', ":<C-u>exe 'vertical resize '.(<SID>linechars('.\\{-\\}\\ze\\d\\ze\\s\\+\\d\\+)')+1-v:count)<CR>", '<silent>')
call s:BlameMaps(1)
endfunction
augroup fugitive_blame
@@ -7020,7 +7176,7 @@ function! s:BrowserOpen(url, mods, echo_copy) abort
endif
endfunction
function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abort
function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, ...) abort
exe s:VersionCheck()
let dir = s:Dir()
try
@@ -7061,12 +7217,10 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
for line in readfile(result.file, '', 4096)
let rev = s:fnameescape(matchstr(line, '\<https\=://[^[:space:]<>]*[^[:space:]<>.,;:"''!?]'))
if len(rev)
break
return s:BrowserOpen(rev, a:mods, a:bang)
endif
endfor
if empty(rev)
return 'echoerr ' . string('fugitive: no URL found in output of :Git')
endif
return 'echoerr ' . string('fugitive: no URL found in output of :Git')
endif
exe s:DirCheck(dir)
if empty(expanded)
@@ -7117,6 +7271,7 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
let type = 'blob'
endif
endif
let config = fugitive#Config(dir)
if type ==# 'tree' && !empty(path)
let path = s:sub(path, '/\=$', '/')
endif
@@ -7148,13 +7303,13 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
let branch = FugitiveHead(0, dir)
endif
if !empty(branch)
let r = FugitiveConfigGet('branch.'.branch.'.remote', dir)
let m = FugitiveConfigGet('branch.'.branch.'.merge', dir)[11:-1]
let r = FugitiveConfigGet('branch.'.branch.'.remote', config)
let m = FugitiveConfigGet('branch.'.branch.'.merge', config)[11:-1]
if r ==# '.' && !empty(m)
let r2 = FugitiveConfigGet('branch.'.m.'.remote', dir)
let r2 = FugitiveConfigGet('branch.'.m.'.remote', config)
if r2 !~# '^\.\=$'
let r = r2
let m = FugitiveConfigGet('branch.'.m.'.merge', dir)[11:-1]
let m = FugitiveConfigGet('branch.'.m.'.merge', config)[11:-1]
endif
endif
if empty(remote)
@@ -7162,7 +7317,7 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
endif
if r ==# '.' || r ==# remote
let remote_ref = 'refs/remotes/' . remote . '/' . branch
if FugitiveConfigGet('push.default', dir) ==# 'upstream' ||
if FugitiveConfigGet('push.default', config) ==# 'upstream' ||
\ !filereadable(FugitiveFind('.git/' . remote_ref, dir)) && empty(s:ChompDefault('', ['rev-parse', '--verify', remote_ref, '--'], dir))
let merge = m
if path =~# '^\.git/refs/heads/.'
@@ -7218,12 +7373,12 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
endif
if empty(remote) || remote ==# '.'
let remote = s:Remote(dir)
let remote = s:RemoteDefault(config)
endif
if remote =~# ':'
let remote_url = remote
else
let remote_url = fugitive#RemoteUrl(remote, dir)
let remote_url = fugitive#RemoteUrl(remote, config)
endif
let raw = empty(remote_url) ? remote : remote_url
let git_dir = s:GitDir(dir)
@@ -7634,6 +7789,15 @@ function! s:cfile() abort
let ref = matchstr(getline('.'),'\x\{40,\}')
echoerr "warning: unknown context ".matchstr(getline('.'),'^\l*')
elseif getline('.') =~# '^[A-Z]\d*\t\S' && len(myhash)
let files = split(getline('.'), "\t")[1:-1]
let ref = 'b/' . files[-1]
if getline('.') =~# '^D'
let ref = 'a/' . files[0]
elseif getline('.') !~# '^A'
let dcmds = ['', 'Gdiffsplit! >' . myhash . '^:' . fnameescape(files[0])]
endif
elseif getline('.') =~# '^[+-]\{3\} [abciow12]\=/'
let ref = getline('.')[4:]
@@ -7725,9 +7889,15 @@ function! s:GF(mode) abort
return 'echoerr ' . string(v:exception)
endtry
if len(results) > 1
return 'G' . a:mode .
let cmd = 'G' . a:mode .
\ (empty(results[1]) ? '' : ' +' . escape(results[1], ' |')) . ' ' .
\ fnameescape(results[0]) . join(map(results[2:-1], '"|" . v:val'), '')
\ fnameescape(results[0])
let tail = join(map(results[2:-1], '"|" . v:val'), '')
if a:mode ==# 'pedit' && len(tail)
return cmd . '|wincmd P|exe ' . string(tail[1:-1]) . '|wincmd p'
else
return cmd . tail
endif
elseif len(results) && len(results[0])
return 'G' . a:mode . ' ' . s:fnameescape(results[0])
else

View File

@@ -318,6 +318,7 @@ dv Perform a |:Gvdiffsplit| on the file under the cursor.
*fugitive_ds* *fugitive_dh*
ds Perform a |:Ghdiffsplit| on the file under the cursor.
dh
*fugitive_dq*
dq Close all but one diff buffer, and |:diffoff|! the
last one.
@@ -656,6 +657,10 @@ FugitiveIndex After loading the |fugitive-summary| buffer.
FugitivePager After loading a temp file created by a command like
:Git --paginate or :Git blame.
*User_FugitiveEditor*
FugitiveEditor After a :Git command (e.g., :Git commit) edits a file
(e.g., the commit message).
*User_FugitiveChanged*
FugitiveChanged After any event which can potentially change the
repository, for example, any invocation of |:Git|.

View File

@@ -1,6 +1,6 @@
" fugitive.vim - A Git wrapper so awesome, it should be illegal
" Maintainer: Tim Pope <http://tpo.pe/>
" Version: 3.4
" Version: 3.5
" GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim
if exists('g:loaded_fugitive')
@@ -210,6 +210,23 @@ function! FugitiveRemoteUrl(...) abort
return call('fugitive#RemoteUrl', a:000)
endfunction
" FugitiveRemote() returns a data structure parsed from the remote URL.
" For example, for remote URL is "https://me@example.com:1234/repo.git",
" the returned dictionary will contain the following:
"
" * "scheme": "https"
" * "authority": "user@example.com:1234"
" * "path": "/repo.git" (for SSH URLs this may be a relative path)
" * "host": "example.com:1234"
" * "hostname": "example.com"
" * "port": "1234"
" * "user": "me"
" * "path": "/repo.git"
" * "url": "https://me@example.com:1234/repo.git"
function! FugitiveRemote(...) abort
return call('fugitive#Remote', a:000)
endfunction
" FugitiveDidChange() triggers a FugitiveChanged event and reloads the summary
" buffer for the current or given buffer number's repository. You can also
" give the result of a FugitiveExecute() and that context will be made
@@ -259,7 +276,7 @@ function! FugitivePath(...) abort
endfunction
function! FugitiveStatusline(...) abort
if empty(get(b:, 'git_dir', ''))
if empty(FugitiveGitDir(bufnr('')))
return ''
endif
return fugitive#Statusline()
@@ -420,6 +437,9 @@ function! FugitiveDetect(...) abort
if exists('b:git_dir') && b:git_dir =~# '^$\|' . s:bad_git_dir
unlet b:git_dir
endif
if a:0 > 1 && a:2 is# 0 && !exists('#User#Fugitive')
return ''
endif
if !exists('b:git_dir')
let b:git_dir = FugitiveExtractGitDir(a:0 ? a:1 : bufnr(''))
endif
@@ -475,7 +495,7 @@ function! s:ProjectionistDetect() abort
if exists('+shellslash') && !&shellslash
let base = tr(base, '/', '\')
endif
let file = FugitiveCommonDir(dir) . '/info/projections.json'
let file = FugitiveFind('.git/info/projections.json', dir)
if filereadable(file)
call projectionist#append(base, file)
endif
@@ -529,50 +549,50 @@ exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Gllog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "l")'
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete GlLog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "l")'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Ge exe fugitive#Open("edit<bang>", 0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gedit exe fugitive#Open("edit<bang>", 0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#ReadComplete Gpedit exe fugitive#Open("pedit", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_other '-complete=customlist,fugitive#ReadComplete Gsplit exe fugitive#Open((<count> > 0 ? <count> : "").(<count> ? "split" : "edit"), <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_other '-complete=customlist,fugitive#ReadComplete Gvsplit exe fugitive#Open((<count> > 0 ? <count> : "").(<count> ? "vsplit" : "edit!"), <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_tabs '-complete=customlist,fugitive#ReadComplete Gtabedit exe fugitive#Open((<count> >= 0 ? <count> : "")."tabedit", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Ge exe fugitive#Open("edit<bang>", 0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gedit exe fugitive#Open("edit<bang>", 0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#ReadComplete Gpedit exe fugitive#Open("pedit", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_other '-complete=customlist,fugitive#ReadComplete Gsplit exe fugitive#Open((<count> > 0 ? <count> : "").(<count> ? "split" : "edit"), <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_other '-complete=customlist,fugitive#ReadComplete Gvsplit exe fugitive#Open((<count> > 0 ? <count> : "").(<count> ? "vsplit" : "edit!"), <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -range=-1' s:addr_tabs '-complete=customlist,fugitive#ReadComplete Gtabedit exe fugitive#Open((<count> >= 0 ? <count> : "")."tabedit", <bang>0, "<mods>", <q-args>)'
if exists(':Gr') != 2
exe 'command! -bar -bang -nargs=* -range=-1 -complete=customlist,fugitive#ReadComplete Gr exe fugitive#ReadCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -range=-1 -complete=customlist,fugitive#ReadComplete Gr exe fugitive#ReadCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
endif
exe 'command! -bar -bang -nargs=* -range=-1 -complete=customlist,fugitive#ReadComplete Gread exe fugitive#ReadCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -range=-1 -complete=customlist,fugitive#ReadComplete Gread exe fugitive#ReadCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gdiffsplit exe fugitive#Diffsplit(1, <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Ghdiffsplit exe fugitive#Diffsplit(0, <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gvdiffsplit exe fugitive#Diffsplit(0, <bang>0, "vertical <mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gdiffsplit exe fugitive#Diffsplit(1, <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Ghdiffsplit exe fugitive#Diffsplit(0, <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gvdiffsplit exe fugitive#Diffsplit(0, <bang>0, "vertical <mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gw exe fugitive#WriteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwrite exe fugitive#WriteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwq exe fugitive#WqCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gw exe fugitive#WriteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwrite exe fugitive#WriteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwq exe fugitive#WqCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=0 GRemove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=0 GDelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject GMove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete GRename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=0 GRemove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=0 GDelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject GMove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete GRename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
if exists(':Gremove') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=0 Gremove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=0 Gremove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Gremove is deprecated in favor of :GRemove"|echohl NONE'
endif
if exists(':Gdelete') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=0 Gdelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=0 Gdelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Gdelete is deprecated in favor of :GDelete"|echohl NONE'
endif
if exists(':Gmove') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject Gmove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject Gmove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Gmove is deprecated in favor of :GMove"|echohl NONE'
endif
if exists(':Grename') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete Grename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete Grename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echomsg ":Grename is deprecated in favor of :GRename"|echohl NONE'
endif
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject GBrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject GBrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
if exists(':Gbrowse') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|if <bang>1|redraw!|endif|echohl WarningMSG|echomsg ":Gbrowse is deprecated in favor of :GBrowse"|echohl NONE'
endif
@@ -600,8 +620,9 @@ let g:io_fugitive = {
augroup fugitive
autocmd!
autocmd BufNewFile,BufReadPost * call FugitiveDetect(expand('<amatch>:p'))
autocmd FileType netrw call FugitiveDetect(fnamemodify(get(b:, 'netrw_curdir', expand('<amatch>')), ':p'))
autocmd BufNewFile,BufReadPost *
\ call FugitiveDetect(expand('<amatch>:p'), 0)
autocmd FileType netrw call FugitiveDetect(fnamemodify(get(b:, 'netrw_curdir', expand('<afile>:p')), ':p'), 1)
autocmd FileType git
\ call fugitive#MapCfile()
@@ -624,7 +645,7 @@ augroup fugitive
autocmd BufReadCmd index{,.lock}
\ if FugitiveIsGitDir(expand('<amatch>:p:h')) |
\ let b:git_dir = s:Slash(expand('<amatch>:p:h')) |
\ exe fugitive#BufReadStatus() |
\ exe fugitive#BufReadStatus(v:cmdbang) |
\ elseif filereadable(expand('<amatch>')) |
\ silent doautocmd BufReadPre |
\ keepalt read <amatch> |
@@ -656,15 +677,12 @@ endif
let s:nowait = v:version >= 704 ? '<nowait>' : ''
function! s:Map(mode, lhs, rhs, ...) abort
for mode in split(a:mode, '\zs')
let flags = (a:0 ? a:1 : '') . (a:rhs =~# '<Plug>' ? '' : '<script>')
let head = a:lhs
let tail = ''
let keys = get(g:, mode.'remap', {})
if type(keys) == type([])
return
endif
function! s:Map(mode, lhs, rhs, flags) abort
let flags = a:flags . (a:rhs =~# '<Plug>' ? '' : '<script>')
let head = a:lhs
let tail = ''
let keys = get(g:, a:mode.'remap', {})
if len(keys) && type(keys) == type({})
while !empty(head)
if has_key(keys, head)
let head = keys[head]
@@ -676,10 +694,10 @@ function! s:Map(mode, lhs, rhs, ...) abort
let tail = matchstr(head, '<[^<>]*>$\|.$') . tail
let head = substitute(head, '<[^<>]*>$\|.$', '', '')
endwhile
if flags !~# '<unique>' || empty(mapcheck(head.tail, mode))
exe mode.'map' s:nowait flags head.tail a:rhs
endif
endfor
endif
if flags !~# '<unique>' || empty(mapcheck(head.tail, a:mode))
exe a:mode.'map' s:nowait flags head.tail a:rhs
endif
endfunction
call s:Map('c', '<C-R><C-G>', 'fnameescape(fugitive#Object(@%))', '<expr>')

View File

@@ -13,10 +13,10 @@ syn match fugitiveHeader /^Pull:\|^Rebase:\|^Merge:\|^Push:/ nextgroup=fugitiveS
syn match fugitiveHelpHeader /^Help:/ nextgroup=fugitiveHelpTag skipwhite
syn match fugitiveHelpTag /\S\+/ contained
syn region fugitiveSection start=/^\%(.*(\d\+)$\)\@=/ contains=fugitiveHeading end=/^$/
syn region fugitiveSection start=/^\%(.*(\d\++\=)$\)\@=/ contains=fugitiveHeading end=/^$/
syn cluster fugitiveSection contains=fugitiveSection
syn match fugitiveHeading /^[A-Z][a-z][^:]*\ze (\d\+)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite
syn match fugitiveCount /(\d\+)/hs=s+1,he=e-1 contained
syn match fugitiveHeading /^[A-Z][a-z][^:]*\ze (\d\++\=)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite
syn match fugitiveCount /(\d\++\=)/hs=s+1,he=e-1 contained
syn match fugitivePreposition /\<\%([io]nto\|from\|to\|Rebasing\%( detached\)\=\)\>/ transparent contained nextgroup=fugitiveHash,fugitiveSymbolicRef skipwhite
syn match fugitiveInstruction /^\l\l\+\>/ contained containedin=@fugitiveSection nextgroup=fugitiveHash skipwhite
@@ -30,10 +30,10 @@ syn match fugitiveHash /\S\@<!\x\{4,\}\S\@!/ contained
syn region fugitiveHunk start=/^\%(@@\+ -\)\@=/ end=/^\%([A-Za-z?@]\|$\)\@=/ contains=diffLine,diffRemoved,diffAdded,diffNoEOL containedin=@fugitiveSection fold
for s:section in ['Untracked', 'Unstaged', 'Staged']
exe 'syn region fugitive' . s:section . 'Section start=/^\%(' . s:section . ' .*(\d\+)$\)\@=/ contains=fugitive' . s:section . 'Heading end=/^$/'
exe 'syn region fugitive' . s:section . 'Section start=/^\%(' . s:section . ' .*(\d\++\=)$\)\@=/ contains=fugitive' . s:section . 'Heading end=/^$/'
exe 'syn match fugitive' . s:section . 'Modifier /^[MADRCU?] / contained containedin=fugitive' . s:section . 'Section'
exe 'syn cluster fugitiveSection add=fugitive' . s:section . 'Section'
exe 'syn match fugitive' . s:section . 'Heading /^[A-Z][a-z][^:]*\ze (\d\+)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite'
exe 'syn match fugitive' . s:section . 'Heading /^[A-Z][a-z][^:]*\ze (\d\++\=)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite'
endfor
unlet s:section