1
0
mirror of https://github.com/amix/vimrc synced 2025-06-16 09:35:01 +08:00

Updated plugins

This commit is contained in:
Amir
2020-01-07 13:45:07 +01:00
parent b56966e13c
commit 46195e4ca4
42 changed files with 1299 additions and 892 deletions

View File

@ -206,8 +206,11 @@ function! s:QuickfixCreate(nr, opts) abort
endif
endfunction
function! s:QuickfixStream(nr, title, cmd, first, callback, ...) abort
call s:QuickfixCreate(a:nr, {'title': a:title})
function! s:QuickfixStream(nr, event, title, cmd, first, callback, ...) abort
let opts = {'title': a:title, 'context': {'items': []}}
call s:QuickfixCreate(a:nr, opts)
let event = (a:nr < 0 ? 'c' : 'l') . 'fugitive-' . a:event
silent exe s:DoAutocmd('QuickFixCmdPre ' . event)
let winnr = winnr()
exe a:nr < 0 ? 'copen' : 'lopen'
if winnr != winnr()
@ -219,12 +222,20 @@ function! s:QuickfixStream(nr, title, cmd, first, callback, ...) abort
for line in lines
call extend(buffer, call(a:callback, a:000 + [line]))
if len(buffer) >= 20
let contexts = map(copy(buffer), 'get(v:val, "context", {})')
lockvar contexts
call extend(opts.context.items, contexts)
unlet contexts
call s:QuickfixSet(a:nr, remove(buffer, 0, -1), 'a')
redraw
endif
endfor
call s:QuickfixSet(a:nr, extend(buffer, call(a:callback, a:000 + [0])), 'a')
call extend(buffer, call(a:callback, a:000 + [0]))
call extend(opts.context.items, map(copy(buffer), 'get(v:val, "context", {})'))
lockvar opts.context.items
call s:QuickfixSet(a:nr, buffer, 'a')
silent exe s:DoAutocmd('QuickFixCmdPost ' . event)
if a:first && len(s:QuickfixGet(a:nr))
call s:BlurStatus()
return a:nr < 0 ? 'cfirst' : 'lfirst'
@ -914,8 +925,8 @@ function! fugitive#Find(object, ...) abort
let f = 'fugitive://' . dir . '//0/' . rev[1:-1]
else
if !exists('f')
let commit = substitute(matchstr(rev, '^[^:.-][^:]*\|^:.*'), '^@\%($\|[~^]\|@{\)\@=', 'HEAD', '')
let file = substitute(matchstr(rev, '^[^:.-][^:]*\zs:.*'), '^:', '/', '')
let commit = substitute(matchstr(rev, '^\%([^:.-]\|\.\.[^/:]\)[^:]*\|^:.*'), '^@\%($\|[~^]\|@{\)\@=', 'HEAD', '')
let file = substitute(matchstr(rev, '^\%([^:.-]\|\.\.[^/:]\)[^:]*\zs:.*'), '^:', '/', '')
if file =~# '^/\.\.\=\%(/\|$\)\|^//\|^/\a\+:'
let file = file =~# '^/\.' ? simplify(getcwd() . file) : file[1:-1]
if s:cpath(base . '/', (file . '/')[0 : len(base)])
@ -2160,7 +2171,10 @@ function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
if exists('*s:' . name . 'Subcommand') && get(args, 1, '') !=# '--help'
try
exe s:DirCheck(dir)
return 'exe ' . string(s:{name}Subcommand(a:line1, a:line2, a:range, a:bang, a:mods, args[1:-1])) . after
let result = s:{name}Subcommand(a:line1, a:line2, a:range, a:bang, a:mods, args[1:-1])
if type(result) == type('')
return 'exe ' . string(result) . after
endif
catch /^fugitive:/
return 'echoerr ' . string(v:exception)
endtry
@ -3782,6 +3796,240 @@ augroup fugitive_merge
\ endif
augroup END
" Section: :Git difftool, :Git mergetool
function! s:ToolItems(state, from, to, offsets, text, ...) abort
let items = []
for i in range(len(a:state.diff))
let diff = a:state.diff[i]
let path = (i == len(a:state.diff) - 1) ? a:to : a:from
if empty(path)
return []
endif
let item = {
\ 'valid': a:0 ? a:1 : 1,
\ 'filename': diff.filename . FugitiveVimPath(path),
\ 'lnum': matchstr(get(a:offsets, i), '\d\+'),
\ 'text': a:text}
if len(get(diff, 'module', ''))
let item.module = diff.module . path
endif
call add(items, item)
endfor
let diff = items[0:-2]
let items[-1].context = {'diff': items[0:-2]}
return [items[-1]]
endfunction
function! s:ToolToFrom(str) abort
if a:str =~# ' => '
let str = a:str =~# '{.* => .*}' ? a:str : '{' . a:str . '}'
return [substitute(str, '{.* => \(.*\)}', '\1', ''),
\ substitute(str, '{\(.*\) => .*}', '\1', '')]
else
return [a:str, a:str]
endif
endfunction
function! s:ToolParse(state, line) abort
if type(a:line) !=# type('') || a:state.mode ==# 'hunk' && a:line =~# '^[ +-]'
return []
elseif a:line =~# '^diff '
let a:state.mode = 'diffhead'
let a:state.from = ''
let a:state.to = ''
elseif a:state.mode ==# 'diffhead' && a:line =~# '^--- [^/]'
let a:state.from = a:line[4:-1]
let a:state.to = a:state.from
elseif a:state.mode ==# 'diffhead' && a:line =~# '^+++ [^/]'
let a:state.to = a:line[4:-1]
if empty(get(a:state, 'from', ''))
let a:state.from = a:state.to
endif
elseif a:line[0] ==# '@'
let a:state.mode = 'hunk'
if has_key(a:state, 'from')
let offsets = split(matchstr(a:line, '^@\+ \zs[-+0-9, ]\+\ze @'), ' ')
return s:ToolItems(a:state, a:state.from, a:state.to, offsets, matchstr(a:line, ' @@\+ \zs.*'))
endif
elseif a:line =~# '^[A-Z]\d*\t.\|^:.*\t.'
" --raw, --name-status
let [status; files] = split(a:line, "\t")
return s:ToolItems(a:state, files[0], files[-1], [], a:state.name_only ? '' : status)
elseif a:line =~# '^ \S.* |'
" --stat
let [_, to, changes; __] = matchlist(a:line, '^ \(.\{-\}\) \+|\zs \(.*\)$')
let [to, from] = s:ToolToFrom(to)
return s:ToolItems(a:state, from, to, [], changes)
elseif a:line =~# '^ *\([0-9.]\+%\) .'
" --dirstat
let [_, changes, to; __] = matchlist(a:line, '^ *\([0-9.]\+%\) \(.*\)')
return s:ToolItems(a:state, to, to, [], changes)
elseif a:line =~# '^\(\d\+\|-\)\t\(\d\+\|-\)\t.'
" --numstat
let [_, add, remove, to; __] = matchlist(a:line, '^\(\d\+\|-\)\t\(\d\+\|-\)\t\(.*\)')
let [to, from] = s:ToolToFrom(to)
return s:ToolItems(a:state, from, to, [], add ==# '-' ? 'Binary file' : '+' . add . ' -' . remove, add !=# '-')
elseif a:state.mode !=# 'diffhead' && a:state.mode !=# 'hunk' && len(a:line) || a:line =~# '^git: \|^usage: \|^error: \|^fatal: '
return [{'text': a:line}]
endif
return []
endfunction
function! s:ToolStream(dir, line1, line2, range, bang, mods, args, state, title) abort
let i = 0
let argv = copy(a:args)
let prompt = 1
let state = a:state
while i < len(argv)
let match = matchlist(argv[i], '^\(-[a-zABDFH-KN-RT-Z]\)\ze\(.*\)')
if len(match) && len(match[2])
call insert(argv, match[1])
let argv[i+1] = '-' . match[2]
continue
endif
let arg = argv[i]
if arg =~# '^-t$\|^--tool=\|^--tool-help$\|^--help$'
return -1
elseif arg =~# '^-y$\|^--no-prompt$'
let prompt = 0
call remove(argv, i)
continue
elseif arg ==# '--prompt'
let prompt = 1
call remove(argv, i)
continue
elseif arg =~# '^--\%(no-\)\=\(symlinks\|trust-exit-code\|gui\)$'
call remove(argv, i)
continue
elseif arg ==# '--'
break
endif
let i += 1
endwhile
let a:state.mode = 'init'
let a:state.from = ''
let a:state.to = ''
let exec = s:UserCommandList(a:dir) + ['--no-pager', '-c', 'diff.context=0', 'diff', '--no-ext-diff', '--no-color', '--no-prefix'] + argv
if prompt
return s:QuickfixStream(a:line2, 'difftool', a:title, exec, !a:bang, s:function('s:ToolParse'), a:state)
else
let filename = ''
let cmd = []
let tabnr = tabpagenr() + 1
for line in split(s:SystemError(s:shellesc(exec))[0], "\n")
for item in s:ToolParse(a:state, line)
if len(get(item, 'filename', '')) && item.filename != filename
call add(cmd, 'tabedit ' . s:fnameescape(item.filename))
for i in reverse(range(len(get(item.context, 'diff', []))))
call add(cmd, (i ? 'rightbelow' : 'leftabove') . ' vert Gdiffsplit! ' . s:fnameescape(item.context.diff[i].filename))
endfor
call add(cmd, 'wincmd =')
let filename = item.filename
endif
endfor
endfor
return join(cmd, '|') . (empty(cmd) ? '' : '|' . tabnr . 'tabnext')
endif
endfunction
function! s:MergetoolSubcommand(line1, line2, range, bang, mods, args) abort
let dir = s:Dir()
let i = 0
let argv = copy(a:args)
let prompt = 1
let title = ':Git mergetool' . (len(a:args) ? ' ' . s:fnameescape(a:args) : '')
let cmd = ['diff', '--diff-filter=U']
let state = {'name_only': 0}
let state.diff = [{'prefix': ':2:', 'module': ':2:'}, {'prefix': ':3:', 'module': ':3:'}, {'prefix': ':(top)'}]
call map(state.diff, 'extend(v:val, {"filename": fugitive#Find(v:val.prefix, dir)})')
return s:ToolStream(dir, a:line1, a:line2, a:range, a:bang, a:mods, ['--diff-filter=U'] + a:args, state, title)
endfunction
function! s:DifftoolSubcommand(line1, line2, range, bang, mods, args) abort
let dir = s:Dir()
let i = 0
let argv = copy(a:args)
let commits = []
let cached = 0
let reverse = 1
let prompt = 1
let state = {'name_only': 0}
let merge_base_against = {}
let dash = (index(argv, '--') > i ? ['--'] : [])
while i < len(argv)
let match = matchlist(argv[i], '^\(-[a-zABDFH-KN-RT-Z]\)\ze\(.*\)')
if len(match) && len(match[2])
call insert(argv, match[1])
let argv[i+1] = '-' . match[2]
continue
endif
let arg = argv[i]
if arg ==# '--cached'
let cached = 1
elseif arg ==# '-R'
let reverse = 1
elseif arg ==# '--name-only'
let state.name_only = 1
let argv[0] = '--name-status'
elseif arg ==# '--'
break
elseif arg !~# '^-\|^\.\.\=\%(/\|$\)'
let parsed = s:LinesError(['rev-parse', '--revs-only', substitute(arg, ':.*', '', '')] + dash)[0]
call map(parsed, '{"uninteresting": v:val =~# "^\\^", "prefix": substitute(v:val, "^\\^", "", "") . ":"}')
let merge_base_against = {}
if arg =~# '\.\.\.' && len(parsed) > 2
let display = map(split(arg, '\.\.\.', 1), 'empty(v:val) ? "@" : v:val')
if len(display) == 2
let parsed[0].module = display[1] . ':'
let parsed[1].module = display[0] . ':'
endif
let parsed[2].module = arg . ':'
if empty(commits)
let merge_base_against = parsed[0]
let parsed = [parsed[2]]
endif
elseif arg =~# '\.\.' && len(parsed) == 2
let display = map(split(arg, '\.\.', 1), 'empty(v:val) ? "@" : v:val')
if len(display) == 2
let parsed[0].module = display[0] . ':'
let parsed[1].module = display[1] . ':'
endif
elseif len(parsed) == 1
let parsed[0].module = arg . ':'
endif
call extend(commits, parsed)
endif
let i += 1
endwhile
let title = ':Git difftool' . (len(a:args) ? ' ' . s:fnameescape(a:args) : '')
if len(merge_base_against)
call add(commits, merge_base_against)
endif
let commits = filter(copy(commits), 'v:val.uninteresting') + filter(commits, '!v:val.uninteresting')
if cached
if empty(commits)
call add(commits, {'prefix': '@:', 'module': '@:'})
endif
call add(commits, {'prefix': ':0:', 'module': ':0:'})
elseif len(commits) < 2
call add(commits, {'prefix': ':(top)'})
if len(commits) < 2
call insert(commits, {'prefix': ':0:', 'module': ':0:'})
endif
endif
if reverse
let commits = [commits[-1]] + repeat([commits[0]], len(commits) - 1)
call reverse(commits)
endif
if len(commits) > 2
call add(commits, remove(commits, 0))
endif
call map(commits, 'extend(v:val, {"filename": fugitive#Find(v:val.prefix, dir)})')
let state.diff = commits
return s:ToolStream(dir, a:line1, a:line2, a:range, a:bang, a:mods, argv, state, title)
endfunction
" Section: :Ggrep, :Glog
if !exists('g:fugitive_summary_format')
@ -3869,10 +4117,16 @@ function! s:GrepSubcommand(line1, line2, range, bang, mods, args) abort
endif
endfunction
function! s:LogFlushQueue(state) abort
let s:log_diff_context = '{"filename": fugitive#Find(v:val . from, a:dir), "lnum": get(offsets, v:key), "module": strpart(v:val, 0, len(a:state.base_module)) . from}'
function! s:LogFlushQueue(state, dir) abort
let queue = remove(a:state, 'queue')
if a:state.child_found
if a:state.child_found && get(a:state, 'ignore_summary')
call remove(queue, 0)
elseif len(queue) && len(a:state.target) && len(get(a:state, 'parents', []))
let from = substitute(a:state.target, '^/', ':', '')
let offsets = []
let queue[0].context.diff = map(copy(a:state.parents), s:log_diff_context)
endif
if len(queue) && queue[-1] ==# {'text': ''}
call remove(queue, -1)
@ -3881,41 +4135,65 @@ function! s:LogFlushQueue(state) abort
endfunction
function! s:LogParse(state, dir, line) abort
if a:state.context ==# 'hunk' && a:line =~# '^[-+ ]'
if a:state.mode ==# 'hunk' && a:line =~# '^[-+ ]'
return []
endif
let list = matchlist(a:line, '^\%(fugitive \(.\{-\}\)\t\|commit \|From \)\=\(\x\{40,\}\)\%( \(.*\)\)\=$')
if len(list)
let a:state.context = 'commit'
let queue = s:LogFlushQueue(a:state, a:dir)
let a:state.mode = 'commit'
let a:state.base = 'fugitive://' . a:dir . '//' . list[2]
let a:state.base_module = len(list[1]) ? list[1] : list[2]
let a:state.message = list[3]
if has_key(a:state, 'diffing')
call remove(a:state, 'diffing')
if len(list[1])
let [a:state.base_module; a:state.parents] = split(list[1], ' ')
else
let a:state.base_module = list[2]
let a:state.parents = []
endif
let queue = s:LogFlushQueue(a:state)
let a:state.message = list[3]
let a:state.from = ''
let a:state.to = ''
let context = {}
let a:state.queue = [{
\ 'valid': 1,
\ 'context': context,
\ 'filename': a:state.base . a:state.target,
\ 'module': a:state.base_module . substitute(a:state.target, '^/', ':', ''),
\ 'text': a:state.message}]
let a:state.child_found = 0
return queue
elseif type(a:line) == type(0)
return s:LogFlushQueue(a:state)
return s:LogFlushQueue(a:state, a:dir)
elseif a:line =~# '^diff'
let a:state.context = 'diffhead'
elseif a:line =~# '^[+-]\{3\} \w/' && a:state.context ==# 'diffhead'
let a:state.diffing = a:line[5:-1]
elseif a:line =~# '^@@[^@]*+\d' && has_key(a:state, 'diffing') && has_key(a:state, 'base')
let a:state.context = 'hunk'
if empty(a:state.target) || a:state.target ==# a:state.diffing
let a:state.mode = 'diffhead'
let a:state.from = ''
let a:state.to = ''
elseif a:state.mode ==# 'diffhead' && a:line =~# '^--- \w/'
let a:state.from = a:line[6:-1]
let a:state.to = a:state.from
elseif a:state.mode ==# 'diffhead' && a:line =~# '^+++ \w/'
let a:state.to = a:line[6:-1]
if empty(get(a:state, 'from', ''))
let a:state.from = a:state.to
endif
elseif a:line =~# '^@@[^@]*+\d' && len(get(a:state, 'to', '')) && has_key(a:state, 'base')
let a:state.mode = 'hunk'
if empty(a:state.target) || a:state.target ==# '/' . a:state.to
if !a:state.child_found && len(a:state.queue) && a:state.queue[-1] ==# {'text': ''}
call remove(a:state.queue, -1)
endif
let a:state.child_found = 1
let offsets = map(split(matchstr(a:line, '^@\+ \zs[-+0-9, ]\+\ze @'), ' '), '+matchstr(v:val, "\\d\\+")')
let context = {}
if len(a:state.parents)
let from = ":" . a:state.from
let context.diff = map(copy(a:state.parents), s:log_diff_context)
endif
call add(a:state.queue, {
\ 'valid': 1,
\ 'filename': a:state.base . a:state.diffing,
\ 'module': a:state.base_module . substitute(a:state.diffing, '^/', ':', ''),
\ 'lnum': +matchstr(a:line, '+\zs\d\+'),
\ 'context': context,
\ 'filename': FugitiveVimPath(a:state.base . '/' . a:state.to),
\ 'module': a:state.base_module . ':' . a:state.to,
\ 'lnum': offsets[-1],
\ 'text': a:state.message . matchstr(a:line, ' @@\+ .\+')})
endif
elseif a:state.follow &&
@ -3930,7 +4208,7 @@ function! s:LogParse(state, dir, line) abort
if !get(a:state, 'ignore_summary')
call add(a:state.queue, {'text': a:line})
endif
elseif a:state.context ==# 'commit' || a:state.context ==# 'init'
elseif a:state.mode ==# 'commit' || a:state.mode ==# 'init'
call add(a:state.queue, {'text': a:line})
endif
return []
@ -3953,32 +4231,36 @@ function! fugitive#LogCommand(line1, count, range, bang, mods, args, type) abort
endif
if a:line1 == 0 && a:count
let path = fugitive#Path(bufname(a:count), '/', dir)
let titlepre = ':0,' . a:count
elseif a:count >= 0
let path = fugitive#Path(@%, '/', dir)
let titlepre = a:count == 0 ? ':0,' . bufnr('') : ':'
else
let path = ''
let titlepre = ':'
let path = ''
endif
let range = ''
let extra = []
let state = {'context': 'init', 'child_found': 0, 'queue': [], 'follow': 0}
let extra_args = []
let extra_paths = []
let state = {'mode': 'init', 'child_found': 0, 'queue': [], 'follow': 0}
if path =~# '^/\.git\%(/\|$\)\|^$'
let path = ''
elseif a:line1 == 0
let range = "0," . (a:count ? a:count : bufnr(''))
let extra = ['.' . path]
let extra_paths = ['.' . path]
if (empty(paths) || paths ==# ['--']) && !s:HasOpt(args, '--no-follow')
let state.follow = 1
if !s:HasOpt(args, '--follow')
call insert(args, '--follow')
call insert(extra_args, '--follow')
endif
if !s:HasOpt(args, '--summary')
call insert(args, '--summary')
call insert(extra_args, '--summary')
let state.ignore_summary = 1
endif
endif
elseif a:count > 0
if !s:HasOpt(args, '--merges', '--no-merges')
call insert(args, '--no-merges')
call insert(extra_args, '--no-merges')
endif
call add(args, '-L' . a:line1 . ',' . a:count . ':' . path[1:-1])
endif
@ -3988,13 +4270,13 @@ function! fugitive#LogCommand(line1, count, range, bang, mods, args, type) abort
call add(args, owner)
endif
endif
if empty(extra)
if empty(extra_paths)
let path = ''
endif
if s:HasOpt(args, '-g', '--walk-reflogs')
let format = "%gd\t%H %gs"
let format = "%gd %P\t%H %gs"
else
let format = "%h\t%H " . g:fugitive_summary_format
let format = "%h %P\t%H " . g:fugitive_summary_format
endif
let cmd = ['--no-pager']
if fugitive#GitVersion(1, 9)
@ -4004,13 +4286,13 @@ function! fugitive#LogCommand(line1, count, range, bang, mods, args, type) abort
endif
call extend(cmd,
\ ['--no-color', '--no-ext-diff', '--pretty=format:fugitive ' . format] +
\ args + paths + extra)
\ args + extra_args + paths + extra_paths)
let state.target = path
let title = (listnr < 0 ? ':Gclog ' : ':Gllog ') . s:fnameescape(args + paths)
if empty(paths + extra) && empty(a:type) && len(s:Relative('/'))
let title = titlepre . (listnr < 0 ? 'Gclog ' : 'Gllog ') . s:fnameescape(args + paths)
if empty(paths + extra_paths) && empty(a:type) && len(s:Relative('/'))
let after = '|echohl WarningMsg|echo ' . string('Use :0Glog or :0Gclog for old behavior of targeting current file') . '|echohl NONE' . after
endif
return s:QuickfixStream(listnr, title, s:UserCommandList(dir) + cmd, !a:bang, s:function('s:LogParse'), state, dir) . after
return s:QuickfixStream(listnr, 'log', title, s:UserCommandList(dir) + cmd, !a:bang, s:function('s:LogParse'), state, dir) . after
endfunction
" Section: :Gedit, :Gpedit, :Gsplit, :Gvsplit, :Gtabedit, :Gread
@ -5428,7 +5710,12 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
endif
let i = 0
while commit =~# '^ref: ' && i < 10
let commit = readfile(cdir . '/' . commit[5:-1], '', 1)[0]
let ref_file = cdir . '/' . commit[5:-1]
if getfsize(ref_file) > 0
let commit = readfile(ref_file, '', 1)[0]
else
let commit = fugitive#RevParse(commit[5:-1], dir)
endif
let i -= 1
endwhile
endif