3 changed files with 231 additions and 0 deletions
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
Show git diff for Git Rebase Interactive |
||||
======================================= |
||||
|
||||
`auto-git-diff` is a vim plugin which shows git diff between each commit and |
||||
its parent commit below the commit list window of git rebase interactive. |
||||
|
||||
When you move a text-cursor in `git-rebase-todo` file, `auto-git-diff` gets |
||||
a commit hash of the line where the cursor exists and update the diff window. |
||||
|
||||
|
||||
 |
||||
|
||||
## Variables |
||||
|
||||
- `g:auto_git_diff_disable_auto_update` |
||||
|
||||
If this variable is set to 1, the diff window won't update automatically. You |
||||
can update the diff window manually with the following key mapping: |
||||
`<Plug>(auto_git_diff_manual_update)`. |
||||
|
||||
- `g:auto_git_diff_show_window_at_right` |
||||
|
||||
If this variable is set to 1, the diff window will be created at right on the |
||||
commit list window. |
||||
|
||||
- `g:auto_git_diff_command_options` |
||||
|
||||
The options passed to `git diff` command. If this variable is not defined, |
||||
`--stat -p --submodule -C -C` will be used. |
||||
|
||||
## Mappings |
||||
|
||||
- `<Plug>(auto_git_diff_manual_update)` |
||||
|
||||
This key mapping updates the diff window manully. |
||||
|
||||
- `<Plug>(auto_git_diff_scroll_down_1)` |
||||
- `<Plug>(auto_git_diff_scroll_up_1)` |
||||
- `<Plug>(auto_git_diff_scroll_down_half)` |
||||
- `<Plug>(auto_git_diff_scroll_up_half)` |
||||
- `<Plug>(auto_git_diff_scroll_down_page)` |
||||
- `<Plug>(auto_git_diff_scroll_up_page)` |
||||
|
||||
These key mappings scroll the diff window without moving the cursor into the |
||||
window. `_1` means scrolling one line (`<C-e>` or `<C-y>`), `_half` means |
||||
scrolling half a page (`<C-d>` or `<C-u>`) and `_page` means scrolling one page |
||||
(`<C-f>` or `<C-b>`). |
||||
|
||||
Following is an example to configure the mappings in your `vimrc`. |
||||
|
||||
```vim |
||||
function! s:setup_auto_git_diff() abort |
||||
nmap <buffer><C-l> <Plug>(auto_git_diff_scroll_manual_update) |
||||
nmap <buffer><C-n> <Plug>(auto_git_diff_scroll_down_half) |
||||
nmap <buffer><C-p> <Plug>(auto_git_diff_scroll_up_half) |
||||
endfunction |
||||
autocmd FileType gitrebase call <SID>setup_auto_git_diff() |
||||
``` |
||||
|
||||
## License |
||||
|
||||
The MIT License (MIT) |
||||
Copyright (c) 2015 hotwatermorning |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining |
||||
a copy of this software and associated documentation files (the |
||||
"Software"), to deal in the Software without restriction, including |
||||
without limitation the rights to use, copy, modify, merge, publish, |
||||
distribute, sublicense, and/or sell copies of the Software, and to |
||||
permit persons to whom the Software is furnished to do so, subject to |
||||
the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be |
||||
included in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
|
@ -0,0 +1,132 @@
@@ -0,0 +1,132 @@
|
||||
let s:save_cpo = &cpo |
||||
let s:previous_hash_string = "" |
||||
set cpo&vim |
||||
|
||||
nnoremap <silent> <Plug>(auto_git_diff_manual_update) :<C-u>call auto_git_diff#show_git_diff()<CR> |
||||
|
||||
" Get commit hash from current line. |
||||
" The first colomn(pick, r, ...) can be empty. |
||||
function! s:get_git_hash() abort |
||||
return matchstr(getline('.'), '^\(\w\+\>\)\=\(\s*\)\zs\x\{4,40\}\>\ze') |
||||
endfunction |
||||
|
||||
" Find the preview window. |
||||
" If not found, return zero. |
||||
function! s:find_preview_window() abort |
||||
for nr in range(1, winnr('$')) |
||||
if getwinvar(nr, "&pvw") == 1 |
||||
" found a preview |
||||
return nr |
||||
endif |
||||
endfor |
||||
return 0 |
||||
endfunction |
||||
|
||||
" Execute git diff between hash~1 and hash with options a:opts, |
||||
" and show the result into the preview window. |
||||
function! s:show_git_diff_impl(hash, vertsplit, opts) abort |
||||
|
||||
let wn = s:find_preview_window() |
||||
|
||||
if wn == 0 |
||||
" The preview window is not found. |
||||
" => Open new window |
||||
|
||||
if a:vertsplit |
||||
rightbelow vnew |
||||
else |
||||
rightbelow new |
||||
endif |
||||
|
||||
silent! setlocal previewwindow bufhidden=delete nobackup noswf nobuflisted nowrap buftype=nofile |
||||
|
||||
let wn = bufwinnr('%') |
||||
else |
||||
" Preview window is found" |
||||
" Move to the window |
||||
silent execute wn."wincmd w" |
||||
endif |
||||
|
||||
let out = s:get_git_diff(a:hash, a:opts) |
||||
|
||||
if v:shell_error |
||||
setlocal ft= |
||||
else |
||||
setlocal ft=diff |
||||
endif |
||||
|
||||
setlocal modifiable |
||||
|
||||
silent! % delete _ |
||||
silent! $ put=out |
||||
silent! 1 delete _ |
||||
|
||||
setlocal nomodifiable |
||||
|
||||
noremap <buffer> q :bw<cr> |
||||
|
||||
silent wincmd p |
||||
endfunction |
||||
|
||||
function! s:get_git_diff(hash, opts) abort |
||||
let prefix = has("win32") ? "set LANG=C & " : "env LANG=C " |
||||
|
||||
let diff_command = "git diff ".a:opts." ".a:hash."~1 ".a:hash |
||||
silent let out = system(prefix.diff_command) |
||||
if !v:shell_error |
||||
return out |
||||
endif |
||||
let save_out = out |
||||
|
||||
let empty_tree_sha1_hex = "4b825dc642cb6eb9a060e54bf8d69288fbee4904" |
||||
let diff_command = "git diff ".a:opts." ".empty_tree_sha1_hex." ".a:hash |
||||
silent let out = system(prefix.diff_command) |
||||
if !v:shell_error |
||||
return out |
||||
endif |
||||
|
||||
return save_out |
||||
endfunction |
||||
|
||||
function! auto_git_diff#show_git_diff() abort |
||||
|
||||
let hash_string = s:get_git_hash() |
||||
if hash_string == "" || hash_string == s:previous_hash_string |
||||
return |
||||
else |
||||
let s:previous_hash_string = hash_string |
||||
endif |
||||
|
||||
call s:show_git_diff_impl( s:get_git_hash() |
||||
\ , get(g:, "auto_git_diff_show_window_at_right", 0) |
||||
\ , get(g:, "auto_git_diff_command_options", "--stat -p --submodule -C -C") |
||||
\ ) |
||||
endfunction |
||||
|
||||
" Called when text-cursor is moved. |
||||
function! auto_git_diff#auto_update_git_diff() abort |
||||
|
||||
if get(g:, "auto_git_diff_disable_auto_update", 0) |
||||
return |
||||
endif |
||||
|
||||
if mode() != "n" |
||||
return |
||||
endif |
||||
|
||||
call auto_git_diff#show_git_diff() |
||||
endfunction |
||||
|
||||
function! auto_git_diff#scroll_in_preview_window(map) abort |
||||
if s:find_preview_window() == 0 |
||||
return |
||||
endif |
||||
wincmd P |
||||
sandbox let input = eval('"\<'.a:map.'>"') |
||||
execute "normal!" input |
||||
wincmd p |
||||
endfunction |
||||
|
||||
let &cpo = s:save_cpo |
||||
unlet s:save_cpo |
||||
|
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
if exists("g:did_auto_git_diff") | finish | endif |
||||
let g:did_auto_git_diff = 1 |
||||
|
||||
augroup auto_git_diff_command_group |
||||
autocmd! |
||||
autocmd CursorMoved git-rebase-todo call auto_git_diff#auto_update_git_diff() |
||||
autocmd FileType gitrebase setlocal nowarn nowb |
||||
augroup END |
||||
|
||||
nnoremap <silent><Plug>(auto_git_diff_scroll_down_1) :<C-u>call auto_git_diff#scroll_in_preview_window("C-e")<CR> |
||||
nnoremap <silent><Plug>(auto_git_diff_scroll_up_1) :<C-u>call auto_git_diff#scroll_in_preview_window("C-y")<CR> |
||||
nnoremap <silent><Plug>(auto_git_diff_scroll_down_half) :<C-u>call auto_git_diff#scroll_in_preview_window("C-d")<CR> |
||||
nnoremap <silent><Plug>(auto_git_diff_scroll_up_half) :<C-u>call auto_git_diff#scroll_in_preview_window("C-u")<CR> |
||||
nnoremap <silent><Plug>(auto_git_diff_scroll_down_page) :<C-u>call auto_git_diff#scroll_in_preview_window("C-f")<CR> |
||||
nnoremap <silent><Plug>(auto_git_diff_scroll_up_page) :<C-u>call auto_git_diff#scroll_in_preview_window("C-b")<CR> |
||||
|
Loading…
Reference in new issue