Created
November 21, 2018 03:17
-
-
Save veirus/c5bb16edbbbbbc0a484f6130adbe5ff5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" It's probably not exactly what you want, because you mentioned autocmds in the original post, but you may be interested in :h :DiffOrig. FWIW, here's a modified version of this custom command which I'm using: | |
com! -bar DiffOrig echo s:diff_orig() | |
fu! s:diff_orig() abort | |
let cole_save = &l:cole | |
setl cole=0 | |
vnew | |
setl bh=wipe nobl bt=nofile noswf | |
sil 0r # | |
$d_ | |
diffthis | |
sil file Original\ File | |
nno <buffer><nowait><silent> q :<c-u>close<cr> | |
let &ft = getbufvar('#', '&ft') | |
setl noma ro | |
let s:tmp_partial = function('s:diff_orig_restore_settings', [cole_save]) | |
augroup diff_orig_restore_settings | |
au! * <buffer> | |
au BufWipeOut <buffer> call timer_start(0, s:tmp_partial) | |
augroup END | |
exe winnr('#').'windo diffthis' | |
return '' | |
endfu | |
fu! s:diff_orig_restore_settings(cole,_) abort | |
exe 'setl cole='.a:cole | |
diffoff! | |
norm! zvzz | |
aug! diff_orig_restore_settings | |
unlet s:tmp_partial | |
endfu | |
" If you execute :DiffOrig in a buffer, it should open a vertical viewport displaying the contents of the original file, and all the differences between the current buffer and the latter. | |
" Edit: | |
" Alternatively, you could try this: | |
fu! s:snr() | |
return matchstr(expand('<sfile>'), '<SNR>\d\+_') | |
endfu | |
fu! s:diff_indicator() abort | |
if exists('b:diff_indicator') | |
return b:diff_indicator | |
endif | |
if !&l:modified || expand('%:p') == '' || &bt != '' | |
return '' | |
endif | |
let buf = getbufline('%', 1, '$') | |
let buf_max_lines = len(buf) | |
let file = readfile(expand('%:p')) | |
let file_max_lines = len(file) | |
if buf_max_lines != file_max_lines | |
let b:diff_indicator = '[!=]' | |
return b:diff_indicator | |
endif | |
for i in range(1,buf_max_lines) | |
if buf[i-1] !=# file[i-1] | |
let b:diff_indicator = '[!=]' | |
return b:diff_indicator | |
endif | |
endfor | |
let b:diff_indicator = '[==]' | |
return b:diff_indicator | |
endfu | |
let &stl .= ' %{'.s:snr().'diff_indicator()}' | |
augroup reset_diff_indicator | |
au! | |
au CursorHold * unlet! b:diff_indicator | |
augroup END | |
" It should add an indicator in the statusline, and update it every time CursorHold is fired. This event is fired every &updatetime ms (4s by default). If you find it's too long, you could reduce the value of the 'updatetime' option, or you could use a timer. In this case, you would replace the autocmd listening to CursorHold with this one: | |
" au VimEnter * call timer_start(1000, {-> execute('unlet! b:diff_indicator')}, {'repeat': -1}) | |
" Here, the timer would cause the indicator to be updated every second, but you could change the value with whatever you prefer. | |
" Edit 2: | |
" If you notice a negative impact on Vim's performance, you may make listen your autocmd to TextChanged and TextChangedI. You would need to start a timer to reset the statusline indicator every time one of these events is fired. And prior to that, you would need to stop a possible previous timer. It would give something like: | |
fu! s:snr() | |
return matchstr(expand('<sfile>'), '<SNR>\d\+_') | |
endfu | |
fu! s:diff_indicator() abort | |
if !&l:modified || &l:buftype != '' || expand('%:p') == '' | |
return '' | |
endif | |
if exists('b:diff_indicator') | |
return b:diff_indicator | |
endif | |
let buf = getbufline('%', 1, '$') | |
let buf_max_lines = len(buf) | |
let file = readfile(expand('%:p')) | |
let file_max_lines = len(file) | |
if buf_max_lines != file_max_lines | |
let b:diff_indicator = '[!=]' | |
return b:diff_indicator | |
endif | |
for i in range(1,buf_max_lines) | |
if buf[i-1] !=# file[i-1] | |
let b:diff_indicator = '[!=]' | |
return b:diff_indicator | |
endif | |
endfor | |
let b:diff_indicator = '[==]' | |
return b:diff_indicator | |
endfu | |
let &stl .= ' %{'.s:snr().'diff_indicator()}' | |
augroup reset_diff_indicator | |
au! | |
au TextChanged,TextChangedI * call s:reset_diff_indicator() | |
augroup END | |
fu! s:reset_diff_indicator() abort | |
if exists('s:unlet_diff_indicator') | |
call timer_stop(s:unlet_diff_indicator) | |
endif | |
let s:unlet_diff_indicator = timer_start(500, | |
\ {-> execute('unlet! b:diff_indicator s:unlet_diff_indicator | redraws')}) | |
endfu |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment