From d420a445363bef98dc50fd622c5c96b202abd605 Mon Sep 17 00:00:00 2001 From: Andy Stewart Date: Tue, 7 Jan 2014 13:34:21 +0100 Subject: [PATCH] Reduce duplicate work due to overlapping autocommands. --- README.mkd | 18 ++++++----- plugin/gitgutter.vim | 75 ++++++++++++++++++++++++++++---------------- 2 files changed, 58 insertions(+), 35 deletions(-) diff --git a/README.mkd b/README.mkd index fc9ac2d..ab49532 100644 --- a/README.mkd +++ b/README.mkd @@ -74,12 +74,12 @@ See the customisation section below for how to change the defaults. By default the signs are updated when you: -* Stop typing -* Change buffer -* Change tab -* Save a buffer -* Change a file outside Vim -* Focus the GUI. +* Stop typing (realtime) +* Change buffer (eager) +* Change tab (eager) +* Save a buffer (always) +* Change a file outside Vim (always) +* Focus the GUI (eager but not gVim on Windows). This can cause a noticeable lag on some systems so you can configure the plugin to update less often. See the customisation section below. @@ -200,7 +200,7 @@ let g:gitgutter_realtime = 0 #### To stop vim-gitgutter running eagerly -By default the plugin also runs every time you read a file, on `BufEnter`, `TabEnter` and `FocusGained`. +By default the plugin also runs on `BufEnter` (to notice `git add` outside vim), `TabEnter` and `FocusGained`. This can cause a noticeable lag for some people so you can set the plugin to run instead only when you read or write a file. @@ -210,7 +210,9 @@ To turn off eager execution, add this to your `~/.vimrc`: let g:gitgutter_eager = 0 ``` -Note that `FocusGained` cannot be used with gVim on Windows due to a Vim/shell bug causing an infinite loop. +Note that `FocusGained` is not activated in gVim on Windows due to a Vim/shell bug causing an infinite loop. + +The plugin always runs on `FileChangedShellPost` to notice `git stash` outside vim. ### FAQ diff --git a/plugin/gitgutter.vim b/plugin/gitgutter.vim index ff9d007..22e346f 100644 --- a/plugin/gitgutter.vim +++ b/plugin/gitgutter.vim @@ -38,38 +38,51 @@ call highlight#define_signs() " Public interface {{{ function! GitGutterAll() - for buffer_id in tabpagebuflist() - call GitGutter(expand('#' . buffer_id . ':p')) + for buffer_id in tabpagebuflist() + let file = expand('#' . buffer_id . ':p') + if !empty(file) + call GitGutter(file, 0, 0) + endif endfor endfunction command GitGutterAll call GitGutterAll() -" Supply optional argument to use realtime mode. -function! GitGutter(file, ...) - call utility#set_file(a:file) - if utility#is_active() - if (a:0 == 1) || utility#has_unsaved_changes(a:file) - let diff = diff#run_diff(1) - else - let diff = diff#run_diff(0) - endif - let s:hunks = diff#parse_diff(diff) - let modified_lines = diff#process_hunks(s:hunks) - if g:gitgutter_sign_column_always - call sign#add_dummy_sign() - else - if utility#differences(s:hunks) - call sign#add_dummy_sign() " prevent flicker +" Does the actual work. +" +" file: (string) the file to process. +" realtime: (boolean) when truthy, do a realtime diff; otherwise do a disk-based diff. +" fresh_changes: (boolean) when truthy, only process if there are buffer changes +" since the last gitgutter process; otherwise always process. +function! GitGutter(file, realtime, fresh_changes) + if !a:fresh_changes || getbufvar(a:file, 'changedtick') != getbufvar(a:file, 'gitgutter_last_tick', -1) + + call utility#set_file(a:file) + if utility#is_active() + if a:realtime || utility#has_unsaved_changes(a:file) + let diff = diff#run_diff(1) else - call sign#remove_dummy_sign() + let diff = diff#run_diff(0) endif + let s:hunks = diff#parse_diff(diff) + let modified_lines = diff#process_hunks(s:hunks) + if g:gitgutter_sign_column_always + call sign#add_dummy_sign() + else + if utility#differences(s:hunks) + call sign#add_dummy_sign() " prevent flicker + else + call sign#remove_dummy_sign() + endif + endif + call sign#update_signs(a:file, modified_lines) + else + call hunk#reset() endif - call sign#update_signs(a:file, modified_lines) - else - call hunk#reset() + + call setbufvar(a:file, 'gitgutter_last_tick', getbufvar(a:file, 'changedtick')) endif endfunction -command GitGutter call GitGutter(utility#current_file()) +command GitGutter call GitGutter(utility#current_file(), 0, 0) function! GitGutterDisable() let g:gitgutter_enabled = 0 @@ -189,18 +202,26 @@ augroup gitgutter autocmd! if g:gitgutter_realtime - autocmd CursorHold,CursorHoldI * call GitGutter(utility#current_file(), 1) + autocmd CursorHold,CursorHoldI * call GitGutter(utility#current_file(), 1, 1) endif if g:gitgutter_eager - autocmd BufEnter,BufWritePost,FileWritePost,FileChangedShellPost * call GitGutter(utility#current_file()) - autocmd TabEnter * call GitGutterAll() + autocmd BufEnter,BufWritePost,FileChangedShellPost * + \ if gettabvar(tabpagenr(), 'gitgutter_didtabenter') + \| call settabvar(tabpagenr(), 'gitgutter_didtabenter', 0) + \| else + \| call GitGutter(utility#current_file(), 0, 0) + \| endif + autocmd TabEnter * + \ call settabvar(tabpagenr(), 'gitgutter_didtabenter', 1) + \| call GitGutterAll() if !has('gui_win32') autocmd FocusGained * call GitGutterAll() endif else - autocmd BufReadPost,BufWritePost,FileReadPost,FileWritePost,FileChangedShellPost * call GitGutter(utility#current_file()) + autocmd BufRead,BufWritePost,FileChangedShellPost * call GitGutter(utility#current_file()) endif + autocmd ColorScheme * call highlight#define_sign_column_highlight() | call highlight#define_highlights() augroup END