diff --git a/.gitignore b/.gitignore index a0b475e..ddc3586 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,13 @@ !.gitignore !CONTRIBUTING.md !README.md +!autoload/sy.vim +!autoload/sy/debug.vim +!autoload/sy/highlight.vim +!autoload/sy/jump.vim !autoload/sy/repo.vim -!autoload/sy/utils.vim +!autoload/sy/sign.vim +!autoload/sy/util.vim !doc/signify.txt !plugin/signify.vim !showcolors.bash diff --git a/autoload/sy.vim b/autoload/sy.vim new file mode 100644 index 0000000..ea3f02e --- /dev/null +++ b/autoload/sy.vim @@ -0,0 +1,103 @@ +if exists('b:autoloaded_sy') + finish +endif +let b:autoloaded_sy = 1 + +" Init: values +let g:signify_sign_overwrite = get(g:, 'signify_sign_overwrite', 1) +let g:id_top = 0x100 + +sign define SignifyPlaceholder text=. texthl=SignifySignChange linehl=NONE + +" Function: #start {{{1 +function! sy#start(path) abort + if !filereadable(a:path) + \ || (exists('g:signify_skip_filetype') && has_key(g:signify_skip_filetype, &ft)) + \ || (exists('g:signify_skip_filename') && has_key(g:signify_skip_filename, a:path)) + return + endif + + " new buffer.. add to list + if !has_key(g:sy, a:path) + let [ diff, type ] = sy#repo#detect(a:path) + if empty(diff) + return + endif + if get(g:, 'signify_disable_by_default') + let g:sy[a:path] = { 'active': 0, 'type': type, 'hunks': [], 'id_top': g:id_top } + return + endif + let g:sy[a:path] = { 'active': 1, 'type': type, 'hunks': [], 'id_top': g:id_top } + " inactive buffer.. bail out + elseif !g:sy[a:path].active + return + " update signs + else + let diff = sy#repo#get_diff_{g:sy[a:path].type}(a:path) + if empty(diff) + call sy#sign#remove_all(a:path) + return + endif + let g:sy[a:path].id_top = g:id_top + endif + + if get(g:, 'signify_line_highlight') + call sy#highlight#line_enable() + else + call sy#highlight#line_disable() + endif + + if !g:signify_sign_overwrite + call sy#sign#get_others(a:path) + endif + + execute 'sign place 99999 line=1 name=SignifyPlaceholder file='. a:path + call sy#sign#remove_all(a:path) + call sy#repo#process_diff(a:path, diff) + sign unplace 99999 + + if !maparg('[c', 'n') + nnoremap ]c :execute v:count1 .'SignifyJumpToNextHunk' + nnoremap [c :execute v:count1 .'SignifyJumpToPrevHunk' + endif + + let g:sy[a:path].id_top = (g:id_top - 1) +endfunction + +" vim: et sw=2 sts=2 +" Function: #stop {{{1 +function! sy#stop(path) abort + if !has_key(g:sy, a:path) + return + endif + + call sy#sign#remove_all(a:path) + + silent! nunmap ]c + silent! nunmap [c + + augroup signify + autocmd! * + augroup END +endfunction + +" Function: #toggle {{{1 +function! sy#toggle() abort + if empty(g:sy_path) + echomsg 'signify: I cannot sy empty buffers!' + return + endif + + if has_key(g:sy, g:sy_path) + if g:sy[g:sy_path].active + call sy#stop(g:sy_path) + let g:sy[g:sy_path].active = 0 + else + let g:sy[g:sy_path].active = 1 + call sy#start(g:sy_path) + endif + else + call sy#start(g:sy_path) + endif +endfunction + diff --git a/autoload/sy/debug.vim b/autoload/sy/debug.vim new file mode 100644 index 0000000..86ce5b9 --- /dev/null +++ b/autoload/sy/debug.vim @@ -0,0 +1,21 @@ +if exists('b:autoloaded_sy_debug') + finish +endif +let b:autoloaded_sy_debug = 1 + +" Function: SignifyDebugListActiveBuffers {{{1 +function! sy#debug#list_active_buffers() abort + if empty(g:sy) + echomsg 'No active buffers!' + return + endif + + for [path, stats] in items(g:sy) + echo "\n". path ."\n". repeat('=', strlen(path)) + for stat in sort(keys(stats)) + echo printf("%20s = %s\n", stat, string(stats[stat])) + endfor + endfor +endfunction + +" vim: et sw=2 sts=2 diff --git a/autoload/sy/highlight.vim b/autoload/sy/highlight.vim new file mode 100644 index 0000000..5eff941 --- /dev/null +++ b/autoload/sy/highlight.vim @@ -0,0 +1,103 @@ +if exists('b:autoloaded_sy_highlight') + finish +endif +let b:autoloaded_sy_highlight = 1 + +" Init: values {{{1 +let s:sign_add = get(g:, 'signify_sign_add', '+') +let s:sign_delete = get(g:, 'signify_sign_delete', '_') +let s:sign_delete_first_line = get(g:, 'signify_sign_delete_first_line', '‾') +let s:sign_change = get(g:, 'signify_sign_change', '!') + +" Function: #setup {{{1 +function! sy#highlight#setup() abort + highlight link SignifyLineAdd DiffAdd + highlight link SignifyLineChange DiffChange + highlight link SignifyLineDelete DiffDelete + + highlight link SignifySignAdd DiffAdd + highlight link SignifySignChange DiffChange + highlight link SignifySignDelete DiffDelete +endfunction + +" Function: #line_enable {{{1 +function! sy#highlight#line_enable() abort + execute 'sign define SignifyAdd text='. s:sign_add ' texthl=SignifySignAdd linehl=SignifyLineAdd' + + execute 'sign define SignifyChange text='. s:sign_change ' texthl=SignifySignChange linehl=SignifyLineChange' + execute 'sign define SignifyChangeDelete1 text='. s:sign_change .'1 texthl=SignifySignChange linehl=SignifyLineChange' + execute 'sign define SignifyChangeDelete2 text='. s:sign_change .'2 texthl=SignifySignChange linehl=SignifyLineChange' + execute 'sign define SignifyChangeDelete3 text='. s:sign_change .'3 texthl=SignifySignChange linehl=SignifyLineChange' + execute 'sign define SignifyChangeDelete4 text='. s:sign_change .'4 texthl=SignifySignChange linehl=SignifyLineChange' + execute 'sign define SignifyChangeDelete5 text='. s:sign_change .'5 texthl=SignifySignChange linehl=SignifyLineChange' + execute 'sign define SignifyChangeDelete6 text='. s:sign_change .'6 texthl=SignifySignChange linehl=SignifyLineChange' + execute 'sign define SignifyChangeDelete7 text='. s:sign_change .'7 texthl=SignifySignChange linehl=SignifyLineChange' + execute 'sign define SignifyChangeDelete8 text='. s:sign_change .'8 texthl=SignifySignChange linehl=SignifyLineChange' + execute 'sign define SignifyChangeDelete9 text='. s:sign_change .'9 texthl=SignifySignChange linehl=SignifyLineChange' + execute 'sign define SignifyChangeDeleteMore text='. s:sign_change .'> texthl=SignifySignChange linehl=SignifyLineChange' + + execute 'sign define SignifyDelete1 text='. s:sign_delete .'1 texthl=SignifySignDelete linehl=SignifyLineDelete' + execute 'sign define SignifyDelete2 text='. s:sign_delete .'2 texthl=SignifySignDelete linehl=SignifyLineDelete' + execute 'sign define SignifyDelete3 text='. s:sign_delete .'3 texthl=SignifySignDelete linehl=SignifyLineDelete' + execute 'sign define SignifyDelete4 text='. s:sign_delete .'4 texthl=SignifySignDelete linehl=SignifyLineDelete' + execute 'sign define SignifyDelete5 text='. s:sign_delete .'5 texthl=SignifySignDelete linehl=SignifyLineDelete' + execute 'sign define SignifyDelete6 text='. s:sign_delete .'6 texthl=SignifySignDelete linehl=SignifyLineDelete' + execute 'sign define SignifyDelete7 text='. s:sign_delete .'7 texthl=SignifySignDelete linehl=SignifyLineDelete' + execute 'sign define SignifyDelete8 text='. s:sign_delete .'8 texthl=SignifySignDelete linehl=SignifyLineDelete' + execute 'sign define SignifyDelete9 text='. s:sign_delete .'9 texthl=SignifySignDelete linehl=SignifyLineDelete' + execute 'sign define SignifyDeleteMore text='. s:sign_delete .'> texthl=SignifySignDelete linehl=SignifyLineDelete' + + execute 'sign define SignifyDeleteFirstLine text='. s:sign_delete_first_line ' texthl=SignifySignDelete linehl=SignifyLineDelete' + + let g:signify_line_highlight = 1 +endfunction + +" Function: #line_disable {{{1 +function! sy#highlight#line_disable() abort + execute 'sign define SignifyAdd text='. s:sign_add ' texthl=SignifySignAdd linehl=none' + + execute 'sign define SignifyChange text='. s:sign_change ' texthl=SignifySignChange linehl=none' + execute 'sign define SignifyChangeDelete1 text='. s:sign_change .'1 texthl=SignifySignChange linehl=none' + execute 'sign define SignifyChangeDelete2 text='. s:sign_change .'2 texthl=SignifySignChange linehl=none' + execute 'sign define SignifyChangeDelete3 text='. s:sign_change .'3 texthl=SignifySignChange linehl=none' + execute 'sign define SignifyChangeDelete4 text='. s:sign_change .'4 texthl=SignifySignChange linehl=none' + execute 'sign define SignifyChangeDelete5 text='. s:sign_change .'5 texthl=SignifySignChange linehl=none' + execute 'sign define SignifyChangeDelete6 text='. s:sign_change .'6 texthl=SignifySignChange linehl=none' + execute 'sign define SignifyChangeDelete7 text='. s:sign_change .'7 texthl=SignifySignChange linehl=none' + execute 'sign define SignifyChangeDelete8 text='. s:sign_change .'8 texthl=SignifySignChange linehl=none' + execute 'sign define SignifyChangeDelete9 text='. s:sign_change .'9 texthl=SignifySignChange linehl=none' + execute 'sign define SignifyChangeDeleteMore text='. s:sign_change .'> texthl=SignifySignChange linehl=none' + + execute 'sign define SignifyDelete1 text='. s:sign_delete .'1 texthl=SignifySignDelete linehl=none' + execute 'sign define SignifyDelete2 text='. s:sign_delete .'2 texthl=SignifySignDelete linehl=none' + execute 'sign define SignifyDelete3 text='. s:sign_delete .'3 texthl=SignifySignDelete linehl=none' + execute 'sign define SignifyDelete4 text='. s:sign_delete .'4 texthl=SignifySignDelete linehl=none' + execute 'sign define SignifyDelete5 text='. s:sign_delete .'5 texthl=SignifySignDelete linehl=none' + execute 'sign define SignifyDelete6 text='. s:sign_delete .'6 texthl=SignifySignDelete linehl=none' + execute 'sign define SignifyDelete7 text='. s:sign_delete .'7 texthl=SignifySignDelete linehl=none' + execute 'sign define SignifyDelete8 text='. s:sign_delete .'8 texthl=SignifySignDelete linehl=none' + execute 'sign define SignifyDelete9 text='. s:sign_delete .'9 texthl=SignifySignDelete linehl=none' + execute 'sign define SignifyDeleteMore text='. s:sign_delete .'> texthl=SignifySignDelete linehl=none' + + execute 'sign define SignifyDeleteFirstLine text='. s:sign_delete_first_line ' texthl=SignifySignDelete linehl=none' + + let g:signify_line_highlight = 0 +endfunction + +" Function: #line_toggle {{{1 +function! sy#highlight#line_toggle() abort + if !has_key(g:sy, g:sy_path) + echomsg 'signify: I cannot detect any changes!' + return + endif + + if g:signify_line_highlight + call sy#highlight#line_disable() + else + call sy#highlight#line_enable() + endif + + call sy#start(g:sy_path) +endfunction + +" vim: et sw=2 sts=2 diff --git a/autoload/sy/jump.vim b/autoload/sy/jump.vim new file mode 100644 index 0000000..77e0c8d --- /dev/null +++ b/autoload/sy/jump.vim @@ -0,0 +1,38 @@ +if exists('b:autoloaded_sy_jump') + finish +endif +let b:autoloaded_sy_jump = 1 + +" Function: #next_hunk {{{1 +function! sy#jump#next_hunk(count) + if !has_key(g:sy, g:sy_path) + echomsg 'signify: I cannot detect any changes!' + return + endif + + let lnum = line('.') + let hunks = filter(copy(g:sy[g:sy_path].hunks), 'v:val.start > lnum') + let hunk = get(hunks, a:count - 1, {}) + + if !empty(hunk) + execute 'sign jump '. hunk.ids[0] .' file='. g:sy_path + endif +endfunction + +" Function: #prev_hunk {{{1 +function! sy#jump#prev_hunk(count) + if !has_key(g:sy, g:sy_path) + echomsg 'signify: I cannot detect any changes!' + return + endif + + let lnum = line('.') + let hunks = filter(copy(g:sy[g:sy_path].hunks), 'v:val.start < lnum') + let hunk = get(hunks, 0 - a:count, {}) + + if !empty(hunk) + execute 'sign jump '. hunk.ids[0] .' file='. g:sy_path + endif +endfunction + +" vim: et sw=2 sts=2 diff --git a/autoload/sy/repo.vim b/autoload/sy/repo.vim index f7b3d1a..d433971 100644 --- a/autoload/sy/repo.vim +++ b/autoload/sy/repo.vim @@ -1,9 +1,30 @@ if exists('b:autoloaded_sy_repo') - finish + finish endif let b:autoloaded_sy_repo = 1 -" Function: sy#repo#detect {{{1 +" Init: values {{{1 +if !empty(get(g:, 'signify_difftool')) + let s:difftool = g:signify_difftool +else + if has('win32') + if $VIMRUNTIME =~ ' ' + let s:difftool = (&sh =~ '\/dev/null') + let diff = system('rcsdiff -U0 '. sy#util#escape(a:path) .' 2>/dev/null') return v:shell_error ? '' : diff endif endfunction -" Function: sy#repo#get_diff_accurev {{{1 +" Function: #get_diff_accurev {{{1 function! sy#repo#get_diff_accurev(path) abort if executable('accurev') - let diff = system('cd '. sy#utils#escape(fnamemodify(a:path, ':h')) .' && accurev diff '. sy#utils#escape(fnamemodify(a:path, ':t')) . ' -- -U0') + let diff = system('cd '. sy#util#escape(fnamemodify(a:path, ':h')) .' && accurev diff '. sy#util#escape(fnamemodify(a:path, ':t')) . ' -- -U0') return (v:shell_error != 1) ? '' : diff endif endfunction -" Function: sy#repo#process_diff {{{1 +" Function: #process_diff {{{1 function! sy#repo#process_diff(path, diff) abort " Determine where we have to put our signs. for line in filter(split(a:diff, '\n'), 'v:val =~ "^@@ "') @@ -141,11 +162,11 @@ function! sy#repo#process_diff(path, diff) abort let offset += 1 endwhile - " 2 lines removed: + " 2 lines removed: - " @@ -6,2 +5,0 @@ this is line 5 - " -this is line 6 - " -this is line 7 + " @@ -6,2 +5,0 @@ this is line 5 + " -this is line 6 + " -this is line 7 elseif (old_count >= 1) && (new_count == 0) if new_line == 0 @@ -154,13 +175,13 @@ function! sy#repo#process_diff(path, diff) abort call add(signs, { 'type': (old_count > 9) ? 'SignifyDeleteMore' : 'SignifyDelete'. old_count, 'lnum': new_line, 'path': a:path }) endif - " 2 lines changed: + " 2 lines changed: - " @@ -5,2 +5,2 @@ this is line 4 - " -this is line 5 - " -this is line 6 - " +this os line 5 - " +this os line 6 + " @@ -5,2 +5,2 @@ this is line 4 + " -this is line 5 + " -this is line 6 + " +this os line 5 + " +this os line 6 elseif old_count == new_count let offset = 0 @@ -189,13 +210,13 @@ function! sy#repo#process_diff(path, diff) abort let deleted = old_count - new_count call add(signs, { 'type': (deleted > 9) ? 'SignifyChangeDeleteMore' : 'SignifyChangeDelete'. deleted, 'lnum': new_line, 'path': a:path }) - " lines changed and added: + " lines changed and added: - " @@ -5 +5,3 @@ this is line 4 - " -this is line 5 - " +this os line 5 - " +this is line 42 - " +this is line 666 + " @@ -5 +5,3 @@ this is line 4 + " -this is line 5 + " +this os line 5 + " +this is line 42 + " +this is line 666 else let offset = 0 @@ -209,7 +230,8 @@ function! sy#repo#process_diff(path, diff) abort endwhile endif endif - call s:sign_set(signs) + call sy#sign#set(signs) endfor endfunction +" vim: et sw=2 sts=2 diff --git a/autoload/sy/sign.vim b/autoload/sy/sign.vim new file mode 100644 index 0000000..e1848d2 --- /dev/null +++ b/autoload/sy/sign.vim @@ -0,0 +1,51 @@ +if exists('b:autoloaded_sy_sign') + finish +endif +let b:autoloaded_sy_sign = 1 + +" Init: values {{{1 +let s:other_signs_line_numbers = {} + +" Function: #get_others {{{1 +function! sy#sign#get_others(path) abort + redir => signlist + silent! execute 'sign place file='. a:path + redir END + + for line in filter(split(signlist, '\n'), 'v:val =~ "^\\s\\+line"') + let lnum = matchlist(line, '\v^\s+line\=(\d+)')[1] + let s:other_signs_line_numbers[lnum] = 1 + endfor +endfunction + +" Function: #set {{{1 +function! sy#sign#set(signs) + let hunk = { 'ids': [], 'start': a:signs[0].lnum, 'end': a:signs[-1].lnum } + for sign in a:signs + " Preserve non-signify signs + if !g:signify_sign_overwrite && has_key(s:other_signs_line_numbers, sign.lnum) + next + endif + + call add(hunk.ids, g:id_top) + execute 'sign place '. g:id_top .' line='. sign.lnum .' name='. sign.type .' file='. sign.path + + let g:id_top += 1 + endfor + call add(g:sy[sign.path].hunks, hunk) +endfunction + +" Function: #remove_all {{{1 +function! sy#sign#remove_all(path) abort + for hunk in g:sy[a:path].hunks + for id in hunk.ids + execute 'sign unplace '. id + endfor + endfor + + let s:other_signs_line_numbers = {} + let g:sy[a:path].hunks = [] +endfunction + + +" vim: et sw=2 sts=2 diff --git a/autoload/sy/util.vim b/autoload/sy/util.vim new file mode 100644 index 0000000..697296d --- /dev/null +++ b/autoload/sy/util.vim @@ -0,0 +1,27 @@ +if exists('b:autoloaded_sy_util') + finish +endif +let b:autoloaded_sy_util = 1 + +" Function: #escape {{{1 +function! sy#util#escape(path) abort + if exists('+shellslash') + let old_ssl = &shellslash + set noshellslash + endif + + let path = shellescape(a:path) + + if exists('old_ssl') + let &shellslash = old_ssl + endif + + return path +endfunction + +" Function: #separator {{{1 +function! sy#util#separator() abort + return !exists('+shellslash') || &shellslash ? '/' : '\' +endfunction + +" vim: et sw=2 sts=2 diff --git a/autoload/sy/utils.vim b/autoload/sy/utils.vim deleted file mode 100644 index 2a6e21a..0000000 --- a/autoload/sy/utils.vim +++ /dev/null @@ -1,27 +0,0 @@ -if exists('b:autoloaded_sy_utils') - finish -endif -let b:autoloaded_sy_utils = 1 - -" Function: #escape {{{1 -function! sy#utils#escape(path) abort - if exists('+shellslash') - let old_ssl = &shellslash - set noshellslash - endif - - let path = shellescape(a:path) - - if exists('old_ssl') - let &shellslash = old_ssl - endif - - return path -endfunction - -" Function: #separator {{{1 -function! sy#utils#separator() abort - return !exists('+shellslash') || &shellslash ? '/' : '\' -endfunction - -" vim: et sw=2 sts=2 diff --git a/plugin/signify.vim b/plugin/signify.vim index 52a13e2..e71b620 100644 --- a/plugin/signify.vim +++ b/plugin/signify.vim @@ -9,88 +9,55 @@ endif let g:loaded_signify = 1 " Init: values {{{1 -let s:sy = {} " the main data structure -let s:other_signs_line_numbers = {} - -" overwrite non-signify signs by default -let s:sign_overwrite = get(g:, 'signify_sign_overwrite', 1) - -let s:id_start = 0x100 -let s:id_top = s:id_start - -let s:sign_add = get(g:, 'signify_sign_add', '+') -let s:sign_delete = get(g:, 'signify_sign_delete', '_') -let s:sign_delete_first_line = get(g:, 'signify_sign_delete_first_line', '‾') -let s:sign_change = get(g:, 'signify_sign_change', '!') - -if !empty(get(g:, 'signify_difftool')) - let s:difftool = g:signify_difftool -else - if has('win32') - if $VIMRUNTIME =~ ' ' - let s:difftool = (&sh =~ '\:p')) - autocmd BufRead,BufWritePost * call s:start(s:path) + autocmd VimEnter * call sy#highlight#setup() + autocmd BufRead,BufEnter * let g:sy_path = resolve(expand(':p')) + autocmd BufRead,BufWritePost * call sy#start(g:sy_path) autocmd BufDelete * \ let path = resolve(expand(':p')) | - \ call s:stop(path) | - \ if has_key(s:sy, path) | - \ call remove(s:sy, path) | + \ call sy#stop(path) | + \ if has_key(g:sy, path) | + \ call remove(g:sy, path) | \ endif if get(g:, 'signify_update_on_bufenter') autocmd BufEnter * nested - \ if has_key(s:sy, s:path) && s:sy[s:path].active && &modified | + \ if has_key(g:sy, g:sy_path) && g:sy[g:sy_path].active && &modified | \ write | \ endif endif if get(g:, 'signify_cursorhold_normal') autocmd CursorHold * nested - \ if has_key(s:sy, s:path) && s:sy[s:path].active && &modified | + \ if has_key(g:sy, g:sy_path) && g:sy[g:sy_path].active && &modified | \ write | \ endif endif if get(g:, 'signify_cursorhold_insert') autocmd CursorHoldI * nested - \ if has_key(s:sy, s:path) && s:sy[s:path].active && &modified | + \ if has_key(g:sy, g:sy_path) && g:sy[g:sy_path].active && &modified | \ write | \ endif endif if !has('gui_win32') - autocmd FocusGained * call s:start(s:path) + autocmd FocusGained * call sy#start(g:sy_path) endif augroup END " Init: commands {{{1 -com! -nargs=0 -bar SignifyToggle call s:toggle() -com! -nargs=0 -bar SignifyToggleHighlight call s:highlight_line_toggle() -com! -nargs=0 -bar -count SignifyJumpToNextHunk call s:jump_to_next_hunk() -com! -nargs=0 -bar -count SignifyJumpToPrevHunk call s:jump_to_prev_hunk() +com! -nargs=0 -bar SignifyToggle call sy#toggle() +com! -nargs=0 -bar SignifyToggleHighlight call sy#highlight#line_toggle() +com! -nargs=0 -bar -count SignifyJumpToNextHunk call sy#jump#next_hunk() +com! -nargs=0 -bar -count SignifyJumpToPrevHunk call sy#jump#prev_hunk() +com! -nargs=0 -bar SyDebug call sy#debug#list_active_buffers() " Init: mappings {{{1 if exists('g:signify_mapping_next_hunk') @@ -117,275 +84,3 @@ else nnoremap gt :SignifyToggle endif -" Function: s:start {{{1 -function! s:start(path) abort - if !filereadable(a:path) - \ || (exists('g:signify_skip_filetype') && has_key(g:signify_skip_filetype, &ft)) - \ || (exists('g:signify_skip_filename') && has_key(g:signify_skip_filename, a:path)) - return - endif - - " new buffer.. add to list - if !has_key(s:sy, a:path) - let [ diff, type ] = sy#repo#detect(a:path) - if empty(diff) - return - endif - if get(g:, 'signify_disable_by_default') - let s:sy[a:path] = { 'active': 0, 'type': type, 'hunks': [], 'id_top': s:id_top } - return - endif - let s:sy[a:path] = { 'active': 1, 'type': type, 'hunks': [], 'id_top': s:id_top } - " inactive buffer.. bail out - elseif !s:sy[a:path].active - return - " update signs - else - let diff = sy#repo#get_diff_{s:sy[a:path].type}(a:path) - if empty(diff) - call s:sign_remove_all(a:path) - return - endif - let s:sy[a:path].id_top = s:id_top - endif - - if !exists('s:line_highlight') - if get(g:, 'signify_line_highlight') - call s:highlight_line_enable() - else - call s:highlight_line_disable() - endif - endif - - if !s:sign_overwrite - call s:sign_get_others(a:path) - endif - - execute 'sign place 99999 line=1 name=SignifyPlaceholder file='. a:path - call s:sign_remove_all(a:path) - call sy#repo#process_diff(a:path, diff) - sign unplace 99999 - - if !maparg('[c', 'n') - nnoremap ]c :execute v:count1 .'SignifyJumpToNextHunk' - nnoremap [c :execute v:count1 .'SignifyJumpToPrevHunk' - endif - - let s:sy[a:path].id_top = (s:id_top - 1) -endfunction - -" Function: s:stop {{{1 -function! s:stop(path) abort - if !has_key(s:sy, a:path) - return - endif - - call s:sign_remove_all(a:path) - - silent! nunmap ]c - silent! nunmap [c - - augroup signify - autocmd! * - augroup END -endfunction - -" Function: s:toggle {{{1 -function! s:toggle() abort - if empty(s:path) - echomsg 'signify: I cannot sy empty buffers!' - return - endif - - if has_key(s:sy, s:path) - if s:sy[s:path].active - call s:stop(s:path) - let s:sy[s:path].active = 0 - else - let s:sy[s:path].active = 1 - call s:start(s:path) - endif - else - call s:start(s:path) - endif -endfunction - -" Function: s:sign_get_others {{{1 -function! s:sign_get_others(path) abort - redir => signlist - silent! execute 'sign place file='. a:path - redir END - - for line in filter(split(signlist, '\n'), 'v:val =~ "^\\s\\+line"') - let lnum = matchlist(line, '\v^\s+line\=(\d+)')[1] - let s:other_signs_line_numbers[lnum] = 1 - endfor -endfunction - -" Function: s:sign_set {{{1 -function! s:sign_set(signs) - let hunk = { 'ids': [], 'start': a:signs[0].lnum, 'end': a:signs[-1].lnum } - for sign in a:signs - " Preserve non-signify signs - if !s:sign_overwrite && has_key(s:other_signs_line_numbers, sign.lnum) - next - endif - - call add(hunk.ids, s:id_top) - execute 'sign place '. s:id_top .' line='. sign.lnum .' name='. sign.type .' file='. sign.path - - let s:id_top += 1 - endfor - call add(s:sy[sign.path].hunks, hunk) -endfunction - -" Function: s:sign_remove_all {{{1 -function! s:sign_remove_all(path) abort - for hunk in s:sy[a:path].hunks - for id in hunk.ids - execute 'sign unplace '. id - endfor - endfor - - let s:other_signs_line_numbers = {} - let s:sy[a:path].hunks = [] -endfunction - -" Function: s:highlight_setup {{{1 -function! s:highlight_setup() abort - highlight link SignifyLineAdd DiffAdd - highlight link SignifyLineChange DiffChange - highlight link SignifyLineDelete DiffDelete - highlight link SignifySignAdd DiffAdd - highlight link SignifySignChange DiffChange - highlight link SignifySignDelete DiffDelete -endfunction - -" Function: s:highlight_line_enable {{{1 -function! s:highlight_line_enable() abort - execute 'sign define SignifyAdd text='. s:sign_add ' texthl=SignifySignAdd linehl=SignifyLineAdd' - - execute 'sign define SignifyChange text='. s:sign_change ' texthl=SignifySignChange linehl=SignifyLineChange' - execute 'sign define SignifyChangeDelete1 text='. s:sign_change .'1 texthl=SignifySignChange linehl=SignifyLineChange' - execute 'sign define SignifyChangeDelete2 text='. s:sign_change .'2 texthl=SignifySignChange linehl=SignifyLineChange' - execute 'sign define SignifyChangeDelete3 text='. s:sign_change .'3 texthl=SignifySignChange linehl=SignifyLineChange' - execute 'sign define SignifyChangeDelete4 text='. s:sign_change .'4 texthl=SignifySignChange linehl=SignifyLineChange' - execute 'sign define SignifyChangeDelete5 text='. s:sign_change .'5 texthl=SignifySignChange linehl=SignifyLineChange' - execute 'sign define SignifyChangeDelete6 text='. s:sign_change .'6 texthl=SignifySignChange linehl=SignifyLineChange' - execute 'sign define SignifyChangeDelete7 text='. s:sign_change .'7 texthl=SignifySignChange linehl=SignifyLineChange' - execute 'sign define SignifyChangeDelete8 text='. s:sign_change .'8 texthl=SignifySignChange linehl=SignifyLineChange' - execute 'sign define SignifyChangeDelete9 text='. s:sign_change .'9 texthl=SignifySignChange linehl=SignifyLineChange' - execute 'sign define SignifyChangeDeleteMore text='. s:sign_change .'> texthl=SignifySignChange linehl=SignifyLineChange' - - execute 'sign define SignifyDelete1 text='. s:sign_delete .'1 texthl=SignifySignDelete linehl=SignifyLineDelete' - execute 'sign define SignifyDelete2 text='. s:sign_delete .'2 texthl=SignifySignDelete linehl=SignifyLineDelete' - execute 'sign define SignifyDelete3 text='. s:sign_delete .'3 texthl=SignifySignDelete linehl=SignifyLineDelete' - execute 'sign define SignifyDelete4 text='. s:sign_delete .'4 texthl=SignifySignDelete linehl=SignifyLineDelete' - execute 'sign define SignifyDelete5 text='. s:sign_delete .'5 texthl=SignifySignDelete linehl=SignifyLineDelete' - execute 'sign define SignifyDelete6 text='. s:sign_delete .'6 texthl=SignifySignDelete linehl=SignifyLineDelete' - execute 'sign define SignifyDelete7 text='. s:sign_delete .'7 texthl=SignifySignDelete linehl=SignifyLineDelete' - execute 'sign define SignifyDelete8 text='. s:sign_delete .'8 texthl=SignifySignDelete linehl=SignifyLineDelete' - execute 'sign define SignifyDelete9 text='. s:sign_delete .'9 texthl=SignifySignDelete linehl=SignifyLineDelete' - execute 'sign define SignifyDeleteMore text='. s:sign_delete .'> texthl=SignifySignDelete linehl=SignifyLineDelete' - - execute 'sign define SignifyDeleteFirstLine text='. s:sign_delete_first_line ' texthl=SignifySignDelete linehl=SignifyLineDelete' - - let s:line_highlight = 1 -endfunction - -" Function: s:highlight_line_disable {{{1 -function! s:highlight_line_disable() abort - execute 'sign define SignifyAdd text='. s:sign_add ' texthl=SignifySignAdd linehl=none' - - execute 'sign define SignifyChange text='. s:sign_change ' texthl=SignifySignChange linehl=none' - execute 'sign define SignifyChangeDelete1 text='. s:sign_change .'1 texthl=SignifySignChange linehl=none' - execute 'sign define SignifyChangeDelete2 text='. s:sign_change .'2 texthl=SignifySignChange linehl=none' - execute 'sign define SignifyChangeDelete3 text='. s:sign_change .'3 texthl=SignifySignChange linehl=none' - execute 'sign define SignifyChangeDelete4 text='. s:sign_change .'4 texthl=SignifySignChange linehl=none' - execute 'sign define SignifyChangeDelete5 text='. s:sign_change .'5 texthl=SignifySignChange linehl=none' - execute 'sign define SignifyChangeDelete6 text='. s:sign_change .'6 texthl=SignifySignChange linehl=none' - execute 'sign define SignifyChangeDelete7 text='. s:sign_change .'7 texthl=SignifySignChange linehl=none' - execute 'sign define SignifyChangeDelete8 text='. s:sign_change .'8 texthl=SignifySignChange linehl=none' - execute 'sign define SignifyChangeDelete9 text='. s:sign_change .'9 texthl=SignifySignChange linehl=none' - execute 'sign define SignifyChangeDeleteMore text='. s:sign_change .'> texthl=SignifySignChange linehl=none' - - execute 'sign define SignifyDelete1 text='. s:sign_delete .'1 texthl=SignifySignDelete linehl=none' - execute 'sign define SignifyDelete2 text='. s:sign_delete .'2 texthl=SignifySignDelete linehl=none' - execute 'sign define SignifyDelete3 text='. s:sign_delete .'3 texthl=SignifySignDelete linehl=none' - execute 'sign define SignifyDelete4 text='. s:sign_delete .'4 texthl=SignifySignDelete linehl=none' - execute 'sign define SignifyDelete5 text='. s:sign_delete .'5 texthl=SignifySignDelete linehl=none' - execute 'sign define SignifyDelete6 text='. s:sign_delete .'6 texthl=SignifySignDelete linehl=none' - execute 'sign define SignifyDelete7 text='. s:sign_delete .'7 texthl=SignifySignDelete linehl=none' - execute 'sign define SignifyDelete8 text='. s:sign_delete .'8 texthl=SignifySignDelete linehl=none' - execute 'sign define SignifyDelete9 text='. s:sign_delete .'9 texthl=SignifySignDelete linehl=none' - execute 'sign define SignifyDeleteMore text='. s:sign_delete .'> texthl=SignifySignDelete linehl=none' - - execute 'sign define SignifyDeleteFirstLine text='. s:sign_delete_first_line ' texthl=SignifySignDelete linehl=none' - - let s:line_highlight = 0 -endfunction - -" Function: s:highlight_line_toggle {{{1 -function! s:highlight_line_toggle() abort - if !has_key(s:sy, s:path) - echomsg 'signify: I cannot detect any changes!' - return - endif - - if s:line_highlight - call s:highlight_line_disable() - else - call s:highlight_line_enable() - endif - - call s:start(s:path) -endfunction - -" Function: s:jump_to_next_hunk {{{1 -function! s:jump_to_next_hunk(count) - if !has_key(s:sy, s:path) - echomsg 'signify: I cannot detect any changes!' - return - endif - - let lnum = line('.') - let hunks = filter(copy(s:sy[s:path].hunks), 'v:val.start > lnum') - let hunk = get(hunks, a:count - 1, {}) - - if !empty(hunk) - execute 'sign jump '. hunk.ids[0] .' file='. s:path - endif -endfunction - -" Function: s:jump_to_prev_hunk {{{1 -function! s:jump_to_prev_hunk(count) - if !has_key(s:sy, s:path) - echomsg 'signify: I cannot detect any changes!' - return - endif - - let lnum = line('.') - let hunks = filter(copy(s:sy[s:path].hunks), 'v:val.start < lnum') - let hunk = get(hunks, 0 - a:count, {}) - - if !empty(hunk) - execute 'sign jump '. hunk.ids[0] .' file='. s:path - endif -endfunction - -" Function: SignifyDebugListActiveBuffers {{{1 -function! SignifyDebugListActiveBuffers() abort - if empty(s:sy) - echomsg 'No active buffers!' - return - endif - - for [path, stats] in items(s:sy) - echo "\n". path ."\n". repeat('=', strlen(path)) - for stat in sort(keys(stats)) - echo printf("%20s = %s\n", stat, string(stats[stat])) - endfor - endfor -endfunction - -" vim: et sw=2 sts=2