+ git-time-lapse
This commit is contained in:
parent
e10d5d74a2
commit
02c993bd2d
@ -37,3 +37,4 @@ ScriptID SourceID Filename
|
|||||||
974 4316 python.vim (indent)
|
974 4316 python.vim (indent)
|
||||||
2975 22815 fugitive.vim
|
2975 22815 fugitive.vim
|
||||||
2830 22798 csv.vim
|
2830 22798 csv.vim
|
||||||
|
3849 22637 git-time-lapse
|
||||||
|
156
vimfiles/plugin/time-lapse.vim
Normal file
156
vimfiles/plugin/time-lapse.vim
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
" vim: sw=4 ts=4 noexpandtab
|
||||||
|
function! Display(commit)
|
||||||
|
" clears all input in every buffer of the tab
|
||||||
|
windo %d
|
||||||
|
diffoff!
|
||||||
|
wincmd t
|
||||||
|
exe ':silent :0 read !git show '.a:commit.'^:'.t:path
|
||||||
|
exe 'doautocmd filetypedetect BufRead '.t:path
|
||||||
|
|
||||||
|
wincmd l
|
||||||
|
exe ':silent :0 read !git show '.a:commit.':'.t:path
|
||||||
|
exe 'doautocmd filetypedetect BufRead '.t:path
|
||||||
|
|
||||||
|
wincmd j
|
||||||
|
exe ':silent :0 read !git log --stat '.a:commit.'^..'.a:commit
|
||||||
|
setfiletype git
|
||||||
|
|
||||||
|
wincmd t
|
||||||
|
diffthis
|
||||||
|
|
||||||
|
wincmd l
|
||||||
|
diffthis
|
||||||
|
|
||||||
|
" Move back to where we were if it's still there, otherwise go to the top
|
||||||
|
if s:here <= line('$')
|
||||||
|
exe ':'.s:here
|
||||||
|
else
|
||||||
|
:0
|
||||||
|
endif
|
||||||
|
|
||||||
|
normal z.
|
||||||
|
|
||||||
|
" Some people have reported that you need to do this to make sure the left
|
||||||
|
" buffer is in the right place.
|
||||||
|
wincmd t
|
||||||
|
normal z.
|
||||||
|
|
||||||
|
wincmd j
|
||||||
|
:0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Goto(pos)
|
||||||
|
let t:current = a:pos
|
||||||
|
|
||||||
|
if t:current < 0
|
||||||
|
let t:current = 0
|
||||||
|
return 0
|
||||||
|
elseif t:current >= t:total - 1
|
||||||
|
let t:current = t:total - 2
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
call Display(t:commits[t:current])
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Move(amount)
|
||||||
|
let t:current = t:current + a:amount
|
||||||
|
call Goto(t:current)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Blame()
|
||||||
|
let current = t:commits[t:current]
|
||||||
|
let line = line('.')
|
||||||
|
|
||||||
|
let output = system('git blame -p -n -L'.line.','.line.' '.
|
||||||
|
\current.' -- '.t:path)
|
||||||
|
|
||||||
|
let results = split(output)
|
||||||
|
|
||||||
|
if results[0] == "fatal:"
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
for i in range(len(t:commits))
|
||||||
|
if t:commits[i] =~ results[0]
|
||||||
|
call Goto(i)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
wincmd t
|
||||||
|
wincmd l
|
||||||
|
exe ':'.results[1]
|
||||||
|
normal z.
|
||||||
|
wincmd j
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! GetLog()
|
||||||
|
let tmpfile = tempname()
|
||||||
|
exe ':silent :!git log --no-merges --pretty=format:"\%H" '.t:path.' > '.tmpfile
|
||||||
|
let t:commits = readfile(tmpfile)
|
||||||
|
call delete(tmpfile)
|
||||||
|
let t:total = len(t:commits)
|
||||||
|
return t:total
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ChDir()
|
||||||
|
" Change directory to the one with .git in it and return path to the
|
||||||
|
" current file from there. If you live in this directory and execute git
|
||||||
|
" commands on that path then everything will work.
|
||||||
|
cd %:p:h
|
||||||
|
let dir = finddir('.git', '.;')
|
||||||
|
exe 'cd '.dir.'/..'
|
||||||
|
let path = fnamemodify(@%, ':.')
|
||||||
|
return path
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! TimeLapse()
|
||||||
|
" Open a new tab with a time-lapse view of the file in the current
|
||||||
|
" buffer.
|
||||||
|
let path = ChDir()
|
||||||
|
let s:here = line('.')
|
||||||
|
|
||||||
|
tabnew
|
||||||
|
let t:path = path
|
||||||
|
|
||||||
|
if GetLog() <= 1
|
||||||
|
tabclose
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
set buftype=nofile
|
||||||
|
|
||||||
|
new
|
||||||
|
set buftype=nofile
|
||||||
|
|
||||||
|
wincmd j
|
||||||
|
resize 10
|
||||||
|
set winfixheight
|
||||||
|
|
||||||
|
wincmd k
|
||||||
|
vnew
|
||||||
|
set buftype=nofile
|
||||||
|
|
||||||
|
" The first line in the file is the most recent commit
|
||||||
|
let t:current = 0
|
||||||
|
call Display(t:commits[t:current])
|
||||||
|
|
||||||
|
" Go backwards and forwards one commit
|
||||||
|
windo map <buffer> <Left> :call Move(1) <cr>
|
||||||
|
windo map <buffer> <Right> :call Move(-1) <cr>
|
||||||
|
|
||||||
|
" Rewind all the way to the start or end
|
||||||
|
windo map <buffer> <S-Left> :call Goto(t:total - 2) <cr>
|
||||||
|
windo map <buffer> <S-Right> :call Goto(0) <cr>
|
||||||
|
|
||||||
|
windo map <buffer>
:call Blame() <cr>
|
||||||
|
|
||||||
|
" Go to the top right window (which contains the latest version of the
|
||||||
|
" file) and go back to the line we were on when we opened the time-lapse,
|
||||||
|
" so we can immediately Blame from there which is a common use-case.
|
||||||
|
2 wincmd w
|
||||||
|
exe ':'.s:here
|
||||||
|
normal z.
|
||||||
|
endfunction
|
Loading…
x
Reference in New Issue
Block a user