|
|
|
@ -553,7 +553,13 @@ endfunction |
|
|
|
|
|
|
|
|
|
function! s:NullError(...) abort |
|
|
|
|
let [out, exec_error] = s:SystemError(call('fugitive#Prepare', a:000)) |
|
|
|
|
return [exec_error ? [] : split(out, "\1"), exec_error ? substitute(out, "\n$", "", "") : '', exec_error] |
|
|
|
|
if exec_error |
|
|
|
|
return [[], substitute(out, "\n$", "", "") : '', exec_error] |
|
|
|
|
else |
|
|
|
|
let list = split(out, "\1", 1) |
|
|
|
|
call remove(list, -1) |
|
|
|
|
return [list, '', exec_error] |
|
|
|
|
endif |
|
|
|
|
endfunction |
|
|
|
|
|
|
|
|
|
function! s:TreeChomp(...) abort |
|
|
|
@ -621,21 +627,23 @@ endfunction |
|
|
|
|
|
|
|
|
|
let s:config = {} |
|
|
|
|
function! fugitive#Config(...) abort |
|
|
|
|
let dir = s:Dir() |
|
|
|
|
let name = '' |
|
|
|
|
let default = get(a:, 3, '') |
|
|
|
|
if a:0 >= 2 && type(a:2) == type({}) |
|
|
|
|
if a:0 >= 2 && type(a:2) == type({}) && !has_key(a:2, 'git_dir') |
|
|
|
|
let name = substitute(a:1, '^[^.]\+\|[^.]\+$', '\L&', 'g') |
|
|
|
|
return len(a:1) ? get(get(a:2, name, []), 0, default) : a:2 |
|
|
|
|
elseif a:0 >= 2 |
|
|
|
|
let dir = a:2 |
|
|
|
|
let dir = s:Dir(a:2) |
|
|
|
|
let name = a:1 |
|
|
|
|
elseif a:0 == 1 && type(a:1) == type({}) |
|
|
|
|
elseif a:0 == 1 && type(a:1) == type({}) && !has_key(a:1, 'git_dir') |
|
|
|
|
return a:1 |
|
|
|
|
elseif a:0 == 1 && a:1 =~# '^[[:alnum:]-]\+\.' |
|
|
|
|
elseif a:0 == 1 && type(a:1) == type('') && a:1 =~# '^[[:alnum:]-]\+\.' |
|
|
|
|
let dir = s:Dir() |
|
|
|
|
let name = a:1 |
|
|
|
|
elseif a:0 == 1 |
|
|
|
|
let dir = a:1 |
|
|
|
|
let dir = s:Dir(a:1) |
|
|
|
|
else |
|
|
|
|
let dir = s:Dir() |
|
|
|
|
endif |
|
|
|
|
let name = substitute(name, '^[^.]\+\|[^.]\+$', '\L&', 'g') |
|
|
|
|
let dir_key = len(dir) ? dir : '_' |
|
|
|
@ -664,6 +672,28 @@ function! fugitive#Config(...) abort |
|
|
|
|
return len(name) ? get(get(dict, name, []), 0, default) : dict |
|
|
|
|
endfunction |
|
|
|
|
|
|
|
|
|
function! fugitive#ConfigGetAll(name, ...) abort |
|
|
|
|
let config = fugitive#Config(a:0 ? a:1 : s:Dir()) |
|
|
|
|
let name = substitute(a:name, '^[^.]\+\|[^.]\+$', '\L&', 'g') |
|
|
|
|
return copy(get(config, name, [])) |
|
|
|
|
endfunction |
|
|
|
|
|
|
|
|
|
function! fugitive#ConfigGetRegexp(pattern, ...) abort |
|
|
|
|
let config = fugitive#Config(a:0 ? a:1 : s:Dir()) |
|
|
|
|
let filtered = map(filter(copy(config), 'v:key =~# "\\." && v:key =~# a:pattern'), 'copy(v:val)') |
|
|
|
|
if a:pattern !~# '\\\@<!\%(\\\\\)*\\z[se]' |
|
|
|
|
return filtered |
|
|
|
|
endif |
|
|
|
|
let transformed = {} |
|
|
|
|
for [k, v] in items(filtered) |
|
|
|
|
let k = matchstr(k, a:pattern) |
|
|
|
|
if len(k) |
|
|
|
|
let transformed[k] = v |
|
|
|
|
endif |
|
|
|
|
endfor |
|
|
|
|
return transformed |
|
|
|
|
endfunction |
|
|
|
|
|
|
|
|
|
function! s:Remote(dir) abort |
|
|
|
|
let head = FugitiveHead(0, a:dir) |
|
|
|
|
let remote = len(head) ? FugitiveConfigGet('branch.' . head . '.remote', a:dir) : '' |
|
|
|
@ -2102,7 +2132,7 @@ function! fugitive#BufReadStatus() abort |
|
|
|
|
if empty(s:Tree()) |
|
|
|
|
call s:AddHeader('Bare', 'yes') |
|
|
|
|
endif |
|
|
|
|
if get(FugitiveConfigGetAll('advice.statusHints', config), 0, 'true') !~# '^\%(false\|no|off\|0\|\)$' |
|
|
|
|
if get(fugitive#ConfigGetAll('advice.statusHints', config), 0, 'true') !~# '^\%(false\|no|off\|0\|\)$' |
|
|
|
|
call s:AddHeader('Help', 'g?') |
|
|
|
|
endif |
|
|
|
|
|
|
|
|
@ -2228,6 +2258,10 @@ function! fugitive#FileWriteCmd(...) abort |
|
|
|
|
if commit !~# '^[0-3]$' || !v:cmdbang && (line("'[") != 1 || line("']") != line('$')) |
|
|
|
|
return "noautocmd '[,']write" . (v:cmdbang ? '!' : '') . ' ' . s:fnameescape(amatch) |
|
|
|
|
endif |
|
|
|
|
if exists('+guioptions') && &guioptions =~# '!' |
|
|
|
|
let guioptions = &guioptions |
|
|
|
|
set guioptions-=! |
|
|
|
|
endif |
|
|
|
|
silent execute "'[,']write !".fugitive#Prepare(dir, 'hash-object', '-w', '--stdin', '--').' > '.tmp |
|
|
|
|
let sha1 = readfile(tmp)[0] |
|
|
|
|
let old_mode = matchstr(s:SystemError([dir, 'ls-files', '--stage', '.' . file])[0], '^\d\+') |
|
|
|
@ -2245,6 +2279,9 @@ function! fugitive#FileWriteCmd(...) abort |
|
|
|
|
return 'echoerr '.string('fugitive: '.error) |
|
|
|
|
endif |
|
|
|
|
finally |
|
|
|
|
if exists('guioptions') |
|
|
|
|
let &guioptions = guioptions |
|
|
|
|
endif |
|
|
|
|
call delete(tmp) |
|
|
|
|
endtry |
|
|
|
|
endfunction |
|
|
|
@ -2473,7 +2510,7 @@ augroup END |
|
|
|
|
|
|
|
|
|
function! s:AskPassArgs(dir) abort |
|
|
|
|
if (len($DISPLAY) || len($TERM_PROGRAM) || has('gui_running')) && |
|
|
|
|
\ empty($GIT_ASKPASS) && empty($SSH_ASKPASS) && empty(FugitiveConfigGetAll('core.askpass', a:dir)) |
|
|
|
|
\ empty($GIT_ASKPASS) && empty($SSH_ASKPASS) && empty(fugitive#ConfigGetAll('core.askpass', a:dir)) |
|
|
|
|
if s:executable(s:ExecPath() . '/git-gui--askpass') |
|
|
|
|
return ['-c', 'core.askPass=' . s:ExecPath() . '/git-gui--askpass'] |
|
|
|
|
elseif s:executable('ssh-askpass') |
|
|
|
@ -2800,7 +2837,7 @@ function! fugitive#PagerFor(argv, ...) abort |
|
|
|
|
return 0 |
|
|
|
|
endif |
|
|
|
|
let config = a:0 ? a:1 : fugitive#Config() |
|
|
|
|
let value = get(FugitiveConfigGetAll('pager.' . args[0], config), 0, -1) |
|
|
|
|
let value = get(fugitive#ConfigGetAll('pager.' . args[0], config), 0, -1) |
|
|
|
|
if value =~# '^\%(true\|yes\|on\|1\)$' |
|
|
|
|
return 1 |
|
|
|
|
elseif value =~# '^\%(false\|no|off\|0\|\)$' |
|
|
|
@ -3075,7 +3112,7 @@ function! s:CompletableSubcommands(dir) abort |
|
|
|
|
endif |
|
|
|
|
call extend(commands, s:path_subcommands[cpath]) |
|
|
|
|
endfor |
|
|
|
|
call extend(commands, keys(FugitiveConfigGetRegexp('^alias\.\zs[^.]\+$', a:dir))) |
|
|
|
|
call extend(commands, keys(fugitive#ConfigGetRegexp('^alias\.\zs[^.]\+$', a:dir))) |
|
|
|
|
let configured = split(FugitiveConfigGet('completion.commands', a:dir), '\s\+') |
|
|
|
|
let rejected = {} |
|
|
|
|
for command in configured |
|
|
|
@ -3213,7 +3250,7 @@ function! s:StageSeek(info, fallback) abort |
|
|
|
|
if empty(info.heading) |
|
|
|
|
return a:fallback |
|
|
|
|
endif |
|
|
|
|
let line = search('^' . escape(substitute(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') |
|
|
|
@ -3433,18 +3470,18 @@ function! s:StageInfo(...) abort |
|
|
|
|
endwhile |
|
|
|
|
endif |
|
|
|
|
let slnum = lnum + 1 |
|
|
|
|
let section = '' |
|
|
|
|
let heading = '' |
|
|
|
|
let index = 0 |
|
|
|
|
while len(getline(slnum - 1)) && empty(section) |
|
|
|
|
while len(getline(slnum - 1)) && empty(heading) |
|
|
|
|
let slnum -= 1 |
|
|
|
|
let section = matchstr(getline(slnum), '^\u\l\+\ze.* (\d\+)$') |
|
|
|
|
if empty(section) && getline(slnum) !~# '^[ @\+-]' |
|
|
|
|
let heading = matchstr(getline(slnum), '^\u\l\+.\{-\}\ze (\d\+)$') |
|
|
|
|
if empty(heading) && getline(slnum) !~# '^[ @\+-]' |
|
|
|
|
let index += 1 |
|
|
|
|
endif |
|
|
|
|
endwhile |
|
|
|
|
let text = matchstr(getline(lnum), '^[A-Z?] \zs.*') |
|
|
|
|
return {'section': section, |
|
|
|
|
\ 'heading': getline(slnum), |
|
|
|
|
return {'section': matchstr(heading, '^\u\l\+'), |
|
|
|
|
\ 'heading': heading, |
|
|
|
|
\ 'sigil': sigil, |
|
|
|
|
\ 'offset': offset, |
|
|
|
|
\ 'filename': text, |
|
|
|
@ -3452,7 +3489,7 @@ function! s:StageInfo(...) abort |
|
|
|
|
\ 'paths': map(reverse(split(text, ' -> ')), 's:Tree() . "/" . v:val'), |
|
|
|
|
\ 'commit': matchstr(getline(lnum), '^\%(\%(\x\x\x\)\@!\l\+\s\+\)\=\zs[0-9a-f]\{4,\}\ze '), |
|
|
|
|
\ 'status': matchstr(getline(lnum), '^[A-Z?]\ze \|^\%(\x\x\x\)\@!\l\+\ze [0-9a-f]'), |
|
|
|
|
\ 'submodule': get(get(get(b:fugitive_files, section, {}), text, {}), 'submodule', ''), |
|
|
|
|
\ 'submodule': get(get(get(b:fugitive_files, heading, {}), text, {}), 'submodule', ''), |
|
|
|
|
\ 'index': index} |
|
|
|
|
endfunction |
|
|
|
|
|
|
|
|
@ -3486,11 +3523,11 @@ function! s:Selection(arg1, ...) abort |
|
|
|
|
let flnum -= 1 |
|
|
|
|
endwhile |
|
|
|
|
let slnum = flnum + 1 |
|
|
|
|
let section = '' |
|
|
|
|
let heading = '' |
|
|
|
|
let index = 0 |
|
|
|
|
while len(getline(slnum - 1)) && empty(section) |
|
|
|
|
while empty(heading) |
|
|
|
|
let slnum -= 1 |
|
|
|
|
let heading = matchstr(getline(slnum), '^\u\l\+.* (\d\+)$') |
|
|
|
|
let heading = matchstr(getline(slnum), '^\u\l\+.\{-\}\ze (\d\+)$') |
|
|
|
|
if empty(heading) && getline(slnum) !~# '^[ @\+-]' |
|
|
|
|
let index += 1 |
|
|
|
|
endif |
|
|
|
@ -3498,7 +3535,7 @@ function! s:Selection(arg1, ...) abort |
|
|
|
|
let results = [] |
|
|
|
|
let template = { |
|
|
|
|
\ 'heading': heading, |
|
|
|
|
\ 'section': matchstr(heading, '^\u\l\+\ze.* (\d\+)$'), |
|
|
|
|
\ 'section': matchstr(heading, '^\u\l\+'), |
|
|
|
|
\ 'filename': '', |
|
|
|
|
\ 'relative': [], |
|
|
|
|
\ 'paths': [], |
|
|
|
@ -3510,9 +3547,10 @@ function! s:Selection(arg1, ...) abort |
|
|
|
|
let lnum = first - (arg1 == flnum ? 0 : 1) |
|
|
|
|
let root = s:Tree() . '/' |
|
|
|
|
while lnum <= last |
|
|
|
|
if line =~# '^\u\l\+\ze.* (\d\+)$' |
|
|
|
|
let template.heading = getline(lnum) |
|
|
|
|
let template.section = matchstr(template.heading, '^\u\l\+\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\+') |
|
|
|
|
let template.index = 0 |
|
|
|
|
elseif line =~# '^[ @\+-]' |
|
|
|
|
let template.index -= 1 |
|
|
|
@ -5895,9 +5933,6 @@ function! s:BlameSubcommand(line1, count, range, bang, mods, options) abort |
|
|
|
|
setlocal signcolumn=no |
|
|
|
|
endif |
|
|
|
|
execute "vertical resize ".(s:linechars('.\{-\}\s\+\d\+\ze)')+1) |
|
|
|
|
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>') |
|
|
|
|
redraw |
|
|
|
|
syncbind |
|
|
|
|
exe s:DoAutocmdChanged(temp_state) |
|
|
|
@ -6128,6 +6163,9 @@ function! fugitive#BlameFileType() abort |
|
|
|
|
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', '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 |
|
|
|
|
|
|
|
|
|
augroup fugitive_blame |
|
|
|
|