Merge branch 'cmd-options'

This merge removes g:signify_diffoptions and replaces it by the much more
general g:signify_vcs_commands. Users can customize the entire command to be
run now.
This commit is contained in:
Marco Hinz 2015-05-24 09:42:03 +02:00
commit 4ed7b37205
4 changed files with 173 additions and 178 deletions

View File

@ -23,6 +23,17 @@ function! sy#start() abort
return
endif
" sy_info is used in autoload/sy/repo
if !exists('b:sy_info')
let b:sy_info = {
\ 'chdir': haslocaldir() ? 'lcd' : 'cd',
\ 'cwd': getcwd(),
\ 'dir': fnamemodify(b:sy_path, ':p:h'),
\ 'path': sy#util#escape(b:sy_path),
\ 'file': sy#util#escape(fnamemodify(b:sy_path, ':t')),
\ }
endif
" new buffer.. add to list of registered files
if !exists('b:sy') || b:sy.path != b:sy_path
let b:sy = {

View File

@ -2,13 +2,119 @@
scriptencoding utf-8
" Init: values {{{1
if !exists('g:signify_diffoptions')
let g:signify_diffoptions = {}
endif
" Function: #detect {{{1
function! sy#repo#detect() abort
let vcs_list = s:vcs_list
" Simple cache. If there is a registered VCS-controlled file in this
" directory already, assume that this file is probably controlled by
" the same VCS. Thus we shuffle that VCS to the top of our copy of
" s:vcs_list, so we don't affect the preference order of s:vcs_list.
if has_key(g:sy_cache, b:sy_info.dir)
let vcs_list = [g:sy_cache[b:sy_info.dir]] +
\ filter(copy(s:vcs_list), 'v:val != "'.
\ g:sy_cache[b:sy_info.dir] .'"')
endif
for type in vcs_list
let [istype, diff] = sy#repo#get_diff_{type}()
if istype
return [diff, type]
endif
endfor
return ['', 'unknown']
endfunction
" Function: #get_diff_git {{{1
function! sy#repo#get_diff_git() abort
let diff = s:run(s:diffcmds.git, b:sy_info.file, 1)
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_hg {{{1
function! sy#repo#get_diff_hg() abort
let diff = s:run(s:diffcmds.hg, b:sy_info.path, 1)
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_svn {{{1
function! sy#repo#get_diff_svn() abort
let diff = s:run(s:diffcmds.svn, b:sy_info.path, 0)
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_bzr {{{1
function! sy#repo#get_diff_bzr() abort
let diff = s:run(s:diffcmds.bzr, b:sy_info.path, 0)
return (v:shell_error =~ '[012]') ? [1, diff] : [0, '']
endfunction
" Function: #get_diff_darcs {{{1
function! sy#repo#get_diff_darcs() abort
let diff = s:run(s:diffcmds.darcs, b:sy_info.path, 1)
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_fossil {{{1
function! sy#repo#get_diff_fossil() abort
let diff = s:run(s:diffcmds.fossil, b:sy_info.path, 1)
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_cvs {{{1
function! sy#repo#get_diff_cvs() abort
let diff = s:run(s:diffcmds.cvs, b:sy_info.file, 1)
return ((v:shell_error == 1) && (diff =~ '+++')) ? [1, diff] : [0, '']
endfunction
" Function: #get_diff_rcs {{{1
function! sy#repo#get_diff_rcs() abort
let diff = s:run(s:diffcmds.rcs, b:sy_info.path, 0)
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_accurev {{{1
function! sy#repo#get_diff_accurev() abort
let diff = s:run(s:diffcmds.accurev, b:sy_info.file, 1)
return (v:shell_error != 1) ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_perforce {{{1
function! sy#repo#get_diff_perforce() abort
let diff = s:run(s:diffcmds.perforce, b:sy_info.path, 0)
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_stats {{{1
function! sy#repo#get_stats() abort
if !exists('b:sy') || !has_key(b:sy, 'stats')
return [-1, -1, -1]
endif
return b:sy.stats
endfunction
" Function: s:run {{{1
function! s:run(cmd, path, do_switch_dir) abort
let cmd = substitute(a:cmd, '%f', a:path, '')
let cmd = substitute(cmd, '%d', s:difftool, '')
let cmd = substitute(cmd, '%n', s:devnull, '')
if a:do_switch_dir
try
execute b:sy_info.chdir fnameescape(b:sy_info.dir)
let ret = system(cmd)
finally
execute b:sy_info.chdir fnameescape(b:sy_info.cwd)
endtry
return ret
endif
return system(cmd)
endfunction
" Variables {{{1
let s:difftool = get(g:, 'signify_difftool', 'diff')
if executable(s:difftool)
let s:vcs_dict = {
\ 'git': 'git',
@ -39,139 +145,22 @@ if empty(s:vcs_list)
let s:vcs_list = keys(filter(s:vcs_dict, 'executable(v:val)'))
endif
" Function: #detect {{{1
function! sy#repo#detect() abort
let dir = fnamemodify(b:sy.path, ':h')
let s:diffcmds = {
\ 'git': 'git diff --no-color --no-ext-diff -U0 -- %f',
\ 'hg': 'hg diff --config extensions.color=! --config defaults.diff= --nodates -U0 -- %f',
\ 'svn': 'svn diff --diff-cmd %d -x -U0 -- %f',
\ 'bzr': 'bzr diff --using %d --diff-options=-U0 -- %f',
\ 'darcs': 'darcs diff --no-pause-for-gui --diff-command="%d -U0 %1 %2" -- %f',
\ 'fossil': 'fossil set diff-command "%d -U 0" && fossil diff --unified -c 0 -- %f',
\ 'cvs': 'cvs diff -U0 -- %f',
\ 'rcs': 'rcsdiff -U0 %f 2>%n',
\ 'accurev': 'accurev diff %f -- -U0',
\ 'perforce': 'p4 info >%n 2>&1 && env P4DIFF=diff p4 diff -dU0 %f',
\ }
let vcs_list = s:vcs_list
" Simple cache. If there is a registered VCS-controlled file in this
" directory already, assume that this file is probably controlled by
" the same VCS. Thus we shuffle that VCS to the top of our copy of
" s:vcs_list, so we don't affect the preference order of s:vcs_list.
if has_key(g:sy_cache, dir)
let vcs_list = [g:sy_cache[dir]] + filter(copy(s:vcs_list), 'v:val != "'. g:sy_cache[dir] .'"')
endif
if exists('g:signify_vcs_cmds')
call extend(s:diffcmds, g:signify_vcs_cmds)
endif
for type in vcs_list
let [istype, diff] = sy#repo#get_diff_{type}()
if istype
return [ diff, type ]
endif
endfor
return [ '', 'unknown' ]
endfunction
" Function: #get_diff_git {{{1
function! sy#repo#get_diff_git() abort
let diffoptions = has_key(g:signify_diffoptions, 'git') ? g:signify_diffoptions.git : ''
let diff = sy#util#run_in_dir(fnamemodify(b:sy.path, ':h'), 'git diff --no-color --no-ext-diff -U0 '. diffoptions .' -- '. sy#util#escape(fnamemodify(b:sy.path, ':t')))
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_stat_git {{{1
function! sy#repo#get_stat_git() abort
let s:stats = []
let root = finddir('.git', fnamemodify(b:sy.path, ':h') .';')
if empty(root)
echohl ErrorMsg | echomsg 'Cannot find the git root directory: '. b:sy.path | echohl None
return
endif
let root = fnamemodify(root, ':h')
let output = sy#util#run_in_dir(root, 'git diff --numstat')
if v:shell_error
echohl ErrorMsg | echomsg "'git diff --numstat' failed" | echohl None
return
endif
for stat in split(output, '\n')
let tokens = matchlist(stat, '\v([0-9-]+)\t([0-9-]+)\t(.*)')
if empty(tokens)
echohl ErrorMsg | echomsg 'Cannot parse this line: '. stat | echohl None
elseif tokens[1] == '-'
continue
else
let path = root . sy#util#separator() . tokens[3]
if !bufexists(path)
execute 'argadd '. path
endif
call add(s:stats, { 'bufnr': bufnr(path), 'text': tokens[1] .' additions, '. tokens[2] .' deletions', 'lnum': 1, 'col': 1 })
endif
endfor
"call setqflist(stats)
endfunction
" Function: #get_diff_hg {{{1
function! sy#repo#get_diff_hg() abort
let diffoptions = has_key(g:signify_diffoptions, 'hg') ? g:signify_diffoptions.hg : ''
let diff = sy#util#run_in_dir(fnamemodify(b:sy.path, ':h'), 'hg diff --config extensions.color=! --config defaults.diff= --nodates -U0 '. diffoptions .' -- '. sy#util#escape(b:sy.path))
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_svn {{{1
function! sy#repo#get_diff_svn() abort
let diffoptions = has_key(g:signify_diffoptions, 'svn') ? g:signify_diffoptions.svn : ''
let diff = system('svn diff --diff-cmd '. s:difftool .' -x -U0 '. diffoptions .' -- '. sy#util#escape(b:sy.path))
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_bzr {{{1
function! sy#repo#get_diff_bzr() abort
let diffoptions = has_key(g:signify_diffoptions, 'bzr') ? g:signify_diffoptions.bzr : ''
let diff = system('bzr diff --using '. s:difftool .' --diff-options=-U0 '. diffoptions .' -- '. sy#util#escape(b:sy.path))
return (v:shell_error =~ '[012]') ? [1, diff] : [0, '']
endfunction
" Function: #get_diff_darcs {{{1
function! sy#repo#get_diff_darcs() abort
let diffoptions = has_key(g:signify_diffoptions, 'darcs') ? g:signify_diffoptions.darcs : ''
let diff = sy#util#run_in_dir(fnamemodify(b:sy.path, ':h'), 'darcs diff --no-pause-for-gui --diff-command="'. s:difftool .' -U0 %1 %2 '. diffoptions .'" -- '. sy#util#escape(b:sy.path))
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_fossil {{{1
function! sy#repo#get_diff_fossil() abort
let diffoptions = has_key(g:signify_diffoptions, 'fossil') ? g:signify_diffoptions.fossil : ''
let diff = sy#util#run_in_dir(fnamemodify(b:sy.path, ':h'), 'fossil set diff-command "'. s:difftool .' -U 0" && fossil diff --unified -c 0 '. diffoptions .' -- '. sy#util#escape(b:sy.path))
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_cvs {{{1
function! sy#repo#get_diff_cvs() abort
let diffoptions = has_key(g:signify_diffoptions, 'cvs') ? g:signify_diffoptions.cvs : ''
let diff = sy#util#run_in_dir(fnamemodify(b:sy.path, ':h'), 'cvs diff -U0 '. diffoptions .' -- '. sy#util#escape(fnamemodify(b:sy.path, ':t')))
return ((v:shell_error == 1) && (diff =~ '+++')) ? [1, diff] : [0, '']
endfunction
" Function: #get_diff_rcs {{{1
function! sy#repo#get_diff_rcs() abort
let diffoptions = has_key(g:signify_diffoptions, 'rcs') ? g:signify_diffoptions.rcs : ''
let diff = system('rcsdiff -U0 '. diffoptions .' '. sy#util#escape(b:sy.path) .' 2>/dev/null')
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_accurev {{{1
function! sy#repo#get_diff_accurev() abort
let diffoptions = has_key(g:signify_diffoptions, 'accurev') ? g:signify_diffoptions.accurev : ''
let diff = sy#util#run_in_dir(fnamemodify(b:sy.path, ':h'), 'accurev diff '. sy#util#escape(fnamemodify(b:sy.path, ':t')) . ' -- -U0 '. diffoptions)
return (v:shell_error != 1) ? [0, ''] : [1, diff]
endfunction
" Function: #get_diff_perforce {{{1
function! sy#repo#get_diff_perforce() abort
let diffoptions = has_key(g:signify_diffoptions, 'perforce') ? g:signify_diffoptions.perforce : ''
let diff = system('p4 info >' . sy#util#devnull() . ' 2>&1 && env P4DIFF=diff p4 diff -dU0 '. diffoptions .' '. sy#util#escape(b:sy.path))
return v:shell_error ? [0, ''] : [1, diff]
endfunction
" Function: #get_stats {{{1
function! sy#repo#get_stats() abort
if !exists('b:sy') || !has_key(b:sy, 'stats')
return [-1, -1, -1]
endif
return b:sy.stats
endfunction
let s:difftool = sy#util#escape(s:difftool)
let s:devnull = has('win32') || has ('win64') ? 'NUL' : '/dev/null'

View File

@ -22,26 +22,6 @@ function! sy#util#escape(path) abort
return path
endfunction
" Function: #separator {{{1
function! sy#util#separator() abort
return !exists('+shellslash') || &shellslash ? '/' : '\'
endfunction
" Function: #run_in_dir {{{1
function! sy#util#run_in_dir(dir, cmd) abort
let chdir = haslocaldir() ? 'lcd' : 'cd'
let cwd = getcwd()
try
execute chdir fnameescape(fnamemodify(a:dir, ':p'))
let ret = system(a:cmd)
finally
execute chdir fnameescape(cwd)
endtry
return ret
endfunction
" Function: #refresh_windows {{{1
function! sy#util#refresh_windows() abort
let winnr = winnr()
@ -76,12 +56,3 @@ function! sy#util#hunk_text_object(emptylines) abort
endif
endfunction
" Function: #devnull {{{1
function! sy#util#devnull() abort
if has('win32') || has ('win64')
let null = 'NUL'
else
let null = '/dev/null'
endif
return null
endfunction

View File

@ -88,6 +88,7 @@ default values, as long as no "Default:" section is given.
All available options:~
|g:signify_vcs_list|
|g:signify_vcs_cmds|
|g:signify_disable_by_default|
|g:signify_skip_filetype|
|g:signify_skip_filename|
@ -103,7 +104,6 @@ All available options:~
|g:signify_cursorhold_normal|
|g:signify_cursorhold_insert|
|g:signify_difftool|
|g:signify_diffoptions|
------------------------------------------------------------------------------
*g:signify_vcs_list*
@ -142,6 +142,39 @@ NOTE: If you don't set this option and Sy is activated, updating signs for a
non-VCS file can lead to significant delay since all supported and installed
VCS will be tested for.
------------------------------------------------------------------------------
*g:signify_vcs_cmds*
>
let g:signify_vcs_cmds = {
\ 'cvs': 'cvs -d '. $CVSROOT .' diff -U0 -- %f' }
<
This is a |dict|. They key is any version control system from |g:signify_vcs_list|
and the value is the corresponding command line.
Modifiers:~
%f actual filepath
%d |g:signify_difftool|
%n Unix: "/dev/null", Windows: "NUL"
NOTE: The output format mustn't change, otherwise Sy won't give any reasonable
results. It's probably wise to start with the respective default values.
Default:
>
let g:signify_vcs_cmds = {
\ 'git': 'git diff --no-color --no-ext-diff -U0 -- %f',
\ 'hg': 'hg diff --config extensions.color=! --config defaults.diff= --nodates -U0 -- %f',
\ 'svn': 'svn diff --diff-cmd %d -x -U0 -- %f',
\ 'bzr': 'bzr diff --using %d --diff-options=-U0 -- %f',
\ 'darcs': 'darcs diff --no-pause-for-gui --diff-command="%d -U0 %1 %2" -- %f',
\ 'fossil': 'fossil set diff-command "%d -U 0" && fossil diff --unified -c 0 -- %f',
\ 'cvs': 'cvs diff -U0 -- %f',
\ 'rcs': 'rcsdiff -U0 %f 2>%n',
\ 'accurev': 'accurev diff %f -- -U0',
\ 'perforce': 'p4 info >%n 2>&1 && env P4DIFF=diff p4 diff -dU0 %f',
\ }
<
------------------------------------------------------------------------------
*g:signify_disable_by_default*
>
@ -246,15 +279,6 @@ are: svn, bzr, darcs, fossil.
Default: "diff"
------------------------------------------------------------------------------
*g:signify_diffoptions*
>
let g:signify_diffoptions = { 'git': '-w', 'hg': '-w' }
<
This will pass the given additional options to the selected VCS diff command.
Default: Does not exist.
==============================================================================
COMMAND *signify-commands*
*signify-:SignifyToggle*