1 Commits

Author SHA1 Message Date
Tim Pope
2685422e17 Attempt to catch overlapping status reloads 2021-10-16 11:14:15 -04:00
2 changed files with 85 additions and 137 deletions

View File

@@ -228,7 +228,7 @@ function! s:Map(mode, lhs, rhs, ...) abort
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 . substitute(flags, '<unique>', '', '') . ' ' . head.tail . ' ' . a:rhs) call add(maps, mode.'map <buffer>' . s:nowait . substitute(flags, '<unique>', '', '') . ' ' . head.tail . ' ' . a:rhs)
if a:0 > 1 && a:2 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 . '"'
endif endif
@@ -263,7 +263,7 @@ 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) if len(jobs) && has('nvim-0.5')
sleep 1m sleep 1m
endif endif
else else
@@ -1272,15 +1272,15 @@ function! s:UrlParse(url) abort
return url return url
endfunction endfunction
function! s:RemoteResolve(url, flags) abort function! s:ResolveRemote(url) abort
let remote = s:UrlParse(a:url) let remote = s:UrlParse(a:url)
if remote.scheme =~# '^https\=$' && index(a:flags, ':nohttp') < 0 if remote.scheme =~# '^https\=$'
let headers = fugitive#RemoteHttpHeaders(remote.scheme . '://' . remote.authority . remote.path) 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)
let remote = s:UrlParse(loc) let remote = s:UrlParse(loc)
else else
let remote.headers = headers let remote.http_headers = headers
endif endif
elseif remote.scheme ==# 'ssh' elseif remote.scheme ==# 'ssh'
let remote.authority = fugitive#SshHostAlias(remote.authority) let remote.authority = fugitive#SshHostAlias(remote.authority)
@@ -1288,68 +1288,25 @@ function! s:RemoteResolve(url, flags) abort
return remote return remote
endfunction 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
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! 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(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$', a:config))
for v in vs
call add(instead_of, [v, k])
endfor
endfor
call sort(instead_of, 's:ConfigLengthSort')
for [orig, replacement] in instead_of
if strpart(url, 0, len(orig)) ==# orig
let url = replacement . strpart(url, len(orig))
break
endif
endfor
if index(a:flags, ':noresolve') < 0
call extend(a:into, s:RemoteResolve(url, a:flags))
else
call extend(a:into, s:UrlParse(url))
endif
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 function! s:RemoteParseArgs(args) abort
" Extract ':noresolve' style flags and an optional callback " Extract ':noresolve' style flags and an optional callback
let args = [] let args = []
@@ -1387,22 +1344,34 @@ function! s:RemoteParseArgs(args) abort
return [dir_or_config, remote, flags, cb] return [dir_or_config, remote, flags, cb]
endfunction 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 function! fugitive#RemoteUrl(...) abort
let [dir_or_config, remote, flags, cb] = s:RemoteParseArgs(a:000) let [dir_or_config, url, flags, cb] = s:RemoteParseArgs(a:000)
if len(cb) let config = fugitive#Config(dir_or_config)
let cb = [function('s:RemoteUrlCallback'), cb] if url =~# '^\.\=$'
let url = s:RemoteDefault(config)
endif endif
let remote = s:Remote(dir_or_config, remote, flags, cb) if url ==# '.git'
return get(remote, 'url', remote) let url = s:GitDir(config)
elseif url !~# ':\|^/\|^\.\.\=/'
let url = FugitiveConfigGet('remote.' . url . '.url', config)
endif
let instead_of = []
for [k, vs] in items(fugitive#ConfigGetRegexp('^url\.\zs.\{-\}\ze\.insteadof$', config))
for v in vs
call add(instead_of, [v, k])
endfor
endfor
call sort(instead_of, 's:ConfigLengthSort')
for [orig, replacement] in instead_of
if strpart(url, 0, len(orig)) ==# orig
let url = replacement . strpart(url, len(orig))
break
endif
endfor
if index(flags, 1) < 0 && index(flags, get(v:, 'true', 1)) < 0 && index(flags, ':noresolve') < 0
let url = fugitive#ResolveRemote(url)
endif
return url
endfunction endfunction
" Section: Quickfix " Section: Quickfix
@@ -2584,13 +2553,18 @@ let s:rebase_abbrevs = {
function! fugitive#BufReadStatus(...) abort function! fugitive#BufReadStatus(...) abort
let amatch = s:Slash(expand('%:p')) let amatch = s:Slash(expand('%:p'))
unlet! b:fugitive_reltime b:fugitive_type let b:fugitive_type = 'index'
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()
let cmd = [fnamemodify(amatch, ':h')] let cmd = [fnamemodify(amatch, ':h')]
setlocal noreadonly modifiable nomodeline buftype=nowrite setlocal noro ma nomodeline buftype=nowrite
if s:cpath(fnamemodify($GIT_INDEX_FILE !=# '' ? FugitiveVimPath($GIT_INDEX_FILE) : fugitive#Find('.git/index'), ':p')) !=# s:cpath(amatch) 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)}}] let cmd += [{'env': {'GIT_INDEX_FILE': FugitiveGitPath(amatch)}}]
endif endif
@@ -2790,7 +2764,7 @@ function! fugitive#BufReadStatus(...) abort
endif endif
let b:fugitive_diff = diff let b:fugitive_diff = diff
if get(a:, 1, v:cmdbang) if !a:0 && v:cmdbang
unlet! b:fugitive_expanded unlet! b:fugitive_expanded
endif endif
let expanded = get(b:, 'fugitive_expanded', {'Staged': {}, 'Unstaged': {}}) let expanded = get(b:, 'fugitive_expanded', {'Staged': {}, 'Unstaged': {}})
@@ -2909,7 +2883,7 @@ function! fugitive#BufReadStatus(...) abort
catch /^fugitive:/ catch /^fugitive:/
return 'echoerr ' . string(v:exception) return 'echoerr ' . string(v:exception)
finally finally
let b:fugitive_type = 'index' unlet! b:fugitive_reloading
endtry endtry
endfunction endfunction
@@ -3194,9 +3168,6 @@ function! s:TempReadPost(file) abort
if dict.filetype ==# 'man' && has('nvim') if dict.filetype ==# 'man' && has('nvim')
let b:man_sect = matchstr(getline(1), '^\w\+(\zs\d\+\ze)') let b:man_sect = matchstr(getline(1), '^\w\+(\zs\d\+\ze)')
endif endif
if !get(g:, 'did_load_ftplugin') && dict.filetype ==# 'fugitiveblame'
call s:BlameMaps(0)
endif
let &l:filetype = dict.filetype let &l:filetype = dict.filetype
endif endif
setlocal foldmarker=<<<<<<<<,>>>>>>>> setlocal foldmarker=<<<<<<<<,>>>>>>>>
@@ -3333,7 +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 !a:state.pager && getwinvar(bufwinid(a:state.capture_bufnr), '&previewwindow') if getwinvar(bufwinid(a:state.capture_bufnr), '&previewwindow')
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()
@@ -3712,7 +3683,6 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
let after_edit = '' let after_edit = ''
let stream = 0 let stream = 0
if a:bang && pager isnot# 2 if a:bang && pager isnot# 2
let state.pager = pager
let pager = 1 let pager = 1
let stream = exists('*setbufline') let stream = exists('*setbufline')
let do_edit = substitute(s:Mods(a:mods, 'Edge'), '\<tab\>', '-tab', 'g') . 'pedit!' let do_edit = substitute(s:Mods(a:mods, 'Edge'), '\<tab\>', '-tab', 'g') . 'pedit!'
@@ -4124,7 +4094,7 @@ function! s:DoAutocmdChanged(dir) abort
finally finally
unlet! g:fugitive_event g:fugitive_result unlet! g:fugitive_event g:fugitive_result
" Force statusline reload with the buffer's Git dir " Force statusline reload with the buffer's Git dir
let &l:ro = &l:ro let &ro = &ro
endtry endtry
return '' return ''
endfunction endfunction
@@ -4135,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(0) 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
@@ -4575,8 +4545,8 @@ endfunction
function! s:PreviousItem(count) abort function! s:PreviousItem(count) abort
for i in range(a:count) for i in range(a:count)
if !search(s:item_pattern, 'Wb') && getline('.') !~# s:item_pattern if !search(s:item_pattern, 'Wbe') && getline('.') !~# s:item_pattern
call search('^commit ', 'Wb') call search('^commit ', 'Wbe')
endif endif
endfor endfor
call s:StageReveal() call s:StageReveal()
@@ -7098,33 +7068,6 @@ function! s:BlameRehighlight() abort
endfor endfor
endfunction 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 function! fugitive#BlameFileType() abort
setlocal nomodeline setlocal nomodeline
setlocal foldmethod=manual setlocal foldmethod=manual
@@ -7139,7 +7082,29 @@ function! fugitive#BlameFileType() abort
if &modifiable if &modifiable
return '' return ''
endif endif
call s:BlameMaps(1) 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>')
endfunction endfunction
augroup fugitive_blame augroup fugitive_blame

View File

@@ -1,6 +1,6 @@
" fugitive.vim - A Git wrapper so awesome, it should be illegal " fugitive.vim - A Git wrapper so awesome, it should be illegal
" Maintainer: Tim Pope <http://tpo.pe/> " Maintainer: Tim Pope <http://tpo.pe/>
" Version: 3.5 " Version: 3.4
" GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim " GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim
if exists('g:loaded_fugitive') if exists('g:loaded_fugitive')
@@ -210,23 +210,6 @@ function! FugitiveRemoteUrl(...) abort
return call('fugitive#RemoteUrl', a:000) return call('fugitive#RemoteUrl', a:000)
endfunction 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 " FugitiveDidChange() triggers a FugitiveChanged event and reloads the summary
" buffer for the current or given buffer number's repository. You can also " 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 " give the result of a FugitiveExecute() and that context will be made
@@ -645,7 +628,7 @@ augroup fugitive
autocmd BufReadCmd index{,.lock} autocmd BufReadCmd index{,.lock}
\ if FugitiveIsGitDir(expand('<amatch>:p:h')) | \ if FugitiveIsGitDir(expand('<amatch>:p:h')) |
\ let b:git_dir = s:Slash(expand('<amatch>:p:h')) | \ let b:git_dir = s:Slash(expand('<amatch>:p:h')) |
\ exe fugitive#BufReadStatus(v:cmdbang) | \ exe fugitive#BufReadStatus() |
\ elseif filereadable(expand('<amatch>')) | \ elseif filereadable(expand('<amatch>')) |
\ silent doautocmd BufReadPre | \ silent doautocmd BufReadPre |
\ keepalt read <amatch> | \ keepalt read <amatch> |