├── README.md ├── autoload └── auto_git_diff.vim └── plugin └── auto-git-diff.vim /README.md: -------------------------------------------------------------------------------- 1 | Show git diff for Git Interactive Rebase 2 | ======================================= 3 | 4 | `auto-git-diff` is a vim plugin which enable showing commit diff while processing git interactive rebase. 5 | 6 | When you move the text cursor in the commit list window, this plugin reads the commit hash of the line and show diff of the commit. 7 | 8 | ![sample_image](https://user-images.githubusercontent.com/359226/33921582-2319e7a0-e008-11e7-8be3-ba9f68a78217.gif) 9 | 10 | ## Variables 11 | 12 | - `g:auto_git_diff_disable_auto_update` 13 | 14 | If this variable is set to 1, the diff window won't be updated automatically. To update the diff window manually, use this key mapping: `(auto_git_diff_manual_update)`. 15 | 16 | - `g:auto_git_diff_show_window_at_right` 17 | 18 | If this variable is set to 1, the diff window will be created at right on the commit list window, instead of bottom. 19 | 20 | - `g:auto_git_diff_command_options` 21 | 22 | The value of this variable will be passed to `git diff` command. If this variable is not defined, `--stat -p --submodule -C -C` will be used. 23 | 24 | ## Mappings 25 | 26 | - `(auto_git_diff_manual_update)` 27 | 28 | This key mapping triggers update of the diff window. This mapping is used when the diff window's automatic update is disabled. 29 | 30 | - `(auto_git_diff_scroll_down_1)` 31 | - `(auto_git_diff_scroll_up_1)` 32 | - `(auto_git_diff_scroll_down_half)` 33 | - `(auto_git_diff_scroll_up_half)` 34 | - `(auto_git_diff_scroll_down_page)` 35 | - `(auto_git_diff_scroll_up_page)` 36 | 37 | These key mappings scroll the diff window without moving the cursor into the window. `_1` means scrolling one line (like `` or ``), `_half` means scrolling half a page (like `` or ``) and `_page` means scrolling one page (like `` or ``). 38 | 39 | This snippet is an example configuration: 40 | 41 | ```vim 42 | function! s:setup_auto_git_diff() abort 43 | nmap (auto_git_diff_scroll_manual_update) 44 | nmap (auto_git_diff_scroll_down_half) 45 | nmap (auto_git_diff_scroll_up_half) 46 | endfunction 47 | autocmd FileType gitrebase call setup_auto_git_diff() 48 | ``` 49 | 50 | ## License 51 | 52 | The MIT License (MIT) 53 | Copyright (c) 2015 hotwatermorning 54 | 55 | Permission is hereby granted, free of charge, to any person obtaining 56 | a copy of this software and associated documentation files (the 57 | "Software"), to deal in the Software without restriction, including 58 | without limitation the rights to use, copy, modify, merge, publish, 59 | distribute, sublicense, and/or sell copies of the Software, and to 60 | permit persons to whom the Software is furnished to do so, subject to 61 | the following conditions: 62 | 63 | The above copyright notice and this permission notice shall be 64 | included in all copies or substantial portions of the Software. 65 | 66 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 67 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 68 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 69 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 70 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 71 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 72 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 73 | 74 | -------------------------------------------------------------------------------- /autoload/auto_git_diff.vim: -------------------------------------------------------------------------------- 1 | let s:save_cpo = &cpo 2 | let s:previous_hash_string = "" 3 | set cpo&vim 4 | 5 | nnoremap (auto_git_diff_manual_update) :call auto_git_diff#show_git_diff() 6 | 7 | " Get commit hash from current line. 8 | " The first colomn(pick, r, ...) can be empty. 9 | function! s:get_git_hash() abort 10 | return matchstr(getline('.'), '^\(\w\+\>\)\=\(\s*\)\zs\x\{4,40\}\>\ze') 11 | endfunction 12 | 13 | " Find the preview window. 14 | " If not found, return zero. 15 | function! s:find_preview_window() abort 16 | for nr in range(1, winnr('$')) 17 | if getwinvar(nr, "&pvw") == 1 18 | " found a preview 19 | return nr 20 | endif 21 | endfor 22 | return 0 23 | endfunction 24 | 25 | " Execute git diff between hash~1 and hash with options a:opts, 26 | " and show the result into the preview window. 27 | function! s:show_git_diff_impl(hash, vertsplit, opts) abort 28 | 29 | let wn = s:find_preview_window() 30 | 31 | if wn == 0 32 | " The preview window is not found. 33 | " => Open new window 34 | 35 | if a:vertsplit 36 | rightbelow vnew 37 | else 38 | rightbelow new 39 | endif 40 | 41 | silent! setlocal previewwindow bufhidden=delete nobackup noswf nobuflisted nowrap buftype=nofile 42 | 43 | let wn = bufwinnr('%') 44 | else 45 | " Preview window is found" 46 | " Move to the window 47 | silent execute wn."wincmd w" 48 | endif 49 | 50 | let out = s:get_git_diff(a:hash, a:opts) 51 | 52 | if v:shell_error 53 | setlocal ft= 54 | else 55 | setlocal ft=diff 56 | endif 57 | 58 | setlocal modifiable 59 | 60 | silent! % delete _ 61 | silent! $ put=out 62 | silent! 1 delete _ 63 | 64 | setlocal nomodifiable 65 | 66 | noremap q :bw 67 | 68 | silent wincmd p 69 | endfunction 70 | 71 | function! s:get_git_diff(hash, opts) abort 72 | let prefix = has("win32") ? "set LANG=C & " : "env LANG=C " 73 | 74 | let diff_command = "git diff ".a:opts." ".a:hash."~1 ".a:hash 75 | silent let out = system(prefix.diff_command) 76 | if !v:shell_error 77 | return out 78 | endif 79 | let save_out = out 80 | 81 | let empty_tree_sha1_hex = "4b825dc642cb6eb9a060e54bf8d69288fbee4904" 82 | let diff_command = "git diff ".a:opts." ".empty_tree_sha1_hex." ".a:hash 83 | silent let out = system(prefix.diff_command) 84 | if !v:shell_error 85 | return out 86 | endif 87 | 88 | return save_out 89 | endfunction 90 | 91 | function! auto_git_diff#show_git_diff() abort 92 | 93 | let hash_string = s:get_git_hash() 94 | if hash_string == "" || hash_string == s:previous_hash_string 95 | return 96 | else 97 | let s:previous_hash_string = hash_string 98 | endif 99 | 100 | call s:show_git_diff_impl( s:get_git_hash() 101 | \ , get(g:, "auto_git_diff_show_window_at_right", 0) 102 | \ , get(g:, "auto_git_diff_command_options", "--stat -p --submodule -C -C") 103 | \ ) 104 | endfunction 105 | 106 | " Called when text-cursor is moved. 107 | function! auto_git_diff#auto_update_git_diff() abort 108 | 109 | if get(g:, "auto_git_diff_disable_auto_update", 0) 110 | return 111 | endif 112 | 113 | if mode() != "n" 114 | return 115 | endif 116 | 117 | call auto_git_diff#show_git_diff() 118 | endfunction 119 | 120 | function! auto_git_diff#scroll_in_preview_window(map) abort 121 | if s:find_preview_window() == 0 122 | return 123 | endif 124 | wincmd P 125 | sandbox let input = eval('"\<'.a:map.'>"') 126 | execute "normal!" input 127 | wincmd p 128 | endfunction 129 | 130 | let &cpo = s:save_cpo 131 | unlet s:save_cpo 132 | 133 | -------------------------------------------------------------------------------- /plugin/auto-git-diff.vim: -------------------------------------------------------------------------------- 1 | if exists("g:did_auto_git_diff") | finish | endif 2 | let g:did_auto_git_diff = 1 3 | 4 | augroup auto_git_diff_command_group 5 | autocmd! 6 | autocmd CursorMoved git-rebase-todo call auto_git_diff#auto_update_git_diff() 7 | autocmd FileType gitrebase setlocal nowarn nowb 8 | augroup END 9 | 10 | nnoremap (auto_git_diff_scroll_down_1) :call auto_git_diff#scroll_in_preview_window("C-e") 11 | nnoremap (auto_git_diff_scroll_up_1) :call auto_git_diff#scroll_in_preview_window("C-y") 12 | nnoremap (auto_git_diff_scroll_down_half) :call auto_git_diff#scroll_in_preview_window("C-d") 13 | nnoremap (auto_git_diff_scroll_up_half) :call auto_git_diff#scroll_in_preview_window("C-u") 14 | nnoremap (auto_git_diff_scroll_down_page) :call auto_git_diff#scroll_in_preview_window("C-f") 15 | nnoremap (auto_git_diff_scroll_up_page) :call auto_git_diff#scroll_in_preview_window("C-b") 16 | 17 | --------------------------------------------------------------------------------