From 843a33066cb0598fd7f334a3cfc83b01ada78c36 Mon Sep 17 00:00:00 2001 From: GoAwayPeter Date: Thu, 28 Jun 2018 11:17:05 +0100 Subject: [PATCH] Fixed config to allow ctrl-a --- .tmux.conf.local | 6 +- .../vim-gitgutter/.github/issue_template.md | 8 + .vim/bundle/vim-gitgutter/.gitignore | 5 + .vim/bundle/vim-gitgutter/LICENCE | 22 + .vim/bundle/vim-gitgutter/README.mkd | 538 ++++++++++++++++ .../vim-gitgutter/autoload/gitgutter.vim | 150 +++++ .../autoload/gitgutter/async.vim | 89 +++ .../autoload/gitgutter/debug.vim | 119 ++++ .../vim-gitgutter/autoload/gitgutter/diff.vim | 356 +++++++++++ .../autoload/gitgutter/highlight.vim | 149 +++++ .../vim-gitgutter/autoload/gitgutter/hunk.vim | 281 +++++++++ .../vim-gitgutter/autoload/gitgutter/sign.vim | 219 +++++++ .../autoload/gitgutter/utility.vim | 210 +++++++ .vim/bundle/vim-gitgutter/doc/gitgutter.txt | 529 ++++++++++++++++ .../bundle/vim-gitgutter/plugin/gitgutter.vim | 230 +++++++ .vim/bundle/vim-gitgutter/screenshot.png | Bin 0 -> 16191 bytes .vim/bundle/vim-gitgutter/test/cp932.txt | 8 + .vim/bundle/vim-gitgutter/test/fixture.txt | 11 + .vim/bundle/vim-gitgutter/test/runner.vim | 162 +++++ .vim/bundle/vim-gitgutter/test/test | 21 + .../vim-gitgutter/test/test_gitgutter.vim | 589 ++++++++++++++++++ .vim/bundle/vim-gitgutter/unplace.vim | 27 + .vimrc | 1 + 23 files changed, 3727 insertions(+), 3 deletions(-) create mode 100644 .vim/bundle/vim-gitgutter/.github/issue_template.md create mode 100644 .vim/bundle/vim-gitgutter/.gitignore create mode 100644 .vim/bundle/vim-gitgutter/LICENCE create mode 100644 .vim/bundle/vim-gitgutter/README.mkd create mode 100644 .vim/bundle/vim-gitgutter/autoload/gitgutter.vim create mode 100644 .vim/bundle/vim-gitgutter/autoload/gitgutter/async.vim create mode 100644 .vim/bundle/vim-gitgutter/autoload/gitgutter/debug.vim create mode 100644 .vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim create mode 100644 .vim/bundle/vim-gitgutter/autoload/gitgutter/highlight.vim create mode 100644 .vim/bundle/vim-gitgutter/autoload/gitgutter/hunk.vim create mode 100644 .vim/bundle/vim-gitgutter/autoload/gitgutter/sign.vim create mode 100644 .vim/bundle/vim-gitgutter/autoload/gitgutter/utility.vim create mode 100644 .vim/bundle/vim-gitgutter/doc/gitgutter.txt create mode 100644 .vim/bundle/vim-gitgutter/plugin/gitgutter.vim create mode 100644 .vim/bundle/vim-gitgutter/screenshot.png create mode 100644 .vim/bundle/vim-gitgutter/test/cp932.txt create mode 100644 .vim/bundle/vim-gitgutter/test/fixture.txt create mode 100644 .vim/bundle/vim-gitgutter/test/runner.vim create mode 100755 .vim/bundle/vim-gitgutter/test/test create mode 100644 .vim/bundle/vim-gitgutter/test/test_gitgutter.vim create mode 100644 .vim/bundle/vim-gitgutter/unplace.vim diff --git a/.tmux.conf.local b/.tmux.conf.local index fd96471..fc1656b 100644 --- a/.tmux.conf.local +++ b/.tmux.conf.local @@ -239,7 +239,7 @@ tmux_conf_theme_clock_style='24' # - false (default) # on macOS, this requires installing reattach-to-user-namespace, see README.md # on Linux, this requires xsel or xclip -tmux_conf_copy_to_os_clipboard=false +tmux_conf_copy_to_os_clipboard=true # -- user customizations ------------------------------------------------------- @@ -257,8 +257,8 @@ tmux_conf_copy_to_os_clipboard=false #set -g mode-keys vi # replace C-b by C-a instead of using both prefixes -# set -gu prefix2 -# unbind C-a +set -gu prefix2 +unbind C-a # unbind C-b # set -g prefix C-a # bind C-a send-prefix diff --git a/.vim/bundle/vim-gitgutter/.github/issue_template.md b/.vim/bundle/vim-gitgutter/.github/issue_template.md new file mode 100644 index 0000000..732d22e --- /dev/null +++ b/.vim/bundle/vim-gitgutter/.github/issue_template.md @@ -0,0 +1,8 @@ +> What is the latest commit SHA in your installed vim-gitgutter? + +> What vim/nvim version are you on? + +> If no signs are showing at all, what does `:echo b:gitgutter.path` give? + +> If no signs are showing at all, and the `path` value is a path and not `-2`, does it work with `let g:gitgutter_grep=''`? + diff --git a/.vim/bundle/vim-gitgutter/.gitignore b/.vim/bundle/vim-gitgutter/.gitignore new file mode 100644 index 0000000..82fb253 --- /dev/null +++ b/.vim/bundle/vim-gitgutter/.gitignore @@ -0,0 +1,5 @@ +/doc/tags +/misc +/test/*.actual +*.log + diff --git a/.vim/bundle/vim-gitgutter/LICENCE b/.vim/bundle/vim-gitgutter/LICENCE new file mode 100644 index 0000000..38e2dc2 --- /dev/null +++ b/.vim/bundle/vim-gitgutter/LICENCE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) Andrew Stewart + +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. + diff --git a/.vim/bundle/vim-gitgutter/README.mkd b/.vim/bundle/vim-gitgutter/README.mkd new file mode 100644 index 0000000..baf712d --- /dev/null +++ b/.vim/bundle/vim-gitgutter/README.mkd @@ -0,0 +1,538 @@ +## vim-gitgutter + +A Vim plugin which shows a git diff in the 'gutter' (sign column). It shows which lines have been added, modified, or removed. You can also preview, stage, and undo individual hunks. The plugin also provides a hunk text object. + +The signs are always up to date and the plugin never saves your buffer. + +Features: + +* Shows signs for added, modified, and removed lines. +* Runs the diffs asynchronously where possible. +* Ensures signs are always up to date. +* Quick jumping between blocks of changed lines ("hunks"). +* Stage/undo/preview individual hunks. +* Provides a hunk text object. +* Diffs against index (default) or any commit. +* Handles line endings correctly, even with repos that do CRLF conversion. +* Optional line highlighting. +* Fully customisable (signs, sign column, line highlights, mappings, extra git-diff arguments, etc). +* Can be toggled on/off. +* Preserves signs from other plugins. +* Easy to integrate diff stats into status line; built-in integration with [vim-airline](https://github.com/bling/vim-airline/). +* Works with fish shell (in addition to the usual shells). + +Constraints: + +* Supports git only. If you work with other version control systems, I recommend [vim-signify](https://github.com/mhinz/vim-signify). +* Relies on the `FocusGained` event. If your terminal doesn't report focus events, either use something like [Terminus][] or set `let g:gitgutter_terminal_reports_focus=0`. + + +### Screenshot + +![screenshot](https://raw.github.com/airblade/vim-gitgutter/master/screenshot.png) + +In the screenshot above you can see: + +* Line 15 has been modified. +* Lines 21-24 are new. +* A line or lines were removed between lines 25 and 26. + + +### Installation + +Before installation, please check your Vim supports signs by running `:echo has('signs')`. `1` means you're all set; `0` means you need to install a Vim with signs support. If you're compiling Vim yourself you need the 'big' or 'huge' feature set. MacVim supports signs. + +You install vim-gitgutter like any other vim plugin. + +##### Pathogen + +``` +cd ~/.vim/bundle +git clone git://github.com/airblade/vim-gitgutter.git +``` + +##### Voom + +Edit your plugin manifest (`voom edit`) and add: + +``` +airblade/vim-gitgutter +``` + +##### VimPlug + +Place this in your .vimrc: + +```viml +Plug 'airblade/vim-gitgutter' +``` + +Then run the following in Vim: + +``` +:source % +:PlugInstall +``` + +##### NeoBundle + +Place this in your .vimrc: + +```viml +NeoBundle 'airblade/vim-gitgutter' +``` + +Then run the following in Vim: + +``` +:source % +:NeoBundleInstall +``` + +##### No plugin manager + +Copy vim-gitgutter's subdirectories into your vim configuration directory: + +``` +cd /tmp && git clone git://github.com/airblade/vim-gitgutter.git +cp -r vim-gitgutter/* ~/.vim/ +``` + +See `:help add-global-plugin`. + + +### Getting started + +When you make a change to a file tracked by git, the diff markers should appear automatically. The delay is governed by vim's `updatetime` option; the default value is `4000`, i.e. 4 seconds, but I suggest reducing it to around 100ms (add `set updatetime=100` to your vimrc). + +You can jump between hunks with `[c` and `]c`. You can preview, stage, and undo hunks with `hp`, `hs`, and `hu` respectively. + +You cannot unstage a staged hunk. + + +#### Activation + +You can explicitly turn vim-gitgutter off and on (defaults to on): + +* turn off with `:GitGutterDisable` +* turn on with `:GitGutterEnable` +* toggle with `:GitGutterToggle`. + +You can turn the signs on and off (defaults to on): + +* turn on with `:GitGutterSignsEnable` +* turn off with `:GitGutterSignsDisable` +* toggle with `:GitGutterSignsToggle`. + +And you can turn line highlighting on and off (defaults to off): + +* turn on with `:GitGutterLineHighlightsEnable` +* turn off with `:GitGutterLineHighlightsDisable` +* toggle with `:GitGutterLineHighlightsToggle`. + +Note that if you have line highlighting on and signs off, you will have an empty sign column – more accurately, a sign column with invisible signs. This is because line highlighting requires signs and Vim always shows the sign column even if the signs are invisible. + +If you switch off both line highlighting and signs, you won't see the sign column. That is unless you configure the sign column always to be there (see Sign Column section). + +To keep your Vim snappy, vim-gitgutter will suppress the signs when a file has more than 500 changes. As soon as the number of changes falls below the limit vim-gitgutter will show the signs again. You can configure the threshold with: + +```viml +let g:gitgutter_max_signs = 500 " default value +``` + +#### Hunks + +You can jump between hunks: + +* jump to next hunk (change): `]c` +* jump to previous hunk (change): `[c`. + +Both of those take a preceding count. + +To set your own mappings for these, for example `]h` and `[h`: + +```viml +nmap ]h GitGutterNextHunk +nmap [h GitGutterPrevHunk +``` + +You can stage or undo an individual hunk when your cursor is in it: + +* stage the hunk with `hs` or +* undo it with `hu`. + +See the FAQ if you want to unstage staged changes. + +The `.` command will work with both these if you install [repeat.vim](https://github.com/tpope/vim-repeat). + +To set your own mappings for these, for example if you prefer the mnemonics hunk-add and hunk-revert: + +```viml +nmap ha GitGutterStageHunk +nmap hr GitGutterUndoHunk +``` + +And you can preview a hunk's changes with `hp`. You can of course change this mapping, e.g: + +```viml +nmap hv GitGutterPreviewHunk +``` + +A hunk text object is provided which works in visual and operator-pending modes. + +- `ic` operates on all lines in the current hunk. +- `ac` operates on all lines in the current hunk and any trailing empty lines. + +To re-map these, for example to `ih` and `ah`: + +```viml +omap ih GitGutterTextObjectInnerPending +omap ah GitGutterTextObjectOuterPending +xmap ih GitGutterTextObjectInnerVisual +xmap ah GitGutterTextObjectOuterVisual +``` + +If you don't want vim-gitgutter to set up any mappings at all, use this: + +```viml +let g:gitgutter_map_keys = 0 +``` + +Finally, you can force vim-gitgutter to update its signs across all visible buffers with `:GitGutterAll`. + +See the customisation section below for how to change the defaults. + + +### Customisation + +You can customise: + +* The sign column's colours +* Whether or not the sign column is shown when there aren't any signs (defaults to no) +* The signs' colours and symbols +* Line highlights +* The base of the diff +* Extra arguments for `git diff` +* Key mappings +* Whether or not vim-gitgutter is on initially (defaults to on) +* Whether or not signs are shown (defaults to yes) +* Whether or not line highlighting is on initially (defaults to off) +* Whether or not vim-gitgutter runs in "realtime" (defaults to yes) +* Whether or not vim-gitgutter runs eagerly (defaults to yes) +* Whether or not vim-gitgutter runs asynchronously (defaults to yes) + +Please note that vim-gitgutter won't override any colours or highlights you've set in your colorscheme. + + +#### Sign column + +By default vim-gitgutter will make the sign column look like the line number column. + +To customise your sign column's background color, first tell vim-gitgutter to leave it alone: + +```viml +let g:gitgutter_override_sign_column_highlight = 0 +``` + +And then either update your colorscheme's `SignColumn` highlight group or set it in your vimrc: + +```viml +highlight SignColumn ctermbg=whatever " terminal Vim +highlight SignColumn guibg=whatever " gVim/MacVim +``` + +By default the sign column will appear when there are signs to show and disappear when there aren't. To always have the sign column, add to your vimrc: + +```viml +if exists('&signcolumn') " Vim 7.4.2201 + set signcolumn=yes +else + let g:gitgutter_sign_column_always = 1 +endif +``` + + +#### Signs' colours and symbols + +To customise the colours, set up the following highlight groups in your colorscheme or `~/.vimrc`: + +```viml +GitGutterAdd " an added line +GitGutterChange " a changed line +GitGutterDelete " at least one removed line +GitGutterChangeDelete " a changed line followed by at least one removed line +``` + +You can either set these with `highlight GitGutterAdd {key}={arg}...` or link them to existing highlight groups with, say, `highlight link GitGutterAdd DiffAdd`. + +To customise the symbols, add the following to your `~/.vimrc`: + +```viml +let g:gitgutter_sign_added = 'xx' +let g:gitgutter_sign_modified = 'yy' +let g:gitgutter_sign_removed = 'zz' +let g:gitgutter_sign_removed_first_line = '^^' +let g:gitgutter_sign_modified_removed = 'ww' +``` + + +#### Line highlights + +Similarly to the signs' colours, set up the following highlight groups in your colorscheme or `~/.vimrc`: + +```viml +GitGutterAddLine " default: links to DiffAdd +GitGutterChangeLine " default: links to DiffChange +GitGutterDeleteLine " default: links to DiffDelete +GitGutterChangeDeleteLine " default: links to GitGutterChangeLineDefault, i.e. DiffChange +``` + + +#### The base of the diff + +By default buffers are diffed against the index. However you can diff against any commit by setting: + +```viml +let g:gitgutter_diff_base = '' +``` + + +#### Extra arguments for `git diff` + +If you want to pass extra arguments to `git diff`, for example to ignore whitespace, do so like this: + +```viml +let g:gitgutter_diff_args = '-w' +``` + +#### Key mappings + +To disable all key mappings: + +```viml +let g:gitgutter_map_keys = 0 +``` + +See above for configuring maps for hunk-jumping and staging/undoing. + + +#### Use a custom `grep` command + +If you use an alternative to grep, you can tell vim-gitgutter to use it here. + +```viml +" Default: +let g:gitgutter_grep = 'grep' +``` + +#### To turn off vim-gitgutter by default + +Add `let g:gitgutter_enabled = 0` to your `~/.vimrc`. + + +#### To turn off signs by default + +Add `let g:gitgutter_signs = 0` to your `~/.vimrc`. + + +#### To turn on line highlighting by default + +Add `let g:gitgutter_highlight_lines = 1` to your `~/.vimrc`. + + +#### To turn off asynchronous updates + +By default diffs are run asynchronously. To run diffs synchronously instead: + +```viml +let g:gitgutter_async = 0 +``` + + +### Extensions + +#### Operate on every line in a hunk + +You can map an operator to do whatever you want to every line in a hunk. + +Let's say, for example, you want to remove trailing whitespace. + +```viml +function! CleanUp(...) + if a:0 " opfunc + let [first, last] = [line("'["), line("']")] + else + let [first, last] = [line("'<"), line("'>")] + endif + for lnum in range(first, last) + let line = getline(lnum) + + " clean up the text, e.g.: + let line = substitute(line, '\s\+$', '', '') + + call setline(lnum, line) + endfor +endfunction + +nmap x :set opfunc=CleanUpg@ +``` + +Then place your cursor in a hunk and type `\xic` (assuming a leader of `\`). + +Alternatively you could place your cursor in a hunk, type `vic` to select it, then `:call CleanUp()`. + + +#### Operate on every changed line in a file + +You can write a command to do whatever you want to every changed line in a file. + +```viml +function! GlobalChangedLines(ex_cmd) + for hunk in GitGutterGetHunks() + for lnum in range(hunk[2], hunk[2]+hunk[3]-1) + let cursor = getcurpos() + silent! execute lnum.a:ex_cmd + call setpos('.', cursor) + endfor + endfor +endfunction + +command -nargs=1 Glines call GlobalChangedLines() +``` + +Let's say, for example, you want to remove trailing whitespace from all changed lines: + +```viml +:Glines s/\s\+$// +``` + + +#### Cycle through hunks in all buffers + +`]c` and `[c` jump from one hunk to the next in the current buffer. You can use this code to jump to the next hunk no matter which buffer it's in. + +```viml +function! NextHunkAllBuffers() + let line = line('.') + GitGutterNextHunk + if line('.') != line + return + endif + + let bufnr = bufnr('') + while 1 + bnext + if bufnr('') == bufnr + return + endif + if !empty(GitGutterGetHunks()) + normal! 1G + GitGutterNextHunk + return + endif + endwhile +endfunction + +function! PrevHunkAllBuffers() + let line = line('.') + GitGutterPrevHunk + if line('.') != line + return + endif + + let bufnr = bufnr('') + while 1 + bprevious + if bufnr('') == bufnr + return + endif + if !empty(GitGutterGetHunks()) + normal! G + GitGutterPrevHunk + return + endif + endwhile +endfunction + +nmap ]c :call NextHunkAllBuffers() +nmap [c :call PrevHunkAllBuffers() +``` + + +### FAQ + +> How can I turn off realtime updates? + +Add this to your vim configuration (in an `/after/plugin` directory): + +```viml +" .vim/after/plugin/gitgutter.vim +autocmd! gitgutter CursorHold,CursorHoldI +``` + +> I turned off realtime updates, how can I have signs updated when I save a file? + +If you really want to update the signs when you save a file, add this to your vimrc: + +```viml +autocmd BufWritePost * GitGutter +``` + +> Why can't I unstage staged changes? + +This plugin is for showing changes between the working tree and the index (and staging/undoing those changes). Unstaging a staged hunk would require showing changes between the index and HEAD, which is out of scope. + +> Why are the colours in the sign column weird? + +Your colorscheme is configuring the `SignColumn` highlight group weirdly. Please see the section above on customising the sign column. + +> What happens if I also use another plugin which uses signs (e.g. Syntastic)? + +Vim only allows one sign per line. Before adding a sign to a line, vim-gitgutter checks whether a sign has already been added by somebody else. If so it doesn't do anything. In other words vim-gitgutter won't overwrite another plugin's signs. It also won't remove another plugin's signs. + + +### Troubleshooting + +#### When no signs are showing at all + +Here are some things you can check: + +* Try adding `let g:gitgutter_grep=''` to your vimrc. If it works, the problem is grep producing non-plain output; e.g. ANSI escape codes or colours. +* Verify `:echo system("git --version")` succeeds. +* Verify your git config is compatible with the version of git returned by the command above. +* Verify your Vim supports signs (`:echo has('signs')` should give `1`). +* Verify your file is being tracked by git and has unstaged changes. + +#### When the whole file is marked as added + +* If you use zsh, and you set `CDPATH`, make sure `CDPATH` doesn't include the current directory. + +#### When signs take a few seconds to appear + +* Try reducing `updatetime`, e.g. `set updatetime=100`. + +#### When signs don't update after focusing Vim + +* Your terminal probably isn't reporting focus events. Either try installing [Terminus][] or set `let g:gitgutter_terminal_reports_focus=0`. + + +### Shameless Plug + +If this plugin has helped you, or you'd like to learn more about Vim, why not check out this screencast I wrote for PeepCode: + +* [Smash Into Vim][siv] + +This was one of PeepCode's all-time top three bestsellers and is now available at Pluralsight. + +You can read reviews on my [website][airblade]. + + +### Intellectual Property + +Copyright Andrew Stewart, AirBlade Software Ltd. Released under the MIT licence. + + + [pathogen]: https://github.com/tpope/vim-pathogen + [siv]: http://pluralsight.com/training/Courses/TableOfContents/smash-into-vim + [airblade]: http://airbladesoftware.com/peepcode-vim + [terminus]: https://github.com/wincent/terminus diff --git a/.vim/bundle/vim-gitgutter/autoload/gitgutter.vim b/.vim/bundle/vim-gitgutter/autoload/gitgutter.vim new file mode 100644 index 0000000..b025161 --- /dev/null +++ b/.vim/bundle/vim-gitgutter/autoload/gitgutter.vim @@ -0,0 +1,150 @@ +let s:t_string = type('') + +" Primary functions {{{ + +function! gitgutter#all(force) abort + for bufnr in s:uniq(tabpagebuflist()) + let file = expand('#'.bufnr.':p') + if !empty(file) + call gitgutter#init_buffer(bufnr) + call gitgutter#process_buffer(bufnr, a:force) + endif + endfor +endfunction + + +" Finds the file's path relative to the repo root. +function! gitgutter#init_buffer(bufnr) + if gitgutter#utility#is_active(a:bufnr) + call s:setup_maps() + let p = gitgutter#utility#repo_path(a:bufnr, 0) + if type(p) != s:t_string || empty(p) + call gitgutter#utility#set_repo_path(a:bufnr) + endif + endif +endfunction + + +function! gitgutter#process_buffer(bufnr, force) abort + " NOTE a:bufnr is not necessarily the current buffer. + + if gitgutter#utility#is_active(a:bufnr) + if a:force || s:has_fresh_changes(a:bufnr) + + let diff = '' + try + let diff = gitgutter#diff#run_diff(a:bufnr, 0) + catch /gitgutter not tracked/ + call gitgutter#debug#log('Not tracked: '.gitgutter#utility#file(a:bufnr)) + catch /gitgutter diff failed/ + call gitgutter#debug#log('Diff failed: '.gitgutter#utility#file(a:bufnr)) + call gitgutter#hunk#reset(a:bufnr) + endtry + + if diff != 'async' + call gitgutter#diff#handler(a:bufnr, diff) + endif + + endif + endif +endfunction + + +function! gitgutter#disable() abort + " get list of all buffers (across all tabs) + let buflist = [] + for i in range(tabpagenr('$')) + call extend(buflist, tabpagebuflist(i + 1)) + endfor + + for bufnr in s:uniq(buflist) + let file = expand('#'.bufnr.':p') + if !empty(file) + call s:clear(bufnr) + endif + endfor + + let g:gitgutter_enabled = 0 +endfunction + +function! gitgutter#enable() abort + let g:gitgutter_enabled = 1 + call gitgutter#all(1) +endfunction + +function! gitgutter#toggle() abort + if g:gitgutter_enabled + call gitgutter#disable() + else + call gitgutter#enable() + endif +endfunction + +" }}} + +function! s:setup_maps() + if !g:gitgutter_map_keys + return + endif + + if !hasmapto('GitGutterPrevHunk') && maparg('[c', 'n') ==# '' + nmap [c GitGutterPrevHunk + endif + if !hasmapto('GitGutterNextHunk') && maparg(']c', 'n') ==# '' + nmap ]c GitGutterNextHunk + endif + + if !hasmapto('GitGutterStageHunk') && maparg('hs', 'n') ==# '' + nmap hs GitGutterStageHunk + endif + if !hasmapto('GitGutterUndoHunk') && maparg('hu', 'n') ==# '' + nmap hu GitGutterUndoHunk + endif + if !hasmapto('GitGutterPreviewHunk') && maparg('hp', 'n') ==# '' + nmap hp GitGutterPreviewHunk + endif + + if !hasmapto('GitGutterTextObjectInnerPending') && maparg('ic', 'o') ==# '' + omap ic GitGutterTextObjectInnerPending + endif + if !hasmapto('GitGutterTextObjectOuterPending') && maparg('ac', 'o') ==# '' + omap ac GitGutterTextObjectOuterPending + endif + if !hasmapto('GitGutterTextObjectInnerVisual') && maparg('ic', 'x') ==# '' + xmap ic GitGutterTextObjectInnerVisual + endif + if !hasmapto('GitGutterTextObjectOuterVisual') && maparg('ac', 'x') ==# '' + xmap ac GitGutterTextObjectOuterVisual + endif +endfunction + +function! s:has_fresh_changes(bufnr) abort + return getbufvar(a:bufnr, 'changedtick') != gitgutter#utility#getbufvar(a:bufnr, 'tick') +endfunction + +function! s:reset_tick(bufnr) abort + call gitgutter#utility#setbufvar(a:bufnr, 'tick', 0) +endfunction + +function! s:clear(bufnr) + call gitgutter#sign#clear_signs(a:bufnr) + call gitgutter#sign#remove_dummy_sign(a:bufnr, 1) + call gitgutter#hunk#reset(a:bufnr) + call s:reset_tick(a:bufnr) +endfunction + +if exists('*uniq') " Vim 7.4.218 + function! s:uniq(list) + return uniq(sort(a:list)) + endfunction +else + function! s:uniq(list) + let processed = [] + for e in a:list + if index(processed, e) == -1 + call add(processed, e) + endif + endfor + return processed + endfunction +endif diff --git a/.vim/bundle/vim-gitgutter/autoload/gitgutter/async.vim b/.vim/bundle/vim-gitgutter/autoload/gitgutter/async.vim new file mode 100644 index 0000000..7413930 --- /dev/null +++ b/.vim/bundle/vim-gitgutter/autoload/gitgutter/async.vim @@ -0,0 +1,89 @@ +let s:available = has('nvim') || ( + \ has('job') && ( + \ (has('patch-7-4-1826') && !has('gui_running')) || + \ (has('patch-7-4-1850') && has('gui_running')) || + \ (has('patch-7-4-1832') && has('gui_macvim')) + \ ) + \ ) + +function! gitgutter#async#available() + return s:available +endfunction + + +function! gitgutter#async#execute(cmd, bufnr, handler) abort + call gitgutter#debug#log('[async] '.a:cmd) + + let options = { + \ 'stdoutbuffer': [], + \ 'buffer': a:bufnr, + \ 'handler': a:handler + \ } + let command = s:build_command(a:cmd) + + if has('nvim') + call jobstart(command, extend(options, { + \ 'on_stdout': function('s:on_stdout_nvim'), + \ 'on_stderr': function('s:on_stderr_nvim'), + \ 'on_exit': function('s:on_exit_nvim') + \ })) + else + call job_start(command, { + \ 'out_cb': function('s:on_stdout_vim', options), + \ 'err_cb': function('s:on_stderr_vim', options), + \ 'close_cb': function('s:on_exit_vim', options) + \ }) + endif +endfunction + + +function! s:build_command(cmd) + if has('unix') + return ['sh', '-c', a:cmd] + endif + + if has('win32') + return has('nvim') ? ['cmd.exe', '/c', a:cmd] : 'cmd.exe /c '.a:cmd + endif + + throw 'unknown os' +endfunction + + +function! s:on_stdout_nvim(_job_id, data, _event) dict abort + if empty(self.stdoutbuffer) + let self.stdoutbuffer = a:data + else + let self.stdoutbuffer = self.stdoutbuffer[:-2] + + \ [self.stdoutbuffer[-1] . a:data[0]] + + \ a:data[1:] + endif +endfunction + +function! s:on_stderr_nvim(_job_id, _data, _event) dict abort + call self.handler.err(self.buffer) +endfunction + +function! s:on_exit_nvim(_job_id, exit_code, _event) dict abort + if !a:exit_code + call self.handler.out(self.buffer, join(self.stdoutbuffer, "\n")) + endif +endfunction + + +function! s:on_stdout_vim(_channel, data) dict abort + call add(self.stdoutbuffer, a:data) +endfunction + +function! s:on_stderr_vim(channel, _data) dict abort + call self.handler.err(self.buffer) + try + call ch_close(a:channel) " so close_cb and its 'out' handler are not triggered + catch /E906/ + " noop + endtry +endfunction + +function! s:on_exit_vim(_channel) dict abort + call self.handler.out(self.buffer, join(self.stdoutbuffer, "\n")) +endfunction diff --git a/.vim/bundle/vim-gitgutter/autoload/gitgutter/debug.vim b/.vim/bundle/vim-gitgutter/autoload/gitgutter/debug.vim new file mode 100644 index 0000000..79d197e --- /dev/null +++ b/.vim/bundle/vim-gitgutter/autoload/gitgutter/debug.vim @@ -0,0 +1,119 @@ +let s:plugin_dir = expand(':p:h:h:h').'/' +let s:log_file = s:plugin_dir.'gitgutter.log' +let s:channel_log = s:plugin_dir.'channel.log' +let s:new_log_session = 1 + + +function! gitgutter#debug#debug() + " Open a scratch buffer + vsplit __GitGutter_Debug__ + normal! ggdG + setlocal buftype=nofile + setlocal bufhidden=delete + setlocal noswapfile + + call s:vim_version() + call s:separator() + + call s:git_version() + call s:separator() + + call s:grep_version() + call s:separator() + + call s:option('updatetime') + call s:option('shell') + call s:option('shellcmdflag') + call s:option('shellpipe') + call s:option('shellquote') + call s:option('shellredir') + call s:option('shellslash') + call s:option('shelltemp') + call s:option('shelltype') + call s:option('shellxescape') + call s:option('shellxquote') +endfunction + + +function! s:separator() + call s:output('') +endfunction + +function! s:vim_version() + redir => version_info + silent execute 'version' + redir END + call s:output(split(version_info, '\n')[0:2]) +endfunction + +function! s:git_version() + let v = system(g:gitgutter_git_executable.' --version') + call s:output( substitute(v, '\n$', '', '') ) +endfunction + +function! s:grep_version() + let v = system('grep --version') + call s:output( substitute(v, '\n$', '', '') ) + + let v = system('grep --help') + call s:output( substitute(v, '\%x00', '', 'g') ) +endfunction + +function! s:option(name) + if exists('+' . a:name) + let v = eval('&' . a:name) + call s:output(a:name . '=' . v) + " redir => output + " silent execute "verbose set " . a:name . "?" + " redir END + " call s:output(a:name . '=' . output) + else + call s:output(a:name . ' [n/a]') + end +endfunction + +function! s:output(text) + call append(line('$'), a:text) +endfunction + +" assumes optional args are calling function's optional args +function! gitgutter#debug#log(message, ...) abort + if g:gitgutter_log + if s:new_log_session && gitgutter#async#available() + if exists('*ch_logfile') + call ch_logfile(s:channel_log, 'w') + endif + endif + + execute 'redir >> '.s:log_file + if s:new_log_session + let s:start = reltime() + silent echo "\n==== start log session ====" + endif + + let elapsed = reltimestr(reltime(s:start)).' ' + silent echo '' + " callers excluding this function + silent echo elapsed.expand('')[:-22].':' + silent echo elapsed.s:format_for_log(a:message) + if a:0 && !empty(a:1) + for msg in a:000 + silent echo elapsed.s:format_for_log(msg) + endfor + endif + redir END + + let s:new_log_session = 0 + endif +endfunction + +function! s:format_for_log(data) abort + if type(a:data) == 1 + return join(split(a:data,'\n'),"\n") + elseif type(a:data) == 3 + return '['.join(a:data,"\n").']' + else + return a:data + endif +endfunction + diff --git a/.vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim b/.vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim new file mode 100644 index 0000000..d9f4419 --- /dev/null +++ b/.vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim @@ -0,0 +1,356 @@ +let s:nomodeline = (v:version > 703 || (v:version == 703 && has('patch442'))) ? '' : '' + +let s:hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@' + +" True for git v1.7.2+. +function! s:git_supports_command_line_config_override() abort + call system(g:gitgutter_git_executable.' -c foo.bar=baz --version') + return !v:shell_error +endfunction + +let s:c_flag = s:git_supports_command_line_config_override() + + +let s:temp_index = tempname() +let s:temp_buffer = tempname() + +" Returns a diff of the buffer. +" +" The buffer contents is not the same as the file on disk so we need to pass +" two instances of the file to git-diff: +" +" git diff myfileA myfileB +" +" where myfileA comes from +" +" git show :myfile > myfileA +" +" and myfileB is the buffer contents. +" +" After running the diff we pass it through grep where available to reduce +" subsequent processing by the plugin. If grep is not available the plugin +" does the filtering instead. +" +" +" Regarding line endings: +" +" git-show does not convert line endings. +" git-diff FILE FILE does convert line endings for the given files. +" +" If a file has CRLF line endings and git's core.autocrlf is true, +" the file in git's object store will have LF line endings. Writing +" it out via git-show will produce a file with LF line endings. +" +" If this last file is one of the files passed to git-diff, git-diff will +" convert its line endings to CRLF before diffing -- which is what we want -- +" but also by default output a warning on stderr. +" +" warning: LF will be replace by CRLF in . +" The file will have its original line endings in your working directory. +" +" When running the diff asynchronously, the warning message triggers the stderr +" callbacks which assume the overall command has failed and reset all the +" signs. As this is not what we want, and we can safely ignore the warning, +" we turn it off by passing the '-c "core.safecrlf=false"' argument to +" git-diff. +" +" When writing the temporary files we preserve the original file's extension +" so that repos using .gitattributes to control EOL conversion continue to +" convert correctly. +function! gitgutter#diff#run_diff(bufnr, preserve_full_diff) abort + while gitgutter#utility#repo_path(a:bufnr, 0) == -1 + sleep 5m + endwhile + + if gitgutter#utility#repo_path(a:bufnr, 0) == -2 + throw 'gitgutter not tracked' + endif + + + " Wrap compound commands in parentheses to make Windows happy. + " bash doesn't mind the parentheses. + let cmd = '(' + + " Append buffer number to avoid race conditions between writing and reading + " the files when asynchronously processing multiple buffers. + " + " Without the buffer number, index_file would have a race in the shell + " between the second process writing it (with git-show) and the first + " reading it (with git-diff). + let index_file = s:temp_index.'.'.a:bufnr + + " Without the buffer number, buff_file would have a race between the + " second gitgutter#process_buffer() writing the file (synchronously, below) + " and the first gitgutter#process_buffer()'s async job reading it (with + " git-diff). + let buff_file = s:temp_buffer.'.'.a:bufnr + + let extension = gitgutter#utility#extension(a:bufnr) + if !empty(extension) + let index_file .= '.'.extension + let buff_file .= '.'.extension + endif + + " Write file from index to temporary file. + let index_name = g:gitgutter_diff_base.':'.gitgutter#utility#repo_path(a:bufnr, 1) + let cmd .= g:gitgutter_git_executable.' --no-pager show '.index_name.' > '.index_file.' && ' + + " Write buffer to temporary file. + " Note: this is synchronous. + call s:write_buffer(a:bufnr, buff_file) + + " Call git-diff with the temporary files. + let cmd .= g:gitgutter_git_executable.' --no-pager' + if s:c_flag + let cmd .= ' -c "diff.autorefreshindex=0"' + let cmd .= ' -c "diff.noprefix=false"' + let cmd .= ' -c "core.safecrlf=false"' + endif + let cmd .= ' diff --no-ext-diff --no-color -U0 '.g:gitgutter_diff_args.' -- '.index_file.' '.buff_file + + " Pipe git-diff output into grep. + if !a:preserve_full_diff && !empty(g:gitgutter_grep) + let cmd .= ' | '.g:gitgutter_grep.' '.gitgutter#utility#shellescape('^@@ ') + endif + + " grep exits with 1 when no matches are found; git-diff exits with 1 when + " differences are found. However we want to treat non-matches and + " differences as non-erroneous behaviour; so we OR the command with one + " which always exits with success (0). + let cmd .= ' || exit 0' + + let cmd .= ')' + + let cmd = gitgutter#utility#cd_cmd(a:bufnr, cmd) + + if g:gitgutter_async && gitgutter#async#available() + call gitgutter#async#execute(cmd, a:bufnr, { + \ 'out': function('gitgutter#diff#handler'), + \ 'err': function('gitgutter#hunk#reset'), + \ }) + return 'async' + + else + let diff = gitgutter#utility#system(cmd) + + if v:shell_error + call gitgutter#debug#log(diff) + throw 'gitgutter diff failed' + endif + + return diff + endif +endfunction + + +function! gitgutter#diff#handler(bufnr, diff) abort + call gitgutter#debug#log(a:diff) + + call gitgutter#hunk#set_hunks(a:bufnr, gitgutter#diff#parse_diff(a:diff)) + let modified_lines = gitgutter#diff#process_hunks(a:bufnr, gitgutter#hunk#hunks(a:bufnr)) + + let signs_count = len(modified_lines) + if signs_count > g:gitgutter_max_signs + call gitgutter#utility#warn_once(a:bufnr, printf( + \ 'exceeded maximum number of signs (%d > %d, configured by g:gitgutter_max_signs).', + \ signs_count, g:gitgutter_max_signs), 'max_signs') + call gitgutter#sign#clear_signs(a:bufnr) + + else + if g:gitgutter_signs || g:gitgutter_highlight_lines + call gitgutter#sign#update_signs(a:bufnr, modified_lines) + endif + endif + + call s:save_last_seen_change(a:bufnr) + if exists('#User#GitGutter') + let g:gitgutter_hook_context = {'bufnr': a:bufnr} + execute 'doautocmd' s:nomodeline 'User GitGutter' + unlet g:gitgutter_hook_context + endif +endfunction + + +function! gitgutter#diff#parse_diff(diff) abort + let hunks = [] + for line in split(a:diff, '\n') + let hunk_info = gitgutter#diff#parse_hunk(line) + if len(hunk_info) == 4 + call add(hunks, hunk_info) + endif + endfor + return hunks +endfunction + +function! gitgutter#diff#parse_hunk(line) abort + let matches = matchlist(a:line, s:hunk_re) + if len(matches) > 0 + let from_line = str2nr(matches[1]) + let from_count = (matches[2] == '') ? 1 : str2nr(matches[2]) + let to_line = str2nr(matches[3]) + let to_count = (matches[4] == '') ? 1 : str2nr(matches[4]) + return [from_line, from_count, to_line, to_count] + else + return [] + end +endfunction + +" This function is public so it may be used by other plugins +" e.g. vim-signature. +function! gitgutter#diff#process_hunks(bufnr, hunks) abort + let modified_lines = [] + for hunk in a:hunks + call extend(modified_lines, s:process_hunk(a:bufnr, hunk)) + endfor + return modified_lines +endfunction + +" Returns [ [, ], ...] +function! s:process_hunk(bufnr, hunk) abort + let modifications = [] + let from_line = a:hunk[0] + let from_count = a:hunk[1] + let to_line = a:hunk[2] + let to_count = a:hunk[3] + + if s:is_added(from_count, to_count) + call s:process_added(modifications, from_count, to_count, to_line) + call gitgutter#hunk#increment_lines_added(a:bufnr, to_count) + + elseif s:is_removed(from_count, to_count) + call s:process_removed(modifications, from_count, to_count, to_line) + call gitgutter#hunk#increment_lines_removed(a:bufnr, from_count) + + elseif s:is_modified(from_count, to_count) + call s:process_modified(modifications, from_count, to_count, to_line) + call gitgutter#hunk#increment_lines_modified(a:bufnr, to_count) + + elseif s:is_modified_and_added(from_count, to_count) + call s:process_modified_and_added(modifications, from_count, to_count, to_line) + call gitgutter#hunk#increment_lines_added(a:bufnr, to_count - from_count) + call gitgutter#hunk#increment_lines_modified(a:bufnr, from_count) + + elseif s:is_modified_and_removed(from_count, to_count) + call s:process_modified_and_removed(modifications, from_count, to_count, to_line) + call gitgutter#hunk#increment_lines_modified(a:bufnr, to_count) + call gitgutter#hunk#increment_lines_removed(a:bufnr, from_count - to_count) + + endif + return modifications +endfunction + +function! s:is_added(from_count, to_count) abort + return a:from_count == 0 && a:to_count > 0 +endfunction + +function! s:is_removed(from_count, to_count) abort + return a:from_count > 0 && a:to_count == 0 +endfunction + +function! s:is_modified(from_count, to_count) abort + return a:from_count > 0 && a:to_count > 0 && a:from_count == a:to_count +endfunction + +function! s:is_modified_and_added(from_count, to_count) abort + return a:from_count > 0 && a:to_count > 0 && a:from_count < a:to_count +endfunction + +function! s:is_modified_and_removed(from_count, to_count) abort + return a:from_count > 0 && a:to_count > 0 && a:from_count > a:to_count +endfunction + +function! s:process_added(modifications, from_count, to_count, to_line) abort + let offset = 0 + while offset < a:to_count + let line_number = a:to_line + offset + call add(a:modifications, [line_number, 'added']) + let offset += 1 + endwhile +endfunction + +function! s:process_removed(modifications, from_count, to_count, to_line) abort + if a:to_line == 0 + call add(a:modifications, [1, 'removed_first_line']) + else + call add(a:modifications, [a:to_line, 'removed']) + endif +endfunction + +function! s:process_modified(modifications, from_count, to_count, to_line) abort + let offset = 0 + while offset < a:to_count + let line_number = a:to_line + offset + call add(a:modifications, [line_number, 'modified']) + let offset += 1 + endwhile +endfunction + +function! s:process_modified_and_added(modifications, from_count, to_count, to_line) abort + let offset = 0 + while offset < a:from_count + let line_number = a:to_line + offset + call add(a:modifications, [line_number, 'modified']) + let offset += 1 + endwhile + while offset < a:to_count + let line_number = a:to_line + offset + call add(a:modifications, [line_number, 'added']) + let offset += 1 + endwhile +endfunction + +function! s:process_modified_and_removed(modifications, from_count, to_count, to_line) abort + let offset = 0 + while offset < a:to_count + let line_number = a:to_line + offset + call add(a:modifications, [line_number, 'modified']) + let offset += 1 + endwhile + let a:modifications[-1] = [a:to_line + offset - 1, 'modified_removed'] +endfunction + + +" Returns a diff for the current hunk. +function! gitgutter#diff#hunk_diff(bufnr, full_diff) + let modified_diff = [] + let keep_line = 1 + " Don't keepempty when splitting because the diff we want may not be the + " final one. Instead add trailing NL at end of function. + for line in split(a:full_diff, '\n') + let hunk_info = gitgutter#diff#parse_hunk(line) + if len(hunk_info) == 4 " start of new hunk + let keep_line = gitgutter#hunk#cursor_in_hunk(hunk_info) + endif + if keep_line + call add(modified_diff, line) + endif + endfor + return join(modified_diff, "\n")."\n" +endfunction + + +function! s:write_buffer(bufnr, file) + let bufcontents = getbufline(a:bufnr, 1, '$') + + if getbufvar(a:bufnr, '&fileformat') ==# 'dos' + call map(bufcontents, 'v:val."\r"') + endif + + let fenc = getbufvar(a:bufnr, '&fileencoding') + if fenc !=# &encoding + call map(bufcontents, 'iconv(v:val, &encoding, "'.fenc.'")') + endif + + if getbufvar(a:bufnr, '&bomb') + let bufcontents[0]=''.bufcontents[0] + endif + + call writefile(bufcontents, a:file) +endfunction + + +function! s:save_last_seen_change(bufnr) abort + call gitgutter#utility#setbufvar(a:bufnr, 'tick', getbufvar(a:bufnr, 'changedtick')) +endfunction + + diff --git a/.vim/bundle/vim-gitgutter/autoload/gitgutter/highlight.vim b/.vim/bundle/vim-gitgutter/autoload/gitgutter/highlight.vim new file mode 100644 index 0000000..3fa4a91 --- /dev/null +++ b/.vim/bundle/vim-gitgutter/autoload/gitgutter/highlight.vim @@ -0,0 +1,149 @@ +function! gitgutter#highlight#line_disable() abort + let g:gitgutter_highlight_lines = 0 + call s:define_sign_line_highlights() + + if !g:gitgutter_signs + call gitgutter#sign#clear_signs(bufnr('')) + call gitgutter#sign#remove_dummy_sign(bufnr(''), 0) + endif + + redraw! +endfunction + +function! gitgutter#highlight#line_enable() abort + let old_highlight_lines = g:gitgutter_highlight_lines + + let g:gitgutter_highlight_lines = 1 + call s:define_sign_line_highlights() + + if !old_highlight_lines && !g:gitgutter_signs + call gitgutter#all(1) + endif + + redraw! +endfunction + +function! gitgutter#highlight#line_toggle() abort + if g:gitgutter_highlight_lines + call gitgutter#highlight#line_disable() + else + call gitgutter#highlight#line_enable() + endif +endfunction + + +function! gitgutter#highlight#define_sign_column_highlight() abort + if g:gitgutter_override_sign_column_highlight + highlight! link SignColumn LineNr + else + highlight default link SignColumn LineNr + endif +endfunction + +function! gitgutter#highlight#define_highlights() abort + let [guibg, ctermbg] = s:get_background_colors('SignColumn') + + " Highlights used by the signs. + + execute "highlight GitGutterAddDefault guifg=#009900 guibg=" . guibg . " ctermfg=2 ctermbg=" . ctermbg + execute "highlight GitGutterChangeDefault guifg=#bbbb00 guibg=" . guibg . " ctermfg=3 ctermbg=" . ctermbg + execute "highlight GitGutterDeleteDefault guifg=#ff2222 guibg=" . guibg . " ctermfg=1 ctermbg=" . ctermbg + highlight default link GitGutterChangeDeleteDefault GitGutterChangeDefault + + execute "highlight GitGutterAddInvisible guifg=bg guibg=" . guibg . " ctermfg=" . ctermbg . " ctermbg=" . ctermbg + execute "highlight GitGutterChangeInvisible guifg=bg guibg=" . guibg . " ctermfg=" . ctermbg . " ctermbg=" . ctermbg + execute "highlight GitGutterDeleteInvisible guifg=bg guibg=" . guibg . " ctermfg=" . ctermbg . " ctermbg=" . ctermbg + highlight default link GitGutterChangeDeleteInvisible GitGutterChangeInvisible + + highlight default link GitGutterAdd GitGutterAddDefault + highlight default link GitGutterChange GitGutterChangeDefault + highlight default link GitGutterDelete GitGutterDeleteDefault + highlight default link GitGutterChangeDelete GitGutterChangeDeleteDefault + + " Highlights used for the whole line. + + highlight default link GitGutterAddLine DiffAdd + highlight default link GitGutterChangeLine DiffChange + highlight default link GitGutterDeleteLine DiffDelete + highlight default link GitGutterChangeDeleteLine GitGutterChangeLine +endfunction + +function! gitgutter#highlight#define_signs() abort + sign define GitGutterLineAdded + sign define GitGutterLineModified + sign define GitGutterLineRemoved + sign define GitGutterLineRemovedFirstLine + sign define GitGutterLineModifiedRemoved + sign define GitGutterDummy + + call s:define_sign_text() + call gitgutter#highlight#define_sign_text_highlights() + call s:define_sign_line_highlights() +endfunction + +function! s:define_sign_text() abort + execute "sign define GitGutterLineAdded text=" . g:gitgutter_sign_added + execute "sign define GitGutterLineModified text=" . g:gitgutter_sign_modified + execute "sign define GitGutterLineRemoved text=" . g:gitgutter_sign_removed + execute "sign define GitGutterLineRemovedFirstLine text=" . g:gitgutter_sign_removed_first_line + execute "sign define GitGutterLineModifiedRemoved text=" . g:gitgutter_sign_modified_removed +endfunction + +function! gitgutter#highlight#define_sign_text_highlights() abort + " Once a sign's text attribute has been defined, it cannot be undefined or + " set to an empty value. So to make signs' text disappear (when toggling + " off or disabling) we make them invisible by setting their foreground colours + " to the background's. + if g:gitgutter_signs + sign define GitGutterLineAdded texthl=GitGutterAdd + sign define GitGutterLineModified texthl=GitGutterChange + sign define GitGutterLineRemoved texthl=GitGutterDelete + sign define GitGutterLineRemovedFirstLine texthl=GitGutterDelete + sign define GitGutterLineModifiedRemoved texthl=GitGutterChangeDelete + else + sign define GitGutterLineAdded texthl=GitGutterAddInvisible + sign define GitGutterLineModified texthl=GitGutterChangeInvisible + sign define GitGutterLineRemoved texthl=GitGutterDeleteInvisible + sign define GitGutterLineRemovedFirstLine texthl=GitGutterDeleteInvisible + sign define GitGutterLineModifiedRemoved texthl=GitGutterChangeDeleteInvisible + endif +endfunction + +function! s:define_sign_line_highlights() abort + if g:gitgutter_highlight_lines + sign define GitGutterLineAdded linehl=GitGutterAddLine + sign define GitGutterLineModified linehl=GitGutterChangeLine + sign define GitGutterLineRemoved linehl=GitGutterDeleteLine + sign define GitGutterLineRemovedFirstLine linehl=GitGutterDeleteLine + sign define GitGutterLineModifiedRemoved linehl=GitGutterChangeDeleteLine + else + sign define GitGutterLineAdded linehl= + sign define GitGutterLineModified linehl= + sign define GitGutterLineRemoved linehl= + sign define GitGutterLineRemovedFirstLine linehl= + sign define GitGutterLineModifiedRemoved linehl= + endif +endfunction + +function! s:get_background_colors(group) abort + redir => highlight + silent execute 'silent highlight ' . a:group + redir END + + let link_matches = matchlist(highlight, 'links to \(\S\+\)') + if len(link_matches) > 0 " follow the link + return s:get_background_colors(link_matches[1]) + endif + + let ctermbg = s:match_highlight(highlight, 'ctermbg=\([0-9A-Za-z]\+\)') + let guibg = s:match_highlight(highlight, 'guibg=\([#0-9A-Za-z]\+\)') + return [guibg, ctermbg] +endfunction + +function! s:match_highlight(highlight, pattern) abort + let matches = matchlist(a:highlight, a:pattern) + if len(matches) == 0 + return 'NONE' + endif + return matches[1] +endfunction diff --git a/.vim/bundle/vim-gitgutter/autoload/gitgutter/hunk.vim b/.vim/bundle/vim-gitgutter/autoload/gitgutter/hunk.vim new file mode 100644 index 0000000..d3e55bb --- /dev/null +++ b/.vim/bundle/vim-gitgutter/autoload/gitgutter/hunk.vim @@ -0,0 +1,281 @@ +function! gitgutter#hunk#set_hunks(bufnr, hunks) abort + call gitgutter#utility#setbufvar(a:bufnr, 'hunks', a:hunks) + call s:reset_summary(a:bufnr) +endfunction + +function! gitgutter#hunk#hunks(bufnr) abort + return gitgutter#utility#getbufvar(a:bufnr, 'hunks', []) +endfunction + +function! gitgutter#hunk#reset(bufnr) abort + call gitgutter#utility#setbufvar(a:bufnr, 'hunks', []) + call s:reset_summary(a:bufnr) +endfunction + + +function! gitgutter#hunk#summary(bufnr) abort + return gitgutter#utility#getbufvar(a:bufnr, 'summary', [0,0,0]) +endfunction + +function! s:reset_summary(bufnr) abort + call gitgutter#utility#setbufvar(a:bufnr, 'summary', [0,0,0]) +endfunction + +function! gitgutter#hunk#increment_lines_added(bufnr, count) abort + let summary = gitgutter#hunk#summary(a:bufnr) + let summary[0] += a:count + call gitgutter#utility#setbufvar(a:bufnr, 'summary', summary) +endfunction + +function! gitgutter#hunk#increment_lines_modified(bufnr, count) abort + let summary = gitgutter#hunk#summary(a:bufnr) + let summary[1] += a:count + call gitgutter#utility#setbufvar(a:bufnr, 'summary', summary) +endfunction + +function! gitgutter#hunk#increment_lines_removed(bufnr, count) abort + let summary = gitgutter#hunk#summary(a:bufnr) + let summary[2] += a:count + call gitgutter#utility#setbufvar(a:bufnr, 'summary', summary) +endfunction + + +function! gitgutter#hunk#next_hunk(count) abort + let bufnr = bufnr('') + if gitgutter#utility#is_active(bufnr) + let current_line = line('.') + let hunk_count = 0 + for hunk in gitgutter#hunk#hunks(bufnr) + if hunk[2] > current_line + let hunk_count += 1 + if hunk_count == a:count + execute 'normal!' hunk[2] . 'Gzv' + return + endif + endif + endfor + call gitgutter#utility#warn('No more hunks') + endif +endfunction + +function! gitgutter#hunk#prev_hunk(count) abort + let bufnr = bufnr('') + if gitgutter#utility#is_active(bufnr) + let current_line = line('.') + let hunk_count = 0 + for hunk in reverse(copy(gitgutter#hunk#hunks(bufnr))) + if hunk[2] < current_line + let hunk_count += 1 + if hunk_count == a:count + let target = hunk[2] == 0 ? 1 : hunk[2] + execute 'normal!' target . 'Gzv' + return + endif + endif + endfor + call gitgutter#utility#warn('No previous hunks') + endif +endfunction + +" Returns the hunk the cursor is currently in or an empty list if the cursor +" isn't in a hunk. +function! s:current_hunk() abort + let bufnr = bufnr('') + let current_hunk = [] + + for hunk in gitgutter#hunk#hunks(bufnr) + if gitgutter#hunk#cursor_in_hunk(hunk) + let current_hunk = hunk + break + endif + endfor + + return current_hunk +endfunction + +function! gitgutter#hunk#cursor_in_hunk(hunk) abort + let current_line = line('.') + + if current_line == 1 && a:hunk[2] == 0 + return 1 + endif + + if current_line >= a:hunk[2] && current_line < a:hunk[2] + (a:hunk[3] == 0 ? 1 : a:hunk[3]) + return 1 + endif + + return 0 +endfunction + +function! gitgutter#hunk#text_object(inner) abort + let hunk = s:current_hunk() + + if empty(hunk) + return + endif + + let [first_line, last_line] = [hunk[2], hunk[2] + hunk[3] - 1] + + if ! a:inner + let lnum = last_line + let eof = line('$') + while lnum < eof && empty(getline(lnum + 1)) + let lnum +=1 + endwhile + let last_line = lnum + endif + + execute 'normal! 'first_line.'GV'.last_line.'G' +endfunction + + +function! gitgutter#hunk#stage() abort + call s:hunk_op(function('s:stage')) + silent! call repeat#set("\GitGutterStageHunk", -1) +endfunction + +function! gitgutter#hunk#undo() abort + call s:hunk_op(function('s:undo')) + silent! call repeat#set("\GitGutterUndoHunk", -1) +endfunction + +function! gitgutter#hunk#preview() abort + call s:hunk_op(function('s:preview')) + silent! call repeat#set("\GitGutterPreviewHunk", -1) +endfunction + + +function! s:hunk_op(op) + let bufnr = bufnr('') + + if gitgutter#utility#is_active(bufnr) + " Get a (synchronous) diff. + let [async, g:gitgutter_async] = [g:gitgutter_async, 0] + let diff = gitgutter#diff#run_diff(bufnr, 1) + let g:gitgutter_async = async + + call gitgutter#hunk#set_hunks(bufnr, gitgutter#diff#parse_diff(diff)) + + if empty(s:current_hunk()) + call gitgutter#utility#warn('cursor is not in a hunk') + else + call a:op(gitgutter#diff#hunk_diff(bufnr, diff)) + endif + endif +endfunction + + +function! s:stage(hunk_diff) + let bufnr = bufnr('') + let diff = s:adjust_header(bufnr, a:hunk_diff) + " Apply patch to index. + call gitgutter#utility#system( + \ gitgutter#utility#cd_cmd(bufnr, g:gitgutter_git_executable.' apply --cached --unidiff-zero - '), + \ diff) + + " Refresh gitgutter's view of buffer. + call gitgutter#process_buffer(bufnr, 1) +endfunction + + +function! s:undo(hunk_diff) + " Apply reverse patch to buffer. + let hunk = gitgutter#diff#parse_hunk(split(a:hunk_diff, '\n')[4]) + let lines = map(split(a:hunk_diff, '\n')[5:], 'v:val[1:]') + let lnum = hunk[2] + let added_only = hunk[1] == 0 && hunk[3] > 0 + let removed_only = hunk[1] > 0 && hunk[3] == 0 + + if removed_only + call append(lnum, lines) + elseif added_only + execute lnum .','. (lnum+len(lines)-1) .'d' + else + call append(lnum-1, lines[0:hunk[1]]) + execute (lnum+hunk[1]) .','. (lnum+hunk[1]+hunk[3]) .'d' + endif +endfunction + + +function! s:preview(hunk_diff) + let hunk_lines = split(s:discard_header(a:hunk_diff), "\n") + let hunk_lines_length = len(hunk_lines) + let previewheight = min([hunk_lines_length, &previewheight]) + + silent! wincmd P + if !&previewwindow + noautocmd execute 'bo' previewheight 'new' + set previewwindow + else + execute 'resize' previewheight + endif + + setlocal noreadonly modifiable filetype=diff buftype=nofile bufhidden=delete noswapfile + execute "%delete_" + call append(0, hunk_lines) + normal! gg + setlocal readonly nomodifiable + + noautocmd wincmd p +endfunction + + +function! s:adjust_header(bufnr, hunk_diff) + let filepath = gitgutter#utility#repo_path(a:bufnr, 0) + return s:adjust_hunk_summary(s:fix_file_references(filepath, a:hunk_diff)) +endfunction + + +" Replaces references to temp files with the actual file. +function! s:fix_file_references(filepath, hunk_diff) + let lines = split(a:hunk_diff, '\n') + + let left_prefix = matchstr(lines[2], '[abciow12]').'/' + let right_prefix = matchstr(lines[3], '[abciow12]').'/' + let quote = lines[0][11] == '"' ? '"' : '' + + let left_file = quote.left_prefix.a:filepath.quote + let right_file = quote.right_prefix.a:filepath.quote + + let lines[0] = 'diff --git '.left_file.' '.right_file + let lines[2] = '--- '.left_file + let lines[3] = '+++ '.right_file + + return join(lines, "\n")."\n" +endfunction + +if $VIM_GITGUTTER_TEST + function! gitgutter#hunk#fix_file_references(filepath, hunk_diff) + return s:fix_file_references(a:filepath, a:hunk_diff) + endfunction +endif + + +function! s:adjust_hunk_summary(hunk_diff) abort + let line_adjustment = s:line_adjustment_for_current_hunk() + let diff = split(a:hunk_diff, '\n', 1) + let diff[4] = substitute(diff[4], '+\@<=\(\d\+\)', '\=submatch(1)+line_adjustment', '') + return join(diff, "\n") +endfunction + + +function! s:discard_header(hunk_diff) + return join(split(a:hunk_diff, '\n', 1)[5:], "\n") +endfunction + + +" Returns the number of lines the current hunk is offset from where it would +" be if any changes above it in the file didn't exist. +function! s:line_adjustment_for_current_hunk() abort + let bufnr = bufnr('') + let adj = 0 + for hunk in gitgutter#hunk#hunks(bufnr) + if gitgutter#hunk#cursor_in_hunk(hunk) + break + else + let adj += hunk[1] - hunk[3] + endif + endfor + return adj +endfunction + diff --git a/.vim/bundle/vim-gitgutter/autoload/gitgutter/sign.vim b/.vim/bundle/vim-gitgutter/autoload/gitgutter/sign.vim new file mode 100644 index 0000000..b65563d --- /dev/null +++ b/.vim/bundle/vim-gitgutter/autoload/gitgutter/sign.vim @@ -0,0 +1,219 @@ +" Vim doesn't namespace sign ids so every plugin shares the same +" namespace. Sign ids are simply integers so to avoid clashes with other +" signs we guess at a clear run. +" +" Note also we currently never reset s:next_sign_id. +let s:first_sign_id = 3000 +let s:next_sign_id = s:first_sign_id +let s:dummy_sign_id = s:first_sign_id - 1 +" Remove-all-signs optimisation requires Vim 7.3.596+. +let s:supports_star = v:version > 703 || (v:version == 703 && has("patch596")) + + +function! gitgutter#sign#enable() abort + let old_signs = g:gitgutter_signs + + let g:gitgutter_signs = 1 + call gitgutter#highlight#define_sign_text_highlights() + + if !old_signs && !g:gitgutter_highlight_lines + call gitgutter#all(1) + endif +endfunction + +function! gitgutter#sign#disable() abort + let g:gitgutter_signs = 0 + call gitgutter#highlight#define_sign_text_highlights() + + if !g:gitgutter_highlight_lines + call gitgutter#sign#clear_signs(bufnr('')) + call gitgutter#sign#remove_dummy_sign(bufnr(''), 0) + endif +endfunction + +function! gitgutter#sign#toggle() abort + if g:gitgutter_signs + call gitgutter#sign#disable() + else + call gitgutter#sign#enable() + endif +endfunction + + +" Removes gitgutter's signs (excluding dummy sign) from the buffer being processed. +function! gitgutter#sign#clear_signs(bufnr) abort + call s:find_current_signs(a:bufnr) + + let sign_ids = map(values(gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs')), 'v:val.id') + call s:remove_signs(a:bufnr, sign_ids, 1) + call gitgutter#utility#setbufvar(a:bufnr, 'gitgutter_signs', {}) +endfunction + + +" Updates gitgutter's signs in the buffer being processed. +" +" modified_lines: list of [, ] +" where name = 'added|removed|modified|modified_removed' +function! gitgutter#sign#update_signs(bufnr, modified_lines) abort + call s:find_current_signs(a:bufnr) + + let new_gitgutter_signs_line_numbers = map(copy(a:modified_lines), 'v:val[0]') + let obsolete_signs = s:obsolete_gitgutter_signs_to_remove(a:bufnr, new_gitgutter_signs_line_numbers) + + let flicker_possible = s:remove_all_old_signs && !empty(a:modified_lines) + if flicker_possible + call s:add_dummy_sign(a:bufnr) + endif + + call s:remove_signs(a:bufnr, obsolete_signs, s:remove_all_old_signs) + call s:upsert_new_gitgutter_signs(a:bufnr, a:modified_lines) + + if flicker_possible + call gitgutter#sign#remove_dummy_sign(a:bufnr, 0) + endif +endfunction + + +function! s:add_dummy_sign(bufnr) abort + if !gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign') + execute "sign place" s:dummy_sign_id "line=" . 9999 "name=GitGutterDummy buffer=" . a:bufnr + call gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', 1) + endif +endfunction + +function! gitgutter#sign#remove_dummy_sign(bufnr, force) abort + if gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign') && (a:force || !g:gitgutter_sign_column_always) + execute "sign unplace" s:dummy_sign_id "buffer=" . a:bufnr + call gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', 0) + endif +endfunction + + +" +" Internal functions +" + + +function! s:find_current_signs(bufnr) abort + let gitgutter_signs = {} " : {'id': , 'name': } + let other_signs = [] " [ signs + silent execute "sign place buffer=" . a:bufnr + redir END + + for sign_line in filter(split(signs, '\n')[2:], 'v:val =~# "="') + " Typical sign line: line=88 id=1234 name=GitGutterLineAdded + " We assume splitting is faster than a regexp. + let components = split(sign_line) + let name = split(components[2], '=')[1] + if name =~# 'GitGutterDummy' + let dummy_sign_placed = 1 + else + let line_number = str2nr(split(components[0], '=')[1]) + if name =~# 'GitGutter' + let id = str2nr(split(components[1], '=')[1]) + " Remove orphaned signs (signs placed on lines which have been deleted). + " (When a line is deleted its sign lingers. Subsequent lines' signs' + " line numbers are decremented appropriately.) + if has_key(gitgutter_signs, line_number) + execute "sign unplace" gitgutter_signs[line_number].id + endif + let gitgutter_signs[line_number] = {'id': id, 'name': name} + else + call add(other_signs, line_number) + endif + end + endfor + + call gitgutter#utility#setbufvar(a:bufnr, 'dummy_sign', dummy_sign_placed) + call gitgutter#utility#setbufvar(a:bufnr, 'gitgutter_signs', gitgutter_signs) + call gitgutter#utility#setbufvar(a:bufnr, 'other_signs', other_signs) +endfunction + + +" Returns a list of [, ...] +" Sets `s:remove_all_old_signs` as a side-effect. +function! s:obsolete_gitgutter_signs_to_remove(bufnr, new_gitgutter_signs_line_numbers) abort + let signs_to_remove = [] " list of [, ...] + let remove_all_signs = 1 + let old_gitgutter_signs = gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs') + for line_number in keys(old_gitgutter_signs) + if index(a:new_gitgutter_signs_line_numbers, str2nr(line_number)) == -1 + call add(signs_to_remove, old_gitgutter_signs[line_number].id) + else + let remove_all_signs = 0 + endif + endfor + let s:remove_all_old_signs = remove_all_signs + return signs_to_remove +endfunction + + +function! s:remove_signs(bufnr, sign_ids, all_signs) abort + if a:all_signs && s:supports_star && empty(gitgutter#utility#getbufvar(a:bufnr, 'other_signs')) + let dummy_sign_present = gitgutter#utility#getbufvar(a:bufnr, 'dummy_sign') + execute "sign unplace * buffer=" . a:bufnr + if dummy_sign_present + execute "sign place" s:dummy_sign_id "line=" . 9999 "name=GitGutterDummy buffer=" . a:bufnr + endif + else + for id in a:sign_ids + execute "sign unplace" id + endfor + endif +endfunction + + +function! s:upsert_new_gitgutter_signs(bufnr, modified_lines) abort + let other_signs = gitgutter#utility#getbufvar(a:bufnr, 'other_signs') + let old_gitgutter_signs = gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs') + + for line in a:modified_lines + let line_number = line[0] " + if index(other_signs, line_number) == -1 " don't clobber others' signs + let name = s:highlight_name_for_change(line[1]) + if !has_key(old_gitgutter_signs, line_number) " insert + let id = s:next_sign_id() + execute "sign place" id "line=" . line_number "name=" . name "buffer=" . a:bufnr + else " update if sign has changed + let old_sign = old_gitgutter_signs[line_number] + if old_sign.name !=# name + execute "sign place" old_sign.id "name=" . name "buffer=" . a:bufnr + end + endif + endif + endfor + " At this point b:gitgutter_gitgutter_signs is out of date. +endfunction + + +function! s:next_sign_id() abort + let next_id = s:next_sign_id + let s:next_sign_id += 1 + return next_id +endfunction + + +" Only for testing. +function! gitgutter#sign#reset() + let s:next_sign_id = s:first_sign_id +endfunction + + +function! s:highlight_name_for_change(text) abort + if a:text ==# 'added' + return 'GitGutterLineAdded' + elseif a:text ==# 'removed' + return 'GitGutterLineRemoved' + elseif a:text ==# 'removed_first_line' + return 'GitGutterLineRemovedFirstLine' + elseif a:text ==# 'modified' + return 'GitGutterLineModified' + elseif a:text ==# 'modified_removed' + return 'GitGutterLineModifiedRemoved' + endif +endfunction + + diff --git a/.vim/bundle/vim-gitgutter/autoload/gitgutter/utility.vim b/.vim/bundle/vim-gitgutter/autoload/gitgutter/utility.vim new file mode 100644 index 0000000..d497938 --- /dev/null +++ b/.vim/bundle/vim-gitgutter/autoload/gitgutter/utility.vim @@ -0,0 +1,210 @@ +function! gitgutter#utility#supports_overscore_sign() + if gitgutter#utility#windows() + return &encoding ==? 'utf-8' + else + return &termencoding ==? &encoding || &termencoding == '' + endif +endfunction + +function! gitgutter#utility#setbufvar(buffer, varname, val) + let dict = get(getbufvar(a:buffer, ''), 'gitgutter', {}) + let needs_setting = empty(dict) + let dict[a:varname] = a:val + if needs_setting + call setbufvar(+a:buffer, 'gitgutter', dict) + endif +endfunction + +function! gitgutter#utility#getbufvar(buffer, varname, ...) + let dict = get(getbufvar(a:buffer, ''), 'gitgutter', {}) + if has_key(dict, a:varname) + return dict[a:varname] + else + if a:0 + return a:1 + endif + endif +endfunction + +function! gitgutter#utility#warn(message) abort + echohl WarningMsg + echo 'vim-gitgutter: ' . a:message + echohl None + let v:warningmsg = a:message +endfunction + +function! gitgutter#utility#warn_once(bufnr, message, key) abort + if empty(gitgutter#utility#getbufvar(a:bufnr, a:key)) + call gitgutter#utility#setbufvar(a:bufnr, a:key, '1') + echohl WarningMsg + redraw | echom 'vim-gitgutter: ' . a:message + echohl None + let v:warningmsg = a:message + endif +endfunction + +" Returns truthy when the buffer's file should be processed; and falsey when it shouldn't. +" This function does not and should not make any system calls. +function! gitgutter#utility#is_active(bufnr) abort + return g:gitgutter_enabled && + \ !pumvisible() && + \ s:is_file_buffer(a:bufnr) && + \ s:exists_file(a:bufnr) && + \ s:not_git_dir(a:bufnr) +endfunction + +function! s:not_git_dir(bufnr) abort + return s:dir(a:bufnr) !~ '[/\\]\.git\($\|[/\\]\)' +endfunction + +function! s:is_file_buffer(bufnr) abort + return empty(getbufvar(a:bufnr, '&buftype')) +endfunction + +" From tpope/vim-fugitive +function! s:winshell() + return &shell =~? 'cmd' || exists('+shellslash') && !&shellslash +endfunction + +" From tpope/vim-fugitive +function! gitgutter#utility#shellescape(arg) abort + if a:arg =~ '^[A-Za-z0-9_/.-]\+$' + return a:arg + elseif s:winshell() + return '"' . substitute(substitute(a:arg, '"', '""', 'g'), '%', '"%"', 'g') . '"' + else + return shellescape(a:arg) + endif +endfunction + +function! gitgutter#utility#file(bufnr) + return s:abs_path(a:bufnr, 1) +endfunction + +" Not shellescaped +function! gitgutter#utility#extension(bufnr) abort + return fnamemodify(s:abs_path(a:bufnr, 0), ':e') +endfunction + +function! gitgutter#utility#system(cmd, ...) abort + call gitgutter#debug#log(a:cmd, a:000) + + call s:use_known_shell() + silent let output = (a:0 == 0) ? system(a:cmd) : system(a:cmd, a:1) + call s:restore_shell() + + return output +endfunction + +" Path of file relative to repo root. +" +" * empty string - not set +" * non-empty string - path +" * -1 - pending +" * -2 - not tracked by git +function! gitgutter#utility#repo_path(bufnr, shellesc) abort + let p = gitgutter#utility#getbufvar(a:bufnr, 'path') + return a:shellesc ? gitgutter#utility#shellescape(p) : p +endfunction + +function! gitgutter#utility#set_repo_path(bufnr) abort + " Values of path: + " * non-empty string - path + " * -1 - pending + " * -2 - not tracked by git + + call gitgutter#utility#setbufvar(a:bufnr, 'path', -1) + let cmd = gitgutter#utility#cd_cmd(a:bufnr, g:gitgutter_git_executable.' ls-files --error-unmatch --full-name -- '.gitgutter#utility#shellescape(s:filename(a:bufnr))) + + if g:gitgutter_async && gitgutter#async#available() + if has('lambda') + call gitgutter#async#execute(cmd, a:bufnr, { + \ 'out': {bufnr, path -> gitgutter#utility#setbufvar(bufnr, 'path', s:strip_trailing_new_line(path))}, + \ 'err': {bufnr -> gitgutter#utility#setbufvar(bufnr, 'path', -2)}, + \ }) + else + if has('nvim') && !has('nvim-0.2.0') + call gitgutter#async#execute(cmd, a:bufnr, { + \ 'out': function('s:set_path'), + \ 'err': function('s:not_tracked_by_git') + \ }) + else + call gitgutter#async#execute(cmd, a:bufnr, { + \ 'out': function('s:set_path'), + \ 'err': function('s:set_path', [-2]) + \ }) + endif + endif + else + let path = gitgutter#utility#system(cmd) + if v:shell_error + call gitgutter#utility#setbufvar(a:bufnr, 'path', -2) + else + call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(path)) + endif + endif +endfunction + +if has('nvim') && !has('nvim-0.2.0') + function! s:not_tracked_by_git(bufnr) + call s:set_path(a:bufnr, -2) + endfunction +endif + +function! s:set_path(bufnr, path) + if a:bufnr == -2 + let [bufnr, path] = [a:path, a:bufnr] + call gitgutter#utility#setbufvar(bufnr, 'path', path) + else + call gitgutter#utility#setbufvar(a:bufnr, 'path', s:strip_trailing_new_line(a:path)) + endif +endfunction + +function! gitgutter#utility#cd_cmd(bufnr, cmd) abort + let cd = s:unc_path(a:bufnr) ? 'pushd' : (gitgutter#utility#windows() ? 'cd /d' : 'cd') + return cd.' '.s:dir(a:bufnr).' && '.a:cmd +endfunction + +function! s:unc_path(bufnr) + return s:abs_path(a:bufnr, 0) =~ '^\\\\' +endfunction + +function! s:use_known_shell() abort + if has('unix') && &shell !=# 'sh' + let [s:shell, s:shellcmdflag, s:shellredir] = [&shell, &shellcmdflag, &shellredir] + let &shell = 'sh' + set shellcmdflag=-c shellredir=>%s\ 2>&1 + endif +endfunction + +function! s:restore_shell() abort + if has('unix') && exists('s:shell') + let [&shell, &shellcmdflag, &shellredir] = [s:shell, s:shellcmdflag, s:shellredir] + endif +endfunction + +function! s:abs_path(bufnr, shellesc) + let p = resolve(expand('#'.a:bufnr.':p')) + return a:shellesc ? gitgutter#utility#shellescape(p) : p +endfunction + +function! s:dir(bufnr) abort + return gitgutter#utility#shellescape(fnamemodify(s:abs_path(a:bufnr, 0), ':h')) +endfunction + +" Not shellescaped. +function! s:filename(bufnr) abort + return fnamemodify(s:abs_path(a:bufnr, 0), ':t') +endfunction + +function! s:exists_file(bufnr) abort + return filereadable(s:abs_path(a:bufnr, 0)) +endfunction + +function! s:strip_trailing_new_line(line) abort + return substitute(a:line, '\n$', '', '') +endfunction + +function! gitgutter#utility#windows() + return has('win64') || has('win32') || has('win16') +endfunction diff --git a/.vim/bundle/vim-gitgutter/doc/gitgutter.txt b/.vim/bundle/vim-gitgutter/doc/gitgutter.txt new file mode 100644 index 0000000..e9c8f01 --- /dev/null +++ b/.vim/bundle/vim-gitgutter/doc/gitgutter.txt @@ -0,0 +1,529 @@ +*gitgutter.txt* A Vim plugin which shows a git diff in the gutter. + + + Vim Git Gutter + + +Author: Andy Stewart +Plugin Homepage: + + +=============================================================================== +CONTENTS *gitgutter* + + Introduction ................. |gitgutter-introduction| + Installation ................. |gitgutter-installation| + Commands ..................... |gitgutter-commands| + Mappings ..................... |gitgutter-mappings| + Autocommand .................. |gitgutter-autocommand| + Options ...................... |gitgutter-options| + Highlights ................... |gitgutter-highlights| + FAQ .......................... |gitgutter-faq| + TROUBLESHOOTING .............. |gitgutter-troubleshooting| + + +=============================================================================== +INTRODUCTION *gitgutter-introduction* + +GitGutter is a Vim plugin which shows a git diff in the 'gutter' (sign column). +It shows which lines have been added, modified, or removed. You can also +preview, stage, and undo individual hunks. The plugin also provides a hunk +text object. + +The signs are always up to date and the plugin never saves your buffer. + + +=============================================================================== +INSTALLATION *gitgutter-installation* + +Pathogen:~ +> + cd ~/.vim/bundle + git clone git://github.com/airblade/vim-gitgutter.git +< +Voom:~ + +Edit your plugin manifest (`voom edit`) and add: +> + airblade/vim-gitgutter +< +VimPlug:~ + +Place this in your .vimrc: +> + Plug 'airblade/vim-gitgutter' +< +Then run the following in Vim: +> + :source % + :PlugInstall +< +NeoBundle:~ + +Place this in your .vimrc: +> + NeoBundle 'airblade/vim-gitgutter' +< +Then run the following in Vim: +> + :source % + :NeoBundleInstall +< +No plugin manager:~ + +Copy vim-gitgutter's subdirectories into your vim configuration directory: +> + cd tmp && git clone git://github.com/airblade/vim-gitgutter.git + cp vim-gitgutter/* ~/.vim/ +< +See |add-global-plugin|. + + +=============================================================================== +COMMANDS *gitgutter-commands* + +Commands for turning vim-gitgutter on and off:~ + + *gitgutter-:GitGutterDisable* +:GitGutterDisable Turn vim-gitgutter off for all buffers. + + *gitgutter-:GitGutterEnable* +:GitGutterEnable Turn vim-gitgutter on for all buffers. + + *gitgutter-:GitGutterToggle* +:GitGutterToggle Toggle vim-gitgutter on or off for all buffers. + + *gitgutter-:GitGutter* +:GitGutter Update signs for the current buffer. You shouldn't + need to run this. + + *gitgutter-:GitGutterAll* +:GitGutterAll Update signs for all buffers. You shouldn't need to + run this. + + +Commands for turning signs on and off (defaults to on):~ + + *gitgutter-:GitGutterSignsEnable* +:GitGutterSignsEnable Show signs for the diff. + + *gitgutter-:GitGutterSignsDisable* +:GitGutterSignsDisable Do not show signs for the diff. + + *gitgutter-:GitGutterSignsToggle* +:GitGutterSignsToggle Toggle signs on or off. + + +Commands for turning line highlighting on and off (defaults to off):~ + + *gitgutter-:GitGutterLineHighlightsEnable* +:GitGutterLineHighlightsEnable Turn on line highlighting. + + *gitgutter-:GitGutterLineHighlightsDisable* +:GitGutterLineHighlightsDisable Turn off line highlighting. + + *gitgutter-:GitGutterLineHighlightsToggle* +:GitGutterLineHighlightsToggle Turn line highlighting on or off. + + +Commands for jumping between hunks:~ + + *gitgutter-:GitGutterNextHunk* +:GitGutterNextHunk Jump to the next [count] hunk. + + *gitgutter-:GitGutterPrevHunk* +:GitGutterPrevHunk Jump to the previous [count] hunk. + + +Commands for operating on a hunk:~ + + *gitgutter-:GitGutterStageHunk* +:GitGutterStageHunk Stage the hunk the cursor is in. + + *gitgutter-:GitGutterUndoHunk* +:GitGutterUndoHunk Undo the hunk the cursor is in. + + *gitgutter-:GitGutterPreviewHunk* +:GitGutterPreviewHunk Preview the hunk the cursor is in. + Use |:pclose| or |CTRL-W_CTRL-Z| to close the preview + window. + + +=============================================================================== +AUTOCOMMAND *gitgutter-autocommand* + +User GitGutter~ + +After updating a buffer's signs vim-gitgutter fires a |User| |autocmd| with the +event GitGutter. You can listen for this event, for example: +> + autocmd User GitGutter call updateMyStatusLine() +< +A dictionary `g:gitgutter_hook_context` is made available during its execution, +which contains an entry `bufnr` that contains the buffer number being updated. + + +=============================================================================== +MAPPINGS *gitgutter-mappings* + +You can disable all these mappings with: +> + let g:gitgutter_map_keys = 0 +< + +Hunk operations:~ + +These can be repeated with `.` if you have vim-repeat installed. + + *gitgutter-hp* +hp Preview the hunk under the cursor. + + *gitgutter-hs* +hs Stage the hunk under the cursor. + + *gitgutter-hu* +hu Undo the hunk under the cursor. + +You can change these mappings like this: +> + nmap ghp GitGutterPreviewHunk + nmap ghs GitGutterStageHunk + nmap ghu GitGutterUndoHunk +< + +Hunk jumping:~ + + *gitgutter-]c* +]c Jump to the next [count] hunk. + + *gitgutter-[c* +[c Jump to the previous [count] hunk. + +You can change these mappings like this: +> + nmap [c GitGutterPrevHunk + nmap ]c GitGutterNextHunk +< + +Hunk text object:~ + + *gitgutter-ic* *gitgutter-ac* *gitgutter-text-object* +"ic" operates on the current hunk's lines. "ac" does the same but also includes +trailing empty lines. +> + omap ic GitGutterTextObjectInnerPending + omap ac GitGutterTextObjectOuterPending + xmap ic GitGutterTextObjectInnerVisual + xmap ac GitGutterTextObjectOuterVisual +< + + +=============================================================================== +OPTIONS *gitgutter-options* + +The most important option is 'updatetime' which determines how long (in +milliseconds) the plugin will wait after you stop typing before it updates the +signs. Vim's default is 4000. I recommend 100. + +Most important option:~ + + 'updatetime' + +Git:~ + + |g:gitgutter_git_executable| + |g:gitgutter_diff_args| + |g:gitgutter_diff_base| + +Grep:~ + + |g:gitgutter_grep| + +Signs:~ + + |g:gitgutter_signs| + |g:gitgutter_highlight_lines| + |g:gitgutter_max_signs| + |g:gitgutter_sign_added| + |g:gitgutter_sign_modified| + |g:gitgutter_sign_removed| + |g:gitgutter_sign_removed_first_line| + |g:gitgutter_sign_modified_removed| + |g:gitgutter_sign_column_always| + |g:gitgutter_override_sign_column_highlight| + +Terminal:~ + + |g:gitgutter_terminal_reports_focus| + +General:~ + + |g:gitgutter_enabled| + |g:gitgutter_map_keys| + |g:gitgutter_async| + |g:gitgutter_log| + + + *g:gitgutter_git_executable* +Default: 'git' + +This option determines what git binary to use. Set this if git is not on your +path. + + *g:gitgutter_diff_args* +Default: empty + +Use this option to pass any extra arguments to git-diff. For example: +> + let g:gitgutter_diff_args = '-w' +< + + *g:gitgutter_diff_base* +Default: empty + +By default buffers are diffed against the index. Use this option to diff against +a revision instead. For example: +> + let g:gitgutter_diff_base = '' +< + + *g:gitgutter_grep* +Default: 'grep' + +The plugin pipes the output of git-diff into grep to minimise the amount of data +vim has to process. Set this option if grep is not on your path. + +grep must produce plain-text output without any ANSI escape codes or colours. +Use this option to turn off colours if necessary. +> + let g:gitgutter_grep = 'grep --color=never' +< +If you do not want to use grep at all (perhaps to debug why signs are not +showing), set this option to an empty string: +> + let g:gitgutter_grep = '' +< + + *g:gitgutter_signs* +Default: 1 + +Determines whether or not to show signs. + + *g:gitgutter_highlight_lines* +Default: 0 + +Determines whether or not to show line highlights. + + *g:gitgutter_max_signs* +Default: 500 + +Sets the maximum number of signs to show in a buffer. Vim is slow at updating +signs, so to avoid slowing down the GUI the number of signs is capped. When +the number of changed lines exceeds this value, the plugin removes all signs +and displays a warning message. + + *g:gitgutter_sign_added* + *g:gitgutter_sign_modified* + *g:gitgutter_sign_removed* + *g:gitgutter_sign_removed_first_line* + *g:gitgutter_sign_modified_removed* +Defaults: +> + let g:gitgutter_sign_added = '+' + let g:gitgutter_sign_modified = '~' + let g:gitgutter_sign_removed = '_' + let g:gitgutter_sign_removed_first_line = '‾' + let g:gitgutter_sign_modified_removed = '~_' +< +You can use unicode characters but not images. Signs must not take up more than +2 columns. + + *g:gitgutter_sign_column_always* +Default: 0 + +This legacy option controls whether the sign column should always be shown, even +if there are no signs to display. + +From Vim 7.4.2201, use 'signcolumn' instead: +> + set signcolumn=yes +< + + *g:gitgutter_override_sign_column_highlight* +Default: 1 + +Controls whether to make the sign column look like the line-number column (i.e. +the |hl-LineNr| highlight group). + +To customise your sign column's background color, first tell vim-gitgutter to +leave it alone: +> + let g:gitgutter_override_sign_column_highlight = 0 +< + +And then either update your colorscheme's |hlSignColumn| highlight group or set +it in your |vimrc|: + + Desired appearance Command ~ + Same as line-number column highlight clear SignColumn + User-defined (terminal Vim) highlight SignColumn ctermbg={whatever} + User-defined (graphical Vim) highlight SignColumn guibg={whatever} + + + *g:gitgutter_terminal_reports_focus* +Default: 1 + +Normally the plugin uses |FocusGained| to force-update all buffers when Vim +receives focus. However some terminals do not report focus events and so the +|FocusGained| autocommand never fires. + +If this applies to you, either install something like Terminus +(https://github.com/wincent/terminus) to make |FocusGained| work or set this +option to 0. + +When this option is 0, the plugin force-updates the buffer on |BufEnter| +(instead of only updating if the buffer's contents has changed since the last +update). + + *g:gitgutter_enabled* +Default: 1 + +Controls whether or not the plugin is on at startup. + + *g:gitgutter_map_keys* +Default: 1 + +Controls whether or not the plugin provides mappings. See |gitgutter-mapppings|. + + *g:gitgutter_async* +Default: 1 + +Controls whether or not diffs are run in the background. This has no effect if +your Vim does not support background jobs. + + *g:gitgutter_log* +Default: 0 + +When switched on, the plugin logs to gitgutter.log in the directory where it is +installed. Additionally it logs channel activity to channel.log. + + +=============================================================================== +HIGHLIGHTS *gitgutter-highlights* + +To change the signs' colours, set up the following highlight groups in your +colorscheme or |vimrc|: +> + GitGutterAdd " an added line + GitGutterChange " a changed line + GitGutterDelete " at least one removed line + GitGutterChangeDelete " a changed line followed by at least one removed line +< + +You can either set these with `highlight GitGutterAdd {key}={arg}...` or link +them to existing highlight groups with, say: +> + highlight link GitGutterAdd DiffAdd +< + +To change the line highlights, set up the following highlight groups in your +colorscheme or |vimrc|: +> + GitGutterAddLine " default: links to DiffAdd + GitGutterChangeLine " default: links to DiffChange + GitGutterDeleteLine " default: links to DiffDelete + GitGutterChangeDeleteLine " default: links to GitGutterChangeLineDefault +< + + +=============================================================================== +FAQ *gitgutter-faq* + +a. How do I turn off realtime updates? + + Add this to your vim configuration in an |after-directory|: +> + autocmd! gitgutter CursorHold,CursorHoldI +< + +b. I turned off realtime updates, how can I have signs updated when I save a + file? + + If you really want to update the signs when you save a file, add this to your + |vimrc|: +> + autocmd BufWritePost * GitGutter +< + +c. Why can't I unstage staged changes? + + This plugin is for showing changes between the working tree and the index + (and staging/undoing those changes). Unstaging a staged hunk would require + showing changes between the index and HEAD, which is out of scope. + +d. Why are the colours in the sign column weird? + + Your colorscheme is configuring the |hl-SignColumn| highlight group weirdly. + Please see |g:gitgutter_override_sign_column_highlight| on customising the + sign column. + +e. What happens if I also use another plugin which uses signs (e.g. Syntastic)? + + Vim only allows one sign per line. Vim-gitgutter will not interfere with + signs it did not add. + + +=============================================================================== +TROUBLESHOOTING *gitgutter-troubleshooting* + +When no signs are showing at all:~ + +1. Try bypassing grep with: +> + let g:gitgutter_grep = '' +< + If it works, the problem is grep outputting ANSI escape codes. Use this + option to pass arguments to grep to turn off the escape codes. + +2. Verify git is on your path: +> + :echo system('git --version') +< + +3. Verify your git config is compatible with the version of git return by the + command above. + +4. Verify your Vim supports signs. The following should give 1: +> + :echo has('signs') +< + +5. Check whether the plugin thinks git knows about your file: +> + :echo getbufvar('','gitgutter').path +< + If the result is -2, the plugin thinks your file is not tracked by git. + + +When the whole file is marked as added:~ + +If you use zsh, and you set "CDPATH", make sure "CDPATH" does not include the +current directory. + + +When signs take a few seconds to appear:~ + +Try reducing 'updatetime': +> + set updatetime=100 +< + + +When signs don't update after focusing Vim:~ + +Your terminal probably isn't reporting focus events. Either try installing +Terminus (https://github.com/wincent/terminus) or set: +> + let g:gitgutter_terminal_reports_focus = 0 +< + diff --git a/.vim/bundle/vim-gitgutter/plugin/gitgutter.vim b/.vim/bundle/vim-gitgutter/plugin/gitgutter.vim new file mode 100644 index 0000000..8e71c9c --- /dev/null +++ b/.vim/bundle/vim-gitgutter/plugin/gitgutter.vim @@ -0,0 +1,230 @@ +scriptencoding utf-8 + +if exists('g:loaded_gitgutter') || !has('signs') || &cp + finish +endif +let g:loaded_gitgutter = 1 + +" Initialisation {{{ + +if v:version < 703 || (v:version == 703 && !has("patch105")) + call gitgutter#utility#warn('requires Vim 7.3.105') + finish +endif + +function! s:set(var, default) abort + if !exists(a:var) + if type(a:default) + execute 'let' a:var '=' string(a:default) + else + execute 'let' a:var '=' a:default + endif + endif +endfunction + +call s:set('g:gitgutter_enabled', 1) +call s:set('g:gitgutter_max_signs', 500) +call s:set('g:gitgutter_signs', 1) +call s:set('g:gitgutter_highlight_lines', 0) +call s:set('g:gitgutter_sign_column_always', 0) +if g:gitgutter_sign_column_always && exists('&signcolumn') + " Vim 7.4.2201. + set signcolumn=yes + let g:gitgutter_sign_column_always = 0 + call gitgutter#utility#warn('please replace "let g:gitgutter_sign_column_always=1" with "set signcolumn=yes"') +endif +call s:set('g:gitgutter_override_sign_column_highlight', 1) +call s:set('g:gitgutter_sign_added', '+') +call s:set('g:gitgutter_sign_modified', '~') +call s:set('g:gitgutter_sign_removed', '_') + +if gitgutter#utility#supports_overscore_sign() + call s:set('g:gitgutter_sign_removed_first_line', '‾') +else + call s:set('g:gitgutter_sign_removed_first_line', '_^') +endif + +call s:set('g:gitgutter_sign_modified_removed', '~_') +call s:set('g:gitgutter_diff_args', '') +call s:set('g:gitgutter_diff_base', '') +call s:set('g:gitgutter_map_keys', 1) +call s:set('g:gitgutter_terminal_reports_focus', 1) +call s:set('g:gitgutter_async', 1) +call s:set('g:gitgutter_log', 0) + +call s:set('g:gitgutter_git_executable', 'git') +if !executable(g:gitgutter_git_executable) + call gitgutter#utility#warn('cannot find git. Please set g:gitgutter_git_executable.') +endif + +let default_grep = 'grep' +call s:set('g:gitgutter_grep', default_grep) +if !empty(g:gitgutter_grep) + if executable(split(g:gitgutter_grep)[0]) + if $GREP_OPTIONS =~# '--color=always' + let g:gitgutter_grep .= ' --color=never' + endif + else + if g:gitgutter_grep !=# default_grep + call gitgutter#utility#warn('cannot find '.g:gitgutter_grep.'. Please check g:gitgutter_grep.') + endif + let g:gitgutter_grep = '' + endif +endif + +call gitgutter#highlight#define_sign_column_highlight() +call gitgutter#highlight#define_highlights() +call gitgutter#highlight#define_signs() + +" Prevent infinite loop where: +" - executing a job in the foreground launches a new window which takes the focus; +" - when the job finishes, focus returns to gvim; +" - the FocusGained event triggers a new job (see below). +if gitgutter#utility#windows() && !(g:gitgutter_async && gitgutter#async#available()) + set noshelltemp +endif + +" }}} + +" Primary functions {{{ + +command! -bar GitGutterAll call gitgutter#all(1) +command! -bar GitGutter call gitgutter#process_buffer(bufnr(''), 1) + +command! -bar GitGutterDisable call gitgutter#disable() +command! -bar GitGutterEnable call gitgutter#enable() +command! -bar GitGutterToggle call gitgutter#toggle() + +" }}} + +" Line highlights {{{ + +command! -bar GitGutterLineHighlightsDisable call gitgutter#highlight#line_disable() +command! -bar GitGutterLineHighlightsEnable call gitgutter#highlight#line_enable() +command! -bar GitGutterLineHighlightsToggle call gitgutter#highlight#line_toggle() + +" }}} + +" Signs {{{ + +command! -bar GitGutterSignsEnable call gitgutter#sign#enable() +command! -bar GitGutterSignsDisable call gitgutter#sign#disable() +command! -bar GitGutterSignsToggle call gitgutter#sign#toggle() + +" }}} + +" Hunks {{{ + +command! -bar -count=1 GitGutterNextHunk call gitgutter#hunk#next_hunk() +command! -bar -count=1 GitGutterPrevHunk call gitgutter#hunk#prev_hunk() + +command! -bar GitGutterStageHunk call gitgutter#hunk#stage() +command! -bar GitGutterUndoHunk call gitgutter#hunk#undo() +command! -bar GitGutterPreviewHunk call gitgutter#hunk#preview() + +" Hunk text object +onoremap GitGutterTextObjectInnerPending :call gitgutter#hunk#text_object(1) +onoremap GitGutterTextObjectOuterPending :call gitgutter#hunk#text_object(0) +xnoremap GitGutterTextObjectInnerVisual :call gitgutter#hunk#text_object(1) +xnoremap GitGutterTextObjectOuterVisual :call gitgutter#hunk#text_object(0) + + +" Returns the git-diff hunks for the file or an empty list if there +" aren't any hunks. +" +" The return value is a list of lists. There is one inner list per hunk. +" +" [ +" [from_line, from_count, to_line, to_count], +" [from_line, from_count, to_line, to_count], +" ... +" ] +" +" where: +" +" `from` - refers to the staged file +" `to` - refers to the working tree's file +" `line` - refers to the line number where the change starts +" `count` - refers to the number of lines the change covers +function! GitGutterGetHunks() + let bufnr = bufnr('') + return gitgutter#utility#is_active(bufnr) ? gitgutter#hunk#hunks(bufnr) : [] +endfunction + +" Returns an array that contains a summary of the hunk status for the current +" window. The format is [ added, modified, removed ], where each value +" represents the number of lines added/modified/removed respectively. +function! GitGutterGetHunkSummary() + return gitgutter#hunk#summary(winbufnr(0)) +endfunction + +" }}} + +command! -bar GitGutterDebug call gitgutter#debug#debug() + +" Maps {{{ + +nnoremap GitGutterNextHunk &diff ? ']c' : ":\execute v:count1 . 'GitGutterNextHunk'\" +nnoremap GitGutterPrevHunk &diff ? '[c' : ":\execute v:count1 . 'GitGutterPrevHunk'\" + +nnoremap GitGutterStageHunk :GitGutterStageHunk +nnoremap GitGutterUndoHunk :GitGutterUndoHunk +nnoremap GitGutterPreviewHunk :GitGutterPreviewHunk + +" }}} + +function! s:flag_inactive_tabs() + let active_tab = tabpagenr() + for i in range(1, tabpagenr('$')) + if i != active_tab + call settabvar(i, 'gitgutter_force', 1) + endif + endfor +endfunction + +function! s:on_bufenter() + if exists('t:gitgutter_didtabenter') && t:gitgutter_didtabenter + let t:gitgutter_didtabenter = 0 + let force = !g:gitgutter_terminal_reports_focus + + if exists('t:gitgutter_force') && t:gitgutter_force + let t:gitgutter_force = 0 + let force = 1 + endif + + call gitgutter#all(force) + else + call gitgutter#init_buffer(bufnr('')) + call gitgutter#process_buffer(bufnr(''), !g:gitgutter_terminal_reports_focus) + endif +endfunction + +" Autocommands {{{ + +augroup gitgutter + autocmd! + + autocmd TabEnter * let t:gitgutter_didtabenter = 1 + + autocmd BufEnter * call s:on_bufenter() + + autocmd CursorHold,CursorHoldI * call gitgutter#process_buffer(bufnr(''), 0) + autocmd FileChangedShellPost,ShellCmdPost * call gitgutter#process_buffer(bufnr(''), 1) + + " Ensure that all buffers are processed when opening vim with multiple files, e.g.: + " + " vim -o file1 file2 + autocmd VimEnter * if winnr() != winnr('$') | call gitgutter#all(0) | endif + + autocmd FocusGained * call gitgutter#all(1) | call s:flag_inactive_tabs() + + autocmd ColorScheme * call gitgutter#highlight#define_sign_column_highlight() | call gitgutter#highlight#define_highlights() + + " Disable during :vimgrep + autocmd QuickFixCmdPre *vimgrep* let g:gitgutter_enabled = 0 + autocmd QuickFixCmdPost *vimgrep* let g:gitgutter_enabled = 1 +augroup END + +" }}} + +" vim:set et sw=2 fdm=marker: diff --git a/.vim/bundle/vim-gitgutter/screenshot.png b/.vim/bundle/vim-gitgutter/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..6b50f839ec91fd623e1191f8ada8c823740be041 GIT binary patch literal 16191 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 P9zj7?MW#y1H01vSr(8@| literal 0 HcmV?d00001 diff --git a/.vim/bundle/vim-gitgutter/test/cp932.txt b/.vim/bundle/vim-gitgutter/test/cp932.txt new file mode 100644 index 0000000..80cb10b --- /dev/null +++ b/.vim/bundle/vim-gitgutter/test/cp932.txt @@ -0,0 +1,8 @@ +The quick brown fox jumps +over the lazy dog + +‚¢‚ë‚Í‚É‚Ù‚Ö‚Æ‚¿‚è‚Ê‚é‚ð +‚í‚©‚悽‚ê‚»‚‚˂Ȃç‚Þ +‚¤‚î‚Ì‚¨‚­‚â‚Ü‚¯‚Ó‚±‚¦‚Ä +‚ ‚³‚«‚ä‚ß‚Ý‚µ‚ï‚Ð‚à‚¹‚· + diff --git a/.vim/bundle/vim-gitgutter/test/fixture.txt b/.vim/bundle/vim-gitgutter/test/fixture.txt new file mode 100644 index 0000000..f5c6aff --- /dev/null +++ b/.vim/bundle/vim-gitgutter/test/fixture.txt @@ -0,0 +1,11 @@ +a +b +c +d +e +f +g +h +i +j + diff --git a/.vim/bundle/vim-gitgutter/test/runner.vim b/.vim/bundle/vim-gitgutter/test/runner.vim new file mode 100644 index 0000000..630693c --- /dev/null +++ b/.vim/bundle/vim-gitgutter/test/runner.vim @@ -0,0 +1,162 @@ +" +" Adapted from https://github.com/vim/vim/blob/master/src/testdir/runtest.vim +" +" When debugging tests it can help to write debug output: +" call Log('oh noes') +" + +function RunTest(test) + if exists("*SetUp") + call SetUp() + endif + + try + execute 'call '.a:test + catch + call Exception() + let s:errored = 1 + endtry + + if exists("*TearDown") + call TearDown() + endif +endfunction + +function Log(msg) + if type(a:msg) == type('') + call add(s:messages, a:msg) + elseif type(a:msg) == type([]) + call extend(s:messages, a:msg) + else + call add(v:errors, 'Exception: unsupported type: '.type(a:msg)) + endif +endfunction + +function Exception() + call add(v:errors, v:throwpoint.'..'.'Exception: '.v:exception) +endfunction + +" Shuffles list in place. +function Shuffle(list) + " Fisher-Yates-Durstenfeld-Knuth + let n = len(a:list) + if n < 2 + return a:list + endif + for i in range(0, n-2) + let j = Random(0, n-i-1) + let e = a:list[i] + let a:list[i] = a:list[i+j] + let a:list[i+j] = e + endfor + return a:list +endfunction + +" Returns a pseudorandom integer i such that 0 <= i <= max +function Random(min, max) + if has('unix') + let i = system('echo $RANDOM') " 0 <= i <= 32767 + else + let i = system('echo %RANDOM%') " 0 <= i <= 32767 + endif + return i * (a:max - a:min + 1) / 32768 + a:min +endfunction + +function FriendlyName(test_name) + return substitute(a:test_name[5:-3], '_', ' ', 'g') +endfunction + +function Align(left, right) + if type(a:right) == type([]) + let result = [] + for s in a:right + if empty(result) + call add(result, printf('%-'.s:indent.'S', a:left).s) + else + call add(result, printf('%-'.s:indent.'S', '').s) + endif + endfor + return result + endif + + return printf('%-'.s:indent.'S', a:left).a:right +endfunction + +let g:testname = expand('%') +let s:errored = 0 +let s:done = 0 +let s:fail = 0 +let s:errors = 0 +let s:messages = [] +let s:indent = '' + +call Log(g:testname.':') + +" Source the test script. +try + source % +catch + let s:errors += 1 + call Exception() +endtry + +" Locate the test functions. +set nomore +redir @q +silent function /^Test_ +redir END +let s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g')) + +" If there is another argument, filter test-functions' names against it. +if argc() > 1 + let s:tests = filter(s:tests, 'v:val =~ argv(1)') +endif + +let s:indent = max(map(copy(s:tests), {_, val -> len(FriendlyName(val))})) + +" Run the tests in random order. +for test in Shuffle(s:tests) + call RunTest(test) + let s:done += 1 + + let friendly_name = FriendlyName(test) + if len(v:errors) == 0 + call Log(Align(friendly_name, ' - ok')) + else + if s:errored + let s:errors += 1 + let s:errored = 0 + else + let s:fail += 1 + endif + call Log(Align(friendly_name, ' - not ok')) + + let i = 0 + for error in v:errors + if i != 0 + call Log(Align('',' ! ----')) + endif + for trace in reverse(split(error, '\.\.')) + call Log(Align('', ' ! '.trace)) + endfor + let i += 1 + endfor + + let v:errors = [] + endif +endfor + +let summary = [ + \ s:done.( s:done == 1 ? ' test' : ' tests'), + \ s:errors.(s:errors == 1 ? ' error' : ' errors'), + \ s:fail.( s:fail == 1 ? ' failure' : ' failures'), + \ ] +call Log('') +call Log(join(summary, ', ')) + +split messages.log +call append(line('$'), s:messages) +write + +qall! + diff --git a/.vim/bundle/vim-gitgutter/test/test b/.vim/bundle/vim-gitgutter/test/test new file mode 100755 index 0000000..4daf052 --- /dev/null +++ b/.vim/bundle/vim-gitgutter/test/test @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +VIM="/Applications/MacVim.app/Contents/MacOS/Vim -v" + +export VIM_GITGUTTER_TEST=1 + +$VIM -u NONE -U NONE -N \ + --cmd 'set rtp+=../' \ + --cmd 'let g:gitgutter_async=0' \ + --cmd 'source ../plugin/gitgutter.vim' \ + -S runner.vim \ + test_*.vim \ + $* + +cat messages.log + +grep -q "0 errors, 0 failures" messages.log +status=$? +rm messages.log +exit $status + diff --git a/.vim/bundle/vim-gitgutter/test/test_gitgutter.vim b/.vim/bundle/vim-gitgutter/test/test_gitgutter.vim new file mode 100644 index 0000000..98b4220 --- /dev/null +++ b/.vim/bundle/vim-gitgutter/test/test_gitgutter.vim @@ -0,0 +1,589 @@ +let s:current_dir = expand('%:p:h') +let s:test_repo = s:current_dir.'/test-repo' +let s:bufnr = bufnr('') + +" +" Helpers +" + +function s:signs(filename) + redir => signs + silent execute 'sign place' + redir END + + let signs = split(signs, '\n') + + " filter out signs for this test file + " assumes a:filename's signs are last set listed + let i = index(signs, 'Signs for '.a:filename.':') + let signs = (i > -1 ? signs[i+1:] : []) + + call map(signs, {_, v -> substitute(v, ' ', '', '')}) + + return signs +endfunction + +function s:git_diff() + return split(system('git diff -U0 fixture.txt'), '\n') +endfunction + +function s:git_diff_staged() + return split(system('git diff -U0 --staged fixture.txt'), '\n') +endfunction + +function s:trigger_gitgutter() + doautocmd CursorHold +endfunction + + +" +" SetUp / TearDown +" + +function SetUp() + call system("git init ".s:test_repo. + \ " && cd ".s:test_repo. + \ " && cp ../fixture.txt .". + \ " && git add . && git commit -m 'initial'". + \ " && git config diff.mnemonicPrefix false") + execute ':cd' s:test_repo + edit! fixture.txt + call gitgutter#sign#reset() +endfunction + +function TearDown() + " delete all buffers except this one + " TODO: move to runner.vim, accounting for multiple test files + if s:bufnr > 1 + silent! execute '1,'.s:bufnr-1.'bdelete!' + endif + silent! execute s:bufnr+1.',$bdelete!' + + execute ':cd' s:current_dir + call system("rm -rf ".s:test_repo) +endfunction + +" +" The tests +" + +function Test_add_lines() + normal ggo* + call s:trigger_gitgutter() + + let expected = ["line=2 id=3000 name=GitGutterLineAdded"] + call assert_equal(expected, s:signs('fixture.txt')) +endfunction + + +function Test_add_lines_fish() + let _shell = &shell + set shell=/usr/local/bin/fish + + normal ggo* + call s:trigger_gitgutter() + + let expected = ["line=2 id=3000 name=GitGutterLineAdded"] + call assert_equal(expected, s:signs('fixture.txt')) + + let &shell = _shell +endfunction + + +function Test_modify_lines() + normal ggi* + call s:trigger_gitgutter() + + let expected = ["line=1 id=3000 name=GitGutterLineModified"] + call assert_equal(expected, s:signs('fixture.txt')) +endfunction + + +function Test_remove_lines() + execute '5d' + call s:trigger_gitgutter() + + let expected = ["line=4 id=3000 name=GitGutterLineRemoved"] + call assert_equal(expected, s:signs('fixture.txt')) +endfunction + + +function Test_remove_first_lines() + execute '1d' + call s:trigger_gitgutter() + + let expected = ["line=1 id=3000 name=GitGutterLineRemovedFirstLine"] + call assert_equal(expected, s:signs('fixture.txt')) +endfunction + + +function Test_edit_file_with_same_name_as_a_branch() + normal 5Gi* + call system('git checkout -b fixture.txt') + call s:trigger_gitgutter() + + let expected = ["line=5 id=3000 name=GitGutterLineModified"] + call assert_equal(expected, s:signs('fixture.txt')) +endfunction + + +function Test_file_added_to_git() + let tmpfile = 'fileAddedToGit.tmp' + call system('touch '.tmpfile.' && git add '.tmpfile) + execute 'edit '.tmpfile + normal ihello + call s:trigger_gitgutter() + + let expected = ["line=1 id=3000 name=GitGutterLineAdded"] + call assert_equal(expected, s:signs('fileAddedToGit.tmp')) +endfunction + + +function Test_filename_with_equals() + call system('touch =fixture=.txt && git add =fixture=.txt') + edit =fixture=.txt + normal ggo* + call s:trigger_gitgutter() + + let expected = [ + \ 'line=1 id=3000 name=GitGutterLineAdded', + \ 'line=2 id=3001 name=GitGutterLineAdded' + \ ] + call assert_equal(expected, s:signs('=fixture=.txt')) +endfunction + + +function Test_filename_with_square_brackets() + call system('touch fix[tu]re.txt && git add fix[tu]re.txt') + edit fix[tu]re.txt + normal ggo* + call s:trigger_gitgutter() + + let expected = [ + \ 'line=1 id=3000 name=GitGutterLineAdded', + \ 'line=2 id=3001 name=GitGutterLineAdded' + \ ] + call assert_equal(expected, s:signs('fix[tu]re.txt')) +endfunction + + +function Test_filename_leading_dash() + call system('touch -- -fixture.txt && git add -- -fixture.txt') + edit -fixture.txt + normal ggo* + call s:trigger_gitgutter() + + let expected = [ + \ 'line=1 id=3000 name=GitGutterLineAdded', + \ 'line=2 id=3001 name=GitGutterLineAdded' + \ ] + call assert_equal(expected, s:signs('-fixture.txt')) +endfunction + + +" FIXME: this test fails when it is the first (or only) test to be run +function Test_follow_symlink() + let tmp = 'symlink' + call system('ln -nfs fixture.txt '.tmp) + execute 'edit '.tmp + 6d + call s:trigger_gitgutter() + + let expected = ['line=5 id=3000 name=GitGutterLineRemoved'] + call assert_equal(expected, s:signs('symlink')) +endfunction + + +function Test_keep_alt() + enew + execute "normal! \" + + call assert_equal('fixture.txt', bufname('')) + call assert_equal('', bufname('#')) + + normal ggx + call s:trigger_gitgutter() + + call assert_equal('', bufname('#')) +endfunction + + +function Test_keep_modified() + normal 5Go* + call assert_equal(1, getbufvar('', '&modified')) + + call s:trigger_gitgutter() + + call assert_equal(1, getbufvar('', '&modified')) +endfunction + + +function Test_keep_op_marks() + normal 5Go* + call assert_equal([0,6,1,0], getpos("'[")) + call assert_equal([0,6,2,0], getpos("']")) + + call s:trigger_gitgutter() + + call assert_equal([0,6,1,0], getpos("'[")) + call assert_equal([0,6,2,0], getpos("']")) +endfunction + + +function Test_no_modifications() + call assert_equal([], s:signs('fixture.txt')) +endfunction + + +function Test_orphaned_signs() + execute "normal 5GoX\Y" + call s:trigger_gitgutter() + 6d + call s:trigger_gitgutter() + + let expected = ['line=6 id=3001 name=GitGutterLineAdded'] + call assert_equal(expected, s:signs('fixture.txt')) +endfunction + + +function Test_untracked_file_outside_repo() + let tmp = tempname() + call system('touch '.tmp) + execute 'edit '.tmp + + call assert_equal([], s:signs(tmp)) +endfunction + + +function Test_untracked_file_within_repo() + let tmp = 'untrackedFileWithinRepo.tmp' + call system('touch '.tmp) + execute 'edit '.tmp + normal ggo* + call s:trigger_gitgutter() + + call assert_equal([], s:signs(tmp)) + + call system('rm '.tmp) +endfunction + + +function Test_untracked_file_square_brackets_within_repo() + let tmp = '[un]trackedFileWithinRepo.tmp' + call system('touch '.tmp) + execute 'edit '.tmp + normal ggo* + call s:trigger_gitgutter() + + call assert_equal([], s:signs(tmp)) + + call system('rm '.tmp) +endfunction + + +function Test_hunk_outside_noop() + normal 5G + GitGutterStageHunk + + call assert_equal([], s:signs('fixture.txt')) + call assert_equal([], s:git_diff()) + call assert_equal([], s:git_diff_staged()) + + GitGutterUndoHunk + + call assert_equal([], s:signs('fixture.txt')) + call assert_equal([], s:git_diff()) + call assert_equal([], s:git_diff_staged()) +endfunction + + +function Test_hunk_stage() + let _shell = &shell + set shell=foo + + normal 5Gi* + GitGutterStageHunk + + call assert_equal('foo', &shell) + let &shell = _shell + + call assert_equal([], s:signs('fixture.txt')) + + " Buffer is unsaved + let expected = [ + \ 'diff --git a/fixture.txt b/fixture.txt', + \ 'index ae8e546..f5c6aff 100644', + \ '--- a/fixture.txt', + \ '+++ b/fixture.txt', + \ '@@ -5 +5 @@ d', + \ '-*e', + \ '+e' + \ ] + call assert_equal(expected, s:git_diff()) + + " Index has been updated + let expected = [ + \ 'diff --git a/fixture.txt b/fixture.txt', + \ 'index f5c6aff..ae8e546 100644', + \ '--- a/fixture.txt', + \ '+++ b/fixture.txt', + \ '@@ -5 +5 @@ d', + \ '-e', + \ '+*e' + \ ] + call assert_equal(expected, s:git_diff_staged()) + + " Save the buffer + write + + call assert_equal([], s:git_diff()) +endfunction + + +function Test_hunk_stage_nearby_hunk() + execute "normal! 2Gox\y\z" + normal 2jdd + normal k + GitGutterStageHunk + + let expected = [ + \ 'line=3 id=3000 name=GitGutterLineAdded', + \ 'line=4 id=3001 name=GitGutterLineAdded', + \ 'line=5 id=3002 name=GitGutterLineAdded' + \ ] + call assert_equal(expected, s:signs('fixture.txt')) + + " Buffer is unsaved + let expected = [ + \ 'diff --git a/fixture.txt b/fixture.txt', + \ 'index 53b13df..f5c6aff 100644', + \ '--- a/fixture.txt', + \ '+++ b/fixture.txt', + \ '@@ -3,0 +4 @@ c', + \ '+d', + \ ] + call assert_equal(expected, s:git_diff()) + + " Index has been updated + let expected = [ + \ 'diff --git a/fixture.txt b/fixture.txt', + \ 'index f5c6aff..53b13df 100644', + \ '--- a/fixture.txt', + \ '+++ b/fixture.txt', + \ '@@ -4 +3,0 @@ c', + \ '-d', + \ ] + call assert_equal(expected, s:git_diff_staged()) + + " Save the buffer + write + + let expected = [ + \ 'diff --git a/fixture.txt b/fixture.txt', + \ 'index 53b13df..8fdfda7 100644', + \ '--- a/fixture.txt', + \ '+++ b/fixture.txt', + \ '@@ -2,0 +3,3 @@ b', + \ '+x', + \ '+y', + \ '+z', + \ ] + call assert_equal(expected, s:git_diff()) +endfunction + + +function Test_hunk_undo() + let _shell = &shell + set shell=foo + + normal 5Gi* + GitGutterUndoHunk + + call assert_equal('foo', &shell) + let &shell = _shell + + call assert_equal([], s:signs('fixture.txt')) + call assert_equal([], s:git_diff()) + call assert_equal([], s:git_diff_staged()) +endfunction + + +function Test_undo_nearby_hunk() + execute "normal! 2Gox\y\z" + normal 2jdd + normal k + call s:trigger_gitgutter() + GitGutterUndoHunk + call s:trigger_gitgutter() + + let expected = [ + \ 'line=3 id=3000 name=GitGutterLineAdded', + \ 'line=4 id=3001 name=GitGutterLineAdded', + \ 'line=5 id=3002 name=GitGutterLineAdded' + \ ] + call assert_equal(expected, s:signs('fixture.txt')) + + call assert_equal([], s:git_diff()) + + call assert_equal([], s:git_diff_staged()) + + " Save the buffer + write + + let expected = [ + \ 'diff --git a/fixture.txt b/fixture.txt', + \ 'index f5c6aff..3fbde56 100644', + \ '--- a/fixture.txt', + \ '+++ b/fixture.txt', + \ '@@ -2,0 +3,3 @@ b', + \ '+x', + \ '+y', + \ '+z', + \ ] + call assert_equal(expected, s:git_diff()) + +endfunction + + +function Test_write_option() + set nowrite + + normal ggo* + call s:trigger_gitgutter() + + let expected = ["line=2 id=3000 name=GitGutterLineAdded"] + call assert_equal(expected, s:signs('fixture.txt')) + + set write +endfunction + + +function Test_inner_text_object() + execute "normal! 2Gox\y\z\\" + call s:trigger_gitgutter() + normal dic + call s:trigger_gitgutter() + + call assert_equal([], s:signs('fixture.txt')) + call assert_equal(readfile('fixture.txt'), getline(1,'$')) + + " Excludes trailing lines + normal 9Gi* + normal 10Gi* + call s:trigger_gitgutter() + execute "normal vic\" + call assert_equal([9, 10], [line("'<"), line("'>")]) +endfunction + + +function Test_around_text_object() + execute "normal! 2Gox\y\z\\" + call s:trigger_gitgutter() + normal dac + call s:trigger_gitgutter() + + call assert_equal([], s:signs('fixture.txt')) + call assert_equal(readfile('fixture.txt'), getline(1,'$')) + + " Includes trailing lines + normal 9Gi* + normal 10Gi* + call s:trigger_gitgutter() + execute "normal vac\" + call assert_equal([9, 11], [line("'<"), line("'>")]) +endfunction + + +function Test_user_autocmd() + autocmd User GitGutter let s:autocmd_user = g:gitgutter_hook_context.bufnr + + " Verify not fired when nothing changed. + let s:autocmd_user = 0 + call s:trigger_gitgutter() + call assert_equal(0, s:autocmd_user) + + " Verify fired when there was a change. + normal ggo* + let bufnr = bufnr('') + call s:trigger_gitgutter() + call assert_equal(bufnr, s:autocmd_user) +endfunction + + +function Test_fix_file_references() + " No special characters + let hunk_diff = join([ + \ 'diff --git a/fixture.txt b/fixture.txt', + \ 'index f5c6aff..3fbde56 100644', + \ '--- a/fixture.txt', + \ '+++ b/fixture.txt', + \ '@@ -2,0 +3,1 @@ b', + \ '+x' + \ ], "\n")."\n" + let filepath = 'blah.txt' + + let expected = join([ + \ 'diff --git a/blah.txt b/blah.txt', + \ 'index f5c6aff..3fbde56 100644', + \ '--- a/blah.txt', + \ '+++ b/blah.txt', + \ '@@ -2,0 +3,1 @@ b', + \ '+x' + \ ], "\n")."\n" + + call assert_equal(expected, gitgutter#hunk#fix_file_references(filepath, hunk_diff)) + + " diff.mnemonicPrefix; spaces in filename + let hunk_diff = join([ + \ 'diff --git i/x/cat dog w/x/cat dog', + \ 'index f5c6aff..3fbde56 100644', + \ '--- i/x/cat dog', + \ '+++ w/x/cat dog', + \ '@@ -2,0 +3,1 @@ b', + \ '+x' + \ ], "\n")."\n" + let filepath = 'blah.txt' + + let expected = join([ + \ 'diff --git i/blah.txt w/blah.txt', + \ 'index f5c6aff..3fbde56 100644', + \ '--- i/blah.txt', + \ '+++ w/blah.txt', + \ '@@ -2,0 +3,1 @@ b', + \ '+x' + \ ], "\n")."\n" + + call assert_equal(expected, gitgutter#hunk#fix_file_references(filepath, hunk_diff)) + + " Backslashes in filename; quotation marks + let hunk_diff = join([ + \ 'diff --git "a/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\11.1.vim" "b/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\12.1.vim"', + \ 'index f42aeb0..4930403 100644', + \ '--- "a/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\11.1.vim"', + \ '+++ "b/C:\\Users\\FOO~1.PAR\\AppData\\Local\\Temp\\nvimJcmSv9\\12.1.vim"', + \ '@@ -172,0 +173 @@ stuff', + \ '+x' + \ ], "\n")."\n" + let filepath = 'init.vim' + + let expected = join([ + \ 'diff --git "a/init.vim" "b/init.vim"', + \ 'index f42aeb0..4930403 100644', + \ '--- "a/init.vim"', + \ '+++ "b/init.vim"', + \ '@@ -172,0 +173 @@ stuff', + \ '+x' + \ ], "\n")."\n" + + call assert_equal(expected, gitgutter#hunk#fix_file_references(filepath, hunk_diff)) +endfunction + + +function Test_encoding() + call system('cp ../cp932.txt . && git add cp932.txt') + edit ++enc=cp932 cp932.txt + + call s:trigger_gitgutter() + + call assert_equal([], s:signs('cp932.txt')) +endfunction diff --git a/.vim/bundle/vim-gitgutter/unplace.vim b/.vim/bundle/vim-gitgutter/unplace.vim new file mode 100644 index 0000000..a97993d --- /dev/null +++ b/.vim/bundle/vim-gitgutter/unplace.vim @@ -0,0 +1,27 @@ +" Measure how long it takes to unplace signs. +" +" Source this file with `:source %` or `vim -S unplace.vim` + + +let num = 500 +sign define Foo text=* + +new + +call append(0, range(1, num)) + +for i in range(1, num) + execute "sign place ".i." line=".i." name=Foo buffer=".bufnr('') +endfor + +let start = reltime() +for i in range(1, num) + execute "sign unplace ".i +endfor +let elapsed = reltime(start) + +bdelete! + +echom split(reltimestr(elapsed))[0]."s to remove ".num." signs" +echom string(reltimefloat(elapsed) * 1000 / num).' ms/sign' +echom string(float2nr(num / reltimefloat(elapsed))).' sign/s' diff --git a/.vimrc b/.vimrc index 7bdddc1..b2624f5 100644 --- a/.vimrc +++ b/.vimrc @@ -23,6 +23,7 @@ Plugin 'tpope/vim-rails' Plugin 'altercation/vim-colors-solarized' Plugin 'scrooloose/nerdtree' Plugin 'jistr/vim-nerdtree-tabs' +Plugin 'airblade/vim-gitgutter' "Plugin 'scrooloose/syntastic' Plugin 'vim-ruby/vim-ruby' Plugin 'peterhoeg/vim-qml'