[
  {
    "path": ".github/issue_template.md",
    "content": "> What is the latest commit SHA in your installed vim-gitgutter?\n\n> What vim/nvim version are you on?\n\n"
  },
  {
    "path": ".gitignore",
    "content": "/doc/tags\n/misc\n/test/*.actual\n*.log\n\n"
  },
  {
    "path": "LICENCE",
    "content": "MIT License\n\nCopyright (c) Andrew Stewart\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "README.mkd",
    "content": "## vim-gitgutter\n\nA Vim plugin which shows a git diff in the sign column.  It shows which lines have been added, modified, or removed.  You can also preview, stage, and undo individual hunks; and stage partial hunks.  The plugin also provides a hunk text object.\n\nThe signs are always up to date and the plugin never saves your buffer.\n\nThe name \"gitgutter\" comes from the Sublime Text 3 plugin which inspired this in 2013.\n\nFeatures:\n\n* Shows signs for added, modified, and removed lines.\n* Runs the diffs asynchronously where possible.\n* Ensures signs are always up to date.\n* Never saves the buffer.\n* Quick jumping between blocks of changed lines (\"hunks\").\n* Stage/undo/preview individual hunks.\n* Previews highlight intra-line changes.\n* Stage partial hunks.\n* Provides a hunk text object.\n* Diffs against index (default) or any commit.\n* Handles file moves / renames.\n* Heeds git's \"assume unchanged\" bit.\n* Allows folding all unchanged text.\n* Provides fold text showing whether folded lines have been changed.\n* Can load all hunk locations into quickfix list or the current window's location list.\n* Handles line endings correctly, even with repos that do CRLF conversion.\n* Handles clean/smudge filters.\n* Optional line highlighting.\n* Optional line number highlighting. (Only available in Neovim 0.3.2 or higher)\n* Fully customisable (signs, sign column, line (number) highlights, mappings, extra git-diff arguments, etc).\n* Can be toggled on/off, globally or per buffer.\n* Preserves signs from other plugins.\n* Does the right thing when viewing revisions with [fugitive](https://github.com/tpope/vim-fugitive)'s `:0Gclog`.\n* Easy to integrate diff stats into status line; built-in integration with [vim-airline](https://github.com/bling/vim-airline/).\n* Works with fish shell (in addition to the usual shells).\n\nConstraints:\n\n* Supports git only.  If you work with other version control systems, I recommend [vim-signify](https://github.com/mhinz/vim-signify).\n* 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`.  For tmux, `set -g focus-events on` in your tmux.conf.\n\nCompatibility:\n\nCompatible back to Vim 7.4, and probably 7.3.\n\n\n### Screenshot\n\n![screenshot](./screenshot.png?raw=true)\n\nIn the screenshot above you can see:\n\n* Lines 183-184 are new.\n* Lines 186-187 have been modified.\n* The preview for the modified lines highlights changed regions within the line.\n\n\n### Installation\n\nFirst, install using your favourite package manager, or use Vim's built-in package support.\n\nVim:\n\n```\nmkdir -p ~/.vim/pack/airblade/start\ncd ~/.vim/pack/airblade/start\ngit clone https://github.com/airblade/vim-gitgutter.git\nvim -u NONE -c \"helptags vim-gitgutter/doc\" -c q\n```\n\nNeovim:\n\n```\nmkdir -p ~/.config/nvim/pack/airblade/start\ncd ~/.config/nvim/pack/airblade/start\ngit clone https://github.com/airblade/vim-gitgutter.git\nnvim -u NONE -c \"helptags vim-gitgutter/doc\" -c q\n```\n\nSecond, ensure your `updatetime` and `signcolumn` options are set appropriately.\n\nWhen you make a change to a file tracked by git, the diff markers should appear automatically after a short delay.  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).  Note `updatetime` also controls the delay before vim writes its swap file (see `:help updatetime`).\n\nThe `signcolumn` option can have any value except `'no'`.\n\n\n### Windows\n\nThere is a potential risk on Windows due to `cmd.exe` prioritising the current folder over folders in `PATH`.  If you have a file named `git.*` (i.e. with any extension in `PATHEXT`) in your current folder, it will be executed instead of git whenever the plugin calls git.\n\nYou can avoid this risk by configuring the full path to your git executable.  For example:\n\n```viml\n\" This path probably won't work\nlet g:gitgutter_git_executable = 'C:\\Program Files\\Git\\bin\\git.exe'\n```\n\nUnfortunately I don't know the correct escaping for the path - if you do, please let me know!\n\n\n### Getting started\n\nWhen you make a change to a file tracked by git, the diff markers should appear automatically after a short delay.\n\nYou can jump between hunks with `[c` and `]c`.  You can preview, stage, and undo hunks with `<leader>hp`, `<leader>hs`, and `<leader>hu` respectively.\n\nYou cannot unstage a staged hunk.\n\nAfter updating the signs, the plugin fires the `GitGutter` User autocommand.\n\nAfter staging a hunk or part of a hunk, the plugin fires the `GitGutterStage` User autocommand.\n\n\n#### Activation\n\nYou can explicitly turn vim-gitgutter off and on (defaults to on):\n\n* turn off with `:GitGutterDisable`\n* turn on with `:GitGutterEnable`\n* toggle with `:GitGutterToggle`.\n\nTo toggle vim-gitgutter per buffer:\n\n* turn off with `:GitGutterBufferDisable`\n* turn on with `:GitGutterBufferEnable`\n* toggle with `:GitGutterBufferToggle`\n\nYou can turn the signs on and off (defaults to on):\n\n* turn on with `:GitGutterSignsEnable`\n* turn off with `:GitGutterSignsDisable`\n* toggle with `:GitGutterSignsToggle`.\n\nAnd you can turn line highlighting on and off (defaults to off):\n\n* turn on with `:GitGutterLineHighlightsEnable`\n* turn off with `:GitGutterLineHighlightsDisable`\n* toggle with `:GitGutterLineHighlightsToggle`.\n\nNote 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/NeoVim always shows the sign column when there are signs even if the signs are invisible.\n\nWith Neovim 0.3.2 or higher, you can turn line number highlighting on and off (defaults to off):\n\n* turn on with `:GitGutterLineNrHighlightsEnable`\n* turn off with `:GitGutterLineNrHighlightsDisable`\n* toggle with `:GitGutterLineNrHighlightsToggle`.\n\nThe same caveat applies to line number highlighting as to line highlighting just above.\n\nIf you switch off both line highlighting and signs, you won't see the sign column.\n\nIn older Vims (pre 8.1.0614 / Neovim 0.4.0) vim-gitgutter will suppress the signs when a file has more than 500 changes, to avoid slowing down the UI.  As soon as the number of changes falls below the limit vim-gitgutter will show the signs again.  You can configure the threshold with:\n\n```viml\nlet g:gitgutter_max_signs = 500  \" default value (Vim < 8.1.0614, Neovim < 0.4.0)\nlet g:gitgutter_max_signs = -1   \" default value (otherwise)\n```\n\nYou can also remove the limit by setting `g:gitgutter_max_signs = -1`.\n\n#### Hunks\n\nYou can jump between hunks:\n\n* jump to next hunk (change): `]c`\n* jump to previous hunk (change): `[c`.\n\nBoth of those take a preceding count.\n\nTo set your own mappings for these, for example `]h` and `[h`:\n\n```viml\nnmap ]h <Plug>(GitGutterNextHunk)\nnmap [h <Plug>(GitGutterPrevHunk)\n```\n\nWhen you jump between hunks, a message like `Hunk 4 of 11` is shown on the command line. If you want to turn the message off, you can use:\n\n```viml\nlet g:gitgutter_show_msg_on_hunk_jumping = 0\n```\n\nYou can load all your hunks into the quickfix list with `:GitGutterQuickFix`.  Note this ignores any unsaved changes in your buffers. If the option `g:gitgutter_use_location_list` is set, this command will load hunks into the current window's location list instead.  Use `:copen` (or `:lopen`) to open the quickfix / location list or add a custom command like this:\n\n```viml\ncommand! Gqf GitGutterQuickFix | copen\n```\n\nYou can stage or undo an individual hunk when your cursor is in it:\n\n* stage the hunk with `<Leader>hs` or\n* undo it with `<Leader>hu`.\n\nTo stage part of an additions-only hunk by:\n\n* either visually selecting the part you want and staging with your mapping, e.g. `<Leader>hs`;\n* or using a range with the `GitGutterStageHunk` command, e.g. `:42,45GitGutterStageHunk`.\n\nTo stage part of any hunk:\n\n* preview the hunk, e.g. `<Leader>hp`;\n* move to the preview window, e.g. `:wincmd P`;\n* delete the lines you do not want to stage;\n* stage the remaining lines: either write (`:w`) the window or stage via `<Leader>hs` or `:GitGutterStageHunk`.\n\nNote the above workflow is not possible if you have opted in to preview hunks with Vim's popup windows.\n\nSee the FAQ if you want to unstage staged changes.\n\nThe `.` command will work with both these if you install [repeat.vim](https://github.com/tpope/vim-repeat).\n\nTo set your own mappings for these, for example if you prefer `g`-based maps:\n\n```viml\nnmap ghs <Plug>(GitGutterStageHunk)\nnmap ghu <Plug>(GitGutterUndoHunk)\n```\n\nAnd you can preview a hunk's changes with `<Leader>hp`.  The location of the preview window is configured with `g:gitgutter_preview_win_location` (default `'bo'`).  You can of course change this mapping, e.g:\n\n```viml\nnmap ghp <Plug>(GitGutterPreviewHunk)\n```\n\nA hunk text object is provided which works in visual and operator-pending modes.\n\n- `ic` operates on all lines in the current hunk.\n- `ac` operates on all lines in the current hunk and any trailing empty lines.\n\nTo re-map these, for example to `ih` and `ah`:\n\n```viml\nomap ih <Plug>(GitGutterTextObjectInnerPending)\nomap ah <Plug>(GitGutterTextObjectOuterPending)\nxmap ih <Plug>(GitGutterTextObjectInnerVisual)\nxmap ah <Plug>(GitGutterTextObjectOuterVisual)\n```\n\nIf you don't want vim-gitgutter to set up any mappings at all, use this:\n\n```viml\nlet g:gitgutter_map_keys = 0\n```\n\nFinally, you can force vim-gitgutter to update its signs across all visible buffers with `:GitGutterAll`.\n\nSee the customisation section below for how to change the defaults.\n\n\n### Vimdiff\n\nUse the `GitGutterDiffOrig` command to open a vimdiff view of the current buffer, respecting `g:gitgutter_diff_relative_to` and `:gitgutter_diff_base`.\n\n\n### Folding\n\nUse the `GitGutterFold` command to fold all unchanged lines, leaving just the hunks visible.  Use `zr` to unfold 3 lines of context above and below a hunk.\n\nExecute `GitGutterFold` a second time to restore the previous view.\n\nUse `gitgutter#fold#foldtext()` to augment the default `foldtext()` with an indicator of whether the folded lines have been changed.\n\n```viml\nset foldtext=gitgutter#fold#foldtext()\n```\n\nFor a closed fold with changed lines:\n\n```\nDefault foldtext():         +-- 45 lines: abcdef\ngitgutter#fold#foldtext():  +-- 45 lines (*): abcdef\n```\n\nYou can use `gitgutter#fold#is_changed()` in your own `foldtext` expression to find out whether the folded lines have been changed.\n\n\n### Status line\n\nCall the `GitGutterGetHunkSummary()` function from your status line to get a list of counts of added, modified, and removed lines in the current buffer.  For example:\n\n```viml\n\" Your vimrc\nfunction! GitStatus()\n  let [a,m,r] = GitGutterGetHunkSummary()\n  return printf('+%d ~%d -%d', a, m, r)\nendfunction\nset statusline+=%{GitStatus()}\n```\n\n\n### Customisation\n\nYou can customise:\n\n* The sign column's colours\n* Whether or not the sign column is shown when there aren't any signs (defaults to no)\n* How to handle non-gitgutter signs\n* The signs' colours and symbols\n* Line highlights\n* Line number highlights (only in Neovim 0.3.2 or higher)\n* The diff syntax colours used in the preview window\n* The intra-line diff highlights used in the preview window\n* Whether the diff is relative to the index (default) or working tree.\n* The base of the diff\n* Extra arguments for `git` when running `git diff`\n* Extra arguments for `git diff`\n* Key mappings\n* Whether vim-gitgutter is on initially (defaults to on)\n* Whether signs are shown (defaults to yes)\n* Whether line highlighting is on initially (defaults to off)\n* Whether line number highlighting is on initially (defaults to off)\n* Whether vim-gitgutter runs asynchronously (defaults to yes)\n* Whether to clobber or preserve non-gitgutter signs\n* The priority of gitgutter's signs.\n* Whether to use a floating/popup window for hunk previews\n* The appearance of a floating/popup window for hunk previews\n* Whether to populate the quickfix list or a location list with all hunks\n\nPlease note that vim-gitgutter won't override any colours or highlights you've set in your colorscheme.\n\n\n#### Sign column\n\nSet the `SignColumn` highlight group to change the sign column's colour.  For example:\n\n```viml\n\" vim-gitgutter used to do this by default:\nhighlight! link SignColumn LineNr\n\n\" or you could do this:\nhighlight SignColumn guibg=whatever ctermbg=whatever\n```\n\nBy 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:\n\n```viml\n\" Vim 7.4.2201\nset signcolumn=yes\n```\n\nGitGutter can preserve or ignore non-gitgutter signs.  For Vim v8.1.0614 and later you can set gitgutter's signs' priorities with `g:gitgutter_sign_priority`, so gitgutter defaults to clobbering other signs.  For Neovim v0.4.0 and later you can set an expanding sign column so gitgutter again defaults to clobbering other signs.  Otherwise, gitgutter defaults to preserving other signs.  You can configure this with:\n\n```viml\nlet g:gitgutter_sign_allow_clobber = 1\n```\n\n\n#### Signs' colours and symbols\n\nIf you or your colourscheme has defined `GitGutter*` highlight groups, the plugin will use them for the signs' colours.\n\nIf you want the background colours to match the sign column, but don't want to update the `GitGutter*` groups yourself, you can get the plugin to do it:\n\n```viml\nlet g:gitgutter_set_sign_backgrounds = 1\n```\n\nIf no `GitGutter*` highlight groups exist, the plugin will check the `Diff*` highlight groups.  If their foreground colours differ the plugin will use them; if not, these colours will be used:\n\n```viml\nhighlight GitGutterAdd    guifg=#009900 ctermfg=2\nhighlight GitGutterChange guifg=#bbbb00 ctermfg=3\nhighlight GitGutterDelete guifg=#ff2222 ctermfg=1\n```\n\nTo customise the symbols, add the following to your `~/.vimrc`:\n\n```viml\nlet g:gitgutter_sign_added = 'xx'\nlet g:gitgutter_sign_modified = 'yy'\nlet g:gitgutter_sign_removed = 'zz'\nlet g:gitgutter_sign_removed_first_line = '^^'\nlet g:gitgutter_sign_removed_above_and_below = '{'\nlet g:gitgutter_sign_modified_removed = 'ww'\n```\n\n\n#### Line highlights\n\nSimilarly to the signs' colours, set up the following highlight groups in your colorscheme or `~/.vimrc`:\n\n```viml\nGitGutterAddLine          \" default: links to DiffAdd\nGitGutterChangeLine       \" default: links to DiffChange\nGitGutterDeleteLine       \" default: links to DiffDelete\nGitGutterChangeDeleteLine \" default: links to GitGutterChangeLine, i.e. DiffChange\n```\n\nFor example, in some colorschemes the `DiffText` highlight group is easier to read than `DiffChange`.  You could use it like this:\n\n```viml\nhighlight link GitGutterChangeLine DiffText\n```\n\n\n#### Line number highlights\n\nNOTE: This feature requires Neovim 0.3.2 or higher.\n\nSimilarly to the signs' colours, set up the following highlight groups in your colorscheme or `~/.vimrc`:\n\n```viml\nGitGutterAddLineNr          \" default: links to CursorLineNr\nGitGutterChangeLineNr       \" default: links to CursorLineNr\nGitGutterDeleteLineNr       \" default: links to CursorLineNr\nGitGutterChangeDeleteLineNr \" default: links to GitGutterChangeLineNr\n```\n\nMaybe you think `CursorLineNr` is a bit annoying.  For example, you could use `Underlined` for this:\n\n```viml\nhighlight link GitGutterChangeLineNr Underlined\n```\n\n\n#### The diff syntax colours used in the preview window\n\nTo change the diff syntax colours used in the preview window, set up the `diff*` highlight groups in your colorscheme or `~/.vimrc`:\n\n```viml\ndiffAdded   \" if not set: use GitGutterAdd's foreground colour\ndiffChanged \" if not set: use GitGutterChange's foreground colour\ndiffRemoved \" if not set: use GitGutterDelete's foreground colour\n```\n\nNote the `diff*` highlight groups are used in any buffer whose `'syntax'` is `diff`.\n\n\n#### The intra-line diff highlights used in the preview window\n\nTo change the intra-line diff highlights used in the preview window, set up the following highlight groups in your colorscheme or `~/.vimrc`:\n\n```viml\nGitGutterAddIntraLine    \" default: gui=reverse cterm=reverse\nGitGutterDeleteIntraLine \" default: gui=reverse cterm=reverse\n```\n\nFor example, to use `DiffAdd` for intra-line added regions:\n\n```viml\nhighlight link GitGutterAddIntraLine DiffAdd\n```\n\n\n#### Whether the diff is relative to the index or working tree\n\nBy default diffs are relative to the index.  How you can make them relative to the working tree:\n\n```viml\nlet g:gitgutter_diff_relative_to = 'working_tree'\n```\n\n\n#### The base of the diff\n\nBy default buffers are diffed against the index.  However you can diff against any commit by setting:\n\n```viml\nlet g:gitgutter_diff_base = '<commit SHA>'\n```\n\nIf you are looking at a previous version of a file with Fugitive (e.g. via `:0Gclog`), gitgutter sets the diff base to the parent of the current revision.\n\nThis setting is ignored when the diffs are relative to the working tree.\n\n\n#### Extra arguments for `git` when running `git diff`\n\nIf you want to pass extra arguments to `git` when running `git diff`, do so like this:\n\n```viml\nlet g:gitgutter_git_args = '--git-dir-\"\"'\n```\n\n#### Extra arguments for `git diff`\n\nIf you want to pass extra arguments to `git diff`, for example to ignore whitespace, do so like this:\n\n```viml\nlet g:gitgutter_diff_args = '-w'\n```\n\n#### Key mappings\n\nTo disable all key mappings:\n\n```viml\nlet g:gitgutter_map_keys = 0\n```\n\nSee above for configuring maps for hunk-jumping and staging/undoing.\n\n#### To turn off vim-gitgutter by default\n\nAdd `let g:gitgutter_enabled = 0` to your `~/.vimrc`.\n\n\n#### To turn off signs by default\n\nAdd `let g:gitgutter_signs = 0` to your `~/.vimrc`.\n\n\n#### To turn on line highlighting by default\n\nAdd `let g:gitgutter_highlight_lines = 1` to your `~/.vimrc`.\n\n\n#### To turn on line number highlighting by default\n\nAdd `let g:gitgutter_highlight_linenrs = 1` to your `~/.vimrc`.\n\n\n#### To turn off asynchronous updates\n\nBy default diffs are run asynchronously.  To run diffs synchronously instead:\n\n```viml\nlet g:gitgutter_async = 0\n```\n\n\n#### To use floating/popup windows for hunk previews\n\nAdd `let g:gitgutter_preview_win_floating = 1` to your `~/.vimrc`.  Note that on Vim this prevents you staging (partial) hunks via the preview window.\n\nOn Neovim, the preview hunk command will move the cursor into the floating window if it is already open.\n\n\n#### The appearance of a floating/popup window for hunk previews\n\nEither set `g:gitgutter_floating_window_options` to a dictionary of the options you want.  This dictionary is passed directly to `popup_create()` (Vim) / `nvim_open_win()` (Neovim).\n\nOr if you just want to override one or two of the defaults, you can do that with a file in an `after/` directory.  For example:\n\n```viml\n\" ~/.vim/after/vim-gitgutter/overrides.vim\nlet g:gitgutter_floating_window_options['border'] = 'single'\n```\n\n\n#### To load all hunks into the current window's location list instead of the quickfix list\n\nAdd `let g:gitgutter_use_location_list = 1` to your `~/.vimrc`.\n\n\n### Extensions\n\n#### Operate on every line in a hunk\n\nYou can map an operator to do whatever you want to every line in a hunk.\n\nLet's say, for example, you want to remove trailing whitespace.\n\n```viml\nfunction! CleanUp(...)\n  if a:0  \" opfunc\n    let [first, last] = [line(\"'[\"), line(\"']\")]\n  else\n    let [first, last] = [line(\"'<\"), line(\"'>\")]\n  endif\n  for lnum in range(first, last)\n    let line = getline(lnum)\n\n    \" clean up the text, e.g.:\n    let line = substitute(line, '\\s\\+$', '', '')\n\n    call setline(lnum, line)\n  endfor\nendfunction\n\nnmap <silent> <Leader>x :set opfunc=CleanUp<CR>g@\n```\n\nThen place your cursor in a hunk and type `\\xic` (assuming a leader of `\\`).\n\nAlternatively you could place your cursor in a hunk, type `vic` to select it, then `:call CleanUp()`.\n\n\n#### Operate on every changed line in a file\n\nYou can write a command to do whatever you want to every changed line in a file.\n\n```viml\nfunction! GlobalChangedLines(ex_cmd)\n  for hunk in GitGutterGetHunks()\n    for lnum in range(hunk[2], hunk[2]+hunk[3]-1)\n      let cursor = getcurpos()\n      silent! execute lnum.a:ex_cmd\n      call setpos('.', cursor)\n    endfor\n  endfor\nendfunction\n\ncommand -nargs=1 Glines call GlobalChangedLines(<q-args>)\n```\n\nLet's say, for example, you want to remove trailing whitespace from all changed lines:\n\n```viml\n:Glines s/\\s\\+$//\n```\n\n\n#### Cycle through hunks in current buffer\n\nThis is like `:GitGutterNextHunk` but when it gets to the last hunk in the buffer it cycles around to the first.\n\n```viml\nfunction! GitGutterNextHunkCycle()\n  let line = line('.')\n  silent! GitGutterNextHunk\n  if line('.') == line\n    1\n    GitGutterNextHunk\n  endif\nendfunction\n```\n\n\n#### Cycle through hunks in all buffers\n\nYou can use `:GitGutterQuickFix` to load all hunks into the quickfix list or the current window's location list.\n\nAlternatively, given that`]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.\n\n```viml\nfunction! NextHunkAllBuffers()\n  let line = line('.')\n  GitGutterNextHunk\n  if line('.') != line\n    return\n  endif\n\n  let bufnr = bufnr('')\n  while 1\n    bnext\n    if bufnr('') == bufnr\n      return\n    endif\n    if !empty(GitGutterGetHunks())\n      1\n      GitGutterNextHunk\n      return\n    endif\n  endwhile\nendfunction\n\nfunction! PrevHunkAllBuffers()\n  let line = line('.')\n  GitGutterPrevHunk\n  if line('.') != line\n    return\n  endif\n\n  let bufnr = bufnr('')\n  while 1\n    bprevious\n    if bufnr('') == bufnr\n      return\n    endif\n    if !empty(GitGutterGetHunks())\n      normal! G\n      GitGutterPrevHunk\n      return\n    endif\n  endwhile\nendfunction\n\nnmap <silent> ]c :call NextHunkAllBuffers()<CR>\nnmap <silent> [c :call PrevHunkAllBuffers()<CR>\n```\n\n\n### FAQ\n\n> How can I turn off realtime updates?\n\nAdd this to your vim configuration (in an `/after/plugin` directory):\n\n```viml\n\" .vim/after/plugin/gitgutter.vim\nautocmd! gitgutter CursorHold,CursorHoldI\n```\n\n> I turned off realtime updates, how can I have signs updated when I save a file?\n\nIf you really want to update the signs when you save a file, add this to your vimrc:\n\n```viml\nautocmd BufWritePost * GitGutter\n```\n\n> Why can't I unstage staged changes?\n\nThis plugin is for showing changes between the buffer 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.\n\n> Why are the colours in the sign column weird?\n\nYour colorscheme is configuring the `SignColumn` highlight group weirdly.  Please see the section above on customising the sign column.\n\n> What happens if I also use another plugin which uses signs (e.g. Syntastic)?\n\nYou can configure whether GitGutter preserves or clobbers other signs using `g:gitgutter_sign_allow_clobber`.  Set to `1` to clobber other signs (default on Vim >= 8.1.0614 and NeoVim >= 0.4.0) or `0` to preserve them.\n\n\n### Troubleshooting\n\n#### When no signs are showing at all\n\nHere are some things you can check:\n\n* Verify `:echo system(\"git --version\")` succeeds.\n* Verify your git config is compatible with the version of git returned by the command above.\n* Verify your Vim supports signs (`:echo has('signs')` should give `1`).\n* Verify your file is being tracked by git and has unstaged changes.  Check whether the plugin thinks git knows about your file: `:echo b:gitgutter.path` should show the path to the file in the repo.\n* Execute `:sign place group=gitgutter`; you should see a list of signs.\n  - If the signs are listed: this is a colorscheme / highlight problem.  Compare `:highlight GitGutterAdd` with `:highlight SignColumn`.\n  - If no signs are listed: the call to git-diff is probably failing.  Add `let g:gitgutter_log=1` to your vimrc, restart, reproduce the problem, and look at the `gitgutter.log` file in the plugin's directory.\n\n#### When the whole file is marked as added\n\n* If you use zsh, and you set `CDPATH`, make sure `CDPATH` doesn't include the current directory.\n\n#### When signs take a few seconds to appear\n\n* Try reducing `updatetime`, e.g. `set updatetime=100`.  Note this also controls the delay before vim writes its swap file.\n\n#### When signs don't update after focusing Vim\n\n* Your terminal probably isn't reporting focus events.  Either try installing [Terminus][] or set `let g:gitgutter_terminal_reports_focus=0`.  For tmux, try `set -g focus-events on` in your tmux.conf.\n\n\n### Shameless Plug\n\nIf this plugin has helped you, or you'd like to learn more about Vim, why not check out this screencast I wrote for PeepCode:\n\n* [Smash Into Vim][siv]\n\nThis was one of PeepCode's all-time top three bestsellers and is now available at Pluralsight.\n\n\n### Intellectual Property\n\nCopyright Andrew Stewart, AirBlade Software Ltd.  Released under the MIT licence.\n\n\n  [pathogen]: https://github.com/tpope/vim-pathogen\n  [siv]: http://pluralsight.com/training/Courses/TableOfContents/smash-into-vim\n  [terminus]: https://github.com/wincent/terminus\n"
  },
  {
    "path": "autoload/gitgutter/async.vim",
    "content": "let s:available = has('nvim') || (\n      \\   has('job') && (\n      \\     (has('patch-7.4.1826') && !has('gui_running')) ||\n      \\     (has('patch-7.4.1850') &&  has('gui_running')) ||\n      \\     (has('patch-7.4.1832') &&  has('gui_macvim'))\n      \\   )\n      \\ )\n\nlet s:jobs = {}\n\nfunction! gitgutter#async#available()\n  return s:available\nendfunction\n\n\nfunction! gitgutter#async#execute(cmd, bufnr, handler) abort\n  call gitgutter#debug#log('[async] '.a:cmd)\n\n  let options = {\n        \\   'stdoutbuffer': [],\n        \\   'buffer': a:bufnr,\n        \\   'handler': a:handler\n        \\ }\n  let command = s:build_command(a:cmd)\n\n  if has('nvim')\n    call jobstart(command, extend(options, {\n          \\   'on_stdout': function('s:on_stdout_nvim'),\n          \\   'on_stderr': function('s:on_stderr_nvim'),\n          \\   'on_exit':   function('s:on_exit_nvim')\n          \\ }))\n  else\n    let job = job_start(command, {\n          \\   'out_cb':   function('s:on_stdout_vim', options),\n          \\   'err_cb':   function('s:on_stderr_vim', options),\n          \\   'close_cb': function('s:on_exit_vim', options)\n          \\ })\n    let s:jobs[s:job_id(job)] = 1\n  endif\nendfunction\n\n\nfunction! s:build_command(cmd)\n  if has('unix')\n    return ['sh', '-c', a:cmd]\n  endif\n\n  if has('win32')\n    return has('nvim') ? a:cmd : 'cmd.exe /c '.a:cmd\n  endif\n\n  throw 'unknown os'\nendfunction\n\n\nfunction! s:on_stdout_nvim(_job_id, data, _event) dict abort\n  if empty(self.stdoutbuffer)\n    let self.stdoutbuffer = a:data\n  else\n    let self.stdoutbuffer = self.stdoutbuffer[:-2] +\n          \\ [self.stdoutbuffer[-1] . a:data[0]] +\n          \\ a:data[1:]\n  endif\nendfunction\n\nfunction! s:on_stderr_nvim(_job_id, data, _event) dict abort\n  if a:data != ['']  \" With Neovim there is always [''] reported on stderr.\n    call self.handler.err(self.buffer)\n  endif\nendfunction\n\nfunction! s:on_exit_nvim(_job_id, exit_code, _event) dict abort\n  if !a:exit_code\n    call self.handler.out(self.buffer, join(self.stdoutbuffer, \"\\n\"))\n  endif\nendfunction\n\n\nfunction! s:on_stdout_vim(_channel, data) dict abort\n  call add(self.stdoutbuffer, a:data)\nendfunction\n\nfunction! s:on_stderr_vim(channel, _data) dict abort\n  call self.handler.err(self.buffer)\nendfunction\n\nfunction! s:on_exit_vim(channel) dict abort\n  let job = ch_getjob(a:channel)\n  let jobid = s:job_id(job)\n  if has_key(s:jobs, jobid) | unlet s:jobs[jobid] | endif\n  while 1\n    if job_status(job) == 'dead'\n      let exit_code = job_info(job).exitval\n      break\n    endif\n    sleep 5m\n  endwhile\n\n  if !exit_code\n    call self.handler.out(self.buffer, join(self.stdoutbuffer, \"\\n\"))\n  endif\nendfunction\n\nfunction! s:job_id(job)\n  \" Vim\n  return job_info(a:job).process\nendfunction\n"
  },
  {
    "path": "autoload/gitgutter/debug.vim",
    "content": "let s:plugin_dir  = expand('<sfile>:p:h:h:h').'/'\nlet s:log_file    = s:plugin_dir.'gitgutter.log'\nlet s:channel_log = s:plugin_dir.'channel.log'\nlet s:new_log_session = 1\n\n\nfunction! gitgutter#debug#debug()\n  \" Open a scratch buffer\n  vsplit __GitGutter_Debug__\n  normal! ggdG\n  setlocal buftype=nofile\n  setlocal bufhidden=delete\n  setlocal noswapfile\n\n  call s:vim_version()\n  call s:separator()\n\n  call s:git_version()\n  call s:separator()\n\n  call s:separator()\n\n  call s:option('updatetime')\nendfunction\n\n\nfunction! s:separator()\n  call s:output('')\nendfunction\n\nfunction! s:vim_version()\n  redir => version_info\n    silent execute 'version'\n  redir END\n  call s:output(split(version_info, '\\n')[0:2])\nendfunction\n\nfunction! s:git_version()\n  let v = system(g:gitgutter_git_executable.' --version')\n  call s:output( substitute(v, '\\n$', '', '') )\nendfunction\n\nfunction! s:option(name)\n  if exists('+' . a:name)\n    let v = eval('&' . a:name)\n    call s:output(a:name . '=' . v)\n    \" redir => output\n    \"   silent execute \"verbose set \" . a:name . \"?\"\n    \" redir END\n    \" call s:output(a:name . '=' . output)\n  else\n    call s:output(a:name . ' [n/a]')\n  end\nendfunction\n\nfunction! s:output(text)\n  call append(line('$'), a:text)\nendfunction\n\n\" assumes optional args are calling function's optional args\nfunction! gitgutter#debug#log(message, ...) abort\n  if g:gitgutter_log\n    if s:new_log_session && gitgutter#async#available()\n      if exists('*ch_logfile')\n        call ch_logfile(s:channel_log, 'w')\n      endif\n    endif\n\n    if s:new_log_session\n      let s:start = reltime()\n      call writefile(['', '========== start log session '.strftime('%d.%m.%Y %H:%M:%S').' =========='], s:log_file, 'a')\n    endif\n\n    let elapsed = reltimestr(reltime(s:start)).' '\n    call writefile([''], s:log_file, 'a')\n    \" callers excluding this function\n    call writefile([elapsed.expand('<sfile>')[:-22].':'], s:log_file, 'a')\n    call writefile([elapsed.s:format_for_log(a:message)], s:log_file, 'a')\n    if a:0 && !empty(a:1)\n      for msg in a:000\n        call writefile([elapsed.s:format_for_log(msg)], s:log_file, 'a')\n      endfor\n    endif\n\n    let s:new_log_session = 0\n  endif\nendfunction\n\nfunction! s:format_for_log(data) abort\n  if type(a:data) == 1\n    return join(split(a:data,'\\n'),\"\\n\")\n  elseif type(a:data) == 3\n    return '['.join(a:data,\"\\n\").']'\n  else\n    return a:data\n  endif\nendfunction\n\n"
  },
  {
    "path": "autoload/gitgutter/diff.vim",
    "content": "scriptencoding utf8\n\nlet s:nomodeline = (v:version > 703 || (v:version == 703 && has('patch442'))) ? '<nomodeline>' : ''\n\nlet s:hunk_re = '^@@ -\\(\\d\\+\\),\\?\\(\\d*\\) +\\(\\d\\+\\),\\?\\(\\d*\\) @@'\n\nlet s:temp_from = tempname()\nlet s:temp_buffer = tempname()\nlet s:counter = 0\n\n\" Returns a diff of the buffer against the index or the working tree.\n\"\n\" When diffing against the index:\n\"\n\" The buffer contents is not the same as the file on disk so we need to pass\n\" two instances of the file to git-diff:\n\"\n\"     git diff myfileA myfileB\n\"\n\" where myfileA comes from\n\"\n\"     git show :myfile > myfileA\n\"\n\" and myfileB is the buffer contents.\n\"\n\" Regarding line endings:\n\"\n\" git-show does not convert line endings.\n\" git-diff FILE FILE does convert line endings for the given files.\n\"\n\" If a file has CRLF line endings and git's core.autocrlf is true,\n\" the file in git's object store will have LF line endings.  Writing\n\" it out via git-show will produce a file with LF line endings.\n\"\n\" If this last file is one of the files passed to git-diff, git-diff will\n\" convert its line endings to CRLF before diffing -- which is what we want --\n\" but also by default output a warning on stderr.\n\"\n\"   warning: LF will be replace by CRLF in <temp file>.\n\"   The file will have its original line endings in your working directory.\n\"\n\" When running the diff asynchronously, the warning message triggers the stderr\n\" callbacks which assume the overall command has failed and reset all the\n\" signs.  As this is not what we want, and we can safely ignore the warning,\n\" we turn it off by passing the '-c \"core.safecrlf=false\"' argument to\n\" git-diff.\n\"\n\" When writing the temporary files we preserve the original file's extension\n\" so that repos using .gitattributes to control EOL conversion continue to\n\" convert correctly.\n\"\n\" Arguments:\n\"\n\" bufnr - the number of the buffer to be diffed\n\" from  - 'index' or 'working_tree'; what the buffer is diffed against\nfunction! gitgutter#diff#run_diff(bufnr, from) abort\n  if gitgutter#utility#repo_path(a:bufnr, 0) == -1\n    throw 'gitgutter path not set'\n  endif\n\n  if gitgutter#utility#repo_path(a:bufnr, 0) == -2\n    throw 'gitgutter not tracked'\n  endif\n\n  if gitgutter#utility#repo_path(a:bufnr, 0) == -3\n    throw 'gitgutter assume unchanged'\n  endif\n\n  \" Wrap compound commands in parentheses to make Windows happy.\n  \" bash doesn't mind the parentheses.\n  let cmd = '('\n\n  \" Append buffer number to temp filenames to avoid race conditions between\n  \" writing and reading the files when asynchronously processing multiple\n  \" buffers.\n\n  \" Without the buffer number, buff_file would have a race between the\n  \" second gitgutter#process_buffer() writing the file (synchronously, below)\n  \" and the first gitgutter#process_buffer()'s async job reading it (with\n  \" git-diff).\n  let buff_file = s:temp_buffer.'.'.a:bufnr\n\n  \" Add a counter to avoid a similar race with two quick writes of the same buffer.\n  \" Use a modulus greater than a maximum reasonable number of visible buffers.\n  let s:counter = (s:counter + 1) % 20\n  let buff_file .= '.'.s:counter\n\n  let extension = gitgutter#utility#extension(a:bufnr)\n  if !empty(extension)\n    let buff_file .= '.'.extension\n  endif\n\n  \" Write buffer to temporary file.\n  \" Note: this is synchronous.\n  call s:write_buffer(a:bufnr, buff_file)\n\n  if a:from ==# 'index'\n    \" Without the buffer number, from_file would have a race in the shell\n    \" between the second process writing it (with git-show) and the first\n    \" reading it (with git-diff).\n    let from_file = s:temp_from.'.'.a:bufnr\n\n    \" Add a counter to avoid a similar race with two quick writes of the same buffer.\n    let from_file .= '.'.s:counter\n\n    if !empty(extension)\n      let from_file .= '.'.extension\n    endif\n\n    \" Write file from index to temporary file.\n    let index_name = gitgutter#utility#get_diff_base(a:bufnr).':'.gitgutter#utility#base_path(a:bufnr)\n    let cmd .= gitgutter#git(a:bufnr).' --no-pager show --textconv '.index_name\n    let cmd .= ' > '.gitgutter#utility#shellescape(from_file).' || exit 0) && ('\n\n  elseif a:from ==# 'working_tree'\n    let from_file = gitgutter#utility#repo_path(a:bufnr, 1)\n  endif\n\n  \" Call git-diff.\n  let cmd .= gitgutter#git(a:bufnr).' --no-pager'\n  if gitgutter#utility#git_supports_command_line_config_override()\n    let cmd .= ' -c \"diff.autorefreshindex=0\"'\n    let cmd .= ' -c \"diff.noprefix=false\"'\n    let cmd .= ' -c \"core.safecrlf=false\"'\n  endif\n  let cmd .= ' diff --no-ext-diff --no-color -U0 '.g:gitgutter_diff_args\n  let cmd .= ' -- '.gitgutter#utility#shellescape(from_file).' '.gitgutter#utility#shellescape(buff_file)\n\n  \" git-diff exits with 1 when differences are found but we want to treat\n  \" differences as non-erroneous behaviour.  So we OR the command with one\n  \" which always exits with success (0).\n  let cmd .= ' || exit 0'\n\n  let cmd .= ')'\n\n  if g:gitgutter_async && gitgutter#async#available()\n    call gitgutter#async#execute(cmd, a:bufnr, {\n          \\   'out': function('gitgutter#diff#handler'),\n          \\   'err': function('gitgutter#hunk#reset'),\n          \\ })\n    return 'async'\n\n  else\n    let [diff, error_code] = gitgutter#utility#system(cmd)\n\n    if error_code\n      call gitgutter#debug#log(diff)\n      throw 'gitgutter diff failed'\n    endif\n\n    return diff\n  endif\nendfunction\n\n\nfunction! gitgutter#diff#handler(bufnr, diff) abort\n  call gitgutter#debug#log(a:diff)\n\n  if !bufexists(a:bufnr)\n    return\n  endif\n\n  call gitgutter#hunk#set_hunks(a:bufnr, gitgutter#diff#parse_diff(a:diff))\n  let modified_lines = gitgutter#diff#process_hunks(a:bufnr, gitgutter#hunk#hunks(a:bufnr))\n\n  let signs_count = len(modified_lines)\n  if g:gitgutter_max_signs != -1 && signs_count > g:gitgutter_max_signs\n    call gitgutter#utility#warn_once(a:bufnr, printf(\n          \\ 'exceeded maximum number of signs (%d > %d, configured by g:gitgutter_max_signs).',\n          \\ signs_count, g:gitgutter_max_signs), 'max_signs')\n    call gitgutter#sign#clear_signs(a:bufnr)\n\n  else\n    if g:gitgutter_signs || g:gitgutter_highlight_lines || g:gitgutter_highlight_linenrs\n      call gitgutter#sign#update_signs(a:bufnr, modified_lines)\n    endif\n  endif\n\n  call s:save_last_seen_change(a:bufnr)\n  if exists('#User#GitGutter')\n    let g:gitgutter_hook_context = {'bufnr': a:bufnr}\n    execute 'doautocmd' s:nomodeline 'User GitGutter'\n    unlet g:gitgutter_hook_context\n  endif\nendfunction\n\n\nfunction! gitgutter#diff#parse_diff(diff) abort\n  let hunks = []\n  for line in split(a:diff, '\\n')\n    let hunk_info = gitgutter#diff#parse_hunk(line)\n    if len(hunk_info) == 4\n      call add(hunks, hunk_info)\n    endif\n  endfor\n  return hunks\nendfunction\n\nfunction! gitgutter#diff#parse_hunk(line) abort\n  let matches = matchlist(a:line, s:hunk_re)\n  if len(matches) > 0\n    let from_line  = str2nr(matches[1])\n    let from_count = (matches[2] == '') ? 1 : str2nr(matches[2])\n    let to_line    = str2nr(matches[3])\n    let to_count   = (matches[4] == '') ? 1 : str2nr(matches[4])\n    return [from_line, from_count, to_line, to_count]\n  else\n    return []\n  end\nendfunction\n\n\" This function is public so it may be used by other plugins\n\" e.g. vim-signature.\nfunction! gitgutter#diff#process_hunks(bufnr, hunks) abort\n  let modified_lines = []\n  for hunk in a:hunks\n    call extend(modified_lines, s:process_hunk(a:bufnr, hunk))\n  endfor\n  return modified_lines\nendfunction\n\n\" Returns [ [<line_number (number)>, <name (string)>], ...]\nfunction! s:process_hunk(bufnr, hunk) abort\n  let modifications = []\n  let from_line  = a:hunk[0]\n  let from_count = a:hunk[1]\n  let to_line    = a:hunk[2]\n  let to_count   = a:hunk[3]\n\n  if s:is_added(from_count, to_count)\n    call s:process_added(modifications, from_count, to_count, to_line)\n    call gitgutter#hunk#increment_lines_added(a:bufnr, to_count)\n\n  elseif s:is_removed(from_count, to_count)\n    call s:process_removed(modifications, from_count, to_count, to_line)\n    call gitgutter#hunk#increment_lines_removed(a:bufnr, from_count)\n\n  elseif s:is_modified(from_count, to_count)\n    call s:process_modified(modifications, from_count, to_count, to_line)\n    call gitgutter#hunk#increment_lines_modified(a:bufnr, to_count)\n\n  elseif s:is_modified_and_added(from_count, to_count)\n    call s:process_modified_and_added(modifications, from_count, to_count, to_line)\n    call gitgutter#hunk#increment_lines_added(a:bufnr, to_count - from_count)\n    call gitgutter#hunk#increment_lines_modified(a:bufnr, from_count)\n\n  elseif s:is_modified_and_removed(from_count, to_count)\n    call s:process_modified_and_removed(modifications, from_count, to_count, to_line)\n    call gitgutter#hunk#increment_lines_modified(a:bufnr, to_count)\n    call gitgutter#hunk#increment_lines_removed(a:bufnr, from_count - to_count)\n\n  endif\n  return modifications\nendfunction\n\nfunction! s:is_added(from_count, to_count) abort\n  return a:from_count == 0 && a:to_count > 0\nendfunction\n\nfunction! s:is_removed(from_count, to_count) abort\n  return a:from_count > 0 && a:to_count == 0\nendfunction\n\nfunction! s:is_modified(from_count, to_count) abort\n  return a:from_count > 0 && a:to_count > 0 && a:from_count == a:to_count\nendfunction\n\nfunction! s:is_modified_and_added(from_count, to_count) abort\n  return a:from_count > 0 && a:to_count > 0 && a:from_count < a:to_count\nendfunction\n\nfunction! s:is_modified_and_removed(from_count, to_count) abort\n  return a:from_count > 0 && a:to_count > 0 && a:from_count > a:to_count\nendfunction\n\nfunction! s:process_added(modifications, from_count, to_count, to_line) abort\n  let offset = 0\n  while offset < a:to_count\n    let line_number = a:to_line + offset\n    call add(a:modifications, [line_number, 'added'])\n    let offset += 1\n  endwhile\nendfunction\n\nfunction! s:process_removed(modifications, from_count, to_count, to_line) abort\n  if a:to_line == 0\n    call add(a:modifications, [1, 'removed_first_line'])\n  else\n    call add(a:modifications, [a:to_line, 'removed'])\n  endif\nendfunction\n\nfunction! s:process_modified(modifications, from_count, to_count, to_line) abort\n  let offset = 0\n  while offset < a:to_count\n    let line_number = a:to_line + offset\n    call add(a:modifications, [line_number, 'modified'])\n    let offset += 1\n  endwhile\nendfunction\n\nfunction! s:process_modified_and_added(modifications, from_count, to_count, to_line) abort\n  let offset = 0\n  while offset < a:from_count\n    let line_number = a:to_line + offset\n    call add(a:modifications, [line_number, 'modified'])\n    let offset += 1\n  endwhile\n  while offset < a:to_count\n    let line_number = a:to_line + offset\n    call add(a:modifications, [line_number, 'added'])\n    let offset += 1\n  endwhile\nendfunction\n\nfunction! s:process_modified_and_removed(modifications, from_count, to_count, to_line) abort\n  let offset = 0\n  while offset < a:to_count\n    let line_number = a:to_line + offset\n    call add(a:modifications, [line_number, 'modified'])\n    let offset += 1\n  endwhile\n  let a:modifications[-1] = [a:to_line + offset - 1, 'modified_removed']\nendfunction\n\n\n\" Returns a diff for the current hunk.\n\" Assumes there is only 1 current hunk unless the optional argument is given,\n\" in which case the cursor is in two hunks and the argument specifies the one\n\" to choose.\n\"\n\" Optional argument: 0 (to use the first hunk) or 1 (to use the second).\nfunction! gitgutter#diff#hunk_diff(bufnr, full_diff, ...)\n  let modified_diff = []\n  let hunk_index = 0\n  let keep_line = 1\n  \" Don't keepempty when splitting because the diff we want may not be the\n  \" final one.  Instead add trailing NL at end of function.\n  for line in split(a:full_diff, '\\n')\n    let hunk_info = gitgutter#diff#parse_hunk(line)\n    if len(hunk_info) == 4  \" start of new hunk\n      let keep_line = gitgutter#hunk#cursor_in_hunk(hunk_info)\n\n      if a:0 && hunk_index != a:1\n        let keep_line = 0\n      endif\n\n      let hunk_index += 1\n    endif\n    if keep_line\n      call add(modified_diff, line)\n    endif\n  endfor\n  return join(modified_diff, \"\\n\").\"\\n\"\nendfunction\n\n\nfunction! s:write_buffer(bufnr, file)\n  let bufcontents = getbufline(a:bufnr, 1, '$')\n\n  if bufcontents == [''] && line2byte(1) == -1\n    \" Special case: completely empty buffer.\n    \" A nearly empty buffer of only a newline has line2byte(1) == 1.\n    call writefile([], a:file)\n    return\n  endif\n\n  if getbufvar(a:bufnr, '&fileformat') ==# 'dos'\n    if getbufvar(a:bufnr, '&endofline')\n      call map(bufcontents, 'v:val.\"\\r\"')\n    else\n      for i in range(len(bufcontents) - 1)\n        let bufcontents[i] = bufcontents[i] . \"\\r\"\n      endfor\n    endif\n  endif\n\n  if getbufvar(a:bufnr, '&endofline')\n    call add(bufcontents, '')\n  endif\n\n  let fenc = getbufvar(a:bufnr, '&fileencoding')\n  if fenc !=# &encoding\n    call map(bufcontents, 'iconv(v:val, &encoding, \"'.fenc.'\")')\n  endif\n\n  if getbufvar(a:bufnr, '&bomb')\n    let bufcontents[0]='﻿'.bufcontents[0]\n  endif\n\n  \" The file we are writing to is a temporary file.  Sometimes the parent\n  \" directory is deleted outside Vim but, because Vim caches the directory\n  \" name at startup and does not check for its existence subsequently, Vim\n  \" does not realise.  This causes E482 errors.\n  try\n    call writefile(bufcontents, a:file, 'b')\n  catch /E482/\n    call mkdir(fnamemodify(a:file, ':h'), '', '0700')\n    call writefile(bufcontents, a:file, 'b')\n  endtry\nendfunction\n\n\nfunction! s:save_last_seen_change(bufnr) abort\n  call gitgutter#utility#setbufvar(a:bufnr, 'tick', getbufvar(a:bufnr, 'changedtick'))\nendfunction\n"
  },
  {
    "path": "autoload/gitgutter/diff_highlight.vim",
    "content": "\" This is the minimum number of characters required between regions of change\n\" in a line.  It's somewhat arbitrary: higher values mean less visual busyness;\n\" lower values mean more detail.\nlet s:gap_between_regions = 5\n\n\n\" Calculates the changed portions of lines.\n\"\n\" Based on:\n\"\n\" - diff-highlight (included with git)\n\"   https://github.com/git/git/blob/master/contrib/diff-highlight/DiffHighlight.pm\n\"\n\" - Diff Strategies, Neil Fraser\n\"   https://neil.fraser.name/writing/diff/\n\n\n\" Returns a list of intra-line changed regions.\n\" Each element is a list:\n\"\n\"   [\n\"     line number (1-based),\n\"     type ('+' or '-'),\n\"     start column (1-based, inclusive),\n\"     stop column (1-based, inclusive),\n\"   ]\n\"\n\" Args:\n\"   hunk_body - list of lines\nfunction! gitgutter#diff_highlight#process(hunk_body)\n  \" Check whether we have the same number of lines added as removed.\n  let [removed, added] = [0, 0]\n  for line in a:hunk_body\n    if line[0] == '-'\n      let removed += 1\n    elseif line[0] == '+'\n      let added += 1\n    endif\n  endfor\n  if removed != added\n    return []\n  endif\n\n  let regions = []\n\n  for i in range(removed)\n    \" pair lines by position\n    let rline = a:hunk_body[i]\n    let aline = a:hunk_body[i + removed]\n\n    call s:diff(rline, aline, i, i+removed, 0, 0, regions, 1)\n  endfor\n\n  return regions\nendfunction\n\n\nfunction! s:diff(rline, aline, rlinenr, alinenr, rprefix, aprefix, regions, whole_line)\n  \" diff marker does not count as a difference in prefix\n  let start = a:whole_line ? 1 : 0\n  let prefix = s:common_prefix(a:rline[start:], a:aline[start:])\n  if a:whole_line\n    let prefix += 1\n  endif\n  let [rsuffix, asuffix] = s:common_suffix(a:rline, a:aline, prefix+1)\n\n  \" region of change (common prefix and suffix removed)\n  let rtext = a:rline[prefix+1:rsuffix-1]\n  let atext = a:aline[prefix+1:asuffix-1]\n\n  \" singular insertion\n  if empty(rtext)\n    if !a:whole_line || len(atext) != len(a:aline)  \" not whole line\n      call add(a:regions, [a:alinenr+1, '+', a:aprefix+prefix+1+1, a:aprefix+asuffix+1-1])\n    endif\n    return\n  endif\n\n  \" singular deletion\n  if empty(atext)\n    if !a:whole_line || len(rtext) != len(a:rline)  \" not whole line\n      call add(a:regions, [a:rlinenr+1, '-', a:rprefix+prefix+1+1, a:rprefix+rsuffix+1-1])\n    endif\n    return\n  endif\n\n  \" two insertions\n  let j = stridx(atext, rtext)\n  if j != -1\n    call add(a:regions, [a:alinenr+1, '+', a:aprefix+prefix+1+1, a:aprefix+prefix+j+1])\n    call add(a:regions, [a:alinenr+1, '+', a:aprefix+prefix+1+1+j+len(rtext), a:aprefix+asuffix+1-1])\n    return\n  endif\n\n  \" two deletions\n  let j = stridx(rtext, atext)\n  if j != -1\n    call add(a:regions, [a:rlinenr+1, '-', a:rprefix+prefix+1+1, a:rprefix+prefix+j+1])\n    call add(a:regions, [a:rlinenr+1, '-', a:rprefix+prefix+1+1+j+len(atext), a:rprefix+rsuffix+1-1])\n    return\n  endif\n\n  \" two edits\n  let lcs = s:lcs(rtext, atext)\n  \" TODO do we need to ensure we don't get more than 2 elements when splitting?\n  if len(lcs) > s:gap_between_regions\n    let redits = s:split(rtext, lcs)\n    let aedits = s:split(atext, lcs)\n    call s:diff(redits[0], aedits[0], a:rlinenr, a:alinenr, a:rprefix+prefix+1,                         a:aprefix+prefix+1,                         a:regions, 0)\n    call s:diff(redits[1], aedits[1], a:rlinenr, a:alinenr, a:rprefix+prefix+1+len(redits[0])+len(lcs), a:aprefix+prefix+1+len(aedits[0])+len(lcs), a:regions, 0)\n    return\n  endif\n\n  \" fall back to highlighting entire changed area\n\n  \" if a change (but not the whole line)\n  if !a:whole_line || ((prefix != 0 || rsuffix != len(a:rline)) && prefix+1 < rsuffix)\n    call add(a:regions, [a:rlinenr+1, '-', a:rprefix+prefix+1+1, a:rprefix+rsuffix+1-1])\n  endif\n\n  \" if a change (but not the whole line)\n  if !a:whole_line || ((prefix != 0 || asuffix != len(a:aline)) && prefix+1 < asuffix)\n    call add(a:regions, [a:alinenr+1, '+', a:aprefix+prefix+1+1, a:aprefix+asuffix+1-1])\n  endif\nendfunction\n\n\nfunction! s:lcs(s1, s2)\n  if empty(a:s1) || empty(a:s2)\n    return ''\n  endif\n\n  let matrix = map(repeat([repeat([0], len(a:s2)+1)], len(a:s1)+1), 'copy(v:val)')\n\n  let maxlength = 0\n  let endindex = len(a:s1)\n\n  for i in range(1, len(a:s1))\n    for j in range(1, len(a:s2))\n      if a:s1[i-1] ==# a:s2[j-1]\n        let matrix[i][j] = 1 + matrix[i-1][j-1]\n        if matrix[i][j] > maxlength\n          let maxlength = matrix[i][j]\n          let endindex = i - 1\n        endif\n      endif\n    endfor\n  endfor\n\n  return a:s1[endindex - maxlength + 1 : endindex]\nendfunction\n\n\n\" Returns 0-based index of last character of common prefix\n\" If there is no common prefix, returns -1.\n\"\n\" a, b - strings\n\"\nfunction! s:common_prefix(a, b)\n  let len = min([len(a:a), len(a:b)])\n  if len == 0\n    return -1\n  endif\n  for i in range(len)\n    if a:a[i:i] !=# a:b[i:i]\n      return i - 1\n    endif\n  endfor\n  return i\nendfunction\n\n\n\" Returns 0-based indices of start of common suffix\n\"\n\" a, b - strings\n\" start - 0-based index to start from\nfunction! s:common_suffix(a, b, start)\n  let [sa, sb] = [len(a:a), len(a:b)]\n  while sa >= a:start && sb >= a:start\n    if a:a[sa] ==# a:b[sb]\n      let sa -= 1\n      let sb -= 1\n    else\n      break\n    endif\n  endwhile\n  return [sa+1, sb+1]\nendfunction\n\n\n\" Split a string on another string.\n\" Assumes 1 occurrence of the delimiter.\nfunction! s:split(str, delimiter)\n  let i = stridx(a:str, a:delimiter)\n\n  if i == 0\n    return ['', a:str[len(a:delimiter):]]\n  endif\n\n  return [a:str[:i-1], a:str[i+len(a:delimiter):]]\nendfunction\n"
  },
  {
    "path": "autoload/gitgutter/fold.vim",
    "content": "function! gitgutter#fold#enable()\n  call s:save_fold_state()\n\n  call s:set_fold_levels()\n  setlocal foldexpr=gitgutter#fold#level(v:lnum)\n  setlocal foldmethod=expr\n  setlocal foldlevel=0\n  setlocal foldenable\n\n  call gitgutter#utility#setbufvar(bufnr(''), 'folded', 1)\nendfunction\n\n\nfunction! gitgutter#fold#disable()\n  call s:restore_fold_state()\n  call gitgutter#utility#setbufvar(bufnr(''), 'folded', 0)\nendfunction\n\n\nfunction! gitgutter#fold#toggle()\n  if s:folded()\n    call gitgutter#fold#disable()\n  else\n    call gitgutter#fold#enable()\n  endif\nendfunction\n\n\nfunction! gitgutter#fold#level(lnum)\n  return gitgutter#utility#getbufvar(bufnr(''), 'fold_levels')[a:lnum]\nendfunction\n\n\nfunction! gitgutter#fold#foldtext()\n  if !gitgutter#fold#is_changed()\n    return foldtext()\n  endif\n\n  return substitute(foldtext(), ':', ' (*):', '')\nendfunction\n\n\n\" Returns 1 if any of the folded lines have been changed\n\" (added, removed, or modified), 0 otherwise.\nfunction! gitgutter#fold#is_changed()\n  for hunk in gitgutter#hunk#hunks(bufnr(''))\n    let hunk_begin = hunk[2]\n    let hunk_end   = hunk[2] + (hunk[3] == 0 ? 1 : hunk[3])\n\n    if hunk_end < v:foldstart\n      continue\n    endif\n\n    if hunk_begin > v:foldend\n      break\n    endif\n\n    return 1\n  endfor\n\n  return 0\nendfunction\n\n\n\" A line in a hunk has a fold level of 0.\n\" A line within 3 lines of a hunk has a fold level of 1.\n\" All other lines have a fold level of 2.\nfunction! s:set_fold_levels()\n  let fold_levels = ['']\n\n  for lnum in range(1, line('$'))\n    let in_hunk = gitgutter#hunk#in_hunk(lnum)\n    call add(fold_levels, (in_hunk ? 0 : 2))\n  endfor\n\n  let lines_of_context = 3\n\n  for lnum in range(1, line('$'))\n    if fold_levels[lnum] == 2\n      let pre = lnum >= 3 ? lnum - lines_of_context : 0\n      let post = lnum + lines_of_context\n      if index(fold_levels[pre:post], 0) != -1\n        let fold_levels[lnum] = 1\n      endif\n    endif\n  endfor\n\n  call gitgutter#utility#setbufvar(bufnr(''), 'fold_levels', fold_levels)\nendfunction\n\n\nfunction! s:save_fold_state()\n  let bufnr = bufnr('')\n  call gitgutter#utility#setbufvar(bufnr, 'foldlevel', &foldlevel)\n  call gitgutter#utility#setbufvar(bufnr, 'foldmethod', &foldmethod)\n  if &foldmethod ==# 'manual'\n    mkview\n  endif\nendfunction\n\nfunction! s:restore_fold_state()\n  let bufnr = bufnr('')\n  let &foldlevel = gitgutter#utility#getbufvar(bufnr, 'foldlevel')\n  let &foldmethod = gitgutter#utility#getbufvar(bufnr, 'foldmethod')\n  if &foldmethod ==# 'manual'\n    loadview\n  else\n    normal! zx\n  endif\nendfunction\n\nfunction! s:folded()\n  return gitgutter#utility#getbufvar(bufnr(''), 'folded')\nendfunction\n\n"
  },
  {
    "path": "autoload/gitgutter/highlight.vim",
    "content": "function! gitgutter#highlight#line_disable() abort\n  let g:gitgutter_highlight_lines = 0\n  call s:define_sign_line_highlights()\n\n  if !g:gitgutter_signs\n    call gitgutter#sign#clear_signs(bufnr(''))\n  endif\n\n  redraw!\nendfunction\n\nfunction! gitgutter#highlight#line_enable() abort\n  let old_highlight_lines = g:gitgutter_highlight_lines\n\n  let g:gitgutter_highlight_lines = 1\n  call s:define_sign_line_highlights()\n\n  if !old_highlight_lines && !g:gitgutter_signs\n    call gitgutter#all(1)\n  endif\n\n  redraw!\nendfunction\n\nfunction! gitgutter#highlight#line_toggle() abort\n  if g:gitgutter_highlight_lines\n    call gitgutter#highlight#line_disable()\n  else\n    call gitgutter#highlight#line_enable()\n  endif\nendfunction\n\n\nfunction! gitgutter#highlight#linenr_disable() abort\n  let g:gitgutter_highlight_linenrs = 0\n  call s:define_sign_linenr_highlights()\n\n  if !g:gitgutter_signs\n    call gitgutter#sign#clear_signs(bufnr(''))\n  endif\n\n  redraw!\nendfunction\n\nfunction! gitgutter#highlight#linenr_enable() abort\n  let old_highlight_linenrs = g:gitgutter_highlight_linenrs\n\n  let g:gitgutter_highlight_linenrs = 1\n  call s:define_sign_linenr_highlights()\n\n  if !old_highlight_linenrs && !g:gitgutter_signs\n    call gitgutter#all(1)\n  endif\n\n  redraw!\nendfunction\n\nfunction! gitgutter#highlight#linenr_toggle() abort\n  if g:gitgutter_highlight_linenrs\n    call gitgutter#highlight#linenr_disable()\n  else\n    call gitgutter#highlight#linenr_enable()\n  endif\nendfunction\n\n\nfunction! gitgutter#highlight#define_highlights() abort\n  let [guibg, ctermbg] = s:get_background_colors('SignColumn')\n\n  \" Highlights used by the signs.\n\n  \" When they are invisible.\n  execute \"highlight GitGutterAddInvisible    guifg=bg guibg=\" . guibg . \" ctermfg=\" . ctermbg . \" ctermbg=\" . ctermbg\n  execute \"highlight GitGutterChangeInvisible guifg=bg guibg=\" . guibg . \" ctermfg=\" . ctermbg . \" ctermbg=\" . ctermbg\n  execute \"highlight GitGutterDeleteInvisible guifg=bg guibg=\" . guibg . \" ctermfg=\" . ctermbg . \" ctermbg=\" . ctermbg\n  highlight default link GitGutterChangeDeleteInvisible GitGutterChangeInvisible\n\n  \" When they are visible.\n  for type in [\"Add\", \"Change\", \"Delete\"]\n    if hlexists(\"GitGutter\".type) && s:get_foreground_colors(\"GitGutter\".type) != ['NONE', 'NONE']\n      if g:gitgutter_set_sign_backgrounds\n        execute \"highlight GitGutter\".type.\" guibg=\".guibg.\" ctermbg=\".ctermbg\n      endif\n      continue\n    elseif s:useful_diff_colours()\n      let [guifg, ctermfg] = s:get_foreground_colors('Diff'.type)\n    else\n      let [guifg, ctermfg] = s:get_foreground_fallback_colors(type)\n    endif\n    execute \"highlight GitGutter\".type.\" guifg=\".guifg.\" guibg=\".guibg.\" ctermfg=\".ctermfg.\" ctermbg=\".ctermbg\n  endfor\n\n  if hlexists(\"GitGutterChangeDelete\") && g:gitgutter_set_sign_backgrounds\n    execute \"highlight GitGutterChangeDelete guibg=\".guibg.\" ctermbg=\".ctermbg\n  endif\n\n  highlight default link GitGutterChangeDelete GitGutterChange\n\n  \" Highlights used for the whole line.\n\n  highlight default link GitGutterAddLine          DiffAdd\n  highlight default link GitGutterChangeLine       DiffChange\n  highlight default link GitGutterDeleteLine       DiffDelete\n  highlight default link GitGutterChangeDeleteLine GitGutterChangeLine\n\n  highlight default link GitGutterAddLineNr          CursorLineNr\n  highlight default link GitGutterChangeLineNr       CursorLineNr\n  highlight default link GitGutterDeleteLineNr       CursorLineNr\n  highlight default link GitGutterChangeDeleteLineNr GitGutterChangeLineNr\n\n  \" Highlights used intra line.\n  highlight default GitGutterAddIntraLine    gui=reverse cterm=reverse\n  highlight default GitGutterDeleteIntraLine gui=reverse cterm=reverse\n  \" Set diff syntax colours (used in the preview window) - diffAdded,diffChanged,diffRemoved -\n  \" to match the signs, if not set aleady.\n  for [dtype,type] in [['Added','Add'], ['Changed','Change'], ['Removed','Delete']]\n    if !hlexists('diff'.dtype)\n      let [guifg, ctermfg] = s:get_foreground_colors('GitGutter'.type)\n      execute \"highlight diff\".dtype.\" guifg=\".guifg.\" ctermfg=\".ctermfg.\" guibg=NONE ctermbg=NONE\"\n    endif\n  endfor\nendfunction\n\nfunction! gitgutter#highlight#define_signs() abort\n  sign define GitGutterLineAdded\n  sign define GitGutterLineModified\n  sign define GitGutterLineRemoved\n  sign define GitGutterLineRemovedFirstLine\n  sign define GitGutterLineRemovedAboveAndBelow\n  sign define GitGutterLineModifiedRemoved\n\n  call s:define_sign_text()\n  call gitgutter#highlight#define_sign_text_highlights()\n  call s:define_sign_line_highlights()\n  call s:define_sign_linenr_highlights()\nendfunction\n\nfunction! s:define_sign_text() abort\n  execute \"sign define GitGutterLineAdded                 text=\" . g:gitgutter_sign_added\n  execute \"sign define GitGutterLineModified              text=\" . g:gitgutter_sign_modified\n  execute \"sign define GitGutterLineRemoved               text=\" . g:gitgutter_sign_removed\n  execute \"sign define GitGutterLineRemovedFirstLine      text=\" . g:gitgutter_sign_removed_first_line\n  execute \"sign define GitGutterLineRemovedAboveAndBelow  text=\" . g:gitgutter_sign_removed_above_and_below\n  execute \"sign define GitGutterLineModifiedRemoved       text=\" . g:gitgutter_sign_modified_removed\nendfunction\n\nfunction! gitgutter#highlight#define_sign_text_highlights() abort\n  \" Once a sign's text attribute has been defined, it cannot be undefined or\n  \" set to an empty value.  So to make signs' text disappear (when toggling\n  \" off or disabling) we make them invisible by setting their foreground colours\n  \" to the background's.\n  if g:gitgutter_signs\n    sign define GitGutterLineAdded                 texthl=GitGutterAdd\n    sign define GitGutterLineModified              texthl=GitGutterChange\n    sign define GitGutterLineRemoved               texthl=GitGutterDelete\n    sign define GitGutterLineRemovedFirstLine      texthl=GitGutterDelete\n    sign define GitGutterLineRemovedAboveAndBelow  texthl=GitGutterDelete\n    sign define GitGutterLineModifiedRemoved       texthl=GitGutterChangeDelete\n  else\n    sign define GitGutterLineAdded                 texthl=GitGutterAddInvisible\n    sign define GitGutterLineModified              texthl=GitGutterChangeInvisible\n    sign define GitGutterLineRemoved               texthl=GitGutterDeleteInvisible\n    sign define GitGutterLineRemovedFirstLine      texthl=GitGutterDeleteInvisible\n    sign define GitGutterLineRemovedAboveAndBelow  texthl=GitGutterDeleteInvisible\n    sign define GitGutterLineModifiedRemoved       texthl=GitGutterChangeDeleteInvisible\n  endif\nendfunction\n\nfunction! s:define_sign_line_highlights() abort\n  if g:gitgutter_highlight_lines\n    sign define GitGutterLineAdded                 linehl=GitGutterAddLine\n    sign define GitGutterLineModified              linehl=GitGutterChangeLine\n    sign define GitGutterLineRemoved               linehl=GitGutterDeleteLine\n    sign define GitGutterLineRemovedFirstLine      linehl=GitGutterDeleteLine\n    sign define GitGutterLineRemovedAboveAndBelow  linehl=GitGutterDeleteLine\n    sign define GitGutterLineModifiedRemoved       linehl=GitGutterChangeDeleteLine\n  else\n    sign define GitGutterLineAdded                 linehl=NONE\n    sign define GitGutterLineModified              linehl=NONE\n    sign define GitGutterLineRemoved               linehl=NONE\n    sign define GitGutterLineRemovedFirstLine      linehl=NONE\n    sign define GitGutterLineRemovedAboveAndBelow  linehl=NONE\n    sign define GitGutterLineModifiedRemoved       linehl=NONE\n  endif\nendfunction\n\nfunction! s:define_sign_linenr_highlights() abort\n  if has('nvim-0.3.2')\n    try\n      if g:gitgutter_highlight_linenrs\n        sign define GitGutterLineAdded                 numhl=GitGutterAddLineNr\n        sign define GitGutterLineModified              numhl=GitGutterChangeLineNr\n        sign define GitGutterLineRemoved               numhl=GitGutterDeleteLineNr\n        sign define GitGutterLineRemovedFirstLine      numhl=GitGutterDeleteLineNr\n        sign define GitGutterLineRemovedAboveAndBelow  numhl=GitGutterDeleteLineNr\n        sign define GitGutterLineModifiedRemoved       numhl=GitGutterChangeDeleteLineNr\n      else\n        sign define GitGutterLineAdded                 numhl=NONE\n        sign define GitGutterLineModified              numhl=NONE\n        sign define GitGutterLineRemoved               numhl=NONE\n        sign define GitGutterLineRemovedFirstLine      numhl=NONE\n        sign define GitGutterLineRemovedAboveAndBelow  numhl=NONE\n        sign define GitGutterLineModifiedRemoved       numhl=NONE\n      endif\n    catch /E475/\n    endtry\n  endif\nendfunction\n\nfunction! s:get_hl(group, what, mode) abort\n  let r = synIDattr(synIDtrans(hlID(a:group)), a:what, a:mode)\n  if empty(r) || r == -1\n    return 'NONE'\n  endif\n  return r\nendfunction\n\nfunction! s:get_foreground_colors(group) abort\n  let ctermfg = s:get_hl(a:group, 'fg', 'cterm')\n  let guifg = s:get_hl(a:group, 'fg', 'gui')\n  return [guifg, ctermfg]\nendfunction\n\nfunction! s:get_background_colors(group) abort\n  let ctermbg = s:get_hl(a:group, 'bg', 'cterm')\n  let guibg = s:get_hl(a:group, 'bg', 'gui')\n  return [guibg, ctermbg]\nendfunction\n\nfunction! s:useful_diff_colours()\n  let [guifg_add, ctermfg_add] = s:get_foreground_colors('DiffAdd')\n  let [guifg_del, ctermfg_del] = s:get_foreground_colors('DiffDelete')\n\n  return guifg_add != guifg_del && ctermfg_add != ctermfg_del\nendfunction\n\nfunction! s:get_foreground_fallback_colors(type)\n  if a:type == 'Add'\n    return ['#009900', '2']\n  elseif a:type == 'Change'\n    return ['#bbbb00', '3']\n  elseif a:type == 'Delete'\n    return ['#ff2222', '1']\n  endif\nendfunction\n"
  },
  {
    "path": "autoload/gitgutter/hunk.vim",
    "content": "let s:winid = 0\nlet s:preview_bufnr = 0\nlet s:nomodeline = (v:version > 703 || (v:version == 703 && has('patch442'))) ? '<nomodeline>' : ''\n\nfunction! gitgutter#hunk#set_hunks(bufnr, hunks) abort\n  call gitgutter#utility#setbufvar(a:bufnr, 'hunks', a:hunks)\n  call s:reset_summary(a:bufnr)\nendfunction\n\nfunction! gitgutter#hunk#hunks(bufnr) abort\n  return gitgutter#utility#getbufvar(a:bufnr, 'hunks', [])\nendfunction\n\nfunction! gitgutter#hunk#reset(bufnr) abort\n  call gitgutter#utility#setbufvar(a:bufnr, 'hunks', [])\n  call s:reset_summary(a:bufnr)\nendfunction\n\n\nfunction! gitgutter#hunk#summary(bufnr) abort\n  return gitgutter#utility#getbufvar(a:bufnr, 'summary', [0,0,0])\nendfunction\n\nfunction! s:reset_summary(bufnr) abort\n  call gitgutter#utility#setbufvar(a:bufnr, 'summary', [0,0,0])\nendfunction\n\nfunction! gitgutter#hunk#increment_lines_added(bufnr, count) abort\n  let summary = gitgutter#hunk#summary(a:bufnr)\n  let summary[0] += a:count\n  call gitgutter#utility#setbufvar(a:bufnr, 'summary', summary)\nendfunction\n\nfunction! gitgutter#hunk#increment_lines_modified(bufnr, count) abort\n  let summary = gitgutter#hunk#summary(a:bufnr)\n  let summary[1] += a:count\n  call gitgutter#utility#setbufvar(a:bufnr, 'summary', summary)\nendfunction\n\nfunction! gitgutter#hunk#increment_lines_removed(bufnr, count) abort\n  let summary = gitgutter#hunk#summary(a:bufnr)\n  let summary[2] += a:count\n  call gitgutter#utility#setbufvar(a:bufnr, 'summary', summary)\nendfunction\n\n\nfunction! gitgutter#hunk#next_hunk(count) abort\n  let bufnr = bufnr('')\n  if !gitgutter#utility#is_active(bufnr) | return | endif\n\n  let hunks = gitgutter#hunk#hunks(bufnr)\n  if empty(hunks)\n    call gitgutter#utility#warn('No hunks in file')\n    return\n  endif\n\n  let current_line = line('.')\n  let hunk_count = 0\n  for hunk in hunks\n    if hunk[2] > current_line\n      let hunk_count += 1\n      if hunk_count == a:count\n        let keys = &foldopen =~# '\\<block\\>' ? 'zv' : ''\n        execute 'normal!' hunk[2] . 'G' . keys\n        if g:gitgutter_show_msg_on_hunk_jumping\n          redraw | echo printf('Hunk %d of %d', index(hunks, hunk) + 1, len(hunks))\n        endif\n        if gitgutter#hunk#is_preview_window_open()\n          call gitgutter#hunk#preview()\n        endif\n        return\n      endif\n    endif\n  endfor\n  call gitgutter#utility#warn('No more hunks')\nendfunction\n\nfunction! gitgutter#hunk#prev_hunk(count) abort\n  let bufnr = bufnr('')\n  if !gitgutter#utility#is_active(bufnr) | return | endif\n\n  let hunks = gitgutter#hunk#hunks(bufnr)\n  if empty(hunks)\n    call gitgutter#utility#warn('No hunks in file')\n    return\n  endif\n\n  let current_line = line('.')\n  let hunk_count = 0\n  for hunk in reverse(copy(hunks))\n    if hunk[2] < current_line\n      let hunk_count += 1\n      if hunk_count == a:count\n        let keys = &foldopen =~# '\\<block\\>' ? 'zv' : ''\n        let target = hunk[2] == 0 ? 1 : hunk[2]\n        execute 'normal!' target . 'G' . keys\n        if g:gitgutter_show_msg_on_hunk_jumping\n          redraw | echo printf('Hunk %d of %d', index(hunks, hunk) + 1, len(hunks))\n        endif\n        if gitgutter#hunk#is_preview_window_open()\n          call gitgutter#hunk#preview()\n        endif\n        return\n      endif\n    endif\n  endfor\n  call gitgutter#utility#warn('No previous hunks')\nendfunction\n\n\" Returns the hunk the cursor is currently in or an empty list if the cursor\n\" isn't in a hunk.\nfunction! s:current_hunk() abort\n  let bufnr = bufnr('')\n  let current_hunk = []\n\n  for hunk in gitgutter#hunk#hunks(bufnr)\n    if gitgutter#hunk#cursor_in_hunk(hunk)\n      let current_hunk = hunk\n      break\n    endif\n  endfor\n\n  return current_hunk\nendfunction\n\n\" Returns truthy if the cursor is in two hunks (which can only happen if the\n\" cursor is on the first line and lines above have been deleted and lines\n\" immediately below have been deleted) or falsey otherwise.\nfunction! s:cursor_in_two_hunks()\n  let hunks = gitgutter#hunk#hunks(bufnr(''))\n\n  if line('.') == 1 && len(hunks) > 1 && hunks[0][2:3] == [0, 0] && hunks[1][2:3] == [1, 0]\n    return 1\n  endif\n\n  return 0\nendfunction\n\n\" A line can be in 0 or 1 hunks, with the following exception: when the first\n\" line(s) of a file has been deleted, and the new second line (and\n\" optionally below) has been deleted, the new first line is in two hunks.\nfunction! gitgutter#hunk#cursor_in_hunk(hunk) abort\n  let current_line = line('.')\n\n  if current_line == 1 && a:hunk[2] == 0\n    return 1\n  endif\n\n  if current_line >= a:hunk[2] && current_line < a:hunk[2] + (a:hunk[3] == 0 ? 1 : a:hunk[3])\n    return 1\n  endif\n\n  return 0\nendfunction\n\n\nfunction! gitgutter#hunk#in_hunk(lnum)\n  \" Hunks are sorted in the order they appear in the buffer.\n  for hunk in gitgutter#hunk#hunks(bufnr(''))\n    \" if in a hunk on first line of buffer\n    if a:lnum == 1 && hunk[2] == 0\n      return 1\n    endif\n\n    \" if in a hunk generally\n    if a:lnum >= hunk[2] && a:lnum < hunk[2] + (hunk[3] == 0 ? 1 : hunk[3])\n      return 1\n    endif\n\n    \" if hunk starts after the given line\n    if a:lnum < hunk[2]\n      return 0\n    endif\n  endfor\n\n  return 0\nendfunction\n\n\nfunction! gitgutter#hunk#text_object(inner) abort\n  let hunk = s:current_hunk()\n\n  if empty(hunk)\n    return\n  endif\n\n  let [first_line, last_line] = [hunk[2], hunk[2] + hunk[3] - 1]\n\n  if ! a:inner\n    let lnum = last_line\n    let eof = line('$')\n    while lnum < eof && empty(getline(lnum + 1))\n      let lnum +=1\n    endwhile\n    let last_line = lnum\n  endif\n\n  execute 'normal! 'first_line.'GV'.last_line.'G'\nendfunction\n\n\nfunction! gitgutter#hunk#stage(...) abort\n  if !s:in_hunk_preview_window() && !gitgutter#utility#has_repo_path(bufnr('')) | return | endif\n\n  if a:0 && (a:1 != 1 || a:2 != line('$'))\n    call s:hunk_op(function('s:stage'), a:1, a:2)\n  else\n    call s:hunk_op(function('s:stage'))\n  endif\n  silent! call repeat#set(\"\\<Plug>(GitGutterStageHunk)\", -1)\nendfunction\n\nfunction! gitgutter#hunk#undo() abort\n  if !gitgutter#utility#has_repo_path(bufnr('')) | return | endif\n\n  call s:hunk_op(function('s:undo'))\n  silent! call repeat#set(\"\\<Plug>(GitGutterUndoHunk)\", -1)\nendfunction\n\nfunction! gitgutter#hunk#preview() abort\n  if !gitgutter#utility#has_repo_path(bufnr('')) | return | endif\n\n  call s:hunk_op(function('s:preview'))\n  silent! call repeat#set(\"\\<Plug>(GitGutterPreviewHunk)\", -1)\nendfunction\n\n\nfunction! s:hunk_op(op, ...)\n  let bufnr = bufnr('')\n\n  if s:in_hunk_preview_window()\n    if string(a:op) =~ '_stage'\n      \" combine hunk-body in preview window with updated hunk-header\n      let hunk_body = getline(1, '$')\n\n      let [removed, added] = [0, 0]\n      for line in hunk_body\n        if line[0] == '-'\n          let removed += 1\n        elseif line[0] == '+'\n          let added += 1\n        endif\n      endfor\n\n      let hunk_header = b:hunk_header\n      \" from count\n      let hunk_header[4] = substitute(hunk_header[4], '\\(-\\d\\+\\)\\(,\\d\\+\\)\\?', '\\=submatch(1).\",\".removed', '')\n      \" to count\n      let hunk_header[4] = substitute(hunk_header[4], '\\(+\\d\\+\\)\\(,\\d\\+\\)\\?', '\\=submatch(1).\",\".added', '')\n\n      let hunk_diff = join(hunk_header + hunk_body, \"\\n\").\"\\n\"\n\n      if &previewwindow\n        call s:goto_original_window()\n      endif\n      call gitgutter#hunk#close_hunk_preview_window()\n      call s:stage(hunk_diff)\n    endif\n\n    return\n  endif\n\n  if gitgutter#utility#is_active(bufnr)\n    \" Get a (synchronous) diff.\n    let [async, g:gitgutter_async] = [g:gitgutter_async, 0]\n    let diff = gitgutter#diff#run_diff(bufnr, g:gitgutter_diff_relative_to)\n    let g:gitgutter_async = async\n\n    call gitgutter#hunk#set_hunks(bufnr, gitgutter#diff#parse_diff(diff))\n    call gitgutter#diff#process_hunks(bufnr, gitgutter#hunk#hunks(bufnr))  \" so the hunk summary is updated\n\n    if empty(s:current_hunk())\n      call gitgutter#utility#warn('Cursor is not in a hunk')\n    elseif s:cursor_in_two_hunks()\n      let choice = input('Choose hunk: upper or lower (u/l)? ')\n      \" Clear input\n      normal! :<ESC>\n      if choice =~ 'u'\n        call a:op(gitgutter#diff#hunk_diff(bufnr, diff, 0))\n      elseif choice =~ 'l'\n        call a:op(gitgutter#diff#hunk_diff(bufnr, diff, 1))\n      else\n        call gitgutter#utility#warn('Did not recognise your choice')\n      endif\n    else\n      let hunk_diff = gitgutter#diff#hunk_diff(bufnr, diff)\n\n      if a:0\n        let hunk_first_line = s:current_hunk()[2]\n        let hunk_diff = s:part_of_diff(hunk_diff, a:1-hunk_first_line, a:2-hunk_first_line)\n      endif\n\n      call a:op(hunk_diff)\n    endif\n  endif\nendfunction\n\n\nfunction! s:stage(hunk_diff)\n  let bufnr = bufnr('')\n\n  if gitgutter#utility#clean_smudge_filter_applies(bufnr)\n    let choice = input('File uses clean/smudge filter. Stage entire file (y/n)? ')\n    normal! :<ESC>\n    if choice =~ 'y'\n      \" We are about to add the file to the index so write the buffer to\n      \" ensure the file on disk matches it (the buffer).\n      write\n      let path = gitgutter#utility#repo_path(bufnr, 1)\n      \" Add file to index.\n      let cmd = gitgutter#git(bufnr).' add '.\n            \\ gitgutter#utility#shellescape(gitgutter#utility#filename(bufnr))\n      let [_, error_code] = gitgutter#utility#system(cmd)\n    else\n      return\n    endif\n\n  else\n    let diff = s:adjust_header(bufnr, a:hunk_diff)\n    \" Apply patch to index.\n    let [_, error_code] = gitgutter#utility#system(\n          \\ gitgutter#git(bufnr).' apply --cached --unidiff-zero - ',\n          \\ diff)\n  endif\n\n  if error_code\n    call gitgutter#utility#warn('Patch does not apply')\n  else\n    if exists('#User#GitGutterStage')\n      execute 'doautocmd' s:nomodeline 'User GitGutterStage'\n    endif\n  endif\n\n  \" Refresh gitgutter's view of buffer.\n  call gitgutter#process_buffer(bufnr, 1)\nendfunction\n\n\nfunction! s:undo(hunk_diff)\n  \" Apply reverse patch to buffer.\n  let hunk  = gitgutter#diff#parse_hunk(split(a:hunk_diff, '\\n')[4])\n  let lines = map(split(a:hunk_diff, '\\r\\?\\n')[5:], 'v:val[1:]')\n  let lnum  = hunk[2]\n  let added_only   = hunk[1] == 0 && hunk[3]  > 0\n  let removed_only = hunk[1]  > 0 && hunk[3] == 0\n\n  if removed_only\n    call append(lnum, lines)\n  elseif added_only\n    execute lnum .','. (lnum+len(lines)-1) .'d _'\n  else\n    call append(lnum-1, lines[0:hunk[1]])\n    execute (lnum+hunk[1]) .','. (lnum+hunk[1]+hunk[3]) .'d _'\n  endif\n\n  \" Refresh gitgutter's view of buffer.\n  call gitgutter#process_buffer(bufnr(''), 1)\nendfunction\n\n\nfunction! s:preview(hunk_diff)\n  if g:gitgutter_preview_win_floating && exists('*nvim_set_current_win') && s:winid != 0\n    call nvim_set_current_win(s:winid)\n    return\n  endif\n\n  let lines = split(a:hunk_diff, '\\r\\?\\n')\n  let header = lines[0:4]\n  let body = lines[5:]\n\n  call s:open_hunk_preview_window()\n  call s:populate_hunk_preview_window(header, body)\n  call s:enable_staging_from_hunk_preview_window()\n  if &previewwindow\n    call s:goto_original_window()\n  endif\nendfunction\n\n\n\" Returns a new hunk diff using the specified lines from the given one.\n\" Assumes all lines are additions.\n\" a:first, a:last - 0-based indexes into the body of the hunk.\nfunction! s:part_of_diff(hunk_diff, first, last)\n  let diff_lines = split(a:hunk_diff, '\\n', 1)\n\n  \" adjust 'to' line count in header\n  let diff_lines[4] = substitute(diff_lines[4], '\\(+\\d\\+\\)\\(,\\d\\+\\)\\?', '\\=submatch(1).\",\".(a:last-a:first+1)', '')\n\n  return join(diff_lines[0:4] + diff_lines[5+a:first:5+a:last], \"\\n\").\"\\n\"\nendfunction\n\n\nfunction! s:adjust_header(bufnr, hunk_diff)\n  let filepath = gitgutter#utility#repo_path(a:bufnr, 0)\n  return s:adjust_hunk_summary(s:fix_file_references(filepath, a:hunk_diff))\nendfunction\n\n\n\" Replaces references to temp files with the actual file.\nfunction! s:fix_file_references(filepath, hunk_diff)\n  let lines = split(a:hunk_diff, '\\n')\n\n  let left_prefix  = matchstr(lines[2], '[abciow12]').'/'\n  let right_prefix = matchstr(lines[3], '[abciow12]').'/'\n  let quote        = lines[0][11] == '\"' ? '\"' : ''\n\n  let left_file  = quote.left_prefix.a:filepath.quote\n  let right_file = quote.right_prefix.a:filepath.quote\n\n  let lines[0] = 'diff --git '.left_file.' '.right_file\n  let lines[2] = '--- '.left_file\n  let lines[3] = '+++ '.right_file\n\n  return join(lines, \"\\n\").\"\\n\"\nendfunction\n\n\nfunction! s:adjust_hunk_summary(hunk_diff) abort\n  let line_adjustment = s:line_adjustment_for_current_hunk()\n  let diff = split(a:hunk_diff, '\\n', 1)\n  let diff[4] = substitute(diff[4], '+\\zs\\(\\d\\+\\)', '\\=submatch(1)+line_adjustment', '')\n  return join(diff, \"\\n\")\nendfunction\n\n\n\" Returns the number of lines the current hunk is offset from where it would\n\" be if any changes above it in the file didn't exist.\nfunction! s:line_adjustment_for_current_hunk() abort\n  let bufnr = bufnr('')\n  let adj = 0\n  for hunk in gitgutter#hunk#hunks(bufnr)\n    if gitgutter#hunk#cursor_in_hunk(hunk)\n      break\n    else\n      let adj += hunk[1] - hunk[3]\n    endif\n  endfor\n  return adj\nendfunction\n\n\nfunction! s:in_hunk_preview_window()\n  if g:gitgutter_preview_win_floating\n    return win_id2win(s:winid) == winnr()\n  else\n    return &previewwindow\n  endif\nendfunction\n\n\n\" Floating window: does not move cursor to floating window.\n\" Preview window: moves cursor to preview window.\n\"\n\" Note the \"diff\" file type treats a line starting \"--- \" as a file header\n\" instead of a removed line, thanks to the syntax group \"diffNewFile\".  We\n\" want it to be treated as a removed line.  Since we never show headers in\n\" the preview window it is safe to remove the offending syntax group.\nfunction! s:open_hunk_preview_window()\n  let source_wrap = &wrap\n  let source_window = winnr()\n\n  if g:gitgutter_preview_win_floating\n    if exists('*nvim_open_win')\n      call gitgutter#hunk#close_hunk_preview_window()\n\n      let buf = nvim_create_buf(v:false, v:false)\n      \" Set default width and height for now.\n      let s:winid = nvim_open_win(buf, v:false, g:gitgutter_floating_window_options)\n      call nvim_win_set_option(s:winid, 'wrap', source_wrap ? v:true : v:false)\n      call nvim_buf_set_option(buf, 'filetype',  'diff')\n      if exists(\"*win_execute\")\n        try\n          call win_execute(s:winid, \"syntax clear diffNewFile\", 1)\n        catch /E28/\n          \" noop\n        endtry\n      endif\n      call nvim_buf_set_option(buf, 'buftype',   'acwrite')\n      call nvim_buf_set_option(buf, 'bufhidden', 'delete')\n      call nvim_buf_set_option(buf, 'swapfile',  v:false)\n      call nvim_buf_set_name(buf, 'gitgutter://hunk-preview')\n\n      if g:gitgutter_close_preview_on_escape\n        let winnr = nvim_win_get_number(s:winid)\n        execute winnr.'wincmd w'\n        nnoremap <buffer> <silent> <Esc> :<C-U>call gitgutter#hunk#close_hunk_preview_window()<CR>\n        wincmd w\n      endif\n\n      \" Assumes cursor is in original window.\n      autocmd CursorMoved,TabLeave <buffer> ++once call gitgutter#hunk#close_hunk_preview_window()\n\n      return\n    endif\n\n    if exists('*popup_create')\n      if g:gitgutter_close_preview_on_escape\n        let g:gitgutter_floating_window_options.filter = function('s:close_popup_on_escape')\n      endif\n\n      let s:winid = popup_create('', g:gitgutter_floating_window_options)\n\n      call setbufvar(winbufnr(s:winid), '&filetype', 'diff')\n      if exists(\"*win_execute\")\n        try\n          call win_execute(s:winid, \"syntax clear diffNewFile\", 1)\n        catch /E28/\n          \" noop\n        endtry\n      endif\n      call setwinvar(s:winid, '&wrap', source_wrap)\n\n      return\n    endif\n  endif\n\n  if exists('&previewpopup')\n    let [previewpopup, &previewpopup] = [&previewpopup, '']\n  endif\n\n  \" Specifying where to open the preview window can lead to the cursor going\n  \" to an unexpected window when the preview window is closed (#769).\n  silent! noautocmd execute g:gitgutter_preview_win_location 'pedit gitgutter://hunk-preview'\n  silent! wincmd P\n  setlocal statusline=%{''}\n  doautocmd WinEnter\n  if exists('*win_getid')\n    let s:winid = win_getid()\n  else\n    let s:preview_bufnr = bufnr('')\n  endif\n  setlocal filetype=diff buftype=acwrite bufhidden=delete\n  try\n    syntax clear diffNewFile\n  catch /E28/\n    \" noop\n  endtry\n  let &l:wrap = source_wrap\n  let b:source_window = source_window\n  \" Reset some defaults in case someone else has changed them.\n  setlocal noreadonly modifiable noswapfile\n  if g:gitgutter_close_preview_on_escape\n    \" Ensure cursor goes to the expected window.\n    nnoremap <buffer> <silent> <Esc> :<C-U>execute b:source_window . \"wincmd w\"<Bar>pclose<CR>\n  endif\n\n  if exists('&previewpopup')\n    let &previewpopup=previewpopup\n  endif\nendfunction\n\n\nfunction! s:close_popup_on_escape(winid, key)\n  if a:key == \"\\<Esc>\"\n    call popup_close(a:winid)\n    return 1\n  endif\n  return 0\nendfunction\n\n\n\" Floating window: does not care where cursor is.\n\" Preview window: assumes cursor is in preview window.\nfunction! s:populate_hunk_preview_window(header, body)\n  if g:gitgutter_preview_win_floating\n    if exists('*nvim_open_win')\n      \" Assumes cursor is not in previewing window.\n      call nvim_buf_set_var(winbufnr(s:winid), 'hunk_header', a:header)\n\n      let [_scrolloff, &scrolloff] = [&scrolloff, 0]\n\n      let [width, height] = s:screen_lines(a:body)\n      let height = min([height, g:gitgutter_floating_window_options.height])\n      call nvim_win_set_width(s:winid, width)\n      call nvim_win_set_height(s:winid, height)\n\n      let &scrolloff=_scrolloff\n\n      call nvim_buf_set_lines(winbufnr(s:winid), 0, -1, v:false, [])\n      call nvim_buf_set_lines(winbufnr(s:winid), 0, -1, v:false, a:body)\n      call nvim_buf_set_option(winbufnr(s:winid), 'modified', v:false)\n\n      let ns_id = nvim_create_namespace('GitGutter')\n      call nvim_buf_clear_namespace(winbufnr(s:winid), ns_id, 0, -1)\n      for region in gitgutter#diff_highlight#process(a:body)\n        let group = region[1] == '+' ? 'GitGutterAddIntraLine' : 'GitGutterDeleteIntraLine'\n        call nvim_buf_add_highlight(winbufnr(s:winid), ns_id, group, region[0]-1, region[2]-1, region[3])\n      endfor\n\n      call nvim_win_set_cursor(s:winid, [1,0])\n    endif\n\n    if exists('*popup_create')\n      call popup_settext(s:winid, a:body)\n\n      for region in gitgutter#diff_highlight#process(a:body)\n        let group = region[1] == '+' ? 'GitGutterAddIntraLine' : 'GitGutterDeleteIntraLine'\n        call win_execute(s:winid, \"call matchaddpos('\".group.\"', [[\".region[0].\", \".region[2].\", \".(region[3]-region[2]+1).\"]])\")\n      endfor\n    endif\n\n  else\n    let b:hunk_header = a:header\n\n    %delete _\n    call setline(1, a:body)\n    setlocal nomodified\n\n    let [_, height] = s:screen_lines(a:body)\n    execute 'resize' height\n    1\n\n    call clearmatches()\n    for region in gitgutter#diff_highlight#process(a:body)\n      let group = region[1] == '+' ? 'GitGutterAddIntraLine' : 'GitGutterDeleteIntraLine'\n      call matchaddpos(group, [[region[0], region[2], region[3]-region[2]+1]])\n    endfor\n\n    1\n  endif\nendfunction\n\n\n\" Calculates the number of columns and the number of screen lines the given\n\" array of lines will take up, taking account of wrapping.\nfunction! s:screen_lines(lines)\n  let [_virtualedit, &virtualedit]=[&virtualedit, 'all']\n  let cursor = getcurpos()\n  normal! 0g$\n  let available_width = virtcol('.')\n  call setpos('.', cursor)\n  let &virtualedit=_virtualedit\n  let width = min([max(map(copy(a:lines), 'strdisplaywidth(v:val)')), available_width])\n\n  if exists('*reduce')\n    let height = reduce(a:lines, { acc, val -> acc + strdisplaywidth(val) / width + (strdisplaywidth(val) % width == 0 ? 0 : 1) }, 0)\n  else\n    let height = eval(join(map(copy(a:lines), 'strdisplaywidth(v:val) / width + (strdisplaywidth(v:val) % width == 0 ? 0 : 1)'), '+'))\n  endif\n\n  return [width, height]\nendfunction\n\n\nfunction! s:enable_staging_from_hunk_preview_window()\n  augroup gitgutter_hunk_preview\n    autocmd!\n    let bufnr = s:winid != 0 ? winbufnr(s:winid) : s:preview_bufnr\n    execute 'autocmd BufWriteCmd <buffer='.bufnr.'> GitGutterStageHunk'\n  augroup END\nendfunction\n\n\nfunction! s:goto_original_window()\n  noautocmd execute b:source_window . \"wincmd w\"\n  doautocmd WinEnter\nendfunction\n\n\nfunction! gitgutter#hunk#close_hunk_preview_window()\n  let bufnr = s:winid != 0 ? winbufnr(s:winid) : s:preview_bufnr\n  call setbufvar(bufnr, '&modified', 0)\n\n  if g:gitgutter_preview_win_floating\n    if win_id2win(s:winid) > 0\n      execute win_id2win(s:winid).'wincmd c'\n    endif\n  else\n    pclose\n  endif\n\n  let s:winid = 0\n  let s:preview_bufnr = 0\nendfunction\n\n\nfunction gitgutter#hunk#is_preview_window_open()\n  if g:gitgutter_preview_win_floating\n    if win_id2win(s:winid) > 0\n      execute win_id2win(s:winid).'wincmd c'\n    endif\n  else\n    for i in range(1, winnr('$'))\n      if getwinvar(i, '&previewwindow')\n        return 1\n      endif\n    endfor\n  endif\n  return 0\nendfunction\n"
  },
  {
    "path": "autoload/gitgutter/sign.vim",
    "content": "\" For older Vims without sign_place() the plugin has to manaage the sign ids.\nlet s:first_sign_id = 3000\nlet s:next_sign_id  = s:first_sign_id\n\" Remove-all-signs optimisation requires Vim 7.3.596+.\nlet s:supports_star = v:version > 703 || (v:version == 703 && has(\"patch596\"))\n\n\nfunction! gitgutter#sign#enable() abort\n  let old_signs = g:gitgutter_signs\n\n  let g:gitgutter_signs = 1\n  call gitgutter#highlight#define_sign_text_highlights()\n\n  if !old_signs && !g:gitgutter_highlight_lines && !g:gitgutter_highlight_linenrs\n    call gitgutter#all(1)\n  endif\nendfunction\n\nfunction! gitgutter#sign#disable() abort\n  let g:gitgutter_signs = 0\n  call gitgutter#highlight#define_sign_text_highlights()\n\n  if !g:gitgutter_highlight_lines && !g:gitgutter_highlight_linenrs\n    call gitgutter#sign#clear_signs(bufnr(''))\n  endif\nendfunction\n\nfunction! gitgutter#sign#toggle() abort\n  if g:gitgutter_signs\n    call gitgutter#sign#disable()\n  else\n    call gitgutter#sign#enable()\n  endif\nendfunction\n\n\n\" Removes gitgutter's signs from the buffer being processed.\nfunction! gitgutter#sign#clear_signs(bufnr) abort\n  if exists('*sign_unplace')\n    call sign_unplace('gitgutter', {'buffer': a:bufnr})\n    return\n  endif\n\n\n  call s:find_current_signs(a:bufnr)\n\n  let sign_ids = map(values(gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs')), 'v:val.id')\n  call s:remove_signs(a:bufnr, sign_ids, 1)\n  call gitgutter#utility#setbufvar(a:bufnr, 'gitgutter_signs', {})\nendfunction\n\n\n\" Updates gitgutter's signs in the buffer being processed.\n\"\n\" modified_lines: list of [<line_number (number)>, <name (string)>]\n\" where name = 'added|removed|modified|modified_removed'\nfunction! gitgutter#sign#update_signs(bufnr, modified_lines) abort\n  if exists('*sign_unplace')\n    \" Vim is (hopefully) now quick enough to remove all signs then place new ones.\n    call sign_unplace('gitgutter', {'buffer': a:bufnr})\n\n    let modified_lines = s:handle_double_hunk(a:modified_lines)\n    let signs = map(copy(modified_lines), '{'.\n          \\ '\"buffer\":   a:bufnr,'.\n          \\ '\"group\":    \"gitgutter\",'.\n          \\ '\"name\":     s:highlight_name_for_change(v:val[1]),'.\n          \\ '\"lnum\":     v:val[0],'.\n          \\ '\"priority\": g:gitgutter_sign_priority'.\n          \\ '}')\n\n    if exists('*sign_placelist')\n      call sign_placelist(signs)\n      return\n    endif\n\n    for sign in signs\n      call sign_place(0, sign.group, sign.name, sign.buffer, {'lnum': sign.lnum, 'priority': sign.priority})\n    endfor\n    return\n  endif\n\n\n  \" Derive a delta between the current signs and the ones we want.\n  \" Remove signs from lines that no longer need a sign.\n  \" Upsert the remaining signs.\n\n  call s:find_current_signs(a:bufnr)\n\n  let new_gitgutter_signs_line_numbers = map(copy(a:modified_lines), 'v:val[0]')\n  let obsolete_signs = s:obsolete_gitgutter_signs_to_remove(a:bufnr, new_gitgutter_signs_line_numbers)\n\n  call s:remove_signs(a:bufnr, obsolete_signs, s:remove_all_old_signs)\n  call s:upsert_new_gitgutter_signs(a:bufnr, a:modified_lines)\nendfunction\n\n\n\"\n\" Internal functions\n\"\n\n\nfunction! s:find_current_signs(bufnr) abort\n  let gitgutter_signs = {}  \" <line_number (string)>: {'id': <id (number)>, 'name': <name (string)>}\n  if !g:gitgutter_sign_allow_clobber\n    let other_signs = []      \" [<line_number (number),...]\n  endif\n\n  if exists('*getbufinfo')\n    let bufinfo = getbufinfo(a:bufnr)[0]\n    let signs = has_key(bufinfo, 'signs') ? bufinfo.signs : []\n  else\n    let signs = []\n\n    redir => signlines\n      silent execute \"sign place buffer=\" . a:bufnr\n    redir END\n\n    for signline in filter(split(signlines, '\\n')[2:], 'v:val =~# \"=\"')\n      \" Typical sign line before v8.1.0614:  line=88 id=1234 name=GitGutterLineAdded\n      \" We assume splitting is faster than a regexp.\n      let components = split(signline)\n      call add(signs, {\n            \\ 'lnum': str2nr(split(components[0], '=')[1]),\n            \\ 'id':   str2nr(split(components[1], '=')[1]),\n            \\ 'name':        split(components[2], '=')[1]\n            \\ })\n    endfor\n  endif\n\n  for sign in signs\n    if sign.name =~# 'GitGutter'\n      \" Remove orphaned signs (signs placed on lines which have been deleted).\n      \" (When a line is deleted its sign lingers.  Subsequent lines' signs'\n      \" line numbers are decremented appropriately.)\n      if has_key(gitgutter_signs, sign.lnum)\n        execute \"sign unplace\" gitgutter_signs[sign.lnum].id\n      endif\n      let gitgutter_signs[sign.lnum] = {'id': sign.id, 'name': sign.name}\n    else\n      if !g:gitgutter_sign_allow_clobber\n        call add(other_signs, sign.lnum)\n      endif\n    endif\n  endfor\n\n  call gitgutter#utility#setbufvar(a:bufnr, 'gitgutter_signs', gitgutter_signs)\n  if !g:gitgutter_sign_allow_clobber\n    call gitgutter#utility#setbufvar(a:bufnr, 'other_signs', other_signs)\n  endif\nendfunction\n\n\n\" Returns a list of [<id (number)>, ...]\n\" Sets `s:remove_all_old_signs` as a side-effect.\nfunction! s:obsolete_gitgutter_signs_to_remove(bufnr, new_gitgutter_signs_line_numbers) abort\n  let signs_to_remove = []  \" list of [<id (number)>, ...]\n  let remove_all_signs = 1\n  let old_gitgutter_signs = gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs')\n  for line_number in keys(old_gitgutter_signs)\n    if index(a:new_gitgutter_signs_line_numbers, str2nr(line_number)) == -1\n      call add(signs_to_remove, old_gitgutter_signs[line_number].id)\n    else\n      let remove_all_signs = 0\n    endif\n  endfor\n  let s:remove_all_old_signs = remove_all_signs\n  return signs_to_remove\nendfunction\n\n\nfunction! s:remove_signs(bufnr, sign_ids, all_signs) abort\n  if a:all_signs && s:supports_star && (g:gitgutter_sign_allow_clobber || empty(gitgutter#utility#getbufvar(a:bufnr, 'other_signs')))\n    execute \"sign unplace * buffer=\" . a:bufnr\n  else\n    for id in a:sign_ids\n      execute \"sign unplace\" id\n    endfor\n  endif\nendfunction\n\n\nfunction! s:upsert_new_gitgutter_signs(bufnr, modified_lines) abort\n  if !g:gitgutter_sign_allow_clobber\n    let other_signs = gitgutter#utility#getbufvar(a:bufnr, 'other_signs')\n  endif\n  let old_gitgutter_signs = gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs')\n\n  let modified_lines = s:handle_double_hunk(a:modified_lines)\n\n  for line in modified_lines\n    let line_number = line[0]  \" <number>\n    if g:gitgutter_sign_allow_clobber || index(other_signs, line_number) == -1  \" don't clobber others' signs\n      let name = s:highlight_name_for_change(line[1])\n      if !has_key(old_gitgutter_signs, line_number)  \" insert\n        let id = s:next_sign_id()\n        execute \"sign place\" id \"line=\" . line_number \"name=\" . name \"buffer=\" . a:bufnr\n      else  \" update if sign has changed\n        let old_sign = old_gitgutter_signs[line_number]\n        if old_sign.name !=# name\n          execute \"sign place\" old_sign.id \"name=\" . name \"buffer=\" . a:bufnr\n        end\n      endif\n    endif\n  endfor\n  \" At this point b:gitgutter_gitgutter_signs is out of date.\nendfunction\n\n\n\" Handle special case where the first line is the site of two hunks:\n\" lines deleted above at the start of the file, and lines deleted\n\" immediately below.\nfunction! s:handle_double_hunk(modified_lines)\n  if a:modified_lines[0:1] == [[1, 'removed_first_line'], [1, 'removed']]\n    return [[1, 'removed_above_and_below']] + a:modified_lines[2:]\n  endif\n\n  return a:modified_lines\nendfunction\n\n\nfunction! s:next_sign_id() abort\n  let next_id = s:next_sign_id\n  let s:next_sign_id += 1\n  return next_id\nendfunction\n\n\n\" Only for testing.\nfunction! gitgutter#sign#reset()\n  let s:next_sign_id  = s:first_sign_id\nendfunction\n\n\nfunction! s:highlight_name_for_change(text) abort\n  if a:text ==# 'added'\n    return 'GitGutterLineAdded'\n  elseif a:text ==# 'removed'\n    return 'GitGutterLineRemoved'\n  elseif a:text ==# 'removed_first_line'\n    return 'GitGutterLineRemovedFirstLine'\n  elseif a:text ==# 'modified'\n    return 'GitGutterLineModified'\n  elseif a:text ==# 'modified_removed'\n    return 'GitGutterLineModifiedRemoved'\n  elseif a:text ==# 'removed_above_and_below'\n    return 'GitGutterLineRemovedAboveAndBelow'\n  endif\nendfunction\n\n\n"
  },
  {
    "path": "autoload/gitgutter/utility.vim",
    "content": "function! gitgutter#utility#supports_overscore_sign()\n  if gitgutter#utility#windows()\n    return &encoding ==? 'utf-8'\n  else\n    return &termencoding ==? &encoding || &termencoding == ''\n  endif\nendfunction\n\n\" True for git v1.7.2+.\nfunction! gitgutter#utility#git_supports_command_line_config_override() abort\n  if !exists('s:c_flag')\n    let [_, error_code] = gitgutter#utility#system(gitgutter#git().' -c foo.bar=baz --version')\n    let s:c_flag = !error_code\n  endif\n  return s:c_flag\nendfunction\n\nfunction! gitgutter#utility#setbufvar(buffer, varname, val)\n  let buffer = +a:buffer\n  \" Default value for getbufvar() was introduced in Vim 7.3.831.\n  let ggvars = getbufvar(buffer, 'gitgutter')\n  if type(ggvars) == type('')\n    unlet ggvars\n    let ggvars = {}\n    call setbufvar(buffer, 'gitgutter', ggvars)\n  endif\n  let ggvars[a:varname] = a:val\nendfunction\n\nfunction! gitgutter#utility#getbufvar(buffer, varname, ...)\n  let buffer = +a:buffer\n  let ggvars = getbufvar(buffer, 'gitgutter')\n  if type(ggvars) == type({}) && has_key(ggvars, a:varname)\n    return ggvars[a:varname]\n  endif\n  if a:0\n    return a:1\n  endif\nendfunction\n\nfunction! gitgutter#utility#warn(message) abort\n  echohl WarningMsg\n  echo a:message\n  echohl None\n  let v:warningmsg = a:message\nendfunction\n\nfunction! gitgutter#utility#warn_once(bufnr, message, key) abort\n  if empty(gitgutter#utility#getbufvar(a:bufnr, a:key))\n    call gitgutter#utility#setbufvar(a:bufnr, a:key, '1')\n    echohl WarningMsg\n    redraw | echom a:message\n    echohl None\n    let v:warningmsg = a:message\n  endif\nendfunction\n\n\" Returns truthy when the buffer's file should be processed; and falsey when it shouldn't.\n\" This function does not and should not make any system calls.\nfunction! gitgutter#utility#is_active(bufnr) abort\n  return gitgutter#utility#getbufvar(a:bufnr, 'enabled') &&\n        \\ !pumvisible() &&\n        \\ s:is_file_buffer(a:bufnr) &&\n        \\ s:exists_file(a:bufnr) &&\n        \\ s:not_git_dir(a:bufnr)\nendfunction\n\nfunction! s:not_git_dir(bufnr) abort\n  return gitgutter#utility#dir(a:bufnr) !~ '[/\\\\]\\.git\\($\\|[/\\\\]\\)'\nendfunction\n\nfunction! s:is_file_buffer(bufnr) abort\n  return empty(getbufvar(a:bufnr, '&buftype'))\nendfunction\n\n\" From tpope/vim-fugitive\nfunction! s:winshell()\n  return &shell =~? 'cmd' || exists('+shellslash') && !&shellslash\nendfunction\n\n\" From tpope/vim-fugitive\nfunction! gitgutter#utility#shellescape(arg) abort\n  if a:arg =~ '^[A-Za-z0-9_/.-]\\+$'\n    return a:arg\n  elseif s:winshell()\n    return '\"' . substitute(substitute(a:arg, '\"', '\"\"', 'g'), '%', '\"%\"', 'g') . '\"'\n  else\n    return shellescape(a:arg)\n  endif\nendfunction\n\nfunction! gitgutter#utility#file(bufnr)\n  return s:abs_path(a:bufnr, 1)\nendfunction\n\n\" Not shellescaped\nfunction! gitgutter#utility#extension(bufnr) abort\n  return fnamemodify(s:abs_path(a:bufnr, 0), ':e')\nendfunction\n\nfunction! gitgutter#utility#system(cmd, ...) abort\n  call gitgutter#debug#log(a:cmd, a:000)\n\n  call s:use_known_shell()\n  let prev_error_code = v:shell_error\n  silent let output = (a:0 == 0) ? system(a:cmd) : system(a:cmd, a:1)\n  let error_code = v:shell_error\n  silent call system('exit ' . prev_error_code)\n  call s:restore_shell()\n\n  return [output, error_code]\nendfunction\n\nfunction! gitgutter#utility#has_repo_path(bufnr)\n  return index(['', -1, -2], gitgutter#utility#repo_path(a:bufnr, 0)) == -1\nendfunction\n\n\" Path of file relative to repo root.\n\"\n\" *     empty string - not set\n\" * non-empty string - path\n\" *               -1 - pending\n\" *               -2 - not tracked by git\n\" *               -3 - assume unchanged\nfunction! gitgutter#utility#repo_path(bufnr, shellesc) abort\n  let p = gitgutter#utility#getbufvar(a:bufnr, 'path', '')\n  return a:shellesc ? gitgutter#utility#shellescape(p) : p\nendfunction\n\n\nlet s:set_path_handler = {}\n\nfunction! s:set_path_handler.out(buffer, listing) abort\n  let listing = s:strip_trailing_new_line(a:listing)\n  let [status, path] = [listing[0], listing[2:]]\n  if status =~# '[a-z]'\n    call gitgutter#utility#setbufvar(a:buffer, 'path', -3)\n  else\n    call gitgutter#utility#setbufvar(a:buffer, 'path', path)\n  endif\n\n  if type(self.continuation) == type(function('tr'))\n    call self.continuation()\n  else\n    call call(self.continuation.function, self.continuation.arguments)\n  endif\nendfunction\n\nfunction! s:set_path_handler.err(buffer) abort\n  call gitgutter#utility#setbufvar(a:buffer, 'path', -2)\nendfunction\n\n\n\" continuation - a funcref or hash to call after setting the repo path asynchronously.\n\"\n\" Returns 'async' if the the path is set asynchronously, 0 otherwise.\nfunction! gitgutter#utility#set_repo_path(bufnr, continuation) abort\n  \" Values of path:\n  \" * non-empty string - path\n  \" *               -1 - pending\n  \" *               -2 - not tracked by git\n  \" *               -3 - assume unchanged\n\n  call gitgutter#utility#setbufvar(a:bufnr, 'path', -1)\n  let cmd = gitgutter#git(a:bufnr).' ls-files -v --error-unmatch --full-name -z -- '.\n        \\ gitgutter#utility#shellescape(gitgutter#utility#filename(a:bufnr))\n\n  if g:gitgutter_async && gitgutter#async#available() && !has('vim_starting')\n    let handler = copy(s:set_path_handler)\n    let handler.continuation = a:continuation\n    call gitgutter#async#execute(cmd, a:bufnr, handler)\n    return 'async'\n  endif\n\n  let [listing, error_code] = gitgutter#utility#system(cmd)\n\n  if error_code\n    call gitgutter#utility#setbufvar(a:bufnr, 'path', -2)\n    return\n  endif\n\n  let listing = s:strip_trailing_new_line(listing)\n  let [status, path] = [listing[0], listing[2:]]\n  if status =~# '[a-z]'\n    call gitgutter#utility#setbufvar(a:bufnr, 'path', -3)\n  else\n    call gitgutter#utility#setbufvar(a:bufnr, 'path', path)\n  endif\nendfunction\n\n\nfunction! gitgutter#utility#clean_smudge_filter_applies(bufnr)\n  let filtered = gitgutter#utility#getbufvar(a:bufnr, 'filter', -1)\n  if filtered == -1\n    let cmd = gitgutter#git(a:bufnr).' check-attr filter -- '.\n          \\ gitgutter#utility#shellescape(gitgutter#utility#filename(a:bufnr))\n    let [out, _] = gitgutter#utility#system(cmd)\n    let filtered = out !~ 'unspecified'\n    call gitgutter#utility#setbufvar(a:bufnr, 'filter', filtered)\n  endif\n  return filtered\nendfunction\n\n\nfunction! s:use_known_shell() abort\n  if has('unix') && &shell !=# 'sh'\n    let [s:shell, s:shellcmdflag, s:shellredir, s:shellpipe, s:shellquote, s:shellxquote] = [&shell, &shellcmdflag, &shellredir, &shellpipe, &shellquote, &shellxquote]\n    let &shell = 'sh'\n    set shellcmdflag=-c shellredir=>%s\\ 2>&1\n  endif\n  if has('win32') && (&shell =~# 'pwsh' || &shell =~# 'powershell')\n    let [s:shell, s:shellcmdflag, s:shellredir, s:shellpipe, s:shellquote, s:shellxquote] = [&shell, &shellcmdflag, &shellredir, &shellpipe, &shellquote, &shellxquote]\n    let &shell = 'cmd.exe'\n    set shellcmdflag=/s\\ /c shellredir=>%s\\ 2>&1 shellpipe=>%s\\ 2>&1 shellquote= shellxquote=\"\n  endif\nendfunction\n\nfunction! s:restore_shell() abort\n  if (has('unix') || has('win32')) && exists('s:shell')\n    let [&shell, &shellcmdflag, &shellredir, &shellpipe, &shellquote, &shellxquote] = [s:shell, s:shellcmdflag, s:shellredir, s:shellpipe, s:shellquote, s:shellxquote]\n  endif\nendfunction\n\nfunction! gitgutter#utility#get_diff_base(bufnr)\n  let p = resolve(expand('#'.a:bufnr.':p'))\n  let ml = matchlist(p, '\\v^fugitive:/.*/(\\x{40,})/')\n  if !empty(ml) && !empty(ml[1])\n    return ml[1].'^'\n  endif\n  return g:gitgutter_diff_base\nendfunction\n\n\" Returns the original path (shellescaped) at the buffer's diff base.\nfunction! gitgutter#utility#base_path(bufnr)\n  let diffbase = gitgutter#utility#get_diff_base(a:bufnr)\n\n  \" If we already know the original path at this diff base, return it.\n  let basepath = gitgutter#utility#getbufvar(a:bufnr, 'basepath', '')\n  if !empty(basepath)\n    \" basepath is diffbase:path\n    \" Note that path can also contain colons.\n    \" List destructuring / unpacking where the remaining items are assigned\n    \" to a single variable (:help let-unpack) is only available in v8.2.0540.\n    let parts = split(basepath, ':', 1)\n    let base = parts[0]\n    let bpath = join(parts[1:], ':')\n\n    if base == diffbase\n      return gitgutter#utility#shellescape(bpath)\n    endif\n  endif\n\n  \" Obtain buffers' paths.\n  let current_paths = {}\n  for bufnr in range(1, bufnr('$') + 1)\n    if gitgutter#utility#has_repo_path(bufnr)\n      let current_paths[gitgutter#utility#repo_path(bufnr, 0)] = bufnr\n    endif\n  endfor\n\n  \" Get a list of file renames at the buffer's diff base.\n  \" Store the original paths on any corresponding buffers.\n  \" If the buffer's file was one of them, return its original path.\n  let op = ''\n  let renames = s:obtain_file_renames(a:bufnr, diffbase)\n  for [current, original] in items(renames)\n    if has_key(current_paths, current)\n      let bufnr = current_paths[current]\n      let basepath = diffbase.':'.original\n      call gitgutter#utility#setbufvar(bufnr, 'basepath', basepath)\n\n      if bufnr == a:bufnr\n        let op = original\n      endif\n    endif\n  endfor\n  if !empty(op)\n    return gitgutter#utility#shellescape(op)\n  endif\n\n  \" Buffer's file was not renamed, so store current path and return it.\n  let current_path = gitgutter#utility#repo_path(a:bufnr, 0)\n  let basepath = diffbase.':'.current_path\n  call gitgutter#utility#setbufvar(a:bufnr, 'basepath', basepath)\n  return gitgutter#utility#shellescape(current_path)\nendfunction\n\n\" Returns a dict of current path to original path at the given base.\nfunction! s:obtain_file_renames(bufnr, base)\n  let renames = {}\n  let cmd = gitgutter#git(a:bufnr)\n  if gitgutter#utility#git_supports_command_line_config_override()\n    let cmd .= ' -c \"core.safecrlf=false\"'\n  endif\n  let cmd .= ' diff --diff-filter=R --name-status '.a:base\n  let [out, error_code] = gitgutter#utility#system(cmd)\n  if error_code\n    \" Assume the problem is the diff base.\n    call gitgutter#utility#warn('g:gitgutter_diff_base ('.a:base.') is invalid')\n    return {}\n  endif\n  for line in split(out, '\\n')\n    let fields = split(line)\n    if len(fields) != 3\n      call gitgutter#utility#warn('gitgutter: unable to list renamed files: '.line)\n      return {}\n    endif\n    let [original, current] = fields[1:]\n    let renames[current] = original\n  endfor\n  return renames\nendfunction\n\nfunction! s:abs_path(bufnr, shellesc)\n  let p = expand('#'.a:bufnr.':p')\n  if p =~ '\\v^fugitive:/.*/(\\x{40,})/'\n    let p = FugitiveReal(expand('#'.a:bufnr.':p'))\n  else\n    let p = resolve(p)\n  endif\n  return a:shellesc ? gitgutter#utility#shellescape(p) : p\nendfunction\n\n\" Shellescaped\nfunction! gitgutter#utility#dir(bufnr) abort\n  return gitgutter#utility#shellescape(fnamemodify(s:abs_path(a:bufnr, 0), ':h'))\nendfunction\n\n\" Not shellescaped.\nfunction! gitgutter#utility#filename(bufnr) abort\n  return fnamemodify(s:abs_path(a:bufnr, 0), ':t')\nendfunction\n\nfunction! s:exists_file(bufnr) abort\n  return filereadable(s:abs_path(a:bufnr, 0))\nendfunction\n\n\" Get rid of any trailing new line or SOH character.\n\"\n\" git ls-files -z produces output with null line termination.\n\" Vim's system() replaces any null characters in the output\n\" with SOH (start of header), i.e. ^A.\nfunction! s:strip_trailing_new_line(line) abort\n  return substitute(a:line, '[[:cntrl:]]$', '', '')\nendfunction\n\nfunction! gitgutter#utility#windows()\n  return has('win64') || has('win32') || has('win16')\nendfunction\n"
  },
  {
    "path": "autoload/gitgutter.vim",
    "content": "\" Primary functions {{{\n\nfunction! gitgutter#all(force) abort\n  let visible = tabpagebuflist()\n\n  for bufnr in range(1, bufnr('$') + 1)\n    if buflisted(bufnr)\n      let file = expand('#'.bufnr.':p')\n      if !empty(file)\n        if index(visible, bufnr) != -1\n          call gitgutter#process_buffer(bufnr, a:force)\n        elseif a:force\n          call s:reset_tick(bufnr)\n        endif\n      endif\n    endif\n  endfor\nendfunction\n\n\nfunction! gitgutter#process_buffer(bufnr, force) abort\n  \" NOTE a:bufnr is not necessarily the current buffer.\n\n  if gitgutter#utility#getbufvar(a:bufnr, 'enabled', -1) == -1\n    call gitgutter#utility#setbufvar(a:bufnr, 'enabled', g:gitgutter_enabled)\n  endif\n\n  if gitgutter#utility#is_active(a:bufnr)\n\n    if has('patch-7.4.1559')\n      let l:Callback = function('gitgutter#process_buffer', [a:bufnr, a:force])\n    else\n      let l:Callback = {'function': 'gitgutter#process_buffer', 'arguments': [a:bufnr, a:force]}\n    endif\n    let how = s:setup_path(a:bufnr, l:Callback)\n    if [how] == ['async']  \" avoid string-to-number conversion if how is a number\n      return\n    endif\n\n    if a:force || s:has_fresh_changes(a:bufnr)\n\n      let diff = 'NOT SET'\n      try\n        let diff = gitgutter#diff#run_diff(a:bufnr, g:gitgutter_diff_relative_to)\n      catch /gitgutter not tracked/\n        call gitgutter#debug#log('Not tracked: '.gitgutter#utility#file(a:bufnr))\n      catch /gitgutter assume unchanged/\n        call gitgutter#debug#log('Assume unchanged: '.gitgutter#utility#file(a:bufnr))\n      catch /gitgutter diff failed/\n        call gitgutter#debug#log('Diff failed: '.gitgutter#utility#file(a:bufnr))\n        call gitgutter#hunk#reset(a:bufnr)\n      endtry\n\n      if diff != 'async' && diff != 'NOT SET'\n        call gitgutter#diff#handler(a:bufnr, diff)\n      endif\n\n    endif\n  endif\nendfunction\n\n\nfunction! gitgutter#disable() abort\n  call s:toggle_each_buffer(0)\n  let g:gitgutter_enabled = 0\nendfunction\n\nfunction! gitgutter#enable() abort\n  call s:toggle_each_buffer(1)\n  let g:gitgutter_enabled = 1\nendfunction\n\nfunction s:toggle_each_buffer(enable)\n  for bufnr in range(1, bufnr('$') + 1)\n    if buflisted(bufnr)\n      let file = expand('#'.bufnr.':p')\n      if !empty(file)\n        if a:enable\n          call gitgutter#buffer_enable(bufnr)\n        else\n          call gitgutter#buffer_disable(bufnr)\n        end\n      endif\n    endif\n  endfor\nendfunction\n\nfunction! gitgutter#toggle() abort\n  if g:gitgutter_enabled\n    call gitgutter#disable()\n  else\n    call gitgutter#enable()\n  endif\nendfunction\n\n\nfunction! gitgutter#buffer_disable(...) abort\n  let bufnr = a:0 ? a:1 : bufnr('')\n  call gitgutter#utility#setbufvar(bufnr, 'enabled', 0)\n  call s:clear(bufnr)\nendfunction\n\nfunction! gitgutter#buffer_enable(...) abort\n  let bufnr = a:0 ? a:1 : bufnr('')\n  call gitgutter#utility#setbufvar(bufnr, 'enabled', 1)\n  call gitgutter#process_buffer(bufnr, 1)\nendfunction\n\nfunction! gitgutter#buffer_toggle(...) abort\n  let bufnr = a:0 ? a:1 : bufnr('')\n  if gitgutter#utility#getbufvar(bufnr, 'enabled', 1)\n    call gitgutter#buffer_disable(bufnr)\n  else\n    call gitgutter#buffer_enable(bufnr)\n  endif\nendfunction\n\n\" }}}\n\n\n\" Optional argument is buffer number\nfunction! gitgutter#git(...)\n  let git = g:gitgutter_git_executable\n  if a:0\n    let git .= ' -C '.gitgutter#utility#dir(a:1)\n  endif\n  if empty(g:gitgutter_git_args)\n    return git\n  else\n    return git.' '.g:gitgutter_git_args\n  endif\nendfunction\n\n\nfunction! gitgutter#setup_maps()\n  if !g:gitgutter_map_keys\n    return\n  endif\n\n  \" Note hasmapto() and maparg() operate on the current buffer.\n\n  let bufnr = bufnr('')\n\n  if gitgutter#utility#getbufvar(bufnr, 'mapped', 0)\n    return\n  endif\n\n  if !hasmapto('<Plug>(GitGutterPrevHunk)') && maparg('[c', 'n') ==# ''\n    nmap <buffer> [c <Plug>(GitGutterPrevHunk)\n  endif\n  if !hasmapto('<Plug>(GitGutterNextHunk)') && maparg(']c', 'n') ==# ''\n    nmap <buffer> ]c <Plug>(GitGutterNextHunk)\n  endif\n\n  if !hasmapto('<Plug>(GitGutterStageHunk)', 'v') && maparg('<Leader>hs', 'x') ==# ''\n    xmap <buffer> <Leader>hs <Plug>(GitGutterStageHunk)\n  endif\n  if !hasmapto('<Plug>(GitGutterStageHunk)', 'n') && maparg('<Leader>hs', 'n') ==# ''\n    nmap <buffer> <Leader>hs <Plug>(GitGutterStageHunk)\n  endif\n  if !hasmapto('<Plug>(GitGutterUndoHunk)') && maparg('<Leader>hu', 'n') ==# ''\n    nmap <buffer> <Leader>hu <Plug>(GitGutterUndoHunk)\n  endif\n  if !hasmapto('<Plug>(GitGutterPreviewHunk)') && maparg('<Leader>hp', 'n') ==# ''\n    nmap <buffer> <Leader>hp <Plug>(GitGutterPreviewHunk)\n  endif\n\n  if !hasmapto('<Plug>(GitGutterTextObjectInnerPending)') && maparg('ic', 'o') ==# ''\n    omap <buffer> ic <Plug>(GitGutterTextObjectInnerPending)\n  endif\n  if !hasmapto('<Plug>(GitGutterTextObjectOuterPending)') && maparg('ac', 'o') ==# ''\n    omap <buffer> ac <Plug>(GitGutterTextObjectOuterPending)\n  endif\n  if !hasmapto('<Plug>(GitGutterTextObjectInnerVisual)') && maparg('ic', 'x') ==# ''\n    xmap <buffer> ic <Plug>(GitGutterTextObjectInnerVisual)\n  endif\n  if !hasmapto('<Plug>(GitGutterTextObjectOuterVisual)') && maparg('ac', 'x') ==# ''\n    xmap <buffer> ac <Plug>(GitGutterTextObjectOuterVisual)\n  endif\n\n  call gitgutter#utility#setbufvar(bufnr, 'mapped', 1)\nendfunction\n\nfunction! s:setup_path(bufnr, continuation)\n  if gitgutter#utility#has_repo_path(a:bufnr) | return | endif\n\n  return gitgutter#utility#set_repo_path(a:bufnr, a:continuation)\nendfunction\n\nfunction! s:has_fresh_changes(bufnr) abort\n  return getbufvar(a:bufnr, 'changedtick') != gitgutter#utility#getbufvar(a:bufnr, 'tick')\nendfunction\n\nfunction! s:reset_tick(bufnr) abort\n  call gitgutter#utility#setbufvar(a:bufnr, 'tick', 0)\nendfunction\n\nfunction! s:clear(bufnr)\n  call gitgutter#sign#clear_signs(a:bufnr)\n  call gitgutter#hunk#reset(a:bufnr)\n  call s:reset_tick(a:bufnr)\n  call gitgutter#utility#setbufvar(a:bufnr, 'path', '')\n  call gitgutter#utility#setbufvar(a:bufnr, 'basepath', '')\nendfunction\n\n\n\" Note:\n\" - this runs synchronously\n\" - it ignores unsaved changes in buffers\n\" - it does not change to the repo root\nfunction! gitgutter#quickfix(current_file)\n  let cmd = gitgutter#git().' rev-parse --show-cdup'\n  let path_to_repo = get(systemlist(cmd), 0, '')\n  if !empty(path_to_repo) && path_to_repo[-1:] != '/'\n    let path_to_repo .= '/'\n  endif\n\n  let locations = []\n  let cmd = gitgutter#git().' --no-pager'.\n        \\ ' diff --no-ext-diff --no-color -U0'.\n        \\ ' --src-prefix=a/'.path_to_repo.' --dst-prefix=b/'.path_to_repo.' '.\n        \\ g:gitgutter_diff_args. ' '. g:gitgutter_diff_base\n  if a:current_file\n    let cmd = cmd.' -- '.expand('%:p')\n  endif\n  let diff = systemlist(cmd)\n  let lnum = 0\n  for line in diff\n    if line =~ '^diff --git [^\"]'\n      \" No quotation mark therefore no spaces in filenames\n      let [fnamel, fnamer] = split(line)[2:3]\n      let fname = fnamel ==# fnamer ? fnamer : fnamer[2:]\n    elseif line =~ '^diff --git \"'\n      \" Quotation mark therefore do not split on space\n      let [_, fnamel, _, fnamer] = split(line, '\"')\n      let fname = fnamel ==# fnamer ? fnamer : fnamer[2:]\n    elseif line =~ '^diff --cc [^\"]'\n      let fname = line[10:]\n    elseif line =~ '^diff --cc \"'\n      let [_, fname] = split(line, '\"')\n    elseif line =~ '^@@'\n      let lnum = matchlist(line, '+\\(\\d\\+\\)')[1]\n    elseif lnum > 0\n      call add(locations, {'filename': fname, 'lnum': lnum, 'text': line})\n      let lnum = 0\n    endif\n  endfor\n  if !g:gitgutter_use_location_list\n    call setqflist(locations)\n  else\n    call setloclist(0, locations)\n  endif\nendfunction\n\n\nfunction! gitgutter#difforig()\n  let bufnr = bufnr('')\n  let filetype = &filetype\n\n  vertical new\n  set buftype=nofile\n  if v:version >= 800\n     setlocal bufhidden=wipe\n  endif\n  setlocal noswapfile\n  let &filetype = filetype\n\n  if g:gitgutter_diff_relative_to ==# 'index'\n    let index_name = gitgutter#utility#get_diff_base(bufnr).':'.gitgutter#utility#base_path(bufnr)\n    let cmd = gitgutter#git(bufnr).' --no-pager show '.index_name\n    \" NOTE: this uses &shell to execute cmd.  Perhaps we should use instead\n    \" gitgutter#utility's use_known_shell() / restore_shell() functions.\n    silent! execute \"read ++edit !\" cmd\n  else\n    silent! execute \"read ++edit\" gitgutter#utility#repo_path(bufnr, 1)\n  endif\n\n  0d_\n  diffthis\n  setlocal nomodifiable\n  wincmd p\n  diffthis\nendfunction\n"
  },
  {
    "path": "doc/gitgutter.txt",
    "content": "*gitgutter.txt*              A Vim plugin which shows a git diff in the gutter.\n\n\n                           Vim GitGutter\n\n\nAuthor:            Andy Stewart <https://airbladesoftware.com/>\nPlugin Homepage:   <https://github.com/airblade/vim-gitgutter>\n\n\n===============================================================================\nCONTENTS                                                            *gitgutter*\n\n  Introduction ................. |gitgutter-introduction|\n  Installation ................. |gitgutter-installation|\n  Windows      ................. |gitgutter-windows|\n  Commands ..................... |gitgutter-commands|\n  Mappings ..................... |gitgutter-mappings|\n  Autocommand .................. |gitgutter-autocommand|\n  Status line .................. |gitgutter-statusline|\n  Options ...................... |gitgutter-options|\n  Highlights ................... |gitgutter-highlights|\n  FAQ .......................... |gitgutter-faq|\n  TROUBLESHOOTING .............. |gitgutter-troubleshooting|\n\n\n===============================================================================\nINTRODUCTION                                           *gitgutter-introduction*\n\nGitGutter is a Vim plugin which shows a git diff in the sign column.\nIt shows which lines have been added, modified, or removed.  You can also\npreview, stage, and undo individual hunks.  The plugin also provides a hunk\ntext object.\n\nThe signs are always up to date and the plugin never saves your buffer.\n\nThe name \"gitgutter\" comes from the Sublime Text 3 plugin which inspired this\none in 2013.\n\n\n===============================================================================\nINSTALLATION                                           *gitgutter-installation*\n\nFirst, use your favourite package manager, or use Vim's built-in package\nsupport.\n\nVim:~\n>\n  mkdir -p ~/.vim/pack/airblade/start\n  cd ~/.vim/pack/airblade/start\n  git clone https://github.com/airblade/vim-gitgutter.git\n  vim -u NONE -c \"helptags vim-gitgutter/doc\" -c q\n<\n\nNeovim:~\n>\n  mkdir -p ~/.config/nvim/pack/airblade/start\n  cd ~/.config/nvim/pack/airblade/start\n  git clone https://github.com/airblade/vim-gitgutter.git\n  nvim -u NONE -c \"helptags vim-gitgutter/doc\" -c q\n<\n\nSecond, ensure your 'updatetime' and 'signcolumn' options are set appropriately.\n\nWhen you make a change to a file tracked by git, the diff markers should\nappear automatically after a short delay.  The delay is governed by vim's\n'updatetime' option; the default value is `4000`, i.e. 4 seconds, but I\nsuggest reducing it to around 100ms (add `set updatetime=100` to your vimrc).\nNote 'updatetime' also controls the delay before vim writes its swap file.\n\nThe 'signcolumn' option can have any value except \"off\".\n\n\n===============================================================================\nWINDOWS                                                     *gitgutter-windows*\n\nThere is a potential risk on Windows due to `cmd.exe` prioritising the current\nfolder over folders in `PATH`.  If you have a file named `git.*` (i.e. with\nany extension in `PATHEXT`) in your current folder, it will be executed\ninstead of git whenever the plugin calls git.\n\nYou can avoid this risk by configuring the full path to your git executable.\nFor example:\n>\n    \" This path probably won't work\n    let g:gitgutter_git_executable = 'C:\\Program Files\\Git\\bin\\git.exe'\n<\n\nUnfortunately I don't know the correct escaping for the path - if you do,\nplease let me know!\n\n\n===============================================================================\nCOMMANDS                                                   *gitgutter-commands*\n\nCommands for turning vim-gitgutter on and off:~\n\n                                                  *gitgutter-:GitGutterDisable*\n:GitGutterDisable       Turn vim-gitgutter off for all buffers.\n\n                                                   *gitgutter-:GitGutterEnable*\n:GitGutterEnable        Turn vim-gitgutter on for all buffers.\n\n                                                   *gitgutter-:GitGutterToggle*\n:GitGutterToggle        Toggle vim-gitgutter on or off for all buffers.\n\n                                            *gitgutter-:GitGutterBufferDisable*\n:GitGutterBufferDisable Turn vim-gitgutter off for current buffer.\n\n                                             *gitgutter-:GitGutterBufferEnable*\n:GitGutterBufferEnable  Turn vim-gitgutter on for current buffer.\n\n                                             *gitgutter-:GitGutterBufferToggle*\n:GitGutterBufferToggle  Toggle vim-gitgutter on or off for current buffer.\n\n                                                         *gitgutter-:GitGutter*\n:GitGutter              Update signs for the current buffer.  You shouldn't\n                        need to run this.\n\n                                                      *gitgutter-:GitGutterAll*\n:GitGutterAll           Update signs for all buffers.  You shouldn't need to\n                        run this.\n\n\nCommands for turning signs on and off (defaults to on):~\n\n                                              *gitgutter-:GitGutterSignsEnable*\n:GitGutterSignsEnable   Show signs for the diff.\n\n                                             *gitgutter-:GitGutterSignsDisable*\n:GitGutterSignsDisable  Do not show signs for the diff.\n\n                                              *gitgutter-:GitGutterSignsToggle*\n:GitGutterSignsToggle   Toggle signs on or off.\n\n\nCommands for turning line highlighting on and off (defaults to off):~\n\n                                     *gitgutter-:GitGutterLineHighlightsEnable*\n:GitGutterLineHighlightsEnable  Turn on line highlighting.\n\n                                    *gitgutter-:GitGutterLineHighlightsDisable*\n:GitGutterLineHighlightsDisable Turn off line highlighting.\n\n                                     *gitgutter-:GitGutterLineHighlightsToggle*\n:GitGutterLineHighlightsToggle  Turn line highlighting on or off.\n\n\nCommands for turning line number highlighting on and off (defaults to off):~\nNOTE: This feature requires Neovim 0.3.2 or higher.\n\n                                   *gitgutter-:GitGutterLineNrHighlightsEnable*\n:GitGutterLineNrHighlightsEnable  Turn on line highlighting.\n\n                                  *gitgutter-:GitGutterLineNrHighlightsDisable*\n:GitGutterLineNrHighlightsDisable Turn off line highlighting.\n\n                                   *gitgutter-:GitGutterLineNrHighlightsToggle*\n:GitGutterLineNrHighlightsToggle  Turn line highlighting on or off.\n\n\nCommands for jumping between hunks:~\n\n                                                 *gitgutter-:GitGutterNextHunk*\n:GitGutterNextHunk      Jump to the next [count] hunk.\n\n                                                 *gitgutter-:GitGutterPrevHunk*\n:GitGutterPrevHunk      Jump to the previous [count] hunk.\n\n                                                 *gitgutter-:GitGutterQuickFix*\n:GitGutterQuickFix      Load all hunks into the |quickfix| list.  Note this\n                        ignores any unsaved changes in your buffers. The\n                        |g:gitgutter_use_location_list| option can be set to\n                        populate the location list of the current window\n                        instead.  Use |:copen| (or |:lopen|) to open a buffer\n                        containing the search results in linked form; or add a\n                        custom command like this:\n>\n                          command! Gqf GitGutterQuickFix | copen\n<\n                                                 *gitgutter-:GitGutterQuickFixCurrentFile*\n:GitGutterQuickFixCurrentFile     Same as :GitGutterQuickFix, but only load hunks for\n                                  the file in the focused buffer. This has the same\n                                  functionality as :GitGutterQuickFix when the focused\n                                  buffer is empty.\n\n\nCommands for operating on a hunk:~\n\n                                                *gitgutter-:GitGutterStageHunk*\n:GitGutterStageHunk     Stage the hunk the cursor is in.  Use a visual selection\n                        to stage part of an (additions-only) hunk; or use a\n                        range.\n\n                        To stage part of any hunk, first |GitGutterPreviewHunk|\n                        it, then move to the preview window, delete the lines\n                        you do not want to stage, and |write| or\n                        |GitGutterStageHunk|.\n\n                                                 *gitgutter-:GitGutterUndoHunk*\n:GitGutterUndoHunk      Undo the hunk the cursor is in.\n\n                                              *gitgutter-:GitGutterPreviewHunk*\n:GitGutterPreviewHunk   Preview the hunk the cursor is in or, if you are using\n                        floating preview windows in Neovim and the window is\n                        already open, move the cursor into the window.\n\n                        To stage part of the hunk, move to the preview window,\n                        delete any lines you do not want to stage, and |write|\n                        or |GitGutterStageHunk|.\n\n                        To close a non-floating preview window use |:pclose|\n                        or |CTRL-W_z| or |CTRL-W_CTRL-Z|; or normal window-\n                        closing (|:quit| or |:close| or |CTRL-W_c|) if your cursor\n                        is in the preview window.\n\n                        To close a floating window when the cursor is in the\n                        original buffer, move the cursor.\n\n                        To close a floating window when the cursor is in the\n                        floating window use normal window-closing, or move to\n                        the original window with |CTRL-W_p|.  Alternatively set\n                        |g:gitgutter_close_preview_on_escape| and use <Esc>.\n\n                        Two functions are available for your own logic:\n>\n                          gitgutter#hunk#is_preview_window_open()\n                          gitgutter#hunk#close_hunk_preview_window()\n<\n\nCommands for folds:~\n\n                                                     *gitgutter-:GitGutterFold*\n:GitGutterFold          Fold all unchanged lines.  Execute again to undo.\n\n\nOther commands:~\n\n                                                 *gitgutter-:GitGutterDiffOrig*\n:GitGutterDiffOrig      Similar to |:DiffOrig| but shows gitgutter's diff.\n\n\n===============================================================================\nAUTOCOMMANDS                                           *gitgutter-autocommands*\n\nUser GitGutter~\n\nAfter updating a buffer's signs vim-gitgutter fires a |User| |autocmd| with the\nevent GitGutter.  You can listen for this event, for example:\n>\n  autocmd User GitGutter call updateMyStatusLine()\n<\nA dictionary `g:gitgutter_hook_context` is made available during its execution,\nwhich contains an entry `bufnr` that contains the buffer number being updated.\n\nUser GitGutterStage~\n\nAfter staging a hunk or part of a hunk vim-gitgutter fires a |User| |autocmd|\nwith the event GitGutterStage.  Staging always happens in the current buffer.\n\n===============================================================================\nMAPPINGS                                                   *gitgutter-mappings*\n\nYou can disable all these mappings with:\n>\n    let g:gitgutter_map_keys = 0\n<\n\nHunk operations:~\n\nThese can be repeated with `.` if you have vim-repeat installed.\n\n                                                         *gitgutter-<Leader>hp*\n<Leader>hp              Preview the hunk under the cursor.\n\n                                                         *gitgutter-<Leader>hs*\n<Leader>hs              Stage the hunk under the cursor.\n\n                                                         *gitgutter-<Leader>hu*\n<Leader>hu              Undo the hunk under the cursor.\n\nYou can change these mappings like this:\n>\n    nmap ghp <Plug>(GitGutterPreviewHunk)\n    nmap ghs <Plug>(GitGutterStageHunk)\n    nmap ghu <Plug>(GitGutterUndoHunk)\n<\n\nHunk jumping:~\n\n                                                                 *gitgutter-]c*\n]c                      Jump to the next [count] hunk.\n\n                                                                 *gitgutter-[c*\n[c                      Jump to the previous [count] hunk.\n\nYou can change these mappings like this:\n>\n    nmap [c <Plug>(GitGutterPrevHunk)\n    nmap ]c <Plug>(GitGutterNextHunk)\n<\n\nHunk text object:~\n\n                          *gitgutter-ic* *gitgutter-ac* *gitgutter-text-object*\n\"ic\" operates on the current hunk's lines.  \"ac\" does the same but also includes\ntrailing empty lines.\n>\n    omap ic <Plug>(GitGutterTextObjectInnerPending)\n    omap ac <Plug>(GitGutterTextObjectOuterPending)\n    xmap ic <Plug>(GitGutterTextObjectInnerVisual)\n    xmap ac <Plug>(GitGutterTextObjectOuterVisual)\n<\n\n\n===============================================================================\nSTATUS LINE                                              *gitgutter-statusline*\n\n\nCall the `GitGutterGetHunkSummary()` function from your status line to get a\nlist of counts of added, modified, and removed lines in the current buffer.\nFor example:\n>\n    \" Your vimrc\n    function! GitStatus()\n      let [a,m,r] = GitGutterGetHunkSummary()\n      return printf('+%d ~%d -%d', a, m, r)\n    endfunction\n    set statusline+=%{GitStatus()}\n<\n\n\n===============================================================================\nOPTIONS                                                     *gitgutter-options*\n\nThe most important option is 'updatetime' which determines how long (in\nmilliseconds) the plugin will wait after you stop typing before it updates the\nsigns.  Vim's default is 4000.  I recommend 100.  Note this also controls how\nlong vim waits before writing its swap file.\n\nMost important option:~\n\n    'updatetime'\n\nGit:~\n\n    |g:gitgutter_git_executable|\n    |g:gitgutter_git_args|\n    |g:gitgutter_diff_args|\n    |g:gitgutter_diff_relative_to|\n    |g:gitgutter_diff_base|\n\nSigns:~\n\n    |g:gitgutter_signs|\n    |g:gitgutter_highlight_lines|\n    |g:gitgutter_highlight_linenrs|\n    |g:gitgutter_max_signs|\n    |g:gitgutter_sign_priority|\n    |g:gitgutter_sign_allow_clobber|\n    |g:gitgutter_sign_added|\n    |g:gitgutter_sign_modified|\n    |g:gitgutter_sign_removed|\n    |g:gitgutter_sign_removed_first_line|\n    |g:gitgutter_sign_modified_removed|\n    |g:gitgutter_set_sign_backgrounds|\n\nHunk jumping:~\n\n    |g:gitgutter_show_msg_on_hunk_jumping|\n\nHunk previews:~\n\n    |g:gitgutter_preview_win_floating|\n    |g:gitgutter_floating_window_options|\n    |g:gitgutter_close_preview_on_escape|\n\nTerminal:~\n\n    |g:gitgutter_terminal_reports_focus|\n\nGeneral:~\n\n    |g:gitgutter_enabled|\n    |g:gitgutter_map_keys|\n    |g:gitgutter_async|\n    |g:gitgutter_log|\n    |g:gitgutter_use_location_list|\n\n\n                                             *g:gitgutter_preview_win_location*\nDefault: 'bo'\n\nThis option determines where the preview window pops up as a result of the\n:GitGutterPreviewHunk command. Other plausible values are 'to', 'bel', 'abo'.\nSee the end of the |opening-window| docs.\n\n                                                   *g:gitgutter_git_executable*\nDefault: 'git'\n\nThis option determines what git binary to use.  Set this if git is not on your\npath.\n\n                                                         *g:gitgutter_git_args*\nDefault: empty\n\nUse this option to pass any extra arguments to git when running git-diff.\nFor example:\n>\n    let g:gitgutter_git_args = '--git-dir=\"\"'\n<\n\n                                                        *g:gitgutter_diff_args*\nDefault: empty\n\nUse this option to pass any extra arguments to git-diff.  For example:\n>\n    let g:gitgutter_diff_args = '-w'\n<\n\n                                                 *g:gitgutter_diff_relative_to*\nDefault: empty\n\nBy default buffers are diffed against the index.  Use this option to diff against\nthe working tree.  For example:\n>\n    let g:gitgutter_diff_relative_to = 'working_tree'\n<\n\n                                                        *g:gitgutter_diff_base*\nDefault: empty\n\nBy default buffers are diffed against the index.  Use this option to diff against\na revision instead.  For example:\n>\n    let g:gitgutter_diff_base = '<some commit SHA>'\n<\n\nIf you are looking at a previous version of a file with Fugitive (e.g.\nvia :0Gclog), gitgutter sets the diff base to the parent of the current revision.\n\nThis setting is ignore when the diff is relative to the working tree\n(|g:gitgutter_diff_relative_to|).\n\n                                                            *g:gitgutter_signs*\nDefault: 1\n\nDetermines whether or not to show signs.\n\n                                                  *g:gitgutter_highlight_lines*\nDefault: 0\n\nDetermines whether or not to show line highlights.\n\n                                                *g:gitgutter_highlight_linenrs*\nDefault: 0\n\nDetermines whether or not to show line number highlights.\n\n                                                        *g:gitgutter_max_signs*\nDefault: 500 (Vim < 8.1.0614, Neovim < 0.4.0)\n          -1 (otherwise)\n\nSets the maximum number of signs to show in a buffer.  Vim is slow at updating\nsigns, so to avoid slowing down the GUI the number of signs is capped.  When\nthe number of changed lines exceeds this value, the plugin removes all signs\nand displays a warning message.\n\nWhen set to -1 the limit is not applied.\n\n                                                   *g:gitgutter_sign_priority*\nDefault: 10\n\nSets the |sign-priority| gitgutter assigns to its signs.\n\n                                               *g:gitgutter_sign_allow_clobber*\nDefault: 0 (Vim < 8.1.0614, Neovim < 0.4.0)\n         1 (otherwise)\n\nDetermines whether gitgutter preserves non-gitgutter signs. When 1, gitgutter\nwill not preserve non-gitgutter signs.\n\n                                          *g:gitgutter_sign_added*\n                                          *g:gitgutter_sign_modified*\n                                          *g:gitgutter_sign_removed*\n                                          *g:gitgutter_sign_removed_first_line*\n                                          *g:gitgutter_sign_removed_above_and_below*\n                                          *g:gitgutter_sign_modified_removed*\nDefaults:\n>\n    let g:gitgutter_sign_added              = '+'\n    let g:gitgutter_sign_modified           = '~'\n    let g:gitgutter_sign_removed            = '_'\n    let g:gitgutter_sign_removed_first_line = '‾'\n    let g:gitgutter_sign_removed_above_and_below = '_¯'\n    let g:gitgutter_sign_modified_removed   = '~_'\n<\nYou can use unicode characters but not images.  Signs must not take up more than\n2 columns.\n\n                                              *g:gitgutter_set_sign_backgrounds*\nDefault: 0\n\nOnly applies to existing GitGutter* highlight groups.  See\n|gitgutter-highlights|.\n\nControls whether to override the signs' background colours to match the\n|hl-SignColumn|.\n\n                                             *g:gitgutter_preview_win_floating*\nDefault: 0 (Vim)\n         0 (NeoVim which does not support floating windows)\n         1 (NeoVim which does support floating windows)\n\nWhether to use floating/popup windows for hunk previews.  Note that if you use\npopup windows on Vim you will not be able to stage partial hunks via the\npreview window.\n\n                                          *g:gitgutter_floating_window_options*\nDefault:\n>\n    \" Vim\n    {\n        \\ 'line': 'cursor+1',\n        \\ 'col': 'cursor',\n        \\ 'moved': 'any'\n    }\n\n    \" Neovim\n    {\n        \\ 'relative': 'cursor',\n        \\ 'row': 1,\n        \\ 'col': 0,\n        \\ 'width': 42,\n        \\ 'height': &previewheight,\n        \\ 'style': 'minimal'\n    }\n<\nThis dictionary is passed directly to |popup_create()| (Vim) or\n|nvim_open_win()| (Neovim).\n\nIf you simply want to override one or two of the default values, create a file\nin an after/ directory.  For example:\n>\n    \" ~/.vim/after/vim-gitgutter/overrides.vim\n    let g:gitgutter_floating_window_options['border'] = 'single'\n<\n\n                                          *g:gitgutter_close_preview_on_escape*\nDefault: 0\n\nWhether pressing <Esc> in a preview window closes it.\n\n                                           *g:gitgutter_terminal_reports_focus*\nDefault: 1\n\nNormally the plugin uses |FocusGained| to force-update all buffers when Vim\nreceives focus.  However some terminals do not report focus events and so the\n|FocusGained| autocommand never fires.\n\nIf this applies to you, either install something like Terminus\n(https://github.com/wincent/terminus) to make |FocusGained| work or set this\noption to 0.\n\nIf you use tmux, try this in your tmux.conf:\n>\n    set -g focus-events on\n<\n\nWhen this option is 0, the plugin force-updates the buffer on |BufEnter|\n(instead of only updating if the buffer's contents has changed since the last\nupdate).\n\n                                                          *g:gitgutter_enabled*\nDefault: 1\n\nControls whether or not the plugin is on at startup.\n\n                                                         *g:gitgutter_map_keys*\nDefault: 1\n\nControls whether or not the plugin provides mappings.  See |gitgutter-mappings|.\n\n                                                            *g:gitgutter_async*\nDefault: 1\n\nControls whether or not diffs are run in the background.  This has no effect if\nyour Vim does not support background jobs.\n\n                                                              *g:gitgutter_log*\nDefault: 0\n\nWhen switched on, the plugin logs to gitgutter.log in the directory where it is\ninstalled.  Additionally it logs channel activity to channel.log.\n\n                                                *g:gitgutter_use_location_list*\nDefault: 0\n\nWhen switched on, the :GitGutterQuickFix command populates the location list\nof the current window instead of the global quickfix list.\n\n                                         *g:gitgutter_show_msg_on_hunk_jumping*\nDefault: 1\n\nWhen switched on, a message like \"Hunk 4 of 11\" is shown on hunk jumping.\n\n\n===============================================================================\nHIGHLIGHTS                                               *gitgutter-highlights*\n\nTo change the signs' colours, specify these highlight groups in your |vimrc|:\n>\n    highlight GitGutterAdd    guifg=#009900 ctermfg=2\n    highlight GitGutterChange guifg=#bbbb00 ctermfg=3\n    highlight GitGutterDelete guifg=#ff2222 ctermfg=1\n<\n\nSee |highlight-guifg| and |highlight-ctermfg| for the values you can use.\n\nIf you do not like the signs' background colours and you do not want to update\nthe GitGutter* highlight groups yourself, you can get the plugin to do it\n|g:gitgutter_set_sign_backgrounds|.\n\nTo change the line highlights, set up the following highlight groups in your\ncolorscheme or |vimrc|:\n>\n    GitGutterAddLine          \" default: links to DiffAdd\n    GitGutterChangeLine       \" default: links to DiffChange\n    GitGutterDeleteLine       \" default: links to DiffDelete\n    GitGutterChangeDeleteLine \" default: links to GitGutterChangeLine\n<\n\nFor example, to use |hl-DiffText| instead of |hl-DiffChange|:\n>\n    highlight link GitGutterChangeLine DiffText\n<\nTo change the line number highlights, set up the following highlight groups in\nyour colorscheme or |vimrc|:\n>\n    GitGutterAddLineNr          \" default: links to CursorLineNr\n    GitGutterChangeLineNr       \" default: links to CursorLineNr\n    GitGutterDeleteLineNr       \" default: links to CursorLineNr\n    GitGutterChangeDeleteLineNr \" default: links to GitGutterChangeLineNr\n<\nFor example, to use |hl-Underlined| instead of |hl-CursorLineNr|:\n>\n    highlight link GitGutterChangeLineNr Underlined\n<\nTo change the diff syntax colours used in the preview window, set up the diff*\nhighlight groups in your colorscheme or |vimrc|:\n>\n    diffAdded   \" if not set: use GitGutterAdd's foreground colour\n    diffChanged \" if not set: use GitGutterChange's foreground colour\n    diffRemoved \" if not set: use GitGutterDelete's foreground colour\n<\nNote the diff* highlight groups are used in any buffer whose 'syntax' is\n\"diff\".\n\nTo change the intra-line diff highlights used in the preview window, set up\nthe following highlight groups in your colorscheme or |vimrc|:\n>\n    GitGutterAddIntraLine    \" default: gui=reverse cterm=reverse\n    GitGutterDeleteIntraLine \" default: gui=reverse cterm=reverse\n<\nFor example, to use |hl-DiffAdd| for intra-line added regions:\n>\n    highlight link GitGutterAddIntraLine DiffAdd\n<\n\n\n===============================================================================\nFAQ                                                             *gitgutter-faq*\n\na. How do I turn off realtime updates?\n\n  Add this to your vim configuration in an |after-directory|:\n>\n    autocmd! gitgutter CursorHold,CursorHoldI\n<\n\nb. I turned off realtime updates, how can I have signs updated when I save a\n   file?\n\n  If you really want to update the signs when you save a file, add this to your\n  |vimrc|:\n>\n    autocmd BufWritePost * GitGutter\n<\n\nc. Why can't I unstage staged changes?\n\n  This plugin is for showing changes between the working tree and the index\n  (and staging/undoing those changes). Unstaging a staged hunk would require\n  showing changes between the index and HEAD, which is out of scope.\n\nd. Why are the colours in the sign column weird?\n\n  Your colorscheme is configuring the |hl-SignColumn| highlight group weirdly.\n  Here are two ways you could change the colours:\n>\n    highlight! link SignColumn LineNr\n    highlight SignColumn guibg=whatever ctermbg=whatever\n<\n\ne. What happens if I also use another plugin which uses signs (e.g. Syntastic)?\n\n  Vim only allows one sign per line.  Vim-gitgutter will not interfere with\n  signs it did not add.\n\n\n===============================================================================\nTROUBLESHOOTING                                     *gitgutter-troubleshooting*\n\nWhen no signs are showing at all:~\n\n1. Verify git is on your path:\n>\n    :echo system('git --version')\n<\n\n2. Verify your git config is compatible with the version of git return by the\n   command above.\n\n3. Verify your Vim supports signs.  The following should give 1:\n>\n    :echo has('signs')\n<\n\n4. Check whether the plugin thinks git knows about your file:\n>\n    :echo b:gitgutter.path\n<\n  If the result is -2, the plugin thinks your file is not tracked by git.\n\n5. Check whether the signs have been placed:\n>\n    :sign place group=gitgutter\n<\n  If you see a list of signs, this is a colorscheme / highlight problem.\n  Compare these two highlight values:\n>\n    :highlight GitGutterAdd\n    :highlight SignColumn\n<\n  If no signs are listed, the call to git-diff is probably failing.  Turn on\n  logging by adding the following to your vimrc, restart, reproduce the problem,\n  and examing the gitgutter.log file in the plugin's directory.\n>\n    let g:gitgutter_log = 1\n<\n\nWhen the whole file is marked as added:~\n\nIf you use zsh, and you set \"CDPATH\", make sure \"CDPATH\" does not include the\ncurrent directory.\n\n\nWhen signs take a few seconds to appear:~\n\nTry reducing 'updatetime':\n>\n    set updatetime=100\n<\n\nNote this also controls how long vim waits before writing its swap file.\n\n\nWhen signs don't update after focusing Vim:~\n\nYour terminal probably isn't reporting focus events.  Either try installing\nTerminus (https://github.com/wincent/terminus) or set:\n>\n    let g:gitgutter_terminal_reports_focus = 0\n<\n\n  vim:tw=78:et:ft=help:norl:\n"
  },
  {
    "path": "plugin/gitgutter.vim",
    "content": "scriptencoding utf-8\n\nif exists('g:loaded_gitgutter') || !has('signs') || &cp\n  finish\nendif\nlet g:loaded_gitgutter = 1\n\n\" Initialisation {{{\n\nif v:version < 703 || (v:version == 703 && !has(\"patch105\"))\n  call gitgutter#utility#warn('Requires Vim 7.3.105')\n  finish\nendif\n\nlet s:nomodeline = (v:version > 703 || (v:version == 703 && has('patch442'))) ? '<nomodeline>' : ''\n\nfunction! s:obsolete(var)\n  if exists(a:var)\n    call gitgutter#utility#warn(a:var.' is obsolete and has no effect.')\n  endif\nendfunction\n\n\nlet g:gitgutter_preview_win_location = get(g:, 'gitgutter_preview_win_location', 'bo')\nif exists('*nvim_open_win')\n  let g:gitgutter_preview_win_floating = get(g:, 'gitgutter_preview_win_floating', 1)\n  let g:gitgutter_floating_window_options = get(g:, 'gitgutter_floating_window_options', {\n        \\ 'relative': 'cursor',\n        \\ 'row': 1,\n        \\ 'col': 0,\n        \\ 'width': 42,\n        \\ 'height': &previewheight,\n        \\ 'style': 'minimal'\n        \\ })\nelse\n  let default = exists('&previewpopup') ? !empty(&previewpopup) : 0\n  let g:gitgutter_preview_win_floating = get(g:, 'gitgutter_preview_win_floating', default)\n  let g:gitgutter_floating_window_options = get(g:, 'gitgutter_floating_window_options', {\n        \\ 'line': 'cursor+1',\n        \\ 'col': 'cursor',\n        \\ 'moved': 'any'\n        \\ })\nendif\nlet g:gitgutter_enabled = get(g:, 'gitgutter_enabled', 1)\nif exists('*sign_unplace')\n  let g:gitgutter_max_signs = get(g:, 'gitgutter_max_signs', -1)\nelse\n  let g:gitgutter_max_signs = get(g:, 'gitgutter_max_signs', 500)\nendif\nlet g:gitgutter_signs             = get(g:, 'gitgutter_signs', 1)\nlet g:gitgutter_highlight_lines   = get(g:, 'gitgutter_highlight_lines', 0)\nlet g:gitgutter_highlight_linenrs = get(g:, 'gitgutter_highlight_linenrs', 0)\nlet g:gitgutter_sign_priority     = get(g:, 'gitgutter_sign_priority', 10)\n\" Nvim 0.4.0 has an expanding sign column\n\" The sign_place() function supports sign priority.\nif (has('nvim-0.4.0') || exists('*sign_place')) && !exists('g:gitgutter_sign_allow_clobber')\n  let g:gitgutter_sign_allow_clobber = 1\nendif\nlet g:gitgutter_sign_allow_clobber   = get(g:, 'gitgutter_sign_allow_clobber', 0)\nlet g:gitgutter_set_sign_backgrounds = get(g:, 'gitgutter_set_sign_backgrounds', 0)\nlet g:gitgutter_sign_added           = get(g:, 'gitgutter_sign_added', '+')\nlet g:gitgutter_sign_modified        = get(g:, 'gitgutter_sign_modified', '~')\nlet g:gitgutter_sign_removed         = get(g:, 'gitgutter_sign_removed', '_')\n\nif gitgutter#utility#supports_overscore_sign()\n  let g:gitgutter_sign_removed_first_line = get(g:, 'gitgutter_sign_removed_first_line', '‾')\nelse\n  let g:gitgutter_sign_removed_first_line = get(g:, 'gitgutter_sign_removed_first_line', '_^')\nendif\n\nlet g:gitgutter_sign_removed_above_and_below = get(g:, 'gitgutter_sign_removed_above_and_below', '_¯')\nlet g:gitgutter_sign_modified_removed        = get(g:, 'gitgutter_sign_modified_removed', '~_')\nlet g:gitgutter_git_args                     = get(g:, 'gitgutter_git_args', '')\nlet g:gitgutter_diff_relative_to             = get(g:, 'gitgutter_diff_relative_to', 'index')\nlet g:gitgutter_diff_args                    = get(g:, 'gitgutter_diff_args', '')\nlet g:gitgutter_diff_base                    = get(g:, 'gitgutter_diff_base', '')\nlet g:gitgutter_map_keys                     = get(g:, 'gitgutter_map_keys', 1)\nlet g:gitgutter_terminal_reports_focus       = get(g:, 'gitgutter_terminal_reports_focus', 1)\nlet g:gitgutter_async                        = get(g:, 'gitgutter_async', 1)\nlet g:gitgutter_log                          = get(g:, 'gitgutter_log', 0)\nlet g:gitgutter_use_location_list            = get(g:, 'gitgutter_use_location_list', 0)\nlet g:gitgutter_close_preview_on_escape      = get(g:, 'gitgutter_close_preview_on_escape', 0)\nlet g:gitgutter_show_msg_on_hunk_jumping     = get(g:, 'gitgutter_show_msg_on_hunk_jumping', 1)\n\nlet g:gitgutter_git_executable = get(g:, 'gitgutter_git_executable', 'git')\nif !executable(g:gitgutter_git_executable)\n  if g:gitgutter_enabled\n    call gitgutter#utility#warn('Cannot find git. Please set g:gitgutter_git_executable.')\n  endif\n  finish\nendif\n\nif exists('g:gitgutter_grep')\n  call gitgutter#utility#warn('g:gitgutter_grep is obsolete')\nendif\n\ncall gitgutter#highlight#define_highlights()\ncall gitgutter#highlight#define_signs()\n\n\" Prevent infinite loop where:\n\" - executing a job in the foreground launches a new window which takes the focus;\n\" - when the job finishes, focus returns to gvim;\n\" - the FocusGained event triggers a new job (see below).\nif gitgutter#utility#windows() && !(g:gitgutter_async && gitgutter#async#available())\n  set noshelltemp\nendif\n\n\" }}}\n\n\" Primary functions {{{\n\ncommand! -bar GitGutterAll call gitgutter#all(1)\ncommand! -bar GitGutter    call gitgutter#process_buffer(bufnr(''), 1)\n\ncommand! -bar GitGutterDisable call gitgutter#disable()\ncommand! -bar GitGutterEnable  call gitgutter#enable()\ncommand! -bar GitGutterToggle  call gitgutter#toggle()\n\ncommand! -bar GitGutterBufferDisable call gitgutter#buffer_disable()\ncommand! -bar GitGutterBufferEnable  call gitgutter#buffer_enable()\ncommand! -bar GitGutterBufferToggle  call gitgutter#buffer_toggle()\n\ncommand! -bar GitGutterQuickFix call gitgutter#quickfix(0)\ncommand! -bar GitGutterQuickFixCurrentFile call gitgutter#quickfix(1)\n\ncommand! -bar GitGutterDiffOrig call gitgutter#difforig()\n\n\" }}}\n\n\" Line highlights {{{\n\ncommand! -bar GitGutterLineHighlightsDisable call gitgutter#highlight#line_disable()\ncommand! -bar GitGutterLineHighlightsEnable  call gitgutter#highlight#line_enable()\ncommand! -bar GitGutterLineHighlightsToggle  call gitgutter#highlight#line_toggle()\n\n\" }}}\n\n\" 'number' column highlights {{{\ncommand! -bar GitGutterLineNrHighlightsDisable call gitgutter#highlight#linenr_disable()\ncommand! -bar GitGutterLineNrHighlightsEnable  call gitgutter#highlight#linenr_enable()\ncommand! -bar GitGutterLineNrHighlightsToggle  call gitgutter#highlight#linenr_toggle()\n\" }}}\n\n\" Signs {{{\n\ncommand! -bar GitGutterSignsEnable  call gitgutter#sign#enable()\ncommand! -bar GitGutterSignsDisable call gitgutter#sign#disable()\ncommand! -bar GitGutterSignsToggle  call gitgutter#sign#toggle()\n\n\" }}}\n\n\" Hunks {{{\n\ncommand! -bar -count=1 GitGutterNextHunk call gitgutter#hunk#next_hunk(<count>)\ncommand! -bar -count=1 GitGutterPrevHunk call gitgutter#hunk#prev_hunk(<count>)\n\ncommand! -bar -range=% GitGutterStageHunk call gitgutter#hunk#stage(<line1>,<line2>)\ncommand! -bar GitGutterUndoHunk    call gitgutter#hunk#undo()\ncommand! -bar GitGutterPreviewHunk call gitgutter#hunk#preview()\n\n\" Hunk text object\nonoremap <silent> <Plug>(GitGutterTextObjectInnerPending) :<C-U>call gitgutter#hunk#text_object(1)<CR>\nonoremap <silent> <Plug>(GitGutterTextObjectOuterPending) :<C-U>call gitgutter#hunk#text_object(0)<CR>\nxnoremap <silent> <Plug>(GitGutterTextObjectInnerVisual)  :<C-U>call gitgutter#hunk#text_object(1)<CR>\nxnoremap <silent> <Plug>(GitGutterTextObjectOuterVisual)  :<C-U>call gitgutter#hunk#text_object(0)<CR>\n\n\n\" Returns the git-diff hunks for the file or an empty list if there\n\" aren't any hunks.\n\"\n\" The return value is a list of lists.  There is one inner list per hunk.\n\"\n\"   [\n\"     [from_line, from_count, to_line, to_count],\n\"     [from_line, from_count, to_line, to_count],\n\"     ...\n\"   ]\n\"\n\" where:\n\"\n\" `from`  - refers to the staged file\n\" `to`    - refers to the working tree's file\n\" `line`  - refers to the line number where the change starts\n\" `count` - refers to the number of lines the change covers\nfunction! GitGutterGetHunks()\n  let bufnr = bufnr('')\n  return gitgutter#utility#is_active(bufnr) ? gitgutter#hunk#hunks(bufnr) : []\nendfunction\n\n\" Returns an array that contains a summary of the hunk status for the current\n\" window.  The format is [ added, modified, removed ], where each value\n\" represents the number of lines added/modified/removed respectively.\nfunction! GitGutterGetHunkSummary()\n  return gitgutter#hunk#summary(winbufnr(0))\nendfunction\n\n\" }}}\n\n\" Folds {{{\n\ncommand! -bar GitGutterFold call gitgutter#fold#toggle()\n\n\" }}}\n\ncommand! -bar GitGutterDebug call gitgutter#debug#debug()\n\n\" Maps {{{\n\nnnoremap <silent> <expr> <Plug>(GitGutterNextHunk) &diff ? ']c' : \":\\<C-U>execute v:count1 . 'GitGutterNextHunk'\\<CR>\"\nnnoremap <silent> <expr> <Plug>GitGutterNextHunk   &diff ? ']c' : \":\\<C-U>call gitgutter#utility#warn('Please change your map \\<lt>Plug>GitGutterNextHunk to \\<lt>Plug>(GitGutterNextHunk)')\\<CR>\"\nnnoremap <silent> <expr> <Plug>(GitGutterPrevHunk) &diff ? '[c' : \":\\<C-U>execute v:count1 . 'GitGutterPrevHunk'\\<CR>\"\nnnoremap <silent> <expr> <Plug>GitGutterPrevHunk   &diff ? '[c' : \":\\<C-U>call gitgutter#utility#warn('Please change your map \\<lt>Plug>GitGutterPrevHunk to \\<lt>Plug>(GitGutterPrevHunk)')\\<CR>\"\n\nxnoremap <silent> <Plug>(GitGutterStageHunk)   :GitGutterStageHunk<CR>\nxnoremap <silent> <Plug>GitGutterStageHunk     :call gitgutter#utility#warn('Please change your map <lt>Plug>GitGutterStageHunk to <lt>Plug>(GitGutterStageHunk)')<CR>\nnnoremap <silent> <Plug>(GitGutterStageHunk)   :GitGutterStageHunk<CR>\nnnoremap <silent> <Plug>GitGutterStageHunk     :call gitgutter#utility#warn('Please change your map <lt>Plug>GitGutterStageHunk to <lt>Plug>(GitGutterStageHunk)')<CR>\nnnoremap <silent> <Plug>(GitGutterUndoHunk)    :GitGutterUndoHunk<CR>\nnnoremap <silent> <Plug>GitGutterUndoHunk      :call gitgutter#utility#warn('Please change your map <lt>Plug>GitGutterUndoHunk to <lt>Plug>(GitGutterUndoHunk)')<CR>\nnnoremap <silent> <Plug>(GitGutterPreviewHunk) :GitGutterPreviewHunk<CR>\nnnoremap <silent> <Plug>GitGutterPreviewHunk   :call gitgutter#utility#warn('Please change your map <lt>Plug>GitGutterPreviewHunk to <lt>Plug>(GitGutterPreviewHunk)')<CR>\n\n\" }}}\n\nfunction! s:on_bufenter()\n  call gitgutter#setup_maps()\n\n  \" To keep vim's start-up fast, do not process the buffer when vim is starting.\n  \" Instead process it a short time later.  Normally we would rely on our\n  \" CursorHold autocommand to handle this but it turns out CursorHold is not\n  \" guaranteed to fire if the user has not typed anything yet; so set up a\n  \" timer instead.  The disadvantage is that if CursorHold does fire, the\n  \" plugin will do a round of unnecessary work; but since there will not have\n  \" been any changes to the buffer since the first round, the second round\n  \" will be cheap.\n  if has('vim_starting') && !$VIM_GITGUTTER_TEST\n    if exists('*timer_start') && has('lambda')\n      call s:next_tick(\"call gitgutter#process_buffer(+\".bufnr('').\", 0)\")\n    else\n      call gitgutter#process_buffer(bufnr(''), 0)\n    endif\n    return\n  endif\n\n  if exists('t:gitgutter_didtabenter') && t:gitgutter_didtabenter\n    let t:gitgutter_didtabenter = 0\n    call gitgutter#all(!g:gitgutter_terminal_reports_focus)\n  else\n    call gitgutter#process_buffer(bufnr(''), !g:gitgutter_terminal_reports_focus)\n  endif\nendfunction\n\nfunction! s:next_tick(cmd)\n  call timer_start(1, {-> execute(a:cmd)})\nendfunction\n\nfunction! s:on_buffilepre(bufnr)\n  if !exists('s:renaming')\n    let s:renaming = []\n    let s:gitgutter_was_enabled = gitgutter#utility#getbufvar(a:bufnr, 'enabled')\n  endif\n\n  let s:renaming += [a:bufnr]\nendfunction\n\nfunction! s:on_buffilepost(bufnr)\n  if len(s:renaming) > 1\n    if s:renaming[0] != a:bufnr\n      throw 'gitgutter rename error' s:renaming[0] a:bufnr\n    endif\n    unlet s:renaming[0]\n    return\n  endif\n\n  \" reset cached values\n  GitGutterBufferDisable\n\n  if s:gitgutter_was_enabled\n    GitGutterBufferEnable\n  endif\n\n  unlet s:renaming\n  unlet s:gitgutter_was_enabled\nendfunction\n\n\" Autocommands {{{\n\naugroup gitgutter\n  autocmd!\n\n  autocmd TabEnter * let t:gitgutter_didtabenter = 1\n\n  autocmd BufEnter * call s:on_bufenter()\n\n  \" Ensure Vim is always checking for CursorMoved to avoid CursorMoved\n  \" being fired at the wrong time in floating preview window on Neovim.\n  \" See vim/vim#2053.\n  autocmd CursorMoved * execute ''\n\n  autocmd CursorHold,CursorHoldI * call gitgutter#process_buffer(bufnr(''), 0)\n  if exists('*timer_start') && has('lambda')\n    autocmd FileChangedShellPost * call s:next_tick(\"call gitgutter#process_buffer(+\".expand('<abuf>').\", 1)\")\n  else\n    autocmd FileChangedShellPost * call gitgutter#process_buffer(+expand('<abuf>'), 1)\n  endif\n\n  \" Ensure that all buffers are processed when opening vim with multiple files, e.g.:\n  \"\n  \"   vim -o file1 file2\n  autocmd VimEnter * if winnr() != winnr('$') | call gitgutter#all(0) | endif\n\n  autocmd ShellCmdPost * call gitgutter#all(1)\n  autocmd BufLeave term://* call gitgutter#all(1)\n\n  autocmd User FugitiveChanged call gitgutter#all(1)\n\n  \" Handle all buffers when focus is gained, but only after it was lost.\n  \" FocusGained gets triggered on startup with Neovim at least already.\n  \" Therefore this tracks also if it was lost before.\n  let s:focus_was_lost = 0\n  autocmd FocusGained * if s:focus_was_lost | let s:focus_was_lost = 0 | call gitgutter#all(1) | endif\n  autocmd FocusLost * let s:focus_was_lost = 1\n\n  if exists('##VimResume')\n    autocmd VimResume * call gitgutter#all(1)\n  endif\n\n  autocmd ColorScheme * call gitgutter#highlight#define_highlights()\n\n  autocmd BufFilePre  * call s:on_buffilepre(expand('<abuf>'))\n  autocmd BufFilePost * call s:on_buffilepost(expand('<abuf>'))\n\n  autocmd QuickFixCmdPre *vimgrep*\n        \\ if gitgutter#utility#getbufvar(expand('<abuf>'), 'enabled') |\n        \\   let s:gitgutter_was_enabled = expand('<abuf>') |\n        \\ else |\n        \\   let s:gitgutter_was_enabled = 0 |\n        \\ endif |\n        \\ GitGutterBufferDisable\n  autocmd QuickFixCmdPost *vimgrep*\n        \\ if s:gitgutter_was_enabled |\n        \\   call gitgutter#buffer_enable(s:gitgutter_was_enabled) |\n        \\ endif |\n        \\ unlet s:gitgutter_was_enabled\naugroup END\n\n\" }}}\n\n\" vim:set et sw=2 fdm=marker:\n"
  },
  {
    "path": "test/.gitattributes",
    "content": "*.foo filter=reverse diff=reverse\n"
  },
  {
    "path": "test/.gitconfig",
    "content": "[filter \"reverse\"]\n  clean = \"rev\"\n  smudge = \"rev\"\n\n[diff \"reverse\"]\n  textconv = \"cat\"\n"
  },
  {
    "path": "test/cp932.txt",
    "content": "The quick brown fox jumps\nover the lazy dog\n\n͂ɂقւƂʂ\n킩悽ꂻ˂Ȃ\n̂܂ӂ\n߂݂Ђ\n\n"
  },
  {
    "path": "test/fixture.foo",
    "content": "one\ntwo\nthree\nfour\n"
  },
  {
    "path": "test/fixture.txt",
    "content": "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\n\n"
  },
  {
    "path": "test/fixture_dos.txt",
    "content": "a\r\nb\r\nc\r\nd\r\ne\r\nf\r\ng\r\nh\r\ni\r\nj\r\n\r\n"
  },
  {
    "path": "test/fixture_dos_noeol.txt",
    "content": "a\r\nb\r\nc\r\nd\r\ne\r\nf\r\ng"
  },
  {
    "path": "test/runner.vim",
    "content": "\"\n\" Adapted from https://github.com/vim/vim/blob/master/src/testdir/runtest.vim\n\"\n\" When debugging tests it can help to write debug output:\n\"    call Log('oh noes')\n\"\n\nfunction RunTest(test)\n  if exists(\"*SetUp\")\n    call SetUp()\n  endif\n\n  try\n    execute 'call '.a:test\n  catch\n    call Exception()\n    let s:errored = 1\n  endtry\n\n  if exists(\"*TearDown\")\n    call TearDown()\n  endif\nendfunction\n\nfunction Log(msg)\n  if type(a:msg) == type('')\n    call add(s:messages, a:msg)\n  elseif type(a:msg) == type([])\n    call extend(s:messages, a:msg)\n  else\n    call add(v:errors, 'Exception: unsupported type: '.type(a:msg))\n  endif\nendfunction\n\nfunction Exception()\n  call add(v:errors, v:throwpoint.'..'.'Exception: '.v:exception)\nendfunction\n\n\" Shuffles list in place.\nfunction Shuffle(list)\n  \" Fisher-Yates-Durstenfeld-Knuth\n  let n = len(a:list)\n  if n < 2\n    return a:list\n  endif\n  for i in range(0, n-2)\n    let j = Random(0, n-i-1)\n    let e = a:list[i]\n    let a:list[i] = a:list[i+j]\n    let a:list[i+j] = e\n  endfor\n  return a:list\nendfunction\n\n\" Returns a pseudorandom integer i such that 0 <= i <= max\nfunction Random(min, max)\n  if has('unix')\n    let i = system('echo $RANDOM')  \" 0 <= i <= 32767\n  else\n    let i = system('echo %RANDOM%')  \" 0 <= i <= 32767\n  endif\n  return i * (a:max - a:min + 1) / 32768 + a:min\nendfunction\n\nfunction FriendlyName(test_name)\n  return substitute(a:test_name[5:-3], '_', ' ', 'g')\nendfunction\n\nfunction Align(left, right)\n  if type(a:right) == type([])\n    let result = []\n    for s in a:right\n      if empty(result)\n        call add(result, printf('%-'.s:indent.'S', a:left).s)\n      else\n        call add(result, printf('%-'.s:indent.'S',     '').s)\n      endif\n    endfor\n    return result\n  endif\n\n  return printf('%-'.s:indent.'S', a:left).a:right\nendfunction\n\nlet g:testname = expand('%')\nlet s:errored = 0\nlet s:done = 0\nlet s:fail = 0\nlet s:errors = 0\nlet s:messages = []\nlet s:indent = ''\n\ncall Log(g:testname.':')\n\n\" Source the test script.\ntry\n  source %\ncatch\n  let s:errors += 1\n  call Exception()\nendtry\n\n\" Locate the test functions.\nset nomore\nredir @q\nsilent function /^Test_\nredir END\nlet s:tests = split(substitute(@q, 'function \\(\\k*()\\)', '\\1', 'g'))\n\n\" If there is another argument, filter test-functions' names against it.\nif argc() > 1\n  let s:tests = filter(s:tests, 'v:val =~ argv(1)')\nendif\n\nlet s:indent = max(map(copy(s:tests), {_, val -> len(FriendlyName(val))}))\n\n\" Run the tests in random order.\nfor test in Shuffle(s:tests)\n  call RunTest(test)\n  let s:done += 1\n\n  let friendly_name = FriendlyName(test)\n  if len(v:errors) == 0\n    call Log(Align(friendly_name, ' - ok'))\n  else\n    if s:errored\n      let s:errors += 1\n      let s:errored = 0\n    else\n      let s:fail += 1\n    endif\n    call Log(Align(friendly_name, ' - not ok'))\n\n    let i = 0\n    for error in v:errors\n      if i != 0\n        call Log(Align('','   ! ----'))\n      endif\n      for trace in reverse(split(error, '\\.\\.'))\n        call Log(Align('', '   ! '.trace))\n      endfor\n      let i += 1\n    endfor\n\n    let v:errors = []\n  endif\nendfor\n\nlet summary = [\n      \\ s:done.(  s:done   == 1 ? ' test'    : ' tests'),\n      \\ s:errors.(s:errors == 1 ? ' error'   : ' errors'),\n      \\ s:fail.(  s:fail   == 1 ? ' failure' : ' failures'),\n      \\ ]\ncall Log('')\ncall Log(join(summary, ', '))\n\nsplit messages.log\ncall append(line('$'), s:messages)\nwrite\n\nqall!\n\n"
  },
  {
    "path": "test/test",
    "content": "#!/usr/bin/env bash\n\nVIM=\"/Applications/MacVim.app/Contents/MacOS/Vim -v\"\n\nexport VIM_GITGUTTER_TEST=1\n\n$VIM -u NONE -U NONE -N                      \\\n  --cmd 'set rtp+=../'                       \\\n  --cmd 'let g:gitgutter_async=0'            \\\n  --cmd 'source ../plugin/gitgutter.vim'     \\\n  -S runner.vim                              \\\n  test_*.vim                                 \\\n  \"$@\"\n\ncat messages.log\n\ngrep -q \"0 errors, 0 failures\" messages.log\nstatus=$?\nrm messages.log\nexit $status\n\n"
  },
  {
    "path": "test/test_gitgutter.vim",
    "content": "let s:current_dir = expand('%:p:h')\nlet s:test_repo   = s:current_dir.'/test-repo'\nlet s:bufnr       = bufnr('')\n\n\"\n\" Helpers\n\"\n\n\" Ignores unexpected keys in actual.\nfunction s:assert_list_of_dicts(expected, actual)\n  if empty(a:expected)\n    call assert_equal([], a:actual)\n    return\n  endif\n\n  let expected_keys = keys(a:expected[0])\n\n  for dict in a:actual\n    for k in keys(dict)\n      if index(expected_keys, k) == -1\n        call remove(dict, k)\n      endif\n    endfor\n  endfor\n\n  call assert_equal(a:expected, a:actual)\nendfunction\n\n\" Ignores unexpected keys.\n\"\n\" expected - list of signs\nfunction s:assert_signs(expected, filename)\n  let actual = sign_getplaced(a:filename, {'group': 'gitgutter'})[0].signs\n  call s:assert_list_of_dicts(a:expected, actual)\nendfunction\n\nfunction s:git_diff(...)\n  return split(system('git diff -U0 '.(a:0 ? a:1 : 'fixture.txt')), '\\n')\nendfunction\n\nfunction s:git_diff_staged(...)\n  return split(system('git diff -U0 --staged '.(a:0 ? a:1 : 'fixture.txt')), '\\n')\nendfunction\n\nfunction s:trigger_gitgutter()\n  doautocmd CursorHold\nendfunction\n\n\n\"\n\" SetUp / TearDown\n\"\n\nfunction SetUp()\n  let g:gitgutter_diff_base = ''\n  call system(\"git init \".s:test_repo.\n        \\ \" && cd \".s:test_repo.\n        \\ \" && cp ../.gitconfig .\".\n        \\ \" && cp ../.gitattributes .\".\n        \\ \" && cp ../fixture.foo .\".\n        \\ \" && cp ../fixture.txt .\".\n        \\ \" && cp ../fixture_dos.txt .\".\n        \\ \" && cp ../fixture_dos_noeol.txt .\".\n        \\ \" && git add . && git commit -m 'initial'\".\n        \\ \" && git config diff.mnemonicPrefix false\")\n  execute ':cd' s:test_repo\n  edit! fixture.txt\n  call gitgutter#sign#reset()\n\n  \" FIXME why won't vim autoload the file?\n  execute 'source' '../../autoload/gitgutter/diff_highlight.vim'\n  execute 'source' '../../autoload/gitgutter/fold.vim'\nendfunction\n\nfunction TearDown()\n  \" delete all buffers except this one\n  \" TODO: move to runner.vim, accounting for multiple test files\n  if s:bufnr > 1\n    silent! execute '1,'.s:bufnr-1.'bdelete!'\n  endif\n  silent! execute s:bufnr+1.',$bdelete!'\n\n  execute ':cd' s:current_dir\n  call system(\"rm -rf \".s:test_repo)\nendfunction\n\n\"\n\" The tests\n\"\n\nfunction Test_add_lines()\n  normal ggo*\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 2, 'name': 'GitGutterLineAdded', 'group': 'gitgutter', 'priority': 10}]\n  call s:assert_signs(expected, 'fixture.txt')\nendfunction\n\n\nfunction Test_add_lines_fish()\n  let _shell = &shell\n  set shell=/usr/local/bin/fish\n\n  normal ggo*\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 2, 'name': 'GitGutterLineAdded'}]\n  call s:assert_signs(expected, 'fixture.txt')\n\n  let &shell = _shell\nendfunction\n\n\nfunction Test_modify_lines()\n  normal ggi*\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 1, 'name': 'GitGutterLineModified'}]\n  call s:assert_signs(expected, 'fixture.txt')\nendfunction\n\n\nfunction Test_remove_lines()\n  execute '5d'\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 4, 'name': 'GitGutterLineRemoved'}]\n  call s:assert_signs(expected, 'fixture.txt')\nendfunction\n\n\nfunction Test_remove_first_lines()\n  execute '1d'\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 1, 'name': 'GitGutterLineRemovedFirstLine'}]\n  call s:assert_signs(expected, 'fixture.txt')\nendfunction\n\n\nfunction Test_priority()\n  let g:gitgutter_sign_priority = 5\n\n  execute '1d'\n  call s:trigger_gitgutter()\n\n  call s:assert_signs([{'priority': 5}], 'fixture.txt')\n\n  let g:gitgutter_sign_priority = 10\nendfunction\n\n\nfunction Test_overlapping_hunks()\n  execute '3d'\n  execute '1d'\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 1, 'name': 'GitGutterLineRemovedAboveAndBelow'}]\n  call s:assert_signs(expected, 'fixture.txt')\nendfunction\n\n\nfunction Test_edit_file_with_same_name_as_a_branch()\n  normal 5Gi*\n  call system('git checkout -b fixture.txt')\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 5, 'name': 'GitGutterLineModified'}]\n  call s:assert_signs(expected, 'fixture.txt')\nendfunction\n\n\nfunction Test_file_added_to_git()\n  let tmpfile = 'fileAddedToGit.tmp'\n  call system('touch '.tmpfile.' && git add '.tmpfile)\n  execute 'edit '.tmpfile\n  normal ihello\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 1, 'name': 'GitGutterLineAdded'}]\n  call s:assert_signs(expected, 'fileAddedToGit.tmp')\nendfunction\n\n\nfunction Test_filename_with_equals()\n  call system('touch =fixture=.txt && git add =fixture=.txt')\n  edit =fixture=.txt\n  normal ggo*\n  call s:trigger_gitgutter()\n\n  let expected = [\n        \\ {'lnum': 1, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 2, 'name': 'GitGutterLineAdded'}\n        \\ ]\n  call s:assert_signs(expected, '=fixture=.txt')\nendfunction\n\n\nfunction Test_filename_with_colon()\n  call system('touch fix:ture.txt && git add fix:ture.txt')\n  edit fix:ture.txt\n  normal ggo*\n  call s:trigger_gitgutter()\n\n  let expected = [\n        \\ {'lnum': 1, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 2, 'name': 'GitGutterLineAdded'}\n        \\ ]\n  call s:assert_signs(expected, 'fix:ture.txt')\nendfunction\n\n\nfunction Test_filename_with_square_brackets()\n  call system('touch fix[tu]re.txt && git add fix[tu]re.txt')\n  edit fix[tu]re.txt\n  normal ggo*\n  call s:trigger_gitgutter()\n\n  let expected = [\n        \\ {'lnum': 1, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 2, 'name': 'GitGutterLineAdded'}\n        \\ ]\n  call s:assert_signs(expected, 'fix[tu]re.txt')\nendfunction\n\n\nfunction Test_filename_with_space()\n  call system('touch fix\\ ture.txt && git add fix\\ ture.txt')\n  edit fix\\ ture.txt\n  normal ggo*\n  call s:trigger_gitgutter()\n\n  let expected = [\n        \\ {'lnum': 1, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 2, 'name': 'GitGutterLineAdded'}\n        \\ ]\n  call s:assert_signs(expected, 'fix\\ ture.txt')\nendfunction\n\n\nfunction Test_filename_leading_dash()\n  call system('touch -- -fixture.txt && git add -- -fixture.txt')\n  edit -fixture.txt\n  normal ggo*\n  call s:trigger_gitgutter()\n\n  let expected = [\n        \\ {'lnum': 1, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 2, 'name': 'GitGutterLineAdded'}\n        \\ ]\n  call s:assert_signs(expected, '-fixture.txt')\nendfunction\n\n\nfunction Test_filename_umlaut()\n  call system('touch -- fixtüre.txt && git add -- fixtüre.txt')\n  edit fixtüre.txt\n  normal ggo*\n  call s:trigger_gitgutter()\n\n  let expected = [\n        \\ {'lnum': 1, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 2, 'name': 'GitGutterLineAdded'}\n        \\ ]\n  call s:assert_signs(expected, 'fixtüre.txt')\nendfunction\n\n\nfunction Test_file_cmd()\n  normal ggo*\n\n  file other.txt\n\n  call s:trigger_gitgutter()\n  call assert_equal(1, b:gitgutter.enabled)\n  call assert_equal('', b:gitgutter.path)\n  call s:assert_signs([], 'other.txt')\n\n  write\n\n  call s:trigger_gitgutter()\n  call assert_equal(-2, b:gitgutter.path)\nendfunction\n\n\nfunction Test_saveas()\n  normal ggo*\n\n  saveas other.txt\n\n  call s:trigger_gitgutter()\n  call assert_equal(1, b:gitgutter.enabled)\n  call assert_equal(-2, b:gitgutter.path)\n  call s:assert_signs([], 'other.txt')\nendfunction\n\n\nfunction Test_file_mv()\n  call system('git mv fixture.txt fixture_moved.txt')\n  edit fixture_moved.txt\n  normal ggo*\n  call s:trigger_gitgutter()\n  let expected = [{'lnum': 2, 'name': 'GitGutterLineAdded'}]\n  call s:assert_signs(expected, 'fixture_moved.txt')\n\n  write\n  call system('git add fixture_moved.txt && git commit -m \"moved and edited\"')\n  GitGutterDisable\n  GitGutterEnable\n  let expected = []\n  call s:assert_signs(expected, 'fixture_moved.txt')\n\n  GitGutterDisable\n  let g:gitgutter_diff_base = 'HEAD^'\n  GitGutterEnable\n  let expected = [{'lnum': 2, 'name': 'GitGutterLineAdded'}]\n  call s:assert_signs(expected, 'fixture_moved.txt')\nendfunction\n\n\n\" FIXME: this test fails when it is the first (or only) test to be run\nfunction Test_follow_symlink()\n  let tmp = 'symlink'\n  call system('ln -nfs fixture.txt '.tmp)\n  execute 'edit '.tmp\n  6d\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 5, 'name': 'GitGutterLineRemoved'}]\n  call s:assert_signs(expected, 'symlink')\nendfunction\n\n\nfunction Test_keep_alt()\n  enew\n  execute \"normal! \\<C-^>\"\n\n  call assert_equal('fixture.txt', bufname(''))\n  call assert_equal('',            bufname('#'))\n\n  normal ggx\n  call s:trigger_gitgutter()\n\n  call assert_equal('', bufname('#'))\nendfunction\n\n\nfunction Test_keep_modified()\n  normal 5Go*\n  call assert_equal(1, getbufvar('', '&modified'))\n\n  call s:trigger_gitgutter()\n\n  call assert_equal(1, getbufvar('', '&modified'))\nendfunction\n\n\nfunction Test_keep_op_marks()\n  normal 5Go*\n  call assert_equal([0,6,1,0], getpos(\"'[\"))\n  call assert_equal([0,6,2,0], getpos(\"']\"))\n\n  call s:trigger_gitgutter()\n\n  call assert_equal([0,6,1,0], getpos(\"'[\"))\n  call assert_equal([0,6,2,0], getpos(\"']\"))\nendfunction\n\n\nfunction Test_no_modifications()\n  call s:assert_signs([], 'fixture.txt')\nendfunction\n\n\nfunction Test_orphaned_signs()\n  execute \"normal 5GoX\\<CR>Y\"\n  call s:trigger_gitgutter()\n  6d\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 6, 'name': 'GitGutterLineAdded'}]\n  call s:assert_signs(expected, 'fixture.txt')\nendfunction\n\n\nfunction Test_untracked_file_outside_repo()\n  let tmp = tempname()\n  call system('touch '.tmp)\n  execute 'edit '.tmp\n\n  call s:assert_signs([], tmp)\nendfunction\n\n\nfunction Test_untracked_file_within_repo()\n  let tmp = 'untrackedFileWithinRepo.tmp'\n  call system('touch '.tmp)\n  execute 'edit '.tmp\n  normal ggo*\n  call s:trigger_gitgutter()\n\n  call s:assert_signs([], tmp)\n  call assert_equal(-2, b:gitgutter.path)\n\n  call system('rm '.tmp)\nendfunction\n\n\nfunction Test_untracked_file_square_brackets_within_repo()\n  let tmp = '[un]trackedFileWithinRepo.tmp'\n  call system('touch '.tmp)\n  execute 'edit '.tmp\n  normal ggo*\n  call s:trigger_gitgutter()\n\n  call s:assert_signs([], tmp)\n\n  call system('rm '.tmp)\nendfunction\n\n\nfunction Test_file_unknown_in_base()\n  let starting_branch = split(system('git branch --show-current'))[0]\n  call system('git checkout -b some-feature')\n  let tmp = 'file-on-this-branch-only.tmp'\n  call system('echo \"hi\" > '.tmp.' && git add '.tmp)\n  execute 'edit '.tmp\n  let g:gitgutter_diff_base = starting_branch\n  GitGutter\n  let expected = [{'lnum': 1, 'name': 'GitGutterLineAdded', 'group': 'gitgutter', 'priority': 10}]\n  call s:assert_signs(expected, tmp)\n  let g:gitgutter_diff_base = ''\nendfunction\n\n\nfunction Test_v_shell_error_not_clobbered()\n  \" set gitgutter up to generate a shell error\n  let starting_branch = split(system('git branch --show-current'))[0]\n  call system('git checkout -b some-feature')\n  let tmp = 'file-on-this-branch-only.tmp'\n  call system('echo \"hi\" > '.tmp.' && git add '.tmp)\n  execute 'edit '.tmp\n  let g:gitgutter_diff_base = starting_branch\n\n  \" run a successful shell command\n  silent !echo foobar >/dev/null\n\n  \" run gitgutter\n  GitGutter\n\n  call assert_equal(0, v:shell_error)\n\n  let g:gitgutter_diff_base = ''\nendfunction\n\n\nfunction Test_hunk_outside_noop()\n  5\n  GitGutterStageHunk\n\n  call s:assert_signs([], 'fixture.txt')\n  call assert_equal([], s:git_diff())\n  call assert_equal([], s:git_diff_staged())\n\n  GitGutterUndoHunk\n\n  call s:assert_signs([], 'fixture.txt')\n  call assert_equal([], s:git_diff())\n  call assert_equal([], s:git_diff_staged())\nendfunction\n\n\nfunction Test_preview()\n  normal 5Gi*\n  GitGutterPreviewHunk\n\n  wincmd P\n  call assert_equal(2, line('$'))\n  call assert_equal('-e', getline(1))\n  call assert_equal('+*e', getline(2))\n  wincmd p\nendfunction\n\n\nfunction Test_preview_dos()\n  edit! fixture_dos.txt\n\n  normal 5Gi*\n  GitGutterPreviewHunk\n\n  wincmd P\n  call assert_equal(2, line('$'))\n  call assert_equal('-e', getline(1))\n  call assert_equal('+*e', getline(2))\n  wincmd p\nendfunction\n\n\nfunction Test_dos_noeol()\n  edit! fixture_dos_noeol.txt\n  GitGutter\n\n  call s:assert_signs([], 'fixture_dos_noeol.txt')\nendfunction\n\n\nfunction Test_hunk_stage()\n  let _shell = &shell\n  set shell=foo\n\n  normal 5Gi*\n  GitGutterStageHunk\n\n  call assert_equal('foo', &shell)\n  let &shell = _shell\n\n  call s:assert_signs([], 'fixture.txt')\n\n  \" Buffer is unsaved\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index ae8e546..f5c6aff 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -5 +5 @@ d',\n        \\ '-*e',\n        \\ '+e'\n        \\ ]\n  call assert_equal(expected, s:git_diff())\n\n  \" Index has been updated\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index f5c6aff..ae8e546 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -5 +5 @@ d',\n        \\ '-e',\n        \\ '+*e'\n        \\ ]\n  call assert_equal(expected, s:git_diff_staged())\n\n  \" Save the buffer\n  write\n\n  call assert_equal([], s:git_diff())\nendfunction\n\n\nfunction Test_hunk_stage_nearby_hunk()\n  execute \"normal! 2Gox\\<CR>y\\<CR>z\"\n  normal 2jdd\n  normal k\n  GitGutterStageHunk\n\n  let expected = [\n        \\ {'lnum': 3, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 4, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 5, 'name': 'GitGutterLineAdded'}\n        \\ ]\n  call s:assert_signs(expected, 'fixture.txt')\n\n  \" Buffer is unsaved\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index 53b13df..f5c6aff 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -3,0 +4 @@ c',\n        \\ '+d',\n        \\ ]\n  call assert_equal(expected, s:git_diff())\n\n  \" Index has been updated\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index f5c6aff..53b13df 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -4 +3,0 @@ c',\n        \\ '-d',\n        \\ ]\n  call assert_equal(expected, s:git_diff_staged())\n\n  \" Save the buffer\n  write\n\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index 53b13df..8fdfda7 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -2,0 +3,3 @@ b',\n        \\ '+x',\n        \\ '+y',\n        \\ '+z',\n        \\ ]\n  call assert_equal(expected, s:git_diff())\nendfunction\n\n\nfunction Test_hunk_stage_partial_visual_added()\n  call append(5, ['A','B','C','D'])\n  execute \"normal 7GVj:GitGutterStageHunk\\<CR>\"\n\n  let expected = [\n        \\ {'lnum': 6, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 9, 'name': 'GitGutterLineAdded'},\n        \\ ]\n  call s:assert_signs(expected, 'fixture.txt')\n\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index 8a7026e..f5c6aff 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -6,2 +5,0 @@ e',\n        \\ '-B',\n        \\ '-C',\n        \\ ]\n  call assert_equal(expected, s:git_diff())\n\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index f5c6aff..8a7026e 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -5,0 +6,2 @@ e',\n        \\ '+B',\n        \\ '+C',\n        \\ ]\n  call assert_equal(expected, s:git_diff_staged())\nendfunction\n\n\nfunction Test_hunk_stage_partial_cmd_added()\n  call append(5, ['A','B','C','D'])\n  6\n  7,8GitGutterStageHunk\n\n  let expected = [\n        \\ {'lnum': 6, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 9, 'name': 'GitGutterLineAdded'},\n        \\ ]\n  call s:assert_signs(expected, 'fixture.txt')\n\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index 8a7026e..f5c6aff 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -6,2 +5,0 @@ e',\n        \\ '-B',\n        \\ '-C',\n        \\ ]\n  call assert_equal(expected, s:git_diff())\n\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index f5c6aff..8a7026e 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -5,0 +6,2 @@ e',\n        \\ '+B',\n        \\ '+C',\n        \\ ]\n  call assert_equal(expected, s:git_diff_staged())\nendfunction\n\n\nfunction Test_hunk_stage_partial_preview_added()\n  call append(5, ['A','B','C','D'])\n  6\n  GitGutterPreviewHunk\n  wincmd P\n\n  \" remove C and A so we stage B and D\n  3delete\n  1delete\n\n  GitGutterStageHunk\n  write\n\n  let expected = [\n        \\ {'lnum': 6, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 8, 'name': 'GitGutterLineAdded'},\n        \\ ]\n  call s:assert_signs(expected, 'fixture.txt')\n\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index 975852f..3dd23a3 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -5,0 +6 @@ e',\n        \\ '+A',\n        \\ '@@ -6,0 +8 @@ B',\n        \\ '+C',\n        \\ ]\n  call assert_equal(expected, s:git_diff())\n\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index f5c6aff..975852f 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -5,0 +6,2 @@ e',\n        \\ '+B',\n        \\ '+D',\n        \\ ]\n  call assert_equal(expected, s:git_diff_staged())\nendfunction\n\n\nfunction Test_hunk_stage_preview_write()\n  call append(5, ['A','B','C','D'])\n  6\n  GitGutterPreviewHunk\n  wincmd P\n\n  \" preview window\n  call feedkeys(\":w\\<CR>\", 'tx')\n  \" original window\n  write\n\n  call s:assert_signs([], 'fixture.txt')\n\n  call assert_equal([], s:git_diff())\n\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index f5c6aff..3dd23a3 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -5,0 +6,4 @@ e',\n        \\ '+A',\n        \\ '+B',\n        \\ '+C',\n        \\ '+D',\n        \\ ]\n  call assert_equal(expected, s:git_diff_staged())\nendfunction\n\n\nfunction Test_hunk_stage_partial_preview_added_removed()\n  4,5delete\n  call append(3, ['A','B','C','D'])\n  4\n  GitGutterPreviewHunk\n  wincmd P\n\n  \" -d\n  \" -e\n  \" +A\n  \" +B\n  \" +C\n  \" +D\n\n  \" remove D and d so they do not get staged\n  6delete\n  1delete\n\n  GitGutterStageHunk\n  write\n\n  let expected = [\n        \\ {'lnum': 3, 'name': 'GitGutterLineRemoved'},\n        \\ {'lnum': 7, 'name': 'GitGutterLineAdded'},\n        \\ ]\n  call s:assert_signs(expected, 'fixture.txt')\n\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index 9a19589..e63fb0a 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -4 +3,0 @@ c',\n        \\ '-d',\n        \\ '@@ -7,0 +7 @@ C',\n        \\ '+D',\n        \\ ]\n  call assert_equal(expected, s:git_diff())\n\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index f5c6aff..9a19589 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -5 +5,3 @@ d',\n        \\ '-e',\n        \\ '+A',\n        \\ '+B',\n        \\ '+C',\n        \\ ]\n  call assert_equal(expected, s:git_diff_staged())\nendfunction\n\n\nfunction Test_hunk_undo()\n  let _shell = &shell\n  set shell=foo\n\n  normal 5Gi*\n  GitGutterUndoHunk\n\n  call assert_equal('foo', &shell)\n  let &shell = _shell\n\n  call s:assert_signs([], 'fixture.txt')\n  call assert_equal([], s:git_diff())\n  call assert_equal([], s:git_diff_staged())\n  call assert_equal('e', getline(5))\nendfunction\n\n\nfunction Test_hunk_undo_dos()\n  edit! fixture_dos.txt\n\n  normal 5Gi*\n  GitGutterUndoHunk\n\n  call s:assert_signs([], 'fixture_dos.txt')\n  call assert_equal([], s:git_diff('fixture_dos.txt'))\n  call assert_equal([], s:git_diff_staged('fixture_dos.txt'))\n  call assert_equal('e', getline(5))\nendfunction\n\n\nfunction Test_undo_nearby_hunk()\n  execute \"normal! 2Gox\\<CR>y\\<CR>z\"\n  normal 2jdd\n  normal k\n  call s:trigger_gitgutter()\n  GitGutterUndoHunk\n  call s:trigger_gitgutter()\n\n  let expected = [\n        \\ {'lnum': 3, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 4, 'name': 'GitGutterLineAdded'},\n        \\ {'lnum': 5, 'name': 'GitGutterLineAdded'}\n        \\ ]\n  call s:assert_signs(expected, 'fixture.txt')\n\n  call assert_equal([], s:git_diff())\n\n  call assert_equal([], s:git_diff_staged())\n\n  \" Save the buffer\n  write\n\n  let expected = [\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index f5c6aff..3fbde56 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -2,0 +3,3 @@ b',\n        \\ '+x',\n        \\ '+y',\n        \\ '+z',\n        \\ ]\n  call assert_equal(expected, s:git_diff())\n\nendfunction\n\n\nfunction Test_overlapping_hunk_op()\n  func! Answer(char)\n    call feedkeys(a:char.\"\\<CR>\")\n  endfunc\n\n  \" Undo upper\n\n  execute '3d'\n  execute '1d'\n  call s:trigger_gitgutter()\n  normal gg\n  call timer_start(100, {-> Answer('u')} )\n  GitGutterUndoHunk\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 2, 'name': 'GitGutterLineRemoved'}]\n  call s:assert_signs(expected, 'fixture.txt')\n\n  \" Undo lower\n\n  execute '1d'\n  call s:trigger_gitgutter()\n  normal gg\n  call timer_start(100, {-> Answer('l')} )\n  GitGutterUndoHunk\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 1, 'name': 'GitGutterLineRemovedFirstLine'}]\n  call s:assert_signs(expected, 'fixture.txt')\nendfunction\n\n\nfunction Test_write_option()\n  set nowrite\n\n  normal ggo*\n  call s:trigger_gitgutter()\n\n  let expected = [{'lnum': 2, 'name': 'GitGutterLineAdded'}]\n  call s:assert_signs(expected, 'fixture.txt')\n\n  set write\nendfunction\n\n\nfunction Test_inner_text_object()\n  execute \"normal! 2Gox\\<CR>y\\<CR>z\\<CR>\\<CR>\"\n  call s:trigger_gitgutter()\n  normal dic\n  call s:trigger_gitgutter()\n\n  call s:assert_signs([], 'fixture.txt')\n  call assert_equal(readfile('fixture.txt'), getline(1,'$'))\n\n  \" Excludes trailing lines\n  normal 9Gi*\n  normal 10Gi*\n  call s:trigger_gitgutter()\n  execute \"normal vic\\<Esc>\"\n  call assert_equal([9, 10], [line(\"'<\"), line(\"'>\")])\nendfunction\n\n\nfunction Test_around_text_object()\n  execute \"normal! 2Gox\\<CR>y\\<CR>z\\<CR>\\<CR>\"\n  call s:trigger_gitgutter()\n  normal dac\n  call s:trigger_gitgutter()\n\n  call s:assert_signs([], 'fixture.txt')\n  call assert_equal(readfile('fixture.txt'), getline(1,'$'))\n\n  \" Includes trailing lines\n  normal 9Gi*\n  normal 10Gi*\n  call s:trigger_gitgutter()\n  execute \"normal vac\\<Esc>\"\n  call assert_equal([9, 11], [line(\"'<\"), line(\"'>\")])\nendfunction\n\n\nfunction Test_user_autocmd()\n  autocmd User GitGutter let s:autocmd_user = g:gitgutter_hook_context.bufnr\n\n  \" Verify not fired when nothing changed.\n  let s:autocmd_user = 0\n  call s:trigger_gitgutter()\n  call assert_equal(0, s:autocmd_user)\n\n  \" Verify fired when there was a change.\n  normal ggo*\n  let bufnr = bufnr('')\n  call s:trigger_gitgutter()\n  call assert_equal(bufnr, s:autocmd_user)\nendfunction\n\n\nfunction Test_fix_file_references()\n  let sid = matchstr(execute('filter autoload/gitgutter/hunk.vim scriptnames'), '\\d\\+')\n  let FixFileReferences = function(\"<SNR>\".sid.\"_fix_file_references\")\n\n  \" No special characters\n  let hunk_diff = join([\n        \\ 'diff --git a/fixture.txt b/fixture.txt',\n        \\ 'index f5c6aff..3fbde56 100644',\n        \\ '--- a/fixture.txt',\n        \\ '+++ b/fixture.txt',\n        \\ '@@ -2,0 +3,1 @@ b',\n        \\ '+x'\n        \\ ], \"\\n\").\"\\n\"\n  let filepath = 'blah.txt'\n\n  let expected = join([\n        \\ 'diff --git a/blah.txt b/blah.txt',\n        \\ 'index f5c6aff..3fbde56 100644',\n        \\ '--- a/blah.txt',\n        \\ '+++ b/blah.txt',\n        \\ '@@ -2,0 +3,1 @@ b',\n        \\ '+x'\n        \\ ], \"\\n\").\"\\n\"\n\n  call assert_equal(expected, FixFileReferences(filepath, hunk_diff))\n\n  \" diff.mnemonicPrefix; spaces in filename\n  let hunk_diff = join([\n        \\ 'diff --git i/x/cat dog w/x/cat dog',\n        \\ 'index f5c6aff..3fbde56 100644',\n        \\ '--- i/x/cat dog',\n        \\ '+++ w/x/cat dog',\n        \\ '@@ -2,0 +3,1 @@ b',\n        \\ '+x'\n        \\ ], \"\\n\").\"\\n\"\n  let filepath = 'blah.txt'\n\n  let expected = join([\n        \\ 'diff --git i/blah.txt w/blah.txt',\n        \\ 'index f5c6aff..3fbde56 100644',\n        \\ '--- i/blah.txt',\n        \\ '+++ w/blah.txt',\n        \\ '@@ -2,0 +3,1 @@ b',\n        \\ '+x'\n        \\ ], \"\\n\").\"\\n\"\n\n  call assert_equal(expected, FixFileReferences(filepath, hunk_diff))\n\n  \" Backslashes in filename; quotation marks\n  let hunk_diff = join([\n        \\ '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\"',\n        \\ 'index f42aeb0..4930403 100644',\n        \\ '--- \"a/C:\\\\Users\\\\FOO~1.PAR\\\\AppData\\\\Local\\\\Temp\\\\nvimJcmSv9\\\\11.1.vim\"',\n        \\ '+++ \"b/C:\\\\Users\\\\FOO~1.PAR\\\\AppData\\\\Local\\\\Temp\\\\nvimJcmSv9\\\\12.1.vim\"',\n        \\ '@@ -172,0 +173 @@ stuff',\n        \\ '+x'\n        \\ ], \"\\n\").\"\\n\"\n  let filepath = 'init.vim'\n\n  let expected = join([\n        \\ 'diff --git \"a/init.vim\" \"b/init.vim\"',\n        \\ 'index f42aeb0..4930403 100644',\n        \\ '--- \"a/init.vim\"',\n        \\ '+++ \"b/init.vim\"',\n        \\ '@@ -172,0 +173 @@ stuff',\n        \\ '+x'\n        \\ ], \"\\n\").\"\\n\"\n\n  call assert_equal(expected, FixFileReferences(filepath, hunk_diff))\nendfunction\n\n\nfunction Test_encoding()\n  call system('cp ../cp932.txt . && git add cp932.txt')\n  edit ++enc=cp932 cp932.txt\n\n  call s:trigger_gitgutter()\n\n  call s:assert_signs([], 'cp932.txt')\nendfunction\n\n\nfunction Test_empty_file()\n  \" 0-byte file\n  call system('touch empty.txt && git add empty.txt')\n  edit empty.txt\n\n  call s:trigger_gitgutter()\n  call s:assert_signs([], 'empty.txt')\n\n\n  \" File consisting only of a newline\n  call system('echo \"\" > newline.txt && git add newline.txt')\n  edit newline.txt\n\n  call s:trigger_gitgutter()\n  call s:assert_signs([], 'newline.txt')\n\n\n  \" 1 line file without newline\n  \" Vim will force a newline unless we tell it not to.\n  call system('echo -n a > oneline.txt && git add oneline.txt')\n  set noeol nofixeol\n  edit! oneline.txt\n\n  call s:trigger_gitgutter()\n  call s:assert_signs([], 'oneline.txt')\n\n  set eol fixeol\nendfunction\n\n\nfunction Test_quickfix()\n  call setline(5, ['A', 'B'])\n  call setline(9, ['C', 'D'])\n  write\n  let bufnr1 = bufnr('')\n\n  edit fixture_dos.txt\n  call setline(2, ['A', 'B'])\n  write\n  let bufnr2 = bufnr('')\n\n  GitGutterQuickFix\n\n  let expected = [\n        \\ {'lnum': 5, 'bufnr': bufnr1, 'text': '-e'},\n        \\ {'lnum': 9, 'bufnr': bufnr1, 'text': '-i'},\n        \\ {'lnum': 2, 'bufnr': bufnr2, 'text': \"-b\\r\"}\n        \\ ]\n\n  call s:assert_list_of_dicts(expected, getqflist())\n\n  GitGutterQuickFixCurrentFile\n\n  let expected = [\n        \\ {'lnum': 2, 'bufnr': bufnr(''), 'text': \"-b\\r\"},\n        \\ ]\n\n  call s:assert_list_of_dicts(expected, getqflist())\nendfunction\n\n\nfunction Test_common_prefix()\n  let sid = matchstr(execute('filter autoload/gitgutter/diff_highlight.vim scriptnames'), '\\d\\+')\n  let CommonPrefix = function(\"<SNR>\".sid.\"_common_prefix\")\n\n  \" zero length\n  call assert_equal(-1, CommonPrefix('', 'foo'))\n  call assert_equal(-1, CommonPrefix('foo', ''))\n  \" nothing in common\n  call assert_equal(-1, CommonPrefix('-abcde', '+pqrst'))\n  call assert_equal(-1, CommonPrefix('abcde', 'pqrst'))\n  \" something in common\n  call assert_equal(-1, CommonPrefix('-abcde', '+abcpq'))\n  call assert_equal(2, CommonPrefix('abcde', 'abcpq'))\n  call assert_equal(0, CommonPrefix('abc', 'apq'))\n  \" everything in common\n  call assert_equal(-1, CommonPrefix('-abcde', '+abcde'))\n  call assert_equal(4, CommonPrefix('abcde', 'abcde'))\n  \" different lengths\n  call assert_equal(-1, CommonPrefix('-abcde', '+abx'))\n  call assert_equal(1, CommonPrefix('abcde', 'abx'))\n  call assert_equal(-1, CommonPrefix('-abx',   '+abcde'))\n  call assert_equal(1, CommonPrefix('abx',   'abcde'))\n  call assert_equal(-1, CommonPrefix('-abcde', '+abc'))\n  call assert_equal(2, CommonPrefix('abcde', 'abc'))\nendfunction\n\n\nfunction Test_common_suffix()\n  let sid = matchstr(execute('filter autoload/gitgutter/diff_highlight.vim scriptnames'), '\\d\\+')\n  let CommonSuffix = function(\"<SNR>\".sid.\"_common_suffix\")\n\n  \" nothing in common\n  call assert_equal([6,6], CommonSuffix('-abcde', '+pqrst', 0))\n  \" something in common\n  call assert_equal([3,3], CommonSuffix('-abcde', '+pqcde', 0))\n  \" everything in common\n  call assert_equal([5,5], CommonSuffix('-abcde', '+abcde', 5))\n  \" different lengths\n  call assert_equal([4,2], CommonSuffix('-abcde', '+xde', 0))\n  call assert_equal([2,4], CommonSuffix('-xde',   '+abcde', 0))\nendfunction\n\n\n\" Note the order of lists within the overall returned list does not matter.\nfunction Test_diff_highlight()\n  \" Ignores mismatched number of added and removed lines.\n  call assert_equal([], gitgutter#diff_highlight#process(['-foo']))\n  call assert_equal([], gitgutter#diff_highlight#process(['+foo']))\n  call assert_equal([], gitgutter#diff_highlight#process(['-foo','-bar','+baz']))\n\n  \" everything changed\n  let hunk = ['-foo', '+cat']\n  let expected = []\n  call assert_equal(expected, gitgutter#diff_highlight#process(hunk))\n\n  \" change in middle\n  let hunk = ['-foo bar baz', '+foo zip baz']\n  let expected = [[1, '-', 6, 8], [2, '+', 6, 8]]\n  call assert_equal(expected, gitgutter#diff_highlight#process(hunk))\n\n  \" change at start\n  let hunk = ['-foo bar baz', '+zip bar baz']\n  let expected = [[1, '-', 2, 4], [2, '+', 2, 4]]\n  call assert_equal(expected, gitgutter#diff_highlight#process(hunk))\n\n  \" change at end\n  let hunk = ['-foo bar baz', '+foo bar zip']\n  let expected = [[1, '-', 10, 12], [2, '+', 10, 12]]\n  call assert_equal(expected, gitgutter#diff_highlight#process(hunk))\n\n  \" removed in middle\n  let hunk = ['-foo bar baz', '+foo baz']\n  let expected = [[1, '-', 8, 11]]\n  call assert_equal(expected, gitgutter#diff_highlight#process(hunk))\n\n  \" added in middle\n  let hunk = ['-foo baz', '+foo bar baz']\n  let expected = [[2, '+', 8, 11]]\n  call assert_equal(expected, gitgutter#diff_highlight#process(hunk))\n\n  \" two insertions at start\n  let hunk = ['-foo bar baz', '+(foo) bar baz']\n  let expected = [[2, '+', 2, 2], [2, '+', 6, 6]]\n  call assert_equal(expected, gitgutter#diff_highlight#process(hunk))\n\n  \" two insertions in middle\n  let hunk = ['-foo bar baz', '+foo (bar) baz']\n  let expected = [[2, '+', 6, 6], [2, '+', 10, 10]]\n  call assert_equal(expected, gitgutter#diff_highlight#process(hunk))\n\n  \" two insertions at end\n  let hunk = ['-foo bar baz', '+foo bar (baz)']\n  let expected = [[2, '+', 10, 10], [2, '+', 14, 14]]\n  call assert_equal(expected, gitgutter#diff_highlight#process(hunk))\n\n  \" singular insertion\n  let hunk = ['-The cat in the hat.', '+The furry cat in the hat.']\n  call assert_equal([[2, '+', 6, 11]], gitgutter#diff_highlight#process(hunk))\n\n  \" singular deletion\n  let hunk = ['-The cat in the hat.', '+The cat.']\n  call assert_equal([[1, '-', 9, 19]], gitgutter#diff_highlight#process(hunk))\n\n  \" two insertions\n  let hunk = ['-The cat in the hat.', '+The furry cat in the teal hat.']\n  call assert_equal([[2, '+', 6, 11], [2, '+', 22, 26]], gitgutter#diff_highlight#process(hunk))\n\n  \" two deletions\n  let hunk = ['-The furry cat in the teal hat.', '+The cat in the hat.']\n  call assert_equal([[1, '-', 6, 11], [1, '-', 22, 26]], gitgutter#diff_highlight#process(hunk))\n\n  \" two edits\n  let hunk = ['-The cat in the hat.', '+The ox in the box.']\n  call assert_equal([[1, '-', 6, 8], [2, '+', 6, 7], [1, '-', 17, 19], [2, '+', 16, 18]], gitgutter#diff_highlight#process(hunk))\n\n  \" Requires s:gap_between_regions = 2 to pass.\n  \" let hunk = ['-foo: bar.zap', '+foo: quux(bar)']\n  \" call assert_equal([[2, '+', 7, 11], [1, '-', 10, 13], [2, '+', 15, 15]], gitgutter#diff_highlight#process(hunk))\n\n  let hunk = ['-gross_value: transaction.unexplained_amount', '+gross_value: amount(transaction)']\n  call assert_equal([[2, '+', 15, 21], [1, '-', 26, 44], [2, '+', 33, 33]], gitgutter#diff_highlight#process(hunk))\n\n  let hunk = ['-gem \"contact_sport\", \"~> 1.0.2\"', '+gem (\"contact_sport\"), \"~> 1.2\"']\n  call assert_equal([[2, '+', 6, 6], [2, '+', 22, 22], [1, '-', 28, 29]], gitgutter#diff_highlight#process(hunk))\nendfunction\n\n\nfunction Test_lcs()\n  let sid = matchstr(execute('filter autoload/gitgutter/diff_highlight.vim scriptnames'), '\\d\\+')\n  let Lcs = function(\"<SNR>\".sid.\"_lcs\")\n\n  call assert_equal('', Lcs('', 'foo'))\n  call assert_equal('', Lcs('foo', ''))\n  call assert_equal('bar', Lcs('foobarbaz', 'bbart'))\n  call assert_equal('transaction', Lcs('transaction.unexplained_amount', 'amount(transaction)'))\nendfunction\n\n\nfunction Test_split()\n  let sid = matchstr(execute('filter autoload/gitgutter/diff_highlight.vim scriptnames'), '\\d\\+')\n  let Split = function(\"<SNR>\".sid.\"_split\")\n\n  call assert_equal(['foo', 'baz'], Split('foobarbaz', 'bar'))\n  call assert_equal(['', 'barbaz'], Split('foobarbaz', 'foo'))\n  call assert_equal(['foobar', ''], Split('foobarbaz', 'baz'))\n  call assert_equal(['1', '2'], Split('1~2', '~'))\nendfunction\n\n\nfunction Test_foldtext()\n  8d\n  call s:trigger_gitgutter()\n  call assert_equal(0, gitgutter#fold#is_changed())\n\n  let v:foldstart = 5\n  let v:foldend = 9\n  call assert_equal(1, gitgutter#fold#is_changed())\n  call assert_equal('+-  5 lines (*): e', gitgutter#fold#foldtext())\n\n  let v:foldstart = 1\n  let v:foldend = 3\n  call assert_equal(0, gitgutter#fold#is_changed())\n  call assert_equal('+-  3 lines: a', gitgutter#fold#foldtext())\nendfunction\n\n\nfunction Test_assume_unchanged()\n  call system(\"git update-index --assume-unchanged fixture.txt\")\n  unlet b:gitgutter.path  \" it was already set when fixture.txt was loaded in SetUp()\n  normal ggo*\n  call s:trigger_gitgutter()\n  call s:assert_signs([], 'fixture.txt')\nendfunction\n\n\nfunction Test_clean_smudge_filter()\n  call system(\"git config --local include.path ../.gitconfig\")\n  call system(\"rm fixture.foo && git checkout fixture.foo\")\n\n  func! Answer(char)\n    call feedkeys(a:char.\"\\<CR>\")\n  endfunc\n\n  edit fixture.foo\n  call setline(2, ['A'])\n  call setline(4, ['B'])\n  call s:trigger_gitgutter()\n  normal! 2G\n  call timer_start(100, {-> Answer('y')} )\n  GitGutterStageHunk\n  call s:trigger_gitgutter()\n\n  let expected = [\n        \\ {'lnum': 2, 'id': 23, 'name': 'GitGutterLineModified', 'priority': 10, 'group': 'gitgutter'},\n        \\ {'lnum': 4, 'id': 24, 'name': 'GitGutterLineModified', 'priority': 10, 'group': 'gitgutter'}\n        \\ ]\n  \" call s:assert_signs(expected, 'fixture.foo')\n  call s:assert_signs([], 'fixture.foo')\nendfunction\n"
  }
]