49 Commits

Author SHA1 Message Date
Tim Pope
2685422e17 Attempt to catch overlapping status reloads 2021-10-16 11:14:15 -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 314 additions and 173 deletions

View File

@@ -125,7 +125,15 @@ function! s:Mods(mods, ...) abort
let mods = substitute(a:mods, '\C<mods>', '', '') let mods = substitute(a:mods, '\C<mods>', '', '')
let mods = mods =~# '\S$' ? mods . ' ' : mods let mods = mods =~# '\S$' ? mods . ' ' : mods
if a:0 && mods !~# '\<\%(aboveleft\|belowright\|leftabove\|rightbelow\|topleft\|botright\|tab\)\>' 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 endif
return substitute(mods, '\s\+', ' ', 'g') return substitute(mods, '\s\+', ' ', 'g')
endfunction endfunction
@@ -219,7 +227,7 @@ function! s:Map(mode, lhs, rhs, ...) abort
let head = substitute(head, '<[^<>]*>$\|.$', '', '') let head = substitute(head, '<[^<>]*>$\|.$', '', '')
endwhile endwhile
if !skip && (flags !~# '<unique>' || empty(mapcheck(head.tail, mode))) if !skip && (flags !~# '<unique>' || empty(mapcheck(head.tail, mode)))
call add(maps, mode.'map <buffer>' . s:nowait . flags . ' ' . head.tail . ' ' . a:rhs) call add(maps, mode.'map <buffer>' . s:nowait . substitute(flags, '<unique>', '', '') . ' ' . head.tail . ' ' . a:rhs)
if a:0 > 1 if a:0 > 1
let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'exe') . let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'exe') .
\ '|sil! exe "' . mode . 'unmap <buffer> ' . head.tail . '"' \ '|sil! exe "' . mode . 'unmap <buffer> ' . head.tail . '"'
@@ -255,6 +263,9 @@ function! fugitive#Wait(job_or_jobs, ...) abort
if exists('*jobwait') if exists('*jobwait')
call map(copy(jobs), 'chanclose(v:val, "stdin")') call map(copy(jobs), 'chanclose(v:val, "stdin")')
call jobwait(jobs, timeout_ms) call jobwait(jobs, timeout_ms)
if len(jobs) && has('nvim-0.5')
sleep 1m
endif
else else
let sleep = has('patch-8.2.2366') ? 'sleep! 1m' : 'sleep 1m' let sleep = has('patch-8.2.2366') ? 'sleep! 1m' : 'sleep 1m'
for job in jobs for job in jobs
@@ -420,7 +431,7 @@ function! s:UserCommandList(...) abort
if empty(tree) if empty(tree)
call add(git, '--git-dir=' . FugitiveGitPath(dir)) call add(git, '--git-dir=' . FugitiveGitPath(dir))
else else
if !s:cpath(tree . '/.git', dir) if !s:cpath(tree . '/.git', dir) || len($GIT_DIR)
call add(git, '--git-dir=' . FugitiveGitPath(dir)) call add(git, '--git-dir=' . FugitiveGitPath(dir))
endif endif
if !s:cpath(tree, getcwd()) 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)) let a:env['GIT_INDEX_FILE'] = FugitiveGitPath(fugitive#Find('.git/index', a:dir))
endif endif
endif endif
if len($GIT_WORK_TREE)
let a:env['GIT_WORK_TREE'] = '.'
endif
endfunction endfunction
let s:prepare_env = { let s:prepare_env = {
@@ -626,8 +640,10 @@ function! fugitive#PrepareDirEnvGitFlagsArgs(...) abort
if !exists('dir') if !exists('dir')
let dir = s:Dir() let dir = s:Dir()
endif endif
if !has_key(env, 'GIT_INDEX_FILE') call extend(autoenv, env)
call s:PrepareEnv(autoenv, dir) call s:PrepareEnv(autoenv, dir)
if len($GPG_TTY) && !has_key(autoenv, 'GPG_TTY')
let autoenv.GPG_TTY = ''
endif endif
call s:PreparePathArgs(cmd, dir, literal_pathspecs, explicit_pathspec_option) 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] : []] 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 else
let dict.cwd = FugitiveVimPath(tree) let dict.cwd = FugitiveVimPath(tree)
call extend(cmd, ['-C', FugitiveGitPath(tree)], 'keep') 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') call extend(cmd, ['--git-dir=' . FugitiveGitPath(dir)], 'keep')
endif endif
endif endif
@@ -740,7 +756,7 @@ function! s:BuildShell(dir, env, git, args) abort
call insert(cmd, '--git-dir=' . FugitiveGitPath(a:dir)) call insert(cmd, '--git-dir=' . FugitiveGitPath(a:dir))
else else
call extend(cmd, ['-C', FugitiveGitPath(tree)], 'keep') 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') call extend(cmd, ['--git-dir=' . FugitiveGitPath(a:dir)], 'keep')
endif endif
endif endif
@@ -1108,7 +1124,7 @@ endfunction
call s:add_methods('config', ['GetAll', 'Get', 'GetRegexp']) 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 head = FugitiveHead(0, a:dir)
let remote = len(head) ? FugitiveConfigGet('branch.' . head . '.remote', a:dir) : '' let remote = len(head) ? FugitiveConfigGet('branch.' . head . '.remote', a:dir) : ''
let i = 10 let i = 10
@@ -1220,7 +1236,7 @@ let s:remote_headers = {}
function! fugitive#RemoteHttpHeaders(remote) abort function! fugitive#RemoteHttpHeaders(remote) abort
let remote = type(a:remote) ==# type({}) ? get(a:remote, 'remote', '') : a:remote 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 {} return {}
endif endif
if !has_key(s:remote_headers, remote) if !has_key(s:remote_headers, remote)
@@ -1234,57 +1250,105 @@ function! fugitive#RemoteHttpHeaders(remote) abort
return s:remote_headers[remote] return s:remote_headers[remote]
endfunction endfunction
function! fugitive#ResolveRemote(remote) abort function! s:UrlParse(url) abort
let scp_authority = matchstr(a:remote, '^[^:/]\+\ze:\%(//\)\@!') let scp_authority = matchstr(a:url, '^[^:/]\+\ze:\%(//\)\@!')
if len(scp_authority) && !(has('win32') && scp_authority =~# '^\a:[\/]') if len(scp_authority) && !(has('win32') && scp_authority =~# '^\a:[\/]')
let path = strpart(a:remote, len(scp_authority) + 1) let url = {'scheme': 'ssh', 'authority': scp_authority,
let authority = fugitive#SshHostAlias(scp_authority) \ 'path': strpart(a:url, len(scp_authority) + 1)}
if path =~# '^/' elseif empty(a:url)
return 'ssh://' . authority . path let url = {'scheme': '', 'authority': '', 'path': ''}
elseif path =~# '^\~' else
return 'ssh://' . authority . '/' . path let match = matchlist(a:url, '^\([[:alnum:].+-]\+\)://\([^/]*\)\(/.*\)\=\%(#\|$\)')
elseif authority !~# ':' if empty(match)
return authority . ':' . path 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 endif
elseif a:remote =~# '^https\=://' endif
let headers = fugitive#RemoteHttpHeaders(a:remote) if (url.scheme ==# 'ssh' || url.scheme ==# 'git') && url.path[0:1] ==# '/~'
let url.path = strpart(url.path, 1)
endif
return url
endfunction
function! s:ResolveRemote(url) abort
let remote = s:UrlParse(a:url)
if remote.scheme =~# '^https\=$'
let headers = fugitive#RemoteHttpHeaders(remote.scheme . '://' . remote.authority . remote.path)
let loc = matchstr(get(headers, 'location', ''), '^https\=://.\{-\}\ze/info/refs?') let loc = matchstr(get(headers, 'location', ''), '^https\=://.\{-\}\ze/info/refs?')
if len(loc) if len(loc)
return loc let remote = s:UrlParse(loc)
else
let remote.http_headers = headers
endif endif
elseif a:remote =~# '^ssh://' elseif remote.scheme ==# 'ssh'
let authority = matchstr(a:remote, '[^/?#]*', 6) let remote.authority = fugitive#SshHostAlias(remote.authority)
return 'ssh://' . fugitive#SshHostAlias(authority) . strpart(a:remote, 6 + len(authority)) endif
return remote
endfunction
function! fugitive#ResolveRemote(url) abort
let remote = s:ResolveRemote(a:url)
if remote.scheme ==# 'file' || remote.scheme ==# ''
return remote.path
elseif remote.path =~# '^/'
return remote.scheme . '://' . remote.authority . remote.path
elseif remote.path =~# '^\~'
return remote.scheme . '://' . remote.authority . '/' . remote.path
elseif remote.scheme ==# 'ssh' && remote.authority !~# ':'
return remote.authority . ':' . remote.path
else
return a:url
endif endif
return a:remote
endfunction endfunction
function! s:ConfigLengthSort(i1, i2) abort function! s:ConfigLengthSort(i1, i2) abort
return len(a:i2[0]) - len(a:i1[0]) return len(a:i2[0]) - len(a:i1[0])
endfunction endfunction
function! fugitive#RemoteUrl(...) abort function! s:RemoteParseArgs(args) abort
let args = a:000 " Extract ':noresolve' style flags and an optional callback
if a:0 && (type(a:1) !=# type('') || a:1 =~# '^/\|^\a:[\\/]' && get(a:, 2, '') !~# '^/\|^\a:[\\/]') let args = []
let config = fugitive#Config(a:1) let flags = []
let args = a:000[1:-1] let cb = copy(a:args)
if type(a:1) ==# type({}) && has_key(a:1, 'remote_name') && (type(get(args, 0, 0)) !=# type('') || args[0] =~# '^:') while len(cb)
call insert(args, a:1.remote_name) 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 endif
elseif a:0 > 1 && a:2 !~# '^:' endwhile
let config = fugitive#Config(a:2)
let args = [a:1] + a:000[2:-1] " 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 else
let config = fugitive#Config() let dir_or_config = args[0]
let args = copy(a:000) let remote = args[1]
endif endif
if empty(args) || args[0] =~# '^:' return [dir_or_config, remote, flags, cb]
let url = s:Remote(config) endfunction
elseif args[0] =~# '^\.\=$'
call remove(args, 0) function! fugitive#RemoteUrl(...) abort
let url = s:Remote(config) let [dir_or_config, url, flags, cb] = s:RemoteParseArgs(a:000)
else let config = fugitive#Config(dir_or_config)
let url = remove(args, 0) if url =~# '^\.\=$'
let url = s:RemoteDefault(config)
endif endif
if url ==# '.git' if url ==# '.git'
let url = s:GitDir(config) let url = s:GitDir(config)
@@ -1304,7 +1368,7 @@ function! fugitive#RemoteUrl(...) abort
break break
endif endif
endfor endfor
if index(args, 1) < 0 && index(args, get(v:, 'true', 1)) < 0 && index(args, ':noresolve') < 0 if index(flags, 1) < 0 && index(flags, get(v:, 'true', 1)) < 0 && index(flags, ':noresolve') < 0
let url = fugitive#ResolveRemote(url) let url = fugitive#ResolveRemote(url)
endif endif
return url return url
@@ -1336,15 +1400,19 @@ function! s:QuickfixCreate(nr, opts) abort
endif endif
endfunction 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 function! s:QuickfixStream(nr, event, title, cmd, first, mods, callback, ...) abort
call s:BlurStatus() call s:BlurStatus()
let mods = s:Mods(a:mods)
let opts = {'title': a:title, 'context': {'items': []}} let opts = {'title': a:title, 'context': {'items': []}}
call s:QuickfixCreate(a:nr, opts) call s:QuickfixCreate(a:nr, opts)
let event = (a:nr < 0 ? 'c' : 'l') . 'fugitive-' . a:event let event = (a:nr < 0 ? 'c' : 'l') . 'fugitive-' . a:event
silent exe s:DoAutocmd('QuickFixCmdPre ' . event) silent exe s:DoAutocmd('QuickFixCmdPre ' . event)
let winnr = winnr() let winnr = winnr()
exe a:nr < 0 ? 'copen' : 'lopen' exe s:QuickfixOpen(a:nr, a:mods)
if winnr != winnr() if winnr != winnr()
wincmd p wincmd p
endif endif
@@ -1359,7 +1427,7 @@ function! s:QuickfixStream(nr, event, title, cmd, first, mods, callback, ...) ab
call extend(opts.context.items, contexts) call extend(opts.context.items, contexts)
unlet contexts unlet contexts
call s:QuickfixSet(a:nr, remove(buffer, 0, -1), 'a') call s:QuickfixSet(a:nr, remove(buffer, 0, -1), 'a')
if mods !~# '\<silent\>' if a:mods !~# '\<silent\>'
redraw redraw
endif endif
endif endif
@@ -1371,7 +1439,7 @@ function! s:QuickfixStream(nr, event, title, cmd, first, mods, callback, ...) ab
silent exe s:DoAutocmd('QuickFixCmdPost ' . event) silent exe s:DoAutocmd('QuickFixCmdPost ' . event)
if a:first && len(s:QuickfixGet(a:nr)) if a:first && len(s:QuickfixGet(a:nr))
return mods . (a:nr < 0 ? 'cfirst' : 'lfirst') return (a:nr < 0 ? 'cfirst' : 'lfirst')
else else
return 'exe' return 'exe'
endif endif
@@ -1868,7 +1936,7 @@ endfunction
function! s:Expand(rev, ...) abort function! s:Expand(rev, ...) abort
if a:rev =~# '^>\=:[0-3]$' if a:rev =~# '^>\=:[0-3]$'
let file = len(expand('%')) ? a:rev[-2:-1] . ':%' : '%' let file = len(expand('%')) ? a:rev[-2:-1] . ':%' : '%'
elseif a:rev ==# '>' elseif a:rev =~# '^>\%(:\=/\)\=$'
let file = '%' let file = '%'
elseif a:rev ==# '>:' elseif a:rev ==# '>:'
let file = empty(s:DirCommitFile(@%)[0]) ? ':0:%' : '%' let file = empty(s:DirCommitFile(@%)[0]) ? ':0:%' : '%'
@@ -2105,7 +2173,8 @@ function! s:BlobTemp(url) abort
endif endif
if commit =~# '^\d$' || !filereadable(tempfile) if commit =~# '^\d$' || !filereadable(tempfile)
let rev = s:DirRev(a:url)[1] 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 if exec_error
call delete(tempfile) call delete(tempfile)
return '' return ''
@@ -2318,7 +2387,7 @@ function! fugitive#CompleteObject(base, ...) abort
let heads += ["stash"] let heads += ["stash"]
let heads += sort(s:LinesError(["stash","list","--pretty=format:%gd"], dir)[0]) let heads += sort(s:LinesError(["stash","list","--pretty=format:%gd"], dir)[0])
endif endif
let results += s:FilterEscape(heads, base) let results += s:FilterEscape(heads, fnameescape(base))
endif endif
let results += a:0 == 1 || a:0 >= 3 ? fugitive#CompletePath(base, 0, '', dir, a:0 >= 4 ? a:4 : tree) : fugitive#CompletePath(base) let results += a:0 == 1 || a:0 >= 3 ? fugitive#CompletePath(base, 0, '', dir, a:0 >= 4 ? a:4 : tree) : fugitive#CompletePath(base)
return results return results
@@ -2340,7 +2409,7 @@ function! fugitive#CompleteObject(base, ...) abort
call map(entries,'s:sub(v:val,"^04.*\\zs$","/")') call map(entries,'s:sub(v:val,"^04.*\\zs$","/")')
call map(entries,'parent.s:sub(v:val,".*\t","")') call map(entries,'parent.s:sub(v:val,".*\t","")')
endif endif
return s:FilterEscape(entries, base) return s:FilterEscape(entries, fnameescape(base))
endfunction endfunction
function! s:CompleteSub(subcommand, A, L, P, ...) abort function! s:CompleteSub(subcommand, A, L, P, ...) abort
@@ -2403,8 +2472,8 @@ function! s:ReplaceCmd(cmd) abort
endif endif
endfunction endfunction
function! s:QueryLog(refspec) abort function! s:QueryLog(refspec, limit) abort
let lines = s:LinesError(['log', '-n', '256', '--pretty=format:%h%x09%s', a:refspec, '--'])[0] 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, 'split(v:val, "\t", 1)')
call map(lines, '{"type": "Log", "commit": v:val[0], "subject": join(v:val[1 : -1], "\t")}') call map(lines, '{"type": "Log", "commit": v:val[0], "subject": join(v:val[1 : -1], "\t")}')
return lines return lines
@@ -2454,6 +2523,20 @@ function! s:AddSection(label, lines, ...) abort
call append(line('$'), ['', a:label . (len(note) ? ': ' . note : ' (' . len(a:lines) . ')')] + s:Format(a:lines)) call append(line('$'), ['', a:label . (len(note) ? ': ' . note : ' (' . len(a:lines) . ')')] + s:Format(a:lines))
endfunction 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 = { let s:rebase_abbrevs = {
\ 'p': 'pick', \ 'p': 'pick',
\ 'r': 'reword', \ 'r': 'reword',
@@ -2468,11 +2551,15 @@ let s:rebase_abbrevs = {
\ 'b': 'break', \ 'b': 'break',
\ } \ }
function! fugitive#BufReadStatus() abort function! fugitive#BufReadStatus(...) abort
let amatch = s:Slash(expand('%:p')) let amatch = s:Slash(expand('%:p'))
let b:fugitive_type = 'index' let b:fugitive_type = 'index'
unlet! b:fugitive_reltime unlet! b:fugitive_reltime
try try
if exists('b:fugitive_reloading')
throw 'double status reload???'
endif
let b:fugitive_reloading = 1
silent doautocmd BufReadPre silent doautocmd BufReadPre
let config = fugitive#Config() let config = fugitive#Config()
@@ -2590,6 +2677,16 @@ function! fugitive#BufReadStatus() abort
endwhile endwhile
endif 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 for dict in staged
let b:fugitive_files['Staged'][dict.filename] = dict let b:fugitive_files['Staged'][dict.filename] = dict
endfor endfor
@@ -2666,16 +2763,10 @@ function! fugitive#BufReadStatus() abort
endfor endfor
endif 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 let b:fugitive_diff = diff
if !a:0 && v:cmdbang
unlet! b:fugitive_expanded
endif
let expanded = get(b:, 'fugitive_expanded', {'Staged': {}, 'Unstaged': {}}) let expanded = get(b:, 'fugitive_expanded', {'Staged': {}, 'Unstaged': {}})
let b:fugitive_expanded = {'Staged': {}, 'Unstaged': {}} let b:fugitive_expanded = {'Staged': {}, 'Unstaged': {}}
@@ -2705,16 +2796,16 @@ function! fugitive#BufReadStatus() abort
let staged_end = len(staged) ? line('$') : 0 let staged_end = len(staged) ? line('$') : 0
if len(pull) && get(props, 'branch.ab') !~# ' -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 endif
if len(push) && push !=# pull if len(push) && push !=# pull
call s:AddSection('Unpulled from ' . push, s:QueryLog(head . '..' . push)) call s:AddLogSection('Unpulled from ' . push, head, push)
endif endif
if len(pull) && push !=# pull if len(pull) && push !=# pull
call s:AddSection('Unpushed to ' . pull, s:QueryLog(pull . '..' . head)) call s:AddLogSection('Unpushed to ' . pull, pull, head)
endif endif
if len(push) && !(push ==# pull && get(props, 'branch.ab') =~# '^+0 ') 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 endif
setlocal nomodified readonly noswapfile setlocal nomodified readonly noswapfile
@@ -2791,6 +2882,8 @@ function! fugitive#BufReadStatus() abort
return s:DoAutocmd('User FugitiveIndex') return s:DoAutocmd('User FugitiveIndex')
catch /^fugitive:/ catch /^fugitive:/
return 'echoerr ' . string(v:exception) return 'echoerr ' . string(v:exception)
finally
unlet! b:fugitive_reloading
endtry endtry
endfunction endfunction
@@ -2930,7 +3023,7 @@ function! fugitive#BufReadCmd(...) abort
if b:fugitive_display_format if b:fugitive_display_format
call s:ReplaceCmd([dir, 'cat-file', b:fugitive_type, rev]) call s:ReplaceCmd([dir, 'cat-file', b:fugitive_type, rev])
else 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 1
keepjumps call search('^parent ') keepjumps call search('^parent ')
if getline('.') ==# 'parent ' if getline('.') ==# 'parent '
@@ -2948,7 +3041,8 @@ function! fugitive#BufReadCmd(...) abort
elseif b:fugitive_type ==# 'stage' elseif b:fugitive_type ==# 'stage'
call s:ReplaceCmd([dir, 'ls-files', '--stage']) call s:ReplaceCmd([dir, 'ls-files', '--stage'])
elseif b:fugitive_type ==# 'blob' 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 endif
finally finally
keepjumps call setpos('.',pos) keepjumps call setpos('.',pos)
@@ -3145,8 +3239,18 @@ function! s:RunEdit(state, tmp, job) abort
let file = FugitiveVimPath(readfile(sentinel, '', 1)[0]) let file = FugitiveVimPath(readfile(sentinel, '', 1)[0])
exe substitute(a:state.mods, '\<tab\>', '-tab', 'g') 'keepalt split' s:fnameescape(file) exe substitute(a:state.mods, '\<tab\>', '-tab', 'g') 'keepalt split' s:fnameescape(file)
set bufhidden=wipe 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) 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 return 1
endfunction endfunction
@@ -3200,11 +3304,7 @@ function! s:RunReceive(state, tmp, type, job, data, ...) abort
call setbufline(a:state.capture_bufnr, line_count + 1, lines) call setbufline(a:state.capture_bufnr, line_count + 1, lines)
endif endif
call setbufvar(a:state.capture_bufnr, '&modifiable', 0) call setbufvar(a:state.capture_bufnr, '&modifiable', 0)
if !getwinvar(bufwinid(a:state.capture_bufnr), '&previewwindow') if getwinvar(bufwinid(a:state.capture_bufnr), '&previewwindow')
" no-op
elseif exists('*win_execute')
call win_execute(bufwinid(a:state.capture_bufnr), '$')
else
let winnr = bufwinnr(a:state.capture_bufnr) let winnr = bufwinnr(a:state.capture_bufnr)
if winnr > 0 if winnr > 0
let old_winnr = winnr() let old_winnr = winnr()
@@ -3421,6 +3521,11 @@ augroup fugitive_job
\ endfor \ endfor
augroup END 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 function! fugitive#PagerFor(argv, ...) abort
let args = a:argv let args = a:argv
if empty(args) if empty(args)
@@ -3580,7 +3685,7 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
if a:bang && pager isnot# 2 if a:bang && pager isnot# 2
let pager = 1 let pager = 1
let stream = exists('*setbufline') 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 elseif pager
let allow_pty = 0 let allow_pty = 0
if pager is# 2 && a:bang && a:line2 >= 0 if pager is# 2 && a:bang && a:line2 >= 0
@@ -3597,7 +3702,7 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
endif endif
if s:run_jobs if s:run_jobs
call extend(env, {'COLUMNS': '' . (&columns - 1)}, 'keep') 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 if !state.pty
let args = s:AskPassArgs(dir) + args let args = s:AskPassArgs(dir) + args
endif endif
@@ -3620,6 +3725,10 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
\ 'GIT_SEQUENCE_EDITOR': editor, \ 'GIT_SEQUENCE_EDITOR': editor,
\ 'GIT_PAGER': 'cat', \ 'GIT_PAGER': 'cat',
\ 'PAGER': 'cat'}, 'keep') \ '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 if stream
call writefile(['fugitive: aborting edit due to background operation.'], state.file . '.exit') call writefile(['fugitive: aborting edit due to background operation.'], state.file . '.exit')
elseif pager elseif pager
@@ -3700,6 +3809,9 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
if !explicit_pathspec_option && get(options.flags, 0, '') ==# '--no-literal-pathspecs' if !explicit_pathspec_option && get(options.flags, 0, '') ==# '--no-literal-pathspecs'
call remove(options.flags, 0) call remove(options.flags, 0)
endif 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 cmd = s:BuildEnvPrefix(env) . s:shellesc(s:UserCommandList(options) + args)
let after = '|call fugitive#DidChange(' . string(dir) . ')' . after 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')) 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 +3913,12 @@ function! fugitive#Complete(lead, ...) abort
let dir = a:0 == 1 ? a:1 : a:0 >= 3 ? s:Dir(a:3) : s:Dir() 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 root = a:0 >= 4 ? a:4 : s:Tree(s:Dir())
let pre = a:0 > 1 ? strpart(a:1, 0, a:2) : '' let pre = a:0 > 1 ? strpart(a:1, 0, a:2) : ''
let subcmd = matchstr(pre, '\u\w*[! ] *\zs[[:alnum:]-]\+\ze ') let subcmd = matchstr(pre, '\u\w*[! ] *\%(\%(++\S\+\|--\S\+-pathspecs\|-c\s\+\S\+\)\s\+\)*\zs[[:alnum:]][[:alnum:]-]*\ze ')
if empty(subcmd) 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) let results = s:CompletableSubcommands(dir)
elseif a:0 ==# 2 && subcmd =~# '^\%(commit\|revert\|push\|fetch\|pull\|merge\|rebase\)$' elseif a:0 ==# 2 && subcmd =~# '^\%(commit\|revert\|push\|fetch\|pull\|merge\|rebase\)$'
let cmdline = substitute(a:1, '\u\w*\([! ] *\)' . subcmd, 'G' . subcmd, '') let cmdline = substitute(a:1, '\u\w*\([! ] *\)' . subcmd, 'G' . subcmd, '')
@@ -3845,7 +3961,7 @@ function! s:StatusCommand(line1, line2, range, count, bang, mods, reg, arg, args
let dir = a:0 ? s:Dir(a:1) : s:Dir() let dir = a:0 ? s:Dir(a:1) : s:Dir()
exe s:DirCheck(dir) exe s:DirCheck(dir)
try try
let mods = s:Mods(a:mods, &splitbelow ? 'botright' : 'topleft') let mods = s:Mods(a:mods, 'Edge')
let file = fugitive#Find(':', dir) let file = fugitive#Find(':', dir)
let arg = ' +setl\ foldmarker=<<<<<<<<,>>>>>>>>\|let\ w:fugitive_status=FugitiveGitDir() ' . let arg = ' +setl\ foldmarker=<<<<<<<<,>>>>>>>>\|let\ w:fugitive_status=FugitiveGitDir() ' .
\ s:fnameescape(file) \ s:fnameescape(file)
@@ -3910,7 +4026,7 @@ function! s:StageSeek(info, fallback) abort
if empty(info.heading) if empty(info.heading)
return a:fallback return a:fallback
endif endif
let line = search('^' . escape(info.heading, '^$.*[]~\') . ' (\d\+)$', 'wn') let line = search('^' . escape(info.heading, '^$.*[]~\') . ' (\d\++\=)$', 'wn')
if !line if !line
for section in get({'Staged': ['Unstaged', 'Untracked'], 'Unstaged': ['Untracked', 'Staged'], 'Untracked': ['Unstaged', 'Staged']}, info.section, []) for section in get({'Staged': ['Unstaged', 'Untracked'], 'Unstaged': ['Untracked', 'Staged'], 'Untracked': ['Unstaged', 'Staged']}, info.section, [])
let line = search('^' . section, 'wn') let line = search('^' . section, 'wn')
@@ -3989,7 +4105,7 @@ function! s:ReloadStatusBuffer(...) abort
endif endif
let original_lnum = a:0 ? a:1 : line('.') let original_lnum = a:0 ? a:1 : line('.')
let info = s:StageInfo(original_lnum) let info = s:StageInfo(original_lnum)
call fugitive#BufReadStatus() call fugitive#BufReadStatus(1)
call setpos('.', [0, s:StageSeek(info, original_lnum), 1, 0]) call setpos('.', [0, s:StageSeek(info, original_lnum), 1, 0])
return '' return ''
endfunction endfunction
@@ -4093,7 +4209,8 @@ endfunction
augroup fugitive_status augroup fugitive_status
autocmd! 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 ShellCmdPost,ShellFilterPost * nested call fugitive#DidChange(0)
autocmd BufDelete * nested autocmd BufDelete * nested
\ if getbufvar(+expand('<abuf>'), 'buftype') ==# 'terminal' | \ if getbufvar(+expand('<abuf>'), 'buftype') ==# 'terminal' |
@@ -4139,7 +4256,7 @@ function! s:StageInfo(...) abort
let index = 0 let index = 0
while len(getline(slnum - 1)) && empty(heading) while len(getline(slnum - 1)) && empty(heading)
let slnum -= 1 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) !~# '^[ @\+-]' if empty(heading) && getline(slnum) !~# '^[ @\+-]'
let index += 1 let index += 1
endif endif
@@ -4194,7 +4311,7 @@ function! s:Selection(arg1, ...) abort
let index = 0 let index = 0
while empty(heading) while empty(heading)
let slnum -= 1 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) !~# '^[ @\+-]' if empty(heading) && getline(slnum) !~# '^[ @\+-]'
let index += 1 let index += 1
endif endif
@@ -4214,7 +4331,7 @@ function! s:Selection(arg1, ...) abort
let lnum = first - (arg1 == flnum ? 0 : 1) let lnum = first - (arg1 == flnum ? 0 : 1)
let root = s:Tree() . '/' let root = s:Tree() . '/'
while lnum <= last while lnum <= last
let heading = matchstr(line, '^\u\l\+\ze.\{-\}\ze (\d\+)$') let heading = matchstr(line, '^\u\l\+\ze.\{-\}\ze (\d\++\=)$')
if len(heading) if len(heading)
let template.heading = heading let template.heading = heading
let template.section = matchstr(heading, '^\u\l\+') let template.section = matchstr(heading, '^\u\l\+')
@@ -4568,7 +4685,7 @@ function! s:StageInline(mode, ...) abort
let diff = [] let diff = []
let index = 0 let index = 0
let start = -1 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] ==# '@' if mode ==# 'await' && line[0] ==# '@'
let mode = 'capture' let mode = 'capture'
endif endif
@@ -4692,10 +4809,11 @@ function! s:StageApply(info, reverse, extra) abort
endif endif
let i = b:fugitive_expanded[info.section][info.filename][0] let i = b:fugitive_expanded[info.section][info.filename][0]
let head = [] let head = []
while get(b:fugitive_diff[info.section], i, '@') !~# '^@' let diff_lines = fugitive#Wait(b:fugitive_diff[info.section]).stdout
let line = b:fugitive_diff[info.section][i] while get(diff_lines, i, '@') !~# '^@'
let line = diff_lines[i]
if line ==# '--- /dev/null' 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 ' elseif line !~# '^new file '
call add(head, line) call add(head, line)
endif endif
@@ -4720,9 +4838,13 @@ function! s:StageDelete(lnum1, lnum2, count) abort
let err = '' let err = ''
let did_conflict_err = 0 let did_conflict_err = 0
let reset_commit = matchstr(getline(a:lnum1), '^Un\w\+ \%(to\| from\) \zs\S\+')
try try
for info in s:Selection(a:lnum1, a:lnum2) for info in s:Selection(a:lnum1, a:lnum2)
if empty(info.paths) if empty(info.paths)
if len(info.commit)
let reset_commit = info.commit . '^'
endif
continue continue
endif endif
let sub = get(get(get(b:fugitive_files, info.section, {}), info.filename, {}), 'submodule') let sub = get(get(get(b:fugitive_files, info.section, {}), info.filename, {}), 'submodule')
@@ -4788,15 +4910,14 @@ function! s:StageDelete(lnum1, lnum2, count) abort
let err .= '|echoerr ' . string(v:exception) let err .= '|echoerr ' . string(v:exception)
endtry endtry
if empty(restore) if empty(restore)
if len(reset_commit) && empty(err)
call feedkeys(':Git reset ' . reset_commit)
endif
return err[1:-1] return err[1:-1]
endif endif
exe s:ReloadStatus() exe s:ReloadStatus()
call s:StageReveal() call s:StageReveal()
if len(restore) return 'checktime|redraw|echomsg ' . string('To restore, ' . join(restore, '|')) . err
return 'checktime|redraw|echomsg ' . string('To restore, ' . join(restore, '|')) . err
else
return 'checktime|redraw' . err
endif
endfunction endfunction
function! s:StageIgnore(lnum1, lnum2, count) abort function! s:StageIgnore(lnum1, lnum2, count) abort
@@ -4972,11 +5093,11 @@ function! s:StagePatch(lnum1,lnum2) abort
for lnum in range(a:lnum1,a:lnum2) for lnum in range(a:lnum1,a:lnum2)
let info = s:StageInfo(lnum) let info = s:StageInfo(lnum)
if empty(info.paths) && info.section ==# 'Staged' if empty(info.paths) && info.section ==# 'Staged'
return 'Git reset --patch' return 'tab Git reset --patch'
elseif empty(info.paths) && info.section ==# 'Unstaged' elseif empty(info.paths) && info.section ==# 'Unstaged'
return 'Git add --patch' return 'tab Git add --patch'
elseif empty(info.paths) && info.section ==# 'Untracked' elseif empty(info.paths) && info.section ==# 'Untracked'
return 'Git add --interactive' return 'tab Git add --interactive'
elseif empty(info.paths) elseif empty(info.paths)
continue continue
endif endif
@@ -4994,10 +5115,10 @@ function! s:StagePatch(lnum1,lnum2) abort
call s:TreeChomp(['add', '--intent-to-add', '--'] + intend) call s:TreeChomp(['add', '--intent-to-add', '--'] + intend)
endif endif
if !empty(add) 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 endif
if !empty(reset) 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 endif
catch /^fugitive:/ catch /^fugitive:/
return 'echoerr ' . string(v:exception) return 'echoerr ' . string(v:exception)
@@ -5082,7 +5203,7 @@ function! s:MergeSubcommand(line1, line2, range, bang, mods, options) abort
\ filereadable(fugitive#Find('.git/MERGE_MSG', a:options)) || \ filereadable(fugitive#Find('.git/MERGE_MSG', a:options)) ||
\ isdirectory(fugitive#Find('.git/rebase-apply', a:options)) || \ isdirectory(fugitive#Find('.git/rebase-apply', a:options)) ||
\ !empty(s:TreeChomp([a:options.git_dir, 'diff-files', '--diff-filter=U']))) \ !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 endif
return {} return {}
endfunction endfunction
@@ -5531,7 +5652,7 @@ function! s:GrepSubcommand(line1, line2, range, bang, mods, options) abort
silent exe s:DoAutocmd('QuickFixCmdPost ' . event) silent exe s:DoAutocmd('QuickFixCmdPost ' . event)
if quiet if quiet
let bufnr = bufnr('') 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 if bufnr != bufnr('') && !a:bang
wincmd p wincmd p
endif endif
@@ -5851,7 +5972,7 @@ function! s:BlurStatus() abort
endfunction endfunction
let s:bang_edits = {'split': 'Git', 'vsplit': 'vertical Git', 'tabedit': 'tab Git', 'pedit': 'Git!'} 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() exe s:VersionCheck()
if a:bang 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') return 'echoerr ' . string(':G' . a:cmd . '! for temp buffer output has been replaced by :' . get(s:bang_edits, a:cmd, 'Git') . ' --paginate')
@@ -5891,7 +6012,7 @@ function! s:ReadPrepare(line1, count, range, mods) abort
return [pre . 'keepalt ' . mods . after . 'read', '|' . delete . 'diffupdate' . (a:count < 0 ? '|' . line('.') : '')] return [pre . 'keepalt ' . mods . after . 'read', '|' . delete . 'diffupdate' . (a:count < 0 ? '|' . line('.') : '')]
endfunction 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() exe s:VersionCheck()
if a:bang if a:bang
return 'echoerr ' . string(':Gread! for temp buffer output has been replaced by :{range}Git! --paginate') return 'echoerr ' . string(':Gread! for temp buffer output has been replaced by :{range}Git! --paginate')
@@ -5926,7 +6047,7 @@ endfunction
" Section: :Gwrite, :Gwq " 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() exe s:VersionCheck()
if s:cpath(expand('%:p'), fugitive#Find('.git/COMMIT_EDITMSG')) && empty(a:arg) if s:cpath(expand('%:p'), fugitive#Find('.git/COMMIT_EDITMSG')) && empty(a:arg)
return (empty($GIT_INDEX_FILE) ? 'write|bdelete' : 'wq') . (a:bang ? '!' : '') return (empty($GIT_INDEX_FILE) ? 'write|bdelete' : 'wq') . (a:bang ? '!' : '')
@@ -6203,7 +6324,7 @@ function! s:IsConflicted() abort
return len(@%) && !empty(s:ChompDefault('', ['ls-files', '--unmerged', '--', expand('%:p')])) return len(@%) && !empty(s:ChompDefault('', ['ls-files', '--unmerged', '--', expand('%:p')]))
endfunction endfunction
function! fugitive#Diffsplit(autodir, keepfocus, mods, arg, args) abort function! fugitive#Diffsplit(autodir, keepfocus, mods, arg, ...) abort
exe s:VersionCheck() exe s:VersionCheck()
let args = s:ArgSplit(a:arg) let args = s:ArgSplit(a:arg)
let post = '' let post = ''
@@ -6414,11 +6535,11 @@ function! fugitive#RenameComplete(A,L,P) abort
endif endif
endfunction 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) return s:Move(a:bang, 0, a:arg)
endfunction 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) return s:Move(a:bang, 1, a:arg)
endfunction endfunction
@@ -6444,11 +6565,11 @@ function! s:Remove(after, force) abort
endif endif
endfunction 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) return s:Remove('edit', a:bang)
endfunction 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) return s:Remove('bdelete', a:bang)
endfunction endfunction
@@ -7020,7 +7141,7 @@ function! s:BrowserOpen(url, mods, echo_copy) abort
endif endif
endfunction 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() exe s:VersionCheck()
let dir = s:Dir() let dir = s:Dir()
try try
@@ -7061,12 +7182,10 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
for line in readfile(result.file, '', 4096) for line in readfile(result.file, '', 4096)
let rev = s:fnameescape(matchstr(line, '\<https\=://[^[:space:]<>]*[^[:space:]<>.,;:"''!?]')) let rev = s:fnameescape(matchstr(line, '\<https\=://[^[:space:]<>]*[^[:space:]<>.,;:"''!?]'))
if len(rev) if len(rev)
break return s:BrowserOpen(rev, a:mods, a:bang)
endif endif
endfor endfor
if empty(rev) return 'echoerr ' . string('fugitive: no URL found in output of :Git')
return 'echoerr ' . string('fugitive: no URL found in output of :Git')
endif
endif endif
exe s:DirCheck(dir) exe s:DirCheck(dir)
if empty(expanded) if empty(expanded)
@@ -7117,6 +7236,7 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
let type = 'blob' let type = 'blob'
endif endif
endif endif
let config = fugitive#Config(dir)
if type ==# 'tree' && !empty(path) if type ==# 'tree' && !empty(path)
let path = s:sub(path, '/\=$', '/') let path = s:sub(path, '/\=$', '/')
endif endif
@@ -7148,13 +7268,13 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
let branch = FugitiveHead(0, dir) let branch = FugitiveHead(0, dir)
endif endif
if !empty(branch) if !empty(branch)
let r = FugitiveConfigGet('branch.'.branch.'.remote', dir) let r = FugitiveConfigGet('branch.'.branch.'.remote', config)
let m = FugitiveConfigGet('branch.'.branch.'.merge', dir)[11:-1] let m = FugitiveConfigGet('branch.'.branch.'.merge', config)[11:-1]
if r ==# '.' && !empty(m) if r ==# '.' && !empty(m)
let r2 = FugitiveConfigGet('branch.'.m.'.remote', dir) let r2 = FugitiveConfigGet('branch.'.m.'.remote', config)
if r2 !~# '^\.\=$' if r2 !~# '^\.\=$'
let r = r2 let r = r2
let m = FugitiveConfigGet('branch.'.m.'.merge', dir)[11:-1] let m = FugitiveConfigGet('branch.'.m.'.merge', config)[11:-1]
endif endif
endif endif
if empty(remote) if empty(remote)
@@ -7162,7 +7282,7 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
endif endif
if r ==# '.' || r ==# remote if r ==# '.' || r ==# remote
let remote_ref = 'refs/remotes/' . remote . '/' . branch 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)) \ !filereadable(FugitiveFind('.git/' . remote_ref, dir)) && empty(s:ChompDefault('', ['rev-parse', '--verify', remote_ref, '--'], dir))
let merge = m let merge = m
if path =~# '^\.git/refs/heads/.' if path =~# '^\.git/refs/heads/.'
@@ -7218,12 +7338,12 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
endif endif
if empty(remote) || remote ==# '.' if empty(remote) || remote ==# '.'
let remote = s:Remote(dir) let remote = s:RemoteDefault(config)
endif endif
if remote =~# ':' if remote =~# ':'
let remote_url = remote let remote_url = remote
else else
let remote_url = fugitive#RemoteUrl(remote, dir) let remote_url = fugitive#RemoteUrl(remote, config)
endif endif
let raw = empty(remote_url) ? remote : remote_url let raw = empty(remote_url) ? remote : remote_url
let git_dir = s:GitDir(dir) let git_dir = s:GitDir(dir)
@@ -7634,6 +7754,15 @@ function! s:cfile() abort
let ref = matchstr(getline('.'),'\x\{40,\}') let ref = matchstr(getline('.'),'\x\{40,\}')
echoerr "warning: unknown context ".matchstr(getline('.'),'^\l*') 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]\=/' elseif getline('.') =~# '^[+-]\{3\} [abciow12]\=/'
let ref = getline('.')[4:] let ref = getline('.')[4:]
@@ -7725,9 +7854,15 @@ function! s:GF(mode) abort
return 'echoerr ' . string(v:exception) return 'echoerr ' . string(v:exception)
endtry endtry
if len(results) > 1 if len(results) > 1
return 'G' . a:mode . let cmd = 'G' . a:mode .
\ (empty(results[1]) ? '' : ' +' . escape(results[1], ' |')) . ' ' . \ (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]) elseif len(results) && len(results[0])
return 'G' . a:mode . ' ' . s:fnameescape(results[0]) return 'G' . a:mode . ' ' . s:fnameescape(results[0])
else else

View File

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

View File

@@ -259,7 +259,7 @@ function! FugitivePath(...) abort
endfunction endfunction
function! FugitiveStatusline(...) abort function! FugitiveStatusline(...) abort
if empty(get(b:, 'git_dir', '')) if empty(FugitiveGitDir(bufnr('')))
return '' return ''
endif endif
return fugitive#Statusline() return fugitive#Statusline()
@@ -420,6 +420,9 @@ function! FugitiveDetect(...) abort
if exists('b:git_dir') && b:git_dir =~# '^$\|' . s:bad_git_dir if exists('b:git_dir') && b:git_dir =~# '^$\|' . s:bad_git_dir
unlet b:git_dir unlet b:git_dir
endif endif
if a:0 > 1 && a:2 is# 0 && !exists('#User#Fugitive')
return ''
endif
if !exists('b:git_dir') if !exists('b:git_dir')
let b:git_dir = FugitiveExtractGitDir(a:0 ? a:1 : bufnr('')) let b:git_dir = FugitiveExtractGitDir(a:0 ? a:1 : bufnr(''))
endif endif
@@ -475,7 +478,7 @@ function! s:ProjectionistDetect() abort
if exists('+shellslash') && !&shellslash if exists('+shellslash') && !&shellslash
let base = tr(base, '/', '\') let base = tr(base, '/', '\')
endif endif
let file = FugitiveCommonDir(dir) . '/info/projections.json' let file = FugitiveFind('.git/info/projections.json', dir)
if filereadable(file) if filereadable(file)
call projectionist#append(base, file) call projectionist#append(base, file)
endif endif
@@ -529,50 +532,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! -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 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>, [<f-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>, [<f-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>, [<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>)'
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_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>, [<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>)'
if exists(':Gr') != 2 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 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 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>, [<f-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>, [<f-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 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>, [<f-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>, [<f-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 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>, [<f-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>, [<f-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>, [<f-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) 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' \ '|echohl WarningMSG|echomsg ":Gremove is deprecated in favor of :GRemove"|echohl NONE'
endif endif
if exists(':Gdelete') != 2 && get(g:, 'fugitive_legacy_commands', 1) 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' \ '|echohl WarningMSG|echomsg ":Gdelete is deprecated in favor of :GDelete"|echohl NONE'
endif endif
if exists(':Gmove') != 2 && get(g:, 'fugitive_legacy_commands', 1) 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' \ '|echohl WarningMSG|echomsg ":Gmove is deprecated in favor of :GMove"|echohl NONE'
endif endif
if exists(':Grename') != 2 && get(g:, 'fugitive_legacy_commands', 1) 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' \ '|echohl WarningMSG|echomsg ":Grename is deprecated in favor of :GRename"|echohl NONE'
endif 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) 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' \ '|if <bang>1|redraw!|endif|echohl WarningMSG|echomsg ":Gbrowse is deprecated in favor of :GBrowse"|echohl NONE'
endif endif
@@ -600,8 +603,9 @@ let g:io_fugitive = {
augroup fugitive augroup fugitive
autocmd! autocmd!
autocmd BufNewFile,BufReadPost * call FugitiveDetect(expand('<amatch>:p')) autocmd BufNewFile,BufReadPost *
autocmd FileType netrw call FugitiveDetect(fnamemodify(get(b:, 'netrw_curdir', expand('<amatch>')), ':p')) \ call FugitiveDetect(expand('<amatch>:p'), 0)
autocmd FileType netrw call FugitiveDetect(fnamemodify(get(b:, 'netrw_curdir', expand('<afile>:p')), ':p'), 1)
autocmd FileType git autocmd FileType git
\ call fugitive#MapCfile() \ call fugitive#MapCfile()
@@ -656,15 +660,12 @@ endif
let s:nowait = v:version >= 704 ? '<nowait>' : '' let s:nowait = v:version >= 704 ? '<nowait>' : ''
function! s:Map(mode, lhs, rhs, ...) abort function! s:Map(mode, lhs, rhs, flags) abort
for mode in split(a:mode, '\zs') let flags = a:flags . (a:rhs =~# '<Plug>' ? '' : '<script>')
let flags = (a:0 ? a:1 : '') . (a:rhs =~# '<Plug>' ? '' : '<script>') let head = a:lhs
let head = a:lhs let tail = ''
let tail = '' let keys = get(g:, a:mode.'remap', {})
let keys = get(g:, mode.'remap', {}) if len(keys) && type(keys) == type({})
if type(keys) == type([])
return
endif
while !empty(head) while !empty(head)
if has_key(keys, head) if has_key(keys, head)
let head = keys[head] let head = keys[head]
@@ -676,10 +677,10 @@ function! s:Map(mode, lhs, rhs, ...) abort
let tail = matchstr(head, '<[^<>]*>$\|.$') . tail let tail = matchstr(head, '<[^<>]*>$\|.$') . tail
let head = substitute(head, '<[^<>]*>$\|.$', '', '') let head = substitute(head, '<[^<>]*>$\|.$', '', '')
endwhile endwhile
if flags !~# '<unique>' || empty(mapcheck(head.tail, mode)) endif
exe mode.'map' s:nowait flags head.tail a:rhs if flags !~# '<unique>' || empty(mapcheck(head.tail, a:mode))
endif exe a:mode.'map' s:nowait flags head.tail a:rhs
endfor endif
endfunction endfunction
call s:Map('c', '<C-R><C-G>', 'fnameescape(fugitive#Object(@%))', '<expr>') 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 fugitiveHelpHeader /^Help:/ nextgroup=fugitiveHelpTag skipwhite
syn match fugitiveHelpTag /\S\+/ contained 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 cluster fugitiveSection contains=fugitiveSection
syn match fugitiveHeading /^[A-Z][a-z][^:]*\ze (\d\+)$/ contains=fugitivePreposition contained nextgroup=fugitiveCount skipwhite 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 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 fugitivePreposition /\<\%([io]nto\|from\|to\|Rebasing\%( detached\)\=\)\>/ transparent contained nextgroup=fugitiveHash,fugitiveSymbolicRef skipwhite
syn match fugitiveInstruction /^\l\l\+\>/ contained containedin=@fugitiveSection nextgroup=fugitiveHash 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 syn region fugitiveHunk start=/^\%(@@\+ -\)\@=/ end=/^\%([A-Za-z?@]\|$\)\@=/ contains=diffLine,diffRemoved,diffAdded,diffNoEOL containedin=@fugitiveSection fold
for s:section in ['Untracked', 'Unstaged', 'Staged'] 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 match fugitive' . s:section . 'Modifier /^[MADRCU?] / contained containedin=fugitive' . s:section . 'Section'
exe 'syn cluster fugitiveSection add=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 endfor
unlet s:section unlet s:section