[
  {
    "path": ".gitattributes",
    "content": "*.sh text eol=lf\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: junegunn\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/issue.yml",
    "content": "---\nname: Issue Template\ndescription: Report a problem or bug related to fzf.vim to help us improve\n\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Check the version of fzf used by running\n\n        ```vim\n        :echo system(fzf#exec() .. ' --version')\n        ```\n\n        If you don't have the latest version, run the following code to download it\n\n        ```vim\n        :call fzf#install()\n        ```\n\n  - type: checkboxes\n    attributes:\n      label: Checklist\n      options:\n        - label: I have fzf 0.54.0 or later\n          required: true\n        - label: I have searched through the existing issues\n          required: true\n\n  - type: input\n    attributes:\n      label: Output of `:echo system(fzf#exec() .. ' --version')`\n    validations:\n      required: true\n\n  - type: checkboxes\n    attributes:\n      label: OS\n      options:\n        - label: Linux\n        - label: macOS\n        - label: Windows\n        - label: Etc.\n\n  - type: textarea\n    attributes:\n      label: Problem / Steps to reproduce\n    validations:\n      required: true\n"
  },
  {
    "path": ".gitignore",
    "content": "doc/tags\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Junegunn Choi\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"
  },
  {
    "path": "README.md",
    "content": "fzf :heart: vim\n===============\n\nThings you can do with [fzf][fzf] and Vim.\n\nRationale\n---------\n\n[fzf][fzf] itself is not a Vim plugin, and the official repository only\nprovides the [basic wrapper function][run] for Vim. It's up to the users to\nwrite their own Vim commands with it. However, I've learned that many users of\nfzf are not familiar with Vimscript and are looking for the \"default\"\nimplementation of the features they can find in the alternative Vim plugins.\n\nWhy you should use fzf on Vim\n-----------------------------\n\nBecause you can and you love fzf.\n\nfzf runs asynchronously and can be orders of magnitude faster than similar Vim\nplugins. However, the benefit may not be noticeable if the size of the input\nis small, which is the case for many of the commands provided here.\nNevertheless I wrote them anyway since it's really easy to implement custom\nselector with fzf.\n\nInstallation\n------------\n\nfzf.vim depends on the basic Vim plugin of [the main fzf\nrepository][fzf-main], which means you need to **set up both \"fzf\" and\n\"fzf.vim\" on Vim**. To learn more about fzf/Vim integration, see\n[README-VIM][README-VIM].\n\n[fzf-main]: https://github.com/junegunn/fzf\n[README-VIM]: https://github.com/junegunn/fzf/blob/master/README-VIM.md\n\n### Using [vim-plug](https://github.com/junegunn/vim-plug)\n\n```vim\nPlug 'junegunn/fzf', { 'do': { -> fzf#install() } }\nPlug 'junegunn/fzf.vim'\n```\n\n`fzf#install()` makes sure that you have the latest binary, but it's optional,\nso you can omit it if you use a plugin manager that doesn't support hooks.\n\n### Dependencies\n\n- [fzf][fzf-main] 0.54.0 or above\n- For syntax-highlighted preview, install [bat](https://github.com/sharkdp/bat)\n- If [delta](https://github.com/dandavison/delta) is available, `GF?`,\n  `Commits` and `BCommits` will use it to format `git diff` output.\n- `Ag` requires [The Silver Searcher (ag)][ag]\n- `Rg` requires [ripgrep (rg)][rg]\n- `Tags` and `Helptags` require Perl\n- `Tags PREFIX` requires `readtags` command from [Universal Ctags](https://ctags.io/)\n\n```sh\n# Installing dependencies using Homebrew\nbrew install fzf bat ripgrep the_silver_searcher perl universal-ctags\n```\n\nCommands\n--------\n\n| Command                | List                                                                                  |\n| ---                    | ---                                                                                   |\n| `:Files [PATH]`        | Files (runs `$FZF_DEFAULT_COMMAND` if defined)                                        |\n| `:GFiles [OPTS]`       | Git files (`git ls-files`)                                                            |\n| `:GFiles?`             | Git files (`git status`)                                                              |\n| `:Buffers`             | Open buffers                                                                          |\n| `:Colors`              | Color schemes                                                                         |\n| `:Ag [PATTERN]`        | [ag][ag] search result (`ALT-A` to select all, `ALT-D` to deselect all)               |\n| `:Rg [PATTERN]`        | [rg][rg] search result (`ALT-A` to select all, `ALT-D` to deselect all)               |\n| `:RG [PATTERN]`        | [rg][rg] search result; relaunch ripgrep on every keystroke                           |\n| `:Lines [QUERY]`       | Lines in loaded buffers                                                               |\n| `:BLines [QUERY]`      | Lines in the current buffer                                                           |\n| `:Tags [PREFIX]`       | Tags in the project (`ctags -R`)                                                      |\n| `:BTags [QUERY]`       | Tags in the current buffer                                                            |\n| `:Changes`             | Changelist across all open buffers                                                    |\n| `:Marks`               | Marks                                                                                 |\n| `:BMarks`              | Marks in the current buffer                                                           |\n| `:Jumps`               | Jumps                                                                                 |\n| `:Windows`             | Windows                                                                               |\n| `:Locate PATTERN`      | `locate` command output                                                               |\n| `:History`             | `v:oldfiles` and open buffers                                                         |\n| `:History:`            | Command history                                                                       |\n| `:History/`            | Search history                                                                        |\n| `:Snippets`            | Snippets ([UltiSnips][us])                                                            |\n| `:Commits [LOG_OPTS]`  | Git commits (requires [fugitive.vim][f])                                              |\n| `:BCommits [LOG_OPTS]` | Git commits for the current buffer; visual-select lines to track changes in the range |\n| `:Commands`            | Commands                                                                              |\n| `:Maps`                | Normal mode mappings                                                                  |\n| `:Helptags`            | Help tags <sup id=\"a1\">[1](#helptags)</sup>                                           |\n| `:Filetypes`           | File types\n\n- Most commands support `CTRL-T` / `CTRL-X` / `CTRL-V` key\n  bindings to open in a new tab, a new split, or in a new vertical split\n- Bang-versions of the commands (e.g. `Ag!`) will open fzf in fullscreen\n- You can set `g:fzf_vim.command_prefix` to give the same prefix to the commands\n    - e.g. `let g:fzf_vim.command_prefix = 'Fzf'` and you have `FzfFiles`, etc.\n\n(<a name=\"helptags\">1</a>: `Helptags` will shadow the command of the same name\nfrom [pathogen][pat]. But its functionality is still available via `call\npathogen#helptags()`. [↩](#a1))\n\n[pat]: https://github.com/tpope/vim-pathogen\n[f]:   https://github.com/tpope/vim-fugitive\n\nCustomization\n-------------\n\n### Configuration options of the base plugin\n\nEvery command in fzf.vim internally calls `fzf#wrap` function of the main\nrepository which supports a set of global option variables. So please read\nthrough [README-VIM][README-VIM] to learn more about them.\n\n### Configuration options for fzf.vim\n\nAll configuration values for this plugin are stored in `g:fzf_vim` dictionary,\nso **make sure to initialize it before assigning any configuration values to\nit**.\n\n```vim\n\" Initialize configuration dictionary\nlet g:fzf_vim = {}\n```\n\n#### Preview window\n\nSome commands will show the preview window on the right. You can customize the\nbehavior with `g:fzf_vim.preview_window`. Here are some examples:\n\n```vim\n\" This is the default option:\n\"   - Preview window on the right with 50% width\n\"   - CTRL-/ will toggle preview window.\n\" - Note that this array is passed as arguments to fzf#vim#with_preview function.\n\" - To learn more about preview window options, see `--preview-window` section of `man fzf`.\nlet g:fzf_vim.preview_window = ['right,50%', 'ctrl-/']\n\n\" Preview window is hidden by default. You can toggle it with ctrl-/.\n\" It will show on the right with 50% width, but if the width is smaller\n\" than 70 columns, it will show above the candidate list\nlet g:fzf_vim.preview_window = ['hidden,right,50%,<70(up,40%)', 'ctrl-/']\n\n\" Empty value to disable preview window altogether\nlet g:fzf_vim.preview_window = []\n\n\" fzf.vim needs bash to display the preview window.\n\" On Windows, fzf.vim will first see if bash is in $PATH, then if\n\" Git bash (C:\\Program Files\\Git\\bin\\bash.exe) is available.\n\" If you want it to use a different bash, set this variable.\n\"   let g:fzf_vim = {}\n\"   let g:fzf_vim.preview_bash = 'C:\\Git\\bin\\bash.exe'\n```\n\n#### Command-level options\n\n```vim\n\" [Buffers] Jump to the existing window if possible (default: 0)\nlet g:fzf_vim.buffers_jump = 1\n\n\" [Ag|Rg|RG] Display path on a separate line for narrow screens (default: 0)\n\" * Requires Perl and fzf 0.56.0 or later\nlet g:fzf_vim.grep_multi_line = 0\n   \" PATH:LINE:COL:LINE\nlet g:fzf_vim.grep_multi_line = 1\n   \" PATH:LINE:COL:\n   \" LINE\nlet g:fzf_vim.grep_multi_line = 2\n   \" PATH:LINE:COL:\n   \" LINE\n   \" (empty line between items using --gap option)\n\n\" [[B]Commits] Customize the options used by 'git log':\nlet g:fzf_vim.commits_log_options = '--graph --color=always --format=\"%C(auto)%h%d %s %C(black)%C(bold)%cr\"'\n\n\" [Tags] Command to generate tags file\nlet g:fzf_vim.tags_command = 'ctags -R'\n\n\" [Commands] --expect expression for directly executing the command\nlet g:fzf_vim.commands_expect = 'alt-enter,ctrl-x'\n```\n\n#### Command-level fzf options\n\nYou can set fzf options for each command by setting\n`g:fzf_vim.{command}_options`.\n\n```vim\n\" In string\nlet g:fzf_vim.buffers_options = '--style full --border-label \" Open Buffers \"'\n\n\" In list (No need to quote or escape values)\nlet g:fzf_vim.buffers_options = ['--style', 'full', '--border-label', ' Open Buffers ']\n```\n\n#### List type to handle multiple selections\n\nThe following commands will fill the quickfix list when multiple entries are\nselected.\n\n* `Ag`\n* `Rg` / `RG`\n* `Lines` / `BLines`\n* `Tags` / `BTags`\n\nBy setting `g:fzf_vim.listproc`, you can make them use location list instead.\n\n```vim\n\" Default: Use quickfix list\nlet g:fzf_vim.listproc = { list -> fzf#vim#listproc#quickfix(list) }\n\n\" Use location list instead of quickfix list\nlet g:fzf_vim.listproc = { list -> fzf#vim#listproc#location(list) }\n```\n\nYou can customize the list type per command by defining variables named\n`g:fzf_vim.listproc_{command_name_in_lowercase}`.\n\n```vim\n\" Command-wise customization\nlet g:fzf_vim.listproc_ag = { list -> fzf#vim#listproc#quickfix(list) }\nlet g:fzf_vim.listproc_rg = { list -> fzf#vim#listproc#location(list) }\n```\n\nYou can further customize the behavior by providing a custom function to\nprocess the list instead of using the predefined `fzf#vim#listproc#quickfix`\nor `fzf#vim#listproc#location`.\n\n```vim\n\" A customized version of fzf#vim#listproc#quickfix.\n\" The last two lines are commented out not to move to the first entry.\nfunction! g:fzf_vim.listproc(list)\n  call setqflist(a:list)\n  copen\n  wincmd p\n  \" cfirst\n  \" normal! zvzz\nendfunction\n```\n\n### Advanced customization\n\n#### Vim functions\n\nEach command in fzf.vim is backed by a Vim function. You can override\na command or define a variation of it by calling its corresponding function.\n\n| Command   | Vim function                                                                     |\n| ---       | ---                                                                              |\n| `Files`   | `fzf#vim#files(dir, [spec dict], [fullscreen bool])`                             |\n| `GFiles`  | `fzf#vim#gitfiles(git_options, [spec dict], [fullscreen bool])`                  |\n| `GFiles?` | `fzf#vim#gitfiles('?', [spec dict], [fullscreen bool])`                          |\n| `Buffers` | `fzf#vim#buffers([query string], [bufnrs list], [spec dict], [fullscreen bool])` |\n| `Colors`  | `fzf#vim#colors([spec dict], [fullscreen bool])`                                 |\n| `Rg`      | `fzf#vim#grep(command, [spec dict], [fullscreen bool])`                          |\n| `RG`      | `fzf#vim#grep2(command_prefix, query, [spec dict], [fullscreen bool])`           |\n| ...       | ...                                                                              |\n\n(We can see that the last two optional arguments of each function are\nidentical. They are directly passed to `fzf#wrap` function. If you haven't\nread [README-VIM][README-VIM] already, please read it before proceeding.)\n\n#### Example: Customizing `Files` command\n\nThis is the default definition of `Files` command:\n\n```vim\ncommand! -bang -nargs=? -complete=dir Files call fzf#vim#files(<q-args>, <bang>0)\n```\n\nLet's say you want to a variation of it called `ProjectFiles` that only\nsearches inside `~/projects` directory. Then you can do it like this:\n\n```vim\ncommand! -bang ProjectFiles call fzf#vim#files('~/projects', <bang>0)\n```\n\nOr, if you want to override the command with different fzf options, just pass\na custom spec to the function.\n\n```vim\ncommand! -bang -nargs=? -complete=dir Files\n    \\ call fzf#vim#files(<q-args>, {'options': ['--layout=reverse', '--info=inline']}, <bang>0)\n```\n\nWant a preview window?\n\n```vim\ncommand! -bang -nargs=? -complete=dir Files\n    \\ call fzf#vim#files(<q-args>, {'options': ['--layout=reverse', '--info=inline', '--preview', 'cat {}']}, <bang>0)\n```\n\nIt kind of works, but you probably want a nicer previewer program than `cat`.\nfzf.vim ships [a versatile preview script](bin/preview.sh) you can readily\nuse. It internally executes [bat](https://github.com/sharkdp/bat) for syntax\nhighlighting, so make sure to install it.\n\n```vim\ncommand! -bang -nargs=? -complete=dir Files\n    \\ call fzf#vim#files(<q-args>, {'options': ['--layout=reverse', '--info=inline', '--preview', '~/.vim/plugged/fzf.vim/bin/preview.sh {}']}, <bang>0)\n```\n\nHowever, it's not ideal to hard-code the path to the script which can be\ndifferent in different circumstances. So in order to make it easier to set up\nthe previewer, fzf.vim provides `fzf#vim#with_preview` helper function.\nSimilarly to `fzf#wrap`, it takes a spec dictionary and returns a copy of it\nwith additional preview options.\n\n```vim\ncommand! -bang -nargs=? -complete=dir Files\n    \\ call fzf#vim#files(<q-args>, fzf#vim#with_preview({'options': ['--layout=reverse', '--info=inline']}), <bang>0)\n```\n\nYou can just omit the spec argument if you only want the previewer.\n\n```vim\ncommand! -bang -nargs=? -complete=dir Files\n    \\ call fzf#vim#files(<q-args>, fzf#vim#with_preview(), <bang>0)\n```\n\n#### Example: `git grep` wrapper\n\nThe following example implements `GGrep` command that works similarly to\npredefined `Ag` or `Rg` using `fzf#vim#grep`.\n\n- We set the base directory to git root by setting `dir` attribute in spec\n  dictionary.\n- [The preview script](bin/preview.sh) supports `grep` format\n  (`FILE_PATH:LINE_NO:...`), so we can just wrap the spec with\n  `fzf#vim#with_preview` as before to enable previewer.\n\n```vim\ncommand! -bang -nargs=* GGrep\n  \\ call fzf#vim#grep(\n  \\   'git grep --line-number -- '.fzf#shellescape(<q-args>),\n  \\   fzf#vim#with_preview({'dir': systemlist('git rev-parse --show-toplevel')[0]}), <bang>0)\n```\n\nMappings\n--------\n\n| Mapping                            | Description                               |\n| ---                                | ---                                       |\n| `<plug>(fzf-maps-n)`               | Normal mode mappings                      |\n| `<plug>(fzf-maps-i)`               | Insert mode mappings                      |\n| `<plug>(fzf-maps-x)`               | Visual mode mappings                      |\n| `<plug>(fzf-maps-o)`               | Operator-pending mappings                 |\n| `<plug>(fzf-complete-word)`        | `cat /usr/share/dict/words`               |\n| `<plug>(fzf-complete-path)`        | Path completion using `find` (file + dir) |\n| `<plug>(fzf-complete-file)`        | File completion using `find`              |\n| `<plug>(fzf-complete-line)`        | Line completion (all open buffers)        |\n| `<plug>(fzf-complete-buffer-line)` | Line completion (current buffer only)     |\n\n```vim\n\" Mapping selecting mappings\nnmap <leader><tab> <plug>(fzf-maps-n)\nxmap <leader><tab> <plug>(fzf-maps-x)\nomap <leader><tab> <plug>(fzf-maps-o)\n\n\" Insert mode completion\nimap <c-x><c-k> <plug>(fzf-complete-word)\nimap <c-x><c-f> <plug>(fzf-complete-path)\nimap <c-x><c-l> <plug>(fzf-complete-line)\n```\n\nCompletion functions\n--------------------\n\n| Function                                 | Description                           |\n| ---                                      | ---                                   |\n| `fzf#vim#complete#path(command, [spec])` | Path completion                       |\n| `fzf#vim#complete#word([spec])`          | Word completion                       |\n| `fzf#vim#complete#line([spec])`          | Line completion (all open buffers)    |\n| `fzf#vim#complete#buffer_line([spec])`   | Line completion (current buffer only) |\n\n```vim\n\" Path completion with custom source command\ninoremap <expr> <c-x><c-f> fzf#vim#complete#path('fd')\ninoremap <expr> <c-x><c-f> fzf#vim#complete#path('rg --files')\n\n\" Word completion with custom spec with popup layout option\ninoremap <expr> <c-x><c-k> fzf#vim#complete#word({'window': { 'width': 0.2, 'height': 0.9, 'xoffset': 1 }})\n```\n\nCustom completion\n-----------------\n\n`fzf#vim#complete` is a helper function for creating custom fuzzy completion\nusing fzf. If the first parameter is a command string or a Vim list, it will\nbe used as the source.\n\n```vim\n\" Replace the default dictionary completion with fzf-based fuzzy completion\ninoremap <expr> <c-x><c-k> fzf#vim#complete('cat /usr/share/dict/words')\n```\n\nFor advanced uses, you can pass an options dictionary to the function. The set\nof options is pretty much identical to that for `fzf#run` only with the\nfollowing exceptions:\n\n- `reducer` (funcref)\n    - Reducer transforms the output lines of fzf into a single string value\n- `prefix` (string or funcref; default: `\\k*$`)\n    - Regular expression pattern to extract the completion prefix\n    - Or a function to extract completion prefix\n- Both `source` and `options` can be given as funcrefs that take the\n  completion prefix as the argument and return the final value\n- `sink` or `sink*` are ignored\n\n```vim\n\" Global line completion (not just open buffers. ripgrep required.)\ninoremap <expr> <c-x><c-l> fzf#vim#complete(fzf#wrap({\n  \\ 'prefix': '^.*$',\n  \\ 'source': 'rg -n ^ --color always',\n  \\ 'options': '--ansi --delimiter : --nth 3..',\n  \\ 'reducer': { lines -> join(split(lines[0], ':\\zs')[2:], '') }}))\n```\n\n### Reducer example\n\n```vim\nfunction! s:make_sentence(lines)\n  return substitute(join(a:lines), '^.', '\\=toupper(submatch(0))', '').'.'\nendfunction\n\ninoremap <expr> <c-x><c-s> fzf#vim#complete({\n  \\ 'source':  'cat /usr/share/dict/words',\n  \\ 'reducer': function('<sid>make_sentence'),\n  \\ 'options': '--multi --reverse --margin 15%,0',\n  \\ 'left':    20})\n```\n\nStatus line of terminal buffer\n------------------------------\n\nWhen fzf starts in a terminal buffer (see [fzf/README-VIM.md][termbuf]), you\nmay want to customize the statusline of the containing buffer.\n\n[termbuf]: https://github.com/junegunn/fzf/blob/master/README-VIM.md#fzf-inside-terminal-buffer\n\n### Hide statusline\n\n```vim\nautocmd! FileType fzf set laststatus=0 noshowmode noruler\n  \\| autocmd BufLeave <buffer> set laststatus=2 showmode ruler\n```\n\n### Custom statusline\n\n```vim\nfunction! s:fzf_statusline()\n  \" Override statusline as you like\n  highlight fzf1 ctermfg=161 ctermbg=251\n  highlight fzf2 ctermfg=23 ctermbg=251\n  highlight fzf3 ctermfg=237 ctermbg=251\n  setlocal statusline=%#fzf1#\\ >\\ %#fzf2#fz%#fzf3#f\nendfunction\n\nautocmd! User FzfStatusLine call <SID>fzf_statusline()\n```\n\nLicense\n-------\n\nMIT\n\n[fzf]:   https://github.com/junegunn/fzf\n[run]:   https://github.com/junegunn/fzf/blob/master/README-VIM.md#fzfrun\n[ag]:    https://github.com/ggreer/the_silver_searcher\n[rg]:    https://github.com/BurntSushi/ripgrep\n[us]:    https://github.com/SirVer/ultisnips\n"
  },
  {
    "path": "autoload/fzf/vim/complete.vim",
    "content": "\" Copyright (c) 2015 Junegunn Choi\n\"\n\" MIT License\n\"\n\" Permission is hereby granted, free of charge, to any person obtaining\n\" a copy of this software and associated documentation files (the\n\" \"Software\"), to deal in the Software without restriction, including\n\" without limitation the rights to use, copy, modify, merge, publish,\n\" distribute, sublicense, and/or sell copies of the Software, and to\n\" permit persons to whom the Software is furnished to do so, subject to\n\" the following conditions:\n\"\n\" The above copyright notice and this permission notice shall be\n\" included in all copies or substantial portions of the Software.\n\"\n\" THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n\" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n\" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n\" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n\" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n\" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nlet s:cpo_save = &cpo\nset cpo&vim\nlet s:is_win = has('win32') || has('win64')\n\nfunction! s:extend(base, extra)\n  let base = copy(a:base)\n  if has_key(a:extra, 'options')\n    let extra = copy(a:extra)\n    let extra.extra_options = remove(extra, 'options')\n    return extend(base, extra)\n  endif\n  return extend(base, a:extra)\nendfunction\n\nif v:version >= 704\n  function! s:function(name)\n    return function(a:name)\n  endfunction\nelse\n  function! s:function(name)\n    \" By Ingo Karkat\n    return function(substitute(a:name, '^s:', matchstr(expand('<sfile>'), '<SNR>\\d\\+_\\zefunction$'), ''))\n  endfunction\nendif\n\nfunction! fzf#vim#complete#word(...)\n  let sources = empty(&dictionary) ? ['/usr/share/dict/words'] : split(&dictionary, ',')\n  return fzf#vim#complete(s:extend({\n    \\ 'source': 'cat ' . join(map(sources, 'fzf#shellescape(v:val)'))},\n    \\ get(a:000, 0, fzf#wrap())))\nendfunction\n\n\" ----------------------------------------------------------------------------\n\" <plug>(fzf-complete-path)\n\" <plug>(fzf-complete-file)\n\" <plug>(fzf-complete-file-ag)\n\" ----------------------------------------------------------------------------\nfunction! s:file_split_prefix(prefix)\n  let expanded = expand(a:prefix)\n  let slash = (s:is_win && !&shellslash) ? '\\\\' : '/'\n  return isdirectory(expanded) ?\n    \\ [expanded,\n    \\  substitute(a:prefix, '[/\\\\]*$', slash, ''),\n    \\  ''] :\n    \\ [fnamemodify(expanded, ':h'),\n    \\  substitute(fnamemodify(a:prefix, ':h'), '[/\\\\]*$', slash, ''),\n    \\  fnamemodify(expanded, ':t')]\nendfunction\n\nfunction! s:file_source(prefix)\n  let [dir, head, tail] = s:file_split_prefix(a:prefix)\n  return printf(\n    \\ \"cd %s && \".s:file_cmd.\" | sed %s\",\n    \\ fzf#shellescape(dir), fzf#shellescape('s:^:'.(empty(a:prefix) || a:prefix == tail ? '' : head).':'))\nendfunction\n\nfunction! s:file_options(prefix)\n  let [_, head, tail] = s:file_split_prefix(a:prefix)\n  return ['--prompt', head, '--query', tail]\nendfunction\n\nfunction! s:fname_prefix(str)\n  let isf = &isfname\n  let white = []\n  let black = []\n  if isf =~ ',,,'\n    call add(white, ',')\n    let isf = substitute(isf, ',,,', ',', 'g')\n  endif\n  if isf =~ ',^,,'\n    call add(black, ',')\n    let isf = substitute(isf, ',^,,', ',', 'g')\n  endif\n\n  for token in split(isf, ',')\n    let target = white\n    if token[0] == '^'\n      let target = black\n      let token = token[1:]\n    endif\n\n    let ends = matchlist(token, '\\(.\\+\\)-\\(.\\+\\)')\n    if empty(ends)\n      call add(target, token)\n    else\n      let ends = map(ends[1:2], \"len(v:val) == 1 ? char2nr(v:val) : str2nr(v:val)\")\n      for i in range(ends[0], ends[1])\n        call add(target, nr2char(i))\n      endfor\n    endif\n  endfor\n\n  let prefix = a:str\n  for offset in range(1, len(a:str))\n    let char = a:str[len(a:str) - offset]\n    if (char =~ '\\w' || index(white, char) >= 0) && index(black, char) < 0\n      continue\n    endif\n    let prefix = strpart(a:str, len(a:str) - offset + 1)\n    break\n  endfor\n\n  return prefix\nendfunction\n\nfunction! fzf#vim#complete#path(command, ...)\n  let s:file_cmd = a:command\n  return fzf#vim#complete(s:extend({\n  \\ 'prefix':  s:function('s:fname_prefix'),\n  \\ 'source':  s:function('s:file_source'),\n  \\ 'options': s:function('s:file_options')}, get(a:000, 0, fzf#wrap())))\nendfunction\n\n\" ----------------------------------------------------------------------------\n\" <plug>(fzf-complete-line)\n\" <plug>(fzf-complete-buffer-line)\n\" ----------------------------------------------------------------------------\nfunction! s:reduce_line(lines)\n  return join(split(a:lines[0], '\\t\\zs')[3:], '')\nendfunction\n\n\nfunction! fzf#vim#complete#line(...)\n  let [display_bufnames, lines] = fzf#vim#_lines(0)\n  let nth = display_bufnames ? 4 : 3\n  return fzf#vim#complete(s:extend({\n  \\ 'prefix':  '^.*$',\n  \\ 'source':  lines,\n  \\ 'options': '--tiebreak=index --ansi --nth '.nth.'.. --tabstop=1',\n  \\ 'reducer': s:function('s:reduce_line')}, get(a:000, 0, fzf#wrap())))\nendfunction\n\nfunction! fzf#vim#complete#buffer_line(...)\n  return fzf#vim#complete(s:extend({\n  \\ 'prefix': '^.*$',\n  \\ 'source': fzf#vim#_uniq(getline(1, '$'))}, get(a:000, 0, fzf#wrap())))\nendfunction\n\nlet &cpo = s:cpo_save\nunlet s:cpo_save\n\n"
  },
  {
    "path": "autoload/fzf/vim/ipc.vim",
    "content": "\" Copyright (c) 2024 Junegunn Choi\n\"\n\" MIT License\n\"\n\" Permission is hereby granted, free of charge, to any person obtaining\n\" a copy of this software and associated documentation files (the\n\" \"Software\"), to deal in the Software without restriction, including\n\" without limitation the rights to use, copy, modify, merge, publish,\n\" distribute, sublicense, and/or sell copies of the Software, and to\n\" permit persons to whom the Software is furnished to do so, subject to\n\" the following conditions:\n\"\n\" The above copyright notice and this permission notice shall be\n\" included in all copies or substantial portions of the Software.\n\"\n\" THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n\" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n\" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n\" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n\" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n\" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction! s:warn(message)\n  echohl WarningMsg\n  echom a:message\n  echohl None\n  return 0\nendfunction\n\nfunction! fzf#vim#ipc#start(Callback)\n  if !exists('*job_start') && !exists('*jobstart')\n    call s:warn('job_start/jobstart function not supported')\n    return ''\n  endif\n\n  if !executable('mkfifo')\n    call s:warn('mkfifo is not available')\n    return ''\n  endif\n\n  call fzf#vim#ipc#stop()\n\n  let g:fzf_ipc = { 'fifo': tempname(), 'callback': a:Callback }\n  if !filereadable(g:fzf_ipc.fifo)\n    call system('mkfifo '..shellescape(g:fzf_ipc.fifo))\n    if v:shell_error\n      call s:warn('Failed to create fifo')\n    endif\n  endif\n\n  call fzf#vim#ipc#restart()\n\n  return g:fzf_ipc.fifo\nendfunction\n\nfunction! fzf#vim#ipc#restart()\n  if !exists('g:fzf_ipc')\n    throw 'fzf#vim#ipc not started'\n  endif\n\n  let Callback = g:fzf_ipc.callback\n  if exists('*job_start')\n    let g:fzf_ipc.job = job_start(\n          \\ ['cat', g:fzf_ipc.fifo],\n          \\ {'out_cb': { _, msg -> call(Callback, [msg]) },\n          \\  'exit_cb': { _, status -> status == 0 ? fzf#vim#ipc#restart() : '' }}\n          \\ )\n  else\n    let eof = ['']\n    let g:fzf_ipc.job = jobstart(\n          \\ ['cat', g:fzf_ipc.fifo],\n          \\ {'stdout_buffered': 1,\n          \\  'on_stdout': { j, msg, e -> msg != eof ? call(Callback, msg) : '' },\n          \\  'on_exit': { j, status, e -> status == 0 ? fzf#vim#ipc#restart() : '' }}\n          \\ )\n  endif\nendfunction\n\nfunction! fzf#vim#ipc#stop()\n  if !exists('g:fzf_ipc')\n    return\n  endif\n\n  let job = g:fzf_ipc.job\n  if exists('*job_stop')\n    call job_stop(job)\n  else\n    call jobstop(job)\n    call jobwait([job])\n  endif\n\n  call delete(g:fzf_ipc.fifo)\n  unlet g:fzf_ipc\nendfunction\n"
  },
  {
    "path": "autoload/fzf/vim/listproc.vim",
    "content": "\" Copyright (c) 2023 Junegunn Choi\n\"\n\" MIT License\n\"\n\" Permission is hereby granted, free of charge, to any person obtaining\n\" a copy of this software and associated documentation files (the\n\" \"Software\"), to deal in the Software without restriction, including\n\" without limitation the rights to use, copy, modify, merge, publish,\n\" distribute, sublicense, and/or sell copies of the Software, and to\n\" permit persons to whom the Software is furnished to do so, subject to\n\" the following conditions:\n\"\n\" The above copyright notice and this permission notice shall be\n\" included in all copies or substantial portions of the Software.\n\"\n\" THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n\" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n\" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n\" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n\" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n\" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction! fzf#vim#listproc#quickfix(list)\n  call setqflist(a:list)\n  copen\n  wincmd p\n  cfirst\n  normal! zvzz\nendfunction\n\nfunction! fzf#vim#listproc#location(list)\n  call setloclist(0, a:list)\n  lopen\n  wincmd p\n  lfirst\n  normal! zvzz\nendfunction\n"
  },
  {
    "path": "autoload/fzf/vim.vim",
    "content": "\" Copyright (c) 2023 Junegunn Choi\n\"\n\" MIT License\n\"\n\" Permission is hereby granted, free of charge, to any person obtaining\n\" a copy of this software and associated documentation files (the\n\" \"Software\"), to deal in the Software without restriction, including\n\" without limitation the rights to use, copy, modify, merge, publish,\n\" distribute, sublicense, and/or sell copies of the Software, and to\n\" permit persons to whom the Software is furnished to do so, subject to\n\" the following conditions:\n\"\n\" The above copyright notice and this permission notice shall be\n\" included in all copies or substantial portions of the Software.\n\"\n\" THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n\" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n\" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n\" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n\" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n\" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nlet s:cpo_save = &cpo\nset cpo&vim\n\n\" ------------------------------------------------------------------\n\" Common\n\" ------------------------------------------------------------------\n\nfunction! s:conf(name, default)\n  let conf = get(g:, 'fzf_vim', {})\n  return get(conf, a:name, get(g:, 'fzf_' . a:name, a:default))\nendfunction\n\nlet s:winpath = {}\nfunction! s:winpath(path)\n  if has_key(s:winpath, a:path)\n    return s:winpath[a:path]\n  endif\n\n  let winpath = split(system('for %A in (\"'.a:path.'\") do @echo %~sA'), \"\\n\")[0]\n  let s:winpath[a:path] = winpath\n\n  return winpath\nendfunction\n\nlet s:warned = 0\nfunction! s:bash()\n  if exists('s:bash')\n    return s:bash\n  endif\n\n  let custom_bash = s:conf('preview_bash', '')\n  let git_bash = 'C:\\Program Files\\Git\\bin\\bash.exe'\n  let scoop_git_bash = exists('$GIT_INSTALL_ROOT') ? $GIT_INSTALL_ROOT . '\\bin\\bash.exe' : ''\n  let candidates = filter(s:is_win ? [custom_bash, git_bash, scoop_git_bash, 'bash'] : [custom_bash, 'bash'], 'len(v:val)')\n\n  let found = filter(map(copy(candidates), 'exepath(v:val)'), 'len(v:val)')\n  if empty(found)\n    if !s:warned\n      call s:warn(printf('Preview window not supported (%s not found)', join(candidates, ', ')))\n      let s:warned = 1\n    endif\n    let s:bash = ''\n    return s:bash\n  endif\n\n  let s:bash = found[0]\n\n  \" Make 8.3 filename via cmd.exe\n  if s:is_win\n    let s:bash = s:winpath(s:bash)\n  endif\n\n  return s:bash\nendfunction\n\nfunction! s:escape_for_bash(path)\n  if !s:is_win\n    return fzf#shellescape(a:path)\n  endif\n\n  if !exists('s:is_linux_like_bash')\n    call system(s:bash . ' -c \"ls /mnt/[A-Za-z]\"')\n    let s:is_linux_like_bash = v:shell_error == 0\n  endif\n\n  let path = substitute(a:path, '\\', '/', 'g')\n  if s:is_linux_like_bash\n    let path = substitute(path, '^\\([A-Z]\\):', '/mnt/\\L\\1', '')\n  endif\n\n  return escape(path, ' ')\nendfunction\n\nlet s:min_version = '0.56.0'\nlet s:is_win = has('win32') || has('win64')\nlet s:is_wsl_bash = s:is_win && (exepath('bash') =~? 'Windows[/\\\\]system32[/\\\\]bash.exe$')\nlet s:layout_keys = ['window', 'up', 'down', 'left', 'right']\nlet s:bin_dir = expand('<sfile>:p:h:h:h').'/bin/'\nlet s:bin = {\n\\ 'preview': s:bin_dir.'preview.sh',\n\\ 'tags':    s:bin_dir.'tags.pl' }\nlet s:TYPE = {'bool': type(0), 'dict': type({}), 'funcref': type(function('call')), 'string': type(''), 'list': type([])}\n\nlet s:wide = 120\nlet s:checked = 0\n\nfunction! s:check_requirements()\n  if s:checked\n    return\n  endif\n\n  if !exists('*fzf#run')\n    throw \"fzf#run function not found. You also need Vim plugin from the main fzf repository (i.e. junegunn/fzf *and* junegunn/fzf.vim)\"\n  endif\n  if !exists('*fzf#exec')\n    throw \"fzf#exec function not found. You need to upgrade Vim plugin from the main fzf repository ('junegunn/fzf')\"\n  endif\n  let s:checked = !empty(fzf#exec(s:min_version))\nendfunction\n\nfunction! s:extend_opts(dict, eopts, prepend)\n  if empty(a:eopts)\n    return\n  endif\n  if has_key(a:dict, 'options')\n    if type(a:dict.options) == s:TYPE.list && type(a:eopts) == s:TYPE.list\n      if a:prepend\n        let a:dict.options = extend(copy(a:eopts), a:dict.options)\n      else\n        call extend(a:dict.options, a:eopts)\n      endif\n    else\n      let all_opts = a:prepend ? [a:eopts, a:dict.options] : [a:dict.options, a:eopts]\n      let a:dict.options = join(map(all_opts, 'type(v:val) == s:TYPE.list ? join(map(copy(v:val), \"fzf#shellescape(v:val)\")) : v:val'))\n    endif\n  else\n    let a:dict.options = a:eopts\n  endif\nendfunction\n\nfunction! s:merge_opts(dict, eopts)\n  return s:extend_opts(a:dict, a:eopts, 0)\nendfunction\n\nfunction! s:prepend_opts(dict, eopts)\n  return s:extend_opts(a:dict, a:eopts, 1)\nendfunction\n\n\" [spec to wrap], [preview window expression], [toggle-preview keys...]\nfunction! fzf#vim#with_preview(...)\n  \" Default spec\n  let spec = {}\n  let window = ''\n\n  let args = copy(a:000)\n\n  \" Spec to wrap\n  if len(args) && type(args[0]) == s:TYPE.dict\n    let spec = copy(args[0])\n    call remove(args, 0)\n  endif\n\n  if !executable(s:bash())\n    return spec\n  endif\n\n  \" Placeholder expression (TODO/TBD: undocumented)\n  let placeholder = get(spec, 'placeholder', '{}')\n\n  \" g:fzf_preview_window\n  if empty(args)\n    let preview_args = s:conf('preview_window', ['', 'ctrl-/'])\n    if empty(preview_args)\n      let args = ['hidden']\n    else\n      \" For backward-compatiblity\n      let args = type(preview_args) == type('') ? [preview_args] : copy(preview_args)\n    endif\n  endif\n\n  if len(args) && type(args[0]) == s:TYPE.string\n    if len(args[0]) && args[0] !~# '^\\(up\\|down\\|left\\|right\\|hidden\\)'\n      throw 'invalid preview window: '.args[0]\n    endif\n    let window = args[0]\n    call remove(args, 0)\n  endif\n\n  let preview = []\n  if len(window)\n    let preview += ['--preview-window', window]\n  endif\n  if s:is_win\n    if empty($MSWINHOME)\n      let $MSWINHOME = $HOME\n    endif\n    if s:is_wsl_bash && $WSLENV !~# '[:]\\?MSWINHOME\\(\\/[^:]*\\)\\?\\(:\\|$\\)'\n      let $WSLENV = 'MSWINHOME/u:'.$WSLENV\n    endif\n  endif\n  let preview_cmd = s:bash() . ' ' . s:escape_for_bash(s:bin.preview)\n  if len(placeholder)\n    let preview += ['--preview', preview_cmd.' '.placeholder]\n  end\n  if &ambiwidth ==# 'double'\n    let preview += ['--no-unicode']\n  end\n\n  if len(args)\n    call extend(preview, ['--bind', join(map(args, 'v:val.\":toggle-preview\"'), ',')])\n  endif\n  call s:merge_opts(spec, preview)\n  return spec\nendfunction\n\nfunction! s:remove_layout(opts)\n  for key in s:layout_keys\n    if has_key(a:opts, key)\n      call remove(a:opts, key)\n    endif\n  endfor\n  return a:opts\nendfunction\n\nfunction! s:reverse_list(opts)\n  let tokens = map(split($FZF_DEFAULT_OPTS, '[^a-z-]'), 'substitute(v:val, \"^--\", \"\", \"\")')\n  if index(tokens, 'reverse') < 0\n    return extend(['--layout=reverse-list'], a:opts)\n  endif\n  return a:opts\nendfunction\n\nfunction! s:wrap(name, opts, bang)\n  \" fzf#wrap does not append --expect if sink or sink* is found\n  let opts = copy(a:opts)\n  let options = ''\n  if has_key(opts, 'options')\n    let options = type(opts.options) == s:TYPE.list ? join(opts.options) : opts.options\n  endif\n  if options !~ '--expect' && has_key(opts, 'sink*')\n    let Sink = remove(opts, 'sink*')\n    let wrapped = fzf#wrap(a:name, opts, a:bang)\n    let wrapped['sink*'] = Sink\n  else\n    let wrapped = fzf#wrap(a:name, opts, a:bang)\n  endif\n  return wrapped\nendfunction\n\nfunction! s:strip(str)\n  return substitute(a:str, '^\\s*\\|\\s*$', '', 'g')\nendfunction\n\nfunction! s:rstrip(str)\n  return substitute(a:str, '\\s*$', '', 'g')\nendfunction\n\nfunction! s:chomp(str)\n  return substitute(a:str, '\\n*$', '', 'g')\nendfunction\n\nfunction! s:escape(path)\n  let path = fnameescape(a:path)\n  return s:is_win ? escape(path, '$') : path\nendfunction\n\nif v:version >= 704\n  function! s:function(name)\n    return function(a:name)\n  endfunction\nelse\n  function! s:function(name)\n    \" By Ingo Karkat\n    return function(substitute(a:name, '^s:', matchstr(expand('<sfile>'), '<SNR>\\d\\+_\\zefunction$'), ''))\n  endfunction\nendif\n\nfunction! s:get_color(attr, ...)\n  let gui = has('termguicolors') && &termguicolors\n  let fam = gui ? 'gui' : 'cterm'\n  let pat = gui ? '^#[a-f0-9]\\+' : '^[0-9]\\+$'\n  for group in a:000\n    let code = synIDattr(synIDtrans(hlID(group)), a:attr, fam)\n    if code =~? pat\n      return code\n    endif\n  endfor\n  return ''\nendfunction\n\nlet s:ansi = {'black': 30, 'red': 31, 'green': 32, 'yellow': 33, 'blue': 34, 'magenta': 35, 'cyan': 36}\n\nfunction! s:csi(color, fg)\n  let prefix = a:fg ? '38;' : '48;'\n  if a:color[0] == '#'\n    return prefix.'2;'.join(map([a:color[1:2], a:color[3:4], a:color[5:6]], 'str2nr(v:val, 16)'), ';')\n  endif\n  return prefix.'5;'.a:color\nendfunction\n\nfunction! s:ansi(str, group, default, ...)\n  let fg = s:get_color('fg', a:group)\n  let bg = s:get_color('bg', a:group)\n  let color = (empty(fg) ? s:ansi[a:default] : s:csi(fg, 1)) .\n        \\ (empty(bg) ? '' : ';'.s:csi(bg, 0))\n  return printf(\"\\x1b[%s%sm%s\\x1b[m\", color, a:0 ? ';1' : '', a:str)\nendfunction\n\nfor s:color_name in keys(s:ansi)\n  execute \"function! s:\".s:color_name.\"(str, ...)\\n\"\n        \\ \"  return s:ansi(a:str, get(a:, 1, ''), '\".s:color_name.\"')\\n\"\n        \\ \"endfunction\"\nendfor\n\nfunction! s:buflisted()\n  return filter(range(1, bufnr('$')), 'buflisted(v:val) && getbufvar(v:val, \"&filetype\") != \"qf\"')\nendfunction\n\nfunction! s:fzf(name, opts, extra)\n  call s:check_requirements()\n\n  let [extra, bang] = [{}, 0]\n  if len(a:extra) <= 1\n    let first = get(a:extra, 0, 0)\n    if type(first) == s:TYPE.dict\n      let extra = first\n    else\n      let bang = first\n    endif\n  elseif len(a:extra) == 2\n    let [extra, bang] = a:extra\n  else\n    throw 'invalid number of arguments'\n  endif\n\n  let extra  = copy(extra)\n  let eopts  = has_key(extra, 'options') ? remove(extra, 'options') : ''\n  let merged = extend(copy(a:opts), extra)\n  call s:merge_opts(merged, eopts)\n\n  \" Command-level fzf options\n  call s:merge_opts(merged, s:conf(a:name.'_options', []))\n\n  return fzf#run(s:wrap(a:name, merged, bang))\nendfunction\n\nlet s:default_action = {\n  \\ 'ctrl-t': 'tab split',\n  \\ 'ctrl-x': 'split',\n  \\ 'ctrl-v': 'vsplit' }\n\nfunction! s:execute_silent(cmd)\n  silent keepjumps keepalt execute a:cmd\nendfunction\n\n\" [key, [filename, [stay_on_edit: 0]]]\nfunction! s:action_for(key, ...)\n  let Cmd = get(get(g:, 'fzf_action', s:default_action), a:key, '')\n  let cmd = type(Cmd) == s:TYPE.string ? Cmd : ''\n\n  \" See If the command is the default action that opens the selected file in\n  \" the current window. i.e. :edit\n  let edit = stridx('edit', cmd) == 0 \" empty, e, ed, ..\n\n  \" If no extra argument is given, we just execute the command and ignore\n  \" errors. e.g. E471: Argument required: tab drop\n  if !a:0\n    if !edit\n      call setpos(\"''\", getpos('.'))\n      silent! call s:execute_silent(cmd)\n    endif\n  else\n    \" For the default edit action, we don't execute the action if the\n    \" selected file is already opened in the current window, or we are\n    \" instructed to stay on the current buffer.\n    let stay = edit && (a:0 > 1 && a:2 || fnamemodify(a:1, ':p') ==# expand('%:p'))\n    if !stay\n      call setpos(\"''\", getpos('.'))\n      call s:execute_silent((len(cmd) ? cmd : 'edit').' '.s:escape(a:1))\n    endif\n  endif\nendfunction\n\nfunction! s:open(target)\n  if fnamemodify(a:target, ':p') ==# expand('%:p')\n    return\n  endif\n  execute 'edit' s:escape(a:target)\nendfunction\n\nfunction! s:align_lists(lists)\n  let maxes = {}\n  for list in a:lists\n    let i = 0\n    while i < len(list)\n      let maxes[i] = max([get(maxes, i, 0), len(list[i])])\n      let i += 1\n    endwhile\n  endfor\n  for list in a:lists\n    call map(list, \"printf('%-'.maxes[v:key].'s', v:val)\")\n  endfor\n  return a:lists\nendfunction\n\nfunction! s:warn(message)\n  echohl WarningMsg\n  echom a:message\n  echohl None\n  return 0\nendfunction\n\nfunction! s:fill_quickfix(name, list)\n  if len(a:list) > 1\n    let Handler = s:conf('listproc_'.a:name, s:conf('listproc', function('fzf#vim#listproc#quickfix')))\n    call call(Handler, [a:list], {})\n    return 1\n  endif\n  return 0\nendfunction\n\nfunction! fzf#vim#_uniq(list)\n  let visited = {}\n  let ret = []\n  for l in a:list\n    if !empty(l) && !has_key(visited, l)\n      call add(ret, l)\n      let visited[l] = 1\n    endif\n  endfor\n  return ret\nendfunction\n\n\" ------------------------------------------------------------------\n\" Files\n\" ------------------------------------------------------------------\nfunction! s:shortpath()\n  let short = fnamemodify(getcwd(), ':~:.')\n  if !has('win32unix')\n    let short = pathshorten(short)\n  endif\n  let slash = (s:is_win && !&shellslash) ? '\\' : '/'\n  return empty(short) ? '~'.slash : short . (short =~ escape(slash, '\\').'$' ? '' : slash)\nendfunction\n\nfunction! fzf#vim#files(dir, ...)\n  let args = {}\n  if !empty(a:dir)\n    if !isdirectory(expand(a:dir))\n      return s:warn('Invalid directory')\n    endif\n    let slash = (s:is_win && !&shellslash) ? '\\\\' : '/'\n    let dir = substitute(a:dir, '[/\\\\]*$', slash, '')\n    let args.dir = dir\n  else\n    let dir = s:shortpath()\n  endif\n\n  let args.options = ['--scheme', 'path', '-m', '--prompt', strwidth(dir) < &columns / 2 - 20 ? dir : '> ']\n  call s:merge_opts(args, s:conf('files_options', []))\n  return s:fzf('files', args, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Lines\n\" ------------------------------------------------------------------\nfunction! s:line_handler(lines)\n  if len(a:lines) < 2\n    return\n  endif\n\n  let qfl = []\n  for line in a:lines[1:]\n    let chunks = split(line, \"\\t\", 1)\n    call add(qfl, {'bufnr': str2nr(chunks[0]), 'lnum': str2nr(chunks[2]), 'text': join(chunks[3:], \"\\t\")})\n  endfor\n\n  call s:action_for(a:lines[0])\n  if !s:fill_quickfix('lines', qfl)\n    let chunks = split(a:lines[1], '\\t')\n    execute 'buffer' chunks[0]\n    execute chunks[2]\n  endif\n  normal! ^zvzz\nendfunction\n\nfunction! fzf#vim#_lines(all)\n  let cur = []\n  let rest = []\n  let buf = bufnr('')\n  let longest_name = 0\n  let display_bufnames = &columns > s:wide\n  if display_bufnames\n    let bufnames = {}\n    for b in s:buflisted()\n      let bufnames[b] = pathshorten(fnamemodify(bufname(b), \":~:.\"))\n      let longest_name = max([longest_name, len(bufnames[b])])\n    endfor\n  endif\n  let len_bufnames = min([15, longest_name])\n  for b in s:buflisted()\n    let lines = getbufline(b, 1, \"$\")\n    if empty(lines)\n      let path = fnamemodify(bufname(b), ':p')\n      let lines = filereadable(path) ? readfile(path) : []\n    endif\n    if display_bufnames\n      let bufname = bufnames[b]\n      if len(bufname) > len_bufnames + 1\n        let bufname = '…' . bufname[-len_bufnames+1:]\n      endif\n      let bufname = printf(s:green(\"%\".len_bufnames.\"s\", \"Directory\"), bufname)\n    else\n      let bufname = ''\n    endif\n    let linefmt = s:blue(\"%2d\\t\", \"TabLine\").\"%s\".s:yellow(\"\\t%4d \", \"LineNr\").\"\\t%s\"\n    call extend(b == buf ? cur : rest,\n    \\ filter(\n    \\   map(lines,\n    \\       '(!a:all && empty(v:val)) ? \"\" : printf(linefmt, b, bufname, v:key + 1, v:val)'),\n    \\   'a:all || !empty(v:val)'))\n  endfor\n  return [display_bufnames, extend(cur, rest)]\nendfunction\n\nfunction! fzf#vim#lines(...)\n  let [display_bufnames, lines] = fzf#vim#_lines(1)\n  let nth = display_bufnames ? 3 : 2\n  let [query, args] = (a:0 && type(a:1) == type('')) ?\n        \\ [a:1, a:000[1:]] : ['', a:000]\n  return s:fzf('lines', {\n  \\ 'source':  lines,\n  \\ 'sink*':   s:function('s:line_handler'),\n  \\ 'options': s:reverse_list(['--tiebreak=index', '--prompt', 'Lines> ', '--ansi', '--extended', '--nth='.nth.'..', '--tabstop=1', '--query', query, '--multi'])\n  \\}, args)\nendfunction\n\n\" ------------------------------------------------------------------\n\" BLines\n\" ------------------------------------------------------------------\nfunction! s:buffer_line_handler(lines)\n  if len(a:lines) < 2\n    return\n  endif\n  let qfl = []\n  for line in a:lines[1:]\n    let chunks = split(line, \"\\t\", 1)\n    let ln = chunks[0]\n    let ltxt = join(chunks[1:], \"\\t\")\n    call add(qfl, {'filename': expand('%'), 'lnum': str2nr(ln), 'text': ltxt})\n  endfor\n  call s:action_for(a:lines[0])\n  if !s:fill_quickfix('blines', qfl)\n    execute split(a:lines[1], '\\t')[0]\n  endif\n  normal! ^zvzz\nendfunction\n\nfunction! s:buffer_lines(query)\n  let linefmt = s:yellow(\" %4d \", \"LineNr\").\"\\t%s\"\n  let fmtexpr = 'printf(linefmt, v:key + 1, v:val)'\n  let lines = getline(1, '$')\n  if empty(a:query)\n    return map(lines, fmtexpr)\n  end\n  return filter(map(lines, 'v:val =~ a:query ? '.fmtexpr.' : \"\"'), 'len(v:val)')\nendfunction\n\nfunction! fzf#vim#buffer_lines(...)\n  let [query, args] = (a:0 && type(a:1) == type('')) ?\n        \\ [a:1, a:000[1:]] : ['', a:000]\n  return s:fzf('blines', {\n  \\ 'source':  s:buffer_lines(query),\n  \\ 'sink*':   s:function('s:buffer_line_handler'),\n  \\ 'options': s:reverse_list(['+m', '--tiebreak=index', '--multi', '--prompt', 'BLines> ', '--ansi', '--extended', '--nth=2..', '--tabstop=1'])\n  \\}, args)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Colors\n\" ------------------------------------------------------------------\nfunction! s:colors_exit(code)\n  if exists('s:colors_name')\n    if a:code > 0 && s:colors_name != g:colors_name\n      execute 'colo' s:colors_name\n    endif\n    unlet s:colors_name\n  endif\n  call fzf#vim#ipc#stop()\nendfunction\n\nfunction! fzf#vim#colors(...)\n  let colors = split(globpath(&rtp, \"colors/*.vim\"), \"\\n\")\n  if has('packages')\n    let colors += split(globpath(&packpath, \"pack/*/opt/*/colors/*.vim\"), \"\\n\")\n  endif\n  let colors = fzf#vim#_uniq(map(colors, \"fnamemodify(v:val, ':t')[:-5]\"))\n\n  \" Put the current colorscheme at the top\n  if exists('g:colors_name')\n    let s:colors_name = g:colors_name\n    let colors = [g:colors_name] + filter(colors, 'g:colors_name != v:val')\n  endif\n\n  let spec = {\n  \\ 'source':  colors,\n  \\ 'sink':    'colo',\n  \\ 'options': ['+m', '--prompt', 'Colors> ']\n  \\}\n\n  if !a:1 \" We can't set up IPC in fullscreen mode in Vim\n    let fifo = fzf#vim#ipc#start({ msg -> execute('colo '.msg) })\n    if len(fifo)\n      call extend(spec.options, ['--no-tmux', '--no-padding', '--no-margin', '--bind', 'focus:execute-silent:echo {} > '.fifo])\n      let spec.exit = s:function('s:colors_exit')\n      let maxwidth = max(map(copy(colors), 'strwidth(v:val)'))\n      let spec.window = { 'width': maxwidth + 8, 'height': len(colors) + 5 }\n    endif\n  endif\n\n  call s:fzf('colors', spec, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Locate\n\" ------------------------------------------------------------------\nfunction! fzf#vim#locate(query, ...)\n  return s:fzf('locate', {\n  \\ 'source':  'locate '.a:query,\n  \\ 'options': '-m --prompt \"Locate> \"'\n  \\}, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" History[:/]\n\" ------------------------------------------------------------------\nfunction! fzf#vim#_recent_files()\n  return fzf#vim#_uniq(map(\n    \\ filter([expand('%')], 'len(v:val)')\n    \\   + filter(map(fzf#vim#_buflisted_sorted(), 'bufname(v:val)'), 'len(v:val)')\n    \\   + filter(copy(v:oldfiles), \"filereadable(fnamemodify(v:val, ':p'))\"),\n    \\ 'fnamemodify(v:val, \":~:.\")'))\nendfunction\n\nfunction! s:history_source(type)\n  let max = histnr(a:type)\n  if max <= 0\n    return ['No entries']\n  endif\n  let fmt = s:yellow(' %'.len(string(max)).'d ', 'Number')\n  let list = filter(map(range(1, max), 'histget(a:type, - v:val)'), '!empty(v:val)')\n  return extend([' :: Press '.s:magenta('CTRL-E', 'Special').' to edit'],\n    \\ map(list, 'printf(fmt, len(list) - v:key).\" \".v:val'))\nendfunction\n\nnnoremap <plug>(-fzf-vim-do) :execute g:__fzf_command<cr>\nnnoremap <plug>(-fzf-/) /\nnnoremap <plug>(-fzf-:) :\n\nfunction! s:history_sink(type, lines)\n  if len(a:lines) < 2\n    return\n  endif\n\n  let prefix = \"\\<plug>(-fzf-\".a:type.')'\n  let key  = a:lines[0]\n  let item = matchstr(a:lines[1], ' *[0-9]\\+ *\\zs.*')\n  if key == 'ctrl-e'\n    redraw\n    call feedkeys(a:type.item, 'nt')\n  else\n    if a:type == ':'\n      call histadd(a:type, item)\n    endif\n    let g:__fzf_command = \"normal \".prefix.item.\"\\<cr>\"\n    call feedkeys(\"\\<plug>(-fzf-vim-do)\")\n  endif\nendfunction\n\nfunction! s:cmd_history_sink(lines)\n  call s:history_sink(':', a:lines)\nendfunction\n\nfunction! fzf#vim#command_history(...)\n  return s:fzf('history-command', {\n  \\ 'source':  s:history_source(':'),\n  \\ 'sink*':   s:function('s:cmd_history_sink'),\n  \\ 'options': '+m --ansi --prompt=\"Hist:> \" --header-lines=1 --expect=ctrl-e --tiebreak=index'}, a:000)\nendfunction\n\nfunction! s:search_history_sink(lines)\n  call s:history_sink('/', a:lines)\nendfunction\n\nfunction! fzf#vim#search_history(...)\n  return s:fzf('history-search', {\n  \\ 'source':  s:history_source('/'),\n  \\ 'sink*':   s:function('s:search_history_sink'),\n  \\ 'options': '+m --ansi --prompt=\"Hist/> \" --header-lines=1 --expect=ctrl-e --tiebreak=index'}, a:000)\nendfunction\n\nfunction! fzf#vim#history(...)\n  return s:fzf('history-files', {\n  \\ 'source':  fzf#vim#_recent_files(),\n  \\ 'options': ['-m', '--header-lines', !empty(expand('%')), '--prompt', 'Hist> ']\n  \\}, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" GFiles[?]\n\" ------------------------------------------------------------------\n\nfunction! s:get_git_root(dir)\n  if empty(a:dir) && exists('*FugitiveWorkTree')\n    return FugitiveWorkTree()\n  endif\n  let dir = len(a:dir) ? a:dir : substitute(split(expand('%:p:h'), '[/\\\\]\\.git\\([/\\\\]\\|$\\)')[0], '^fugitive://', '', '')\n  silent let root = systemlist('git -C ' . shellescape(dir) . ' rev-parse --show-toplevel')[0]\n  return v:shell_error ? '' : (len(a:dir) ? fnamemodify(a:dir, ':p') : root)\nendfunction\n\nfunction! s:version_requirement(val, min)\n  for idx in range(0, len(a:min) - 1)\n    let v = get(a:val, idx, 0)\n    if     v < a:min[idx] | return 0\n    elseif v > a:min[idx] | return 1\n    endif\n  endfor\n  return 1\nendfunction\n\nfunction! s:git_version_requirement(...)\n  if !exists('s:git_version')\n    let s:git_version = map(split(split(system('git --version'))[2], '\\.'), 'str2nr(v:val)')\n  endif\n  return s:version_requirement(s:git_version, a:000)\nendfunction\n\nfunction! fzf#vim#gitfiles(args, ...)\n  let dir = get(get(a:, 1, {}), 'dir', '')\n  let root = s:get_git_root(dir)\n  if empty(root)\n    return s:warn('Not in git repo')\n  endif\n  let prefix = 'git -C ' . fzf#shellescape(root) . ' '\n  if a:args != '?'\n    let source = prefix . 'ls-files -z ' . a:args\n    if s:git_version_requirement(2, 31)\n      let source .= ' --deduplicate'\n    endif\n    return s:fzf('gfiles', {\n    \\ 'source':  source,\n    \\ 'dir':     root,\n    \\ 'options': '--scheme path -m --read0 --prompt \"GitFiles> \"'\n    \\}, a:000)\n  endif\n\n  \" Here be dragons!\n  \" We're trying to access the common sink function that fzf#wrap injects to\n  \" the options dictionary.\n  let bar = s:is_win ? '^|' : '|'\n  let diff_prefix = 'git -C ' . s:escape_for_bash(root) . ' '\n  let preview = printf(\n    \\ s:bash() . ' -c \"if [[ {1} =~ M ]]; then %s; else %s {-1}; fi\"',\n    \\ executable('delta')\n      \\ ? diff_prefix . 'diff -- {-1} ' . bar . ' delta --width $FZF_PREVIEW_COLUMNS --file-style=omit ' . bar . ' sed 1d'\n      \\ : diff_prefix . 'diff --color=always -- {-1} ' . bar . ' sed 1,4d',\n    \\ s:escape_for_bash(s:bin.preview))\n  let wrapped = fzf#wrap({\n  \\ 'source':  prefix . '-c color.status=always status --short --untracked-files=all',\n  \\ 'dir':     root,\n  \\ 'options': ['--scheme', 'path', '--ansi', '--multi', '--nth', '2..,..', '--tiebreak=index', '--prompt', 'GitFiles?> ', '--preview', preview]\n  \\})\n  call s:remove_layout(wrapped)\n  let wrapped.common_sink = remove(wrapped, 'sink*')\n  function! wrapped.newsink(lines)\n    let lines = extend(a:lines[0:0], map(a:lines[1:], 'substitute(v:val[3:], \".* -> \", \"\", \"\")'))\n    return self.common_sink(lines)\n  endfunction\n  let wrapped['sink*'] = remove(wrapped, 'newsink')\n  return s:fzf('gfiles-diff', wrapped, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Buffers\n\" ------------------------------------------------------------------\nfunction! s:find_open_window(b)\n  let [tcur, tcnt] = [tabpagenr() - 1, tabpagenr('$')]\n  for toff in range(0, tabpagenr('$') - 1)\n    let t = (tcur + toff) % tcnt + 1\n    let buffers = tabpagebuflist(t)\n    for w in range(1, len(buffers))\n      let b = buffers[w - 1]\n      if b == a:b\n        return [t, w]\n      endif\n    endfor\n  endfor\n  return [0, 0]\nendfunction\n\nfunction! s:jump(t, w)\n  execute a:t.'tabnext'\n  execute a:w.'wincmd w'\nendfunction\n\nfunction! s:bufopen(lines)\n  if len(a:lines) < 2\n    return\n  endif\n  let b = matchstr(a:lines[1], '\\[\\zs[0-9]*\\ze\\]')\n  if empty(a:lines[0]) && s:conf('buffers_jump', 0)\n    let [t, w] = s:find_open_window(b)\n    if t\n      call s:jump(t, w)\n      return\n    endif\n  endif\n  call s:action_for(a:lines[0])\n  execute 'buffer' b\nendfunction\n\nfunction! fzf#vim#_format_buffer(b)\n  let name = bufname(a:b)\n  let line = exists('*getbufinfo') ? getbufinfo(a:b)[0]['lnum'] : 0\n  let fullname = empty(name) ? '' : fnamemodify(name, \":p:~:.\")\n  let dispname = empty(name) ? '[No Name]' : name\n  let flag = a:b == bufnr('')  ? s:blue('%', 'Conditional') :\n          \\ (a:b == bufnr('#') ? s:magenta('#', 'Special') : ' ')\n  let modified = getbufvar(a:b, '&modified') ? s:red(' [+]', 'Exception') : ''\n  let readonly = getbufvar(a:b, '&modifiable') ? '' : s:green(' [RO]', 'Constant')\n  let extra = join(filter([modified, readonly], '!empty(v:val)'), '')\n  let target = empty(name) ? '' : (line == 0 ? fullname : fullname.':'.line)\n  return s:rstrip(printf(\"%s\\t%d\\t[%s] %s\\t%s\\t%s\", target, line, s:yellow(a:b, 'Number'), flag, dispname, extra))\nendfunction\n\nfunction! s:sort_buffers(...)\n  let [b1, b2] = map(copy(a:000), 'get(g:fzf#vim#buffers, v:val, v:val)')\n  \" Using minus between a float and a number in a sort function causes an error\n  return b1 < b2 ? 1 : -1\nendfunction\n\nfunction! fzf#vim#_buflisted_sorted()\n  return sort(s:buflisted(), 's:sort_buffers')\nendfunction\n\n\" [query (string)], [bufnrs (list)], [spec (dict)], [fullscreen (bool)]\nfunction! fzf#vim#buffers(...)\n  let [query, args] = (a:0 && type(a:1) == type('')) ?\n        \\ [a:1, a:000[1:]] : ['', a:000]\n  if len(args) && type(args[0]) == s:TYPE.list\n    let [buffers; args] = args\n  else\n    let buffers = s:buflisted()\n  endif\n  let sorted = sort(buffers, 's:sort_buffers')\n  let header_lines = '--header-lines=' . (bufnr('') == get(sorted, 0, 0) ? 1 : 0)\n  let tabstop = len(max(sorted)) >= 4 ? 9 : 8\n  return s:fzf('buffers', {\n  \\ 'source':  map(sorted, 'fzf#vim#_format_buffer(v:val)'),\n  \\ 'sink*':   s:function('s:bufopen'),\n  \\ 'options': ['+m', '-x', '--tiebreak=index', header_lines, '--ansi', '-d', '\\t', '--with-nth', '3..', '-n', '2,1..2', '--prompt', 'Buf> ', '--query', query, '--preview-window', '+{2}/2', '--tabstop', tabstop]\n  \\}, args)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Ag / Rg\n\" ------------------------------------------------------------------\nfunction! s:ag_to_qf(line)\n  let parts = matchlist(a:line, '\\(.\\{-}\\)\\s*:\\s*\\(\\d\\+\\)\\%(\\s*:\\s*\\(\\d\\+\\)\\)\\?\\%(\\s*:\\(.*\\)\\)\\?')\n  let file = &acd ? fnamemodify(parts[1], ':p') : parts[1]\n  if has('win32unix') && file !~ '/'\n    let file = substitute(file, '\\', '/', 'g')\n  endif\n  let dict = {'filename': file, 'lnum': parts[2], 'text': parts[4]}\n  if len(parts[3])\n    let dict.col = parts[3]\n  endif\n  return dict\nendfunction\n\nfunction! s:ag_handler(name, lines)\n  if len(a:lines) < 2\n    return\n  endif\n\n  let multi_line = min([s:conf('grep_multi_line', 0), 1])\n  let lines = []\n  if multi_line && executable('perl')\n    for idx in range(1, len(a:lines), multi_line + 1)\n      call add(lines, join(a:lines[idx:idx + multi_line], ''))\n    endfor\n  else\n    let lines = a:lines[1:]\n  endif\n\n  let list = map(filter(lines, 'len(v:val)'), 's:ag_to_qf(v:val)')\n  if empty(list)\n    return\n  endif\n\n  call s:action_for(a:lines[0], list[0].filename, len(list) > 1)\n  if s:fill_quickfix(a:name, list)\n    return\n  endif\n\n  \" Single item selected\n  let first = list[0]\n  try\n    execute first.lnum\n    if has_key(first, 'col')\n      call cursor(0, first.col)\n    endif\n    normal! zvzz\n  catch\n  endtry\nendfunction\n\n\" query, [ag options], [spec (dict)], [fullscreen (bool)]\nfunction! fzf#vim#ag(query, ...)\n  if type(a:query) != s:TYPE.string\n    return s:warn('Invalid query argument')\n  endif\n  let query = empty(a:query) ? '^(?=.)' : a:query\n  let args = copy(a:000)\n  let ag_opts = len(args) > 1 && type(args[0]) == s:TYPE.string ? remove(args, 0) : ''\n  let command = ag_opts . ' -- ' . fzf#shellescape(query)\n  return call('fzf#vim#ag_raw', insert(args, command, 0))\nendfunction\n\n\" ag command suffix, [spec (dict)], [fullscreen (bool)]\nfunction! fzf#vim#ag_raw(command_suffix, ...)\n  if !executable('ag')\n    return s:warn('ag is not found')\n  endif\n  return call('fzf#vim#grep', extend(['ag --nogroup --column --color '.a:command_suffix, 1], a:000))\nendfunction\n\nfunction! s:grep_multi_line(opts)\n  \" TODO: Non-global option\n  let multi_line = s:conf('grep_multi_line', 0)\n  if multi_line && executable('perl')\n    let opts = copy(a:opts)\n    let extra = ['--read0', '--highlight-line']\n    if multi_line > 1\n      call extend(extra, ['--gap', multi_line - 1])\n    endif\n    let opts.options = extend(copy(opts.options), extra)\n    return [opts, printf(\" | perl -pe 's/\\\\n/%s/; s/^([^:]+:){2,3}/$&\\\\n  /'\", '\\0')]\n  endif\n\n  return [a:opts, '']\nendfunction\n\n\" command (string), [spec (dict)], [fullscreen (bool)]\nfunction! fzf#vim#grep(grep_command, ...)\n  let args = copy(a:000)\n  let words = []\n  for word in split(a:grep_command)\n    if word !~# '^[a-z]'\n      break\n    endif\n    call add(words, word)\n  endfor\n  let words   = empty(words) ? ['grep'] : words\n  let name    = join(words, '-')\n  let capname = join(map(words, 'toupper(v:val[0]).v:val[1:]'), '')\n  let opts = {\n  \\ 'options': ['--ansi', '--prompt', capname.'> ',\n  \\             '--multi', '--bind', 'alt-a:select-all,alt-d:deselect-all',\n  \\             '--delimiter', ':', '--preview-window', '+{2}/2']\n  \\}\n  if len(args) && type(args[0]) == s:TYPE.bool\n    call remove(args, 0)\n  endif\n\n  function! opts.sink(lines) closure\n    return s:ag_handler(get(opts, 'name', name), a:lines)\n  endfunction\n  let opts['sink*'] = remove(opts, 'sink')\n  let [opts, suffix] = s:grep_multi_line(opts)\n  let command = a:grep_command . suffix\n  try\n    let prev_default_command = $FZF_DEFAULT_COMMAND\n    let $FZF_DEFAULT_COMMAND = command\n    return s:fzf(name, opts, args)\n  finally\n    let $FZF_DEFAULT_COMMAND = prev_default_command\n  endtry\nendfunction\n\n\n\" command_prefix (string), initial_query (string), [spec (dict)], [fullscreen (bool)]\nfunction! fzf#vim#grep2(command_prefix, query, ...)\n  let args = copy(a:000)\n  let words = []\n  for word in split(a:command_prefix)\n    if word !~# '^[a-z]'\n      break\n    endif\n    call add(words, word)\n  endfor\n  let words = empty(words) ? ['grep'] : words\n  let name = join(words, '-')\n  let fallback = s:is_win ? '' : ' || :'\n  let opts = {\n  \\ 'source':  s:is_win ? 'cd .' : ':',\n  \\ 'options': ['--ansi', '--prompt', toupper(name).'> ', '--query', a:query,\n  \\             '--disabled',\n  \\             '--multi', '--bind', 'alt-a:select-all,alt-d:deselect-all',\n  \\             '--delimiter', ':', '--preview-window', '+{2}/2']\n  \\}\n\n  let [opts, suffix] = s:grep_multi_line(opts)\n  let suffix = escape(suffix, '{')\n  call extend(opts.options, ['--bind', 'start:reload:'.a:command_prefix.' '.fzf#shellescape(a:query).suffix])\n  call extend(opts.options, ['--bind', 'change:reload:'.a:command_prefix.' {q}'.suffix.fallback])\n\n  if len(args) && type(args[0]) == s:TYPE.bool\n    call remove(args, 0)\n  endif\n  function! opts.sink(lines) closure\n    return s:ag_handler(name, a:lines)\n  endfunction\n  let opts['sink*'] = remove(opts, 'sink')\n  return s:fzf(name, opts, args)\nendfunction\n\n\" ------------------------------------------------------------------\n\" BTags\n\" ------------------------------------------------------------------\nfunction! s:btags_source(tag_cmds)\n  if !filereadable(expand('%'))\n    throw 'Save the file first'\n  endif\n\n  for cmd in a:tag_cmds\n    let lines = split(system(cmd), \"\\n\")\n    if !v:shell_error && len(lines)\n      break\n    endif\n  endfor\n  if v:shell_error\n    throw get(lines, 0, 'Failed to extract tags')\n  elseif empty(lines)\n    throw 'No tags found'\n  endif\n  return map(s:align_lists(map(lines, 'split(v:val, \"\\t\")')), 'join(v:val, \"\\t\")')\nendfunction\n\nfunction! s:btags_sink(lines)\n  if len(a:lines) < 2\n    return\n  endif\n  call s:action_for(a:lines[0])\n  let qfl = []\n  for line in a:lines[1:]\n    call s:execute_silent(split(line, \"\\t\")[2])\n    call add(qfl, {'filename': expand('%'), 'lnum': line('.'), 'text': getline('.')})\n  endfor\n\n  if len(qfl) > 1\n    \" Go back to the original position\n    normal! g`'\n    \" Because 'listproc' will use 'cfirst' to go to the first item in the list\n    call s:fill_quickfix('btags', qfl)\n  else\n    normal! zvzz\n  endif\nendfunction\n\n\" query, [tag commands], [spec (dict)], [fullscreen (bool)]\nfunction! fzf#vim#buffer_tags(query, ...)\n  let args = copy(a:000)\n  let escaped = fzf#shellescape(expand('%'))\n  let null = s:is_win ? 'nul' : '/dev/null'\n  let sort = has('unix') && !has('win32unix') && executable('sort') ? '| sort -s -k 5' : ''\n  let tag_cmds = (len(args) > 1 && type(args[0]) != type({})) ? remove(args, 0) : [\n    \\ printf('ctags -f - --sort=yes --excmd=number --language-force=%s %s 2> %s %s', get({ 'cpp': 'c++' }, &filetype, &filetype), escaped, null, sort),\n    \\ printf('ctags -f - --sort=yes --excmd=number %s 2> %s %s', escaped, null, sort)]\n  if type(tag_cmds) != type([])\n    let tag_cmds = [tag_cmds]\n  endif\n  try\n    return s:fzf('btags', {\n    \\ 'source':  s:btags_source(tag_cmds),\n    \\ 'sink*':   s:function('s:btags_sink'),\n    \\ 'options': s:reverse_list(['-m', '-d', '\\t', '--with-nth', '1,4..', '-n', '1', '--prompt', 'BTags> ', '--query', a:query, '--preview-window', '+{3}/2'])}, args)\n  catch\n    return s:warn(v:exception)\n  endtry\nendfunction\n\n\" ------------------------------------------------------------------\n\" Tags\n\" ------------------------------------------------------------------\nfunction! s:tags_sink(lines)\n  if len(a:lines) < 2\n    return\n  endif\n\n  \" Remember the current position\n  let buf = bufnr('')\n  let view = winsaveview()\n\n  let qfl = []\n  let [key; list] = a:lines\n\n  try\n    let [magic, &magic, wrapscan, &wrapscan, acd, &acd] = [&magic, 0, &wrapscan, 1, &acd, 0]\n    for line in list\n      try\n        let parts   = split(line, '\\t\\zs')\n        let excmd   = matchstr(join(parts[2:-2], '')[:-2], '^.\\{-}\\ze;\\?\"\\t')\n        let base    = fnamemodify(parts[-1], ':h')\n        let relpath = parts[1][:-2]\n        let abspath = relpath =~ (s:is_win ? '^[A-Z]:\\' : '^/') ? relpath : join([base, relpath], '/')\n\n        if len(list) == 1\n          call s:action_for(key, expand(abspath, 1))\n        else\n          call s:open(expand(abspath, 1))\n        endif\n        call s:execute_silent(excmd)\n        call add(qfl, {'filename': expand('%'), 'lnum': line('.'), 'text': getline('.')})\n      catch /^Vim:Interrupt$/\n        break\n      catch\n        call s:warn(v:exception)\n      endtry\n    endfor\n  finally\n    let [&magic, &wrapscan, &acd] = [magic, wrapscan, acd]\n  endtry\n\n  if len(qfl) > 1\n    \" Go back to the original position. Because 'listproc' will use 'cfirst'\n    \" to go to the first item in the list.\n    call s:execute_silent('b '.buf)\n    call winrestview(view)\n\n    \" However, if a non-default action is triggered, we need to open the first\n    \" entry using the action, to be as backward compatible as possible.\n    call s:action_for(key, qfl[0].filename, 1)\n\n    call s:fill_quickfix('tags', qfl)\n  else\n    normal! ^zvzz\n  endif\nendfunction\n\nfunction! fzf#vim#tags(query, ...)\n  if !executable('perl')\n    return s:warn('Tags command requires perl')\n  endif\n  if len(a:query) && !executable('readtags')\n    return s:warn('readtags from universal-ctags is required to pre-filter tags with a prefix')\n  endif\n\n  if empty(tagfiles())\n    call inputsave()\n    echohl WarningMsg\n    let gen = input('tags not found. Generate? (y/N) ')\n    echohl None\n    call inputrestore()\n    redraw\n    if gen =~? '^y'\n      call s:warn('Preparing tags')\n      call system(s:conf('tags_command', 'ctags -R'.(s:is_win ? ' --output-format=e-ctags' : '')))\n      if empty(tagfiles())\n        return s:warn('Failed to create tags')\n      endif\n    else\n      return s:warn('No tags found')\n    endif\n  endif\n\n  let tagfiles = tagfiles()\n  let v2_limit = 1024 * 1024 * 200\n  for tagfile in tagfiles\n    let v2_limit -= getfsize(tagfile)\n    if v2_limit < 0\n      break\n    endif\n  endfor\n  let opts = v2_limit < 0 ? ['--algo=v1'] : []\n\n  let args = insert(map(tagfiles, 'fzf#shellescape(fnamemodify(v:val, \":p\"))'), fzf#shellescape(a:query), 0)\n  return s:fzf('tags', {\n  \\ 'source':  join(['perl', fzf#shellescape(s:bin.tags), join(args)]),\n  \\ 'sink*':   s:function('s:tags_sink'),\n  \\ 'options': extend(opts, ['--nth', '1..2', '-m', '-d', '\\t', '--tiebreak=begin', '--prompt', 'Tags> ', '--query', a:query])}, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Snippets (UltiSnips)\n\" ------------------------------------------------------------------\nfunction! s:inject_snippet(line)\n  let snip = split(a:line, \"\\t\")[0]\n  execute 'normal! a'.s:strip(snip).\"\\<c-r>=UltiSnips#ExpandSnippet()\\<cr>\"\nendfunction\n\nfunction! fzf#vim#snippets(...)\n  if !exists(':UltiSnipsEdit')\n    return s:warn('UltiSnips not found')\n  endif\n  let list = UltiSnips#SnippetsInCurrentScope()\n  if empty(list)\n    return s:warn('No snippets available here')\n  endif\n  let aligned = sort(s:align_lists(items(list)))\n  let colored = map(aligned, 's:yellow(v:val[0]).\"\\t\".v:val[1]')\n  return s:fzf('snippets', {\n  \\ 'source':  colored,\n  \\ 'options': '--ansi --tiebreak=index +m -n 1,.. -d \"\\t\"',\n  \\ 'sink':    s:function('s:inject_snippet')}, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Commands\n\" ------------------------------------------------------------------\nlet s:tab = \"\\t\"\n\nfunction! s:format_cmd(line)\n  return substitute(a:line, '\\C \\([A-Z]\\S*\\) ',\n        \\ '\\=s:tab.s:yellow(submatch(1), \"Function\").s:tab', '')\nendfunction\n\nfunction! s:command_sink(lines)\n  if len(a:lines) < 2\n    return\n  endif\n  let cmd = matchstr(a:lines[1], s:tab.'\\zs\\S*\\ze'.s:tab)\n  if empty(a:lines[0])\n    call feedkeys(':'.cmd.(a:lines[1][0] == '!' ? '' : ' '), 'nt')\n  else\n    call feedkeys(':'.cmd.\"\\<cr>\", 'nt')\n  endif\nendfunction\n\nlet s:fmt_excmd = '   '.s:blue('%-38s', 'Statement').'%s'\n\nfunction! s:format_excmd(ex)\n  let match = matchlist(a:ex, '^|:\\(\\S\\+\\)|\\s*\\S*\\(.*\\)')\n  return printf(s:fmt_excmd, s:tab.match[1].s:tab, s:strip(match[2]))\nendfunction\n\nfunction! s:excmds()\n  let help = globpath($VIMRUNTIME, 'doc/index.txt')\n  if empty(help)\n    return []\n  endif\n\n  let commands = []\n  let command = ''\n  for line in readfile(help)\n    if line =~ '^|:[^|]'\n      if !empty(command)\n        call add(commands, s:format_excmd(command))\n      endif\n      let command = line\n    elseif line =~ '^\\s\\+\\S' && !empty(command)\n      let command .= substitute(line, '^\\s*', ' ', '')\n    elseif !empty(commands) && line =~ '^\\s*$'\n      break\n    endif\n  endfor\n  if !empty(command)\n    call add(commands, s:format_excmd(command))\n  endif\n  return commands\nendfunction\n\nfunction! fzf#vim#commands(...)\n  redir => cout\n  silent command\n  redir END\n  let list = split(cout, \"\\n\")\n  return s:fzf('commands', {\n  \\ 'source':  extend(extend(list[0:0], map(list[1:], 's:format_cmd(v:val)')), s:excmds()),\n  \\ 'sink*':   s:function('s:command_sink'),\n  \\ 'options': '--ansi --expect '.s:conf('commands_expect', 'ctrl-x').\n  \\            ' --tiebreak=index --header-lines 1 -x --prompt \"Commands> \" -n2,3,2..3 --tabstop=1 -d \"\\t\"'}, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Changes\n\" ------------------------------------------------------------------\n\nfunction! s:format_change(bufnr, offset, item)\n  let buflines = getbufline(a:bufnr, a:item.lnum)\n  if empty(buflines)\n    return ''\n  endif\n  return printf(\"%3d  %s  %4d  %3d  %s\", a:bufnr, s:yellow(printf('%6s', a:offset)), a:item.lnum, a:item.col, buflines[0])\nendfunction\n\nfunction! s:changes_sink(lines)\n  if len(a:lines) < 2\n    return\n  endif\n\n  call s:action_for(a:lines[0])\n  let [b, o, l, c] = split(a:lines[1])[0:3]\n\n  if o == '-'\n    execute 'buffer' b\n    call cursor(l, c)\n  elseif o[0] == '+'\n    execute 'normal!' o[1:].'g,'\n  else\n    execute 'normal!' o.'g;'\n  endif\nendfunction\n\nfunction! s:format_change_offset(current, index, cursor)\n  if !a:current\n    return '-'\n  endif\n\n  let offset = a:index - a:cursor + 1\n  if offset < 0\n    return '+'.-offset\n  endif\n  return offset\nendfunction\n\nfunction! fzf#vim#changes(...)\n  let all_changes = [\"buf  offset  line  col  text\"]\n  let cursor = 0\n  for bufnr in fzf#vim#_buflisted_sorted()\n    let [changes, position_or_length] = getchangelist(bufnr)\n    let current = bufnr('') == bufnr\n    if current\n      let cursor = len(changes) - position_or_length\n    endif\n    let all_changes += filter(map(reverse(changes), { idx, val -> s:format_change(bufnr, s:format_change_offset(current, idx, cursor), val) }), '!empty(v:val)')\n  endfor\n\n  return s:fzf('changes', {\n  \\ 'source':  all_changes,\n  \\ 'sink*':   s:function('s:changes_sink'),\n  \\ 'options': printf('+m -x --ansi --tiebreak=index --header-lines=1 --cycle --scroll-off 999 --sync --bind start:pos:%d --prompt \"Changes> \"', cursor)}, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Marks\n\" ------------------------------------------------------------------\nfunction! s:format_mark(line)\n  return substitute(a:line, '\\S', '\\=s:yellow(submatch(0), \"Number\")', '')\nendfunction\n\nfunction! s:mark_sink(lines)\n  if len(a:lines) < 2\n    return\n  endif\n  call s:action_for(a:lines[0])\n  execute 'normal! `'.matchstr(a:lines[1], '\\S').'zz'\nendfunction\n\nfunction! fzf#vim#marks(...) abort\n  let [initial_marks, extra] = (a:0 && type(a:1) == type('')) ?\n      \\ [a:1, a:000[1:]] : ['', a:000]\n\n  redir => cout\n  execute 'silent! marks' initial_marks\n  redir END\n\n  let list = split(cout, \"\\n\")\n\n  \" If first line is not the expected header, no marks found\n  if empty(list) || list[0] =~# '^E'\n    return s:warn('No marks found')\n  endif\n\n  return s:fzf('marks', {\n  \\ 'source':  extend(list[0:0], map(list[1:], 's:format_mark(v:val)')),\n  \\ 'sink*':   s:function('s:mark_sink'),\n  \\ 'options': '+m -x --ansi --tiebreak=index --header-lines 1 --tiebreak=begin --prompt \"Marks> \"'}, extra)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Jumps\n\" ------------------------------------------------------------------\nfunction! s:jump_format(line)\n  let line = substitute(a:line, '[0-9]\\+', '\\=s:yellow(submatch(0), \"Number\")', '')\n  let line = substitute(line, '\\s.\\{-}\\ze:[0-9]\\+:', '\\=s:green(submatch(0), \"Directory\")', '')\n  let line = substitute(line, '\\%(:[0-9]\\+\\)\\+:', '\\=s:black(submatch(0), \"NonText\")', '')\n  return line\nendfunction\n\nfunction! s:jump_sink(lines)\n  if len(a:lines) < 2\n    return\n  endif\n  keepjumps call s:action_for(a:lines[0])\n  let idx = str2nr(a:lines[1])\n  let delta = idx - s:jump_current - 1\n  if delta < 0\n    execute 'normal! ' . -delta . \"\\<C-O>\"\n  else\n    execute 'normal! ' . delta . \"\\<C-I>\"\n  endif\n  normal! zvzz\nendfunction\n\nfunction! fzf#vim#jumps(...)\n  let [jumps, pos] = getjumplist()\n  if empty(jumps)\n    return s:warn('No jumps')\n  endif\n  let s:jumplist = []\n  for idx in range(len(jumps))\n    let jump = jumps[idx]\n    let loc = expand('#'.jump.bufnr.':p:~:.')\n    if empty(loc)\n      let loc = '[No Name]'\n    endif\n    let loc .= ':'.jump.lnum\n    if jump.col\n      let loc .= ':'.jump.col\n    endif\n    let line = printf('%-2d %s: %s', idx+1, loc, getbufoneline(jump.bufnr, jump.lnum))\n    call add(s:jumplist, line)\n  endfor\n  let s:jump_current = pos\n  let current = -pos-1\n  return s:fzf('jumps', {\n  \\ 'source':  map(s:jumplist, 's:jump_format(v:val)'),\n  \\ 'sink*':   s:function('s:jump_sink'),\n  \\ 'options': ['+m', '-x', '--ansi', '--tiebreak=index', '--cycle', '--scroll-off=999', '--sync', '--bind', 'start:pos('.current.')+offset-middle', '--tac', '--tiebreak=begin', '--prompt', 'Jumps> ', '--preview-window', '+{3}/2', '--tabstop=2', '--delimiter', '[:\\s]+'],\n  \\ }, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Help tags\n\" ------------------------------------------------------------------\nfunction! s:helptag_sink(line)\n  let [tag, file, path] = split(a:line, \"\\t\")[0:2]\n  let rtp = fnamemodify(path, ':p:h:h')\n  if stridx(&rtp, rtp) < 0\n    execute 'set rtp+='.s:escape(rtp)\n  endif\n  execute 'help' tag\nendfunction\n\nfunction! fzf#vim#helptags(...)\n  if !executable('perl')\n    return s:warn('Helptags command requires perl')\n  endif\n  let sorted = sort(split(globpath(&runtimepath, 'doc/tags', 1), '\\n'))\n  let tags = exists('*uniq') ? uniq(sorted) : fzf#vim#_uniq(sorted)\n\n  if exists('s:helptags_script')\n    silent! call delete(s:helptags_script)\n  endif\n  let s:helptags_script = tempname()\n\n  call writefile(['for my $filename (@ARGV) { open(my $file,q(<),$filename) or die; while (<$file>) { /(.*?)\\t(.*?)\\t(.*)/; push @lines, sprintf(qq('.s:green('%-40s', 'Label').'\\t%s\\t%s\\t%s\\n), $1, $2, $filename, $3); } close($file) or die; } print for sort @lines;'], s:helptags_script)\n  return s:fzf('helptags', {\n  \\ 'source': 'perl '.fzf#shellescape(s:helptags_script).' '.join(map(tags, 'fzf#shellescape(v:val)')),\n  \\ 'sink':    s:function('s:helptag_sink'),\n  \\ 'options': ['--ansi', '+m', '--tiebreak=begin', '--with-nth', '..3']}, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" File types\n\" ------------------------------------------------------------------\nfunction! fzf#vim#filetypes(...)\n  return s:fzf('filetypes', {\n  \\ 'source':  fzf#vim#_uniq(sort(map(split(globpath(&rtp, 'syntax/*.vim'), '\\n'),\n  \\            'fnamemodify(v:val, \":t:r\")'))),\n  \\ 'sink':    'setf',\n  \\ 'options': '+m --prompt=\"File types> \"'\n  \\}, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Windows\n\" ------------------------------------------------------------------\nfunction! s:format_win(tab, win, buf)\n  let modified = getbufvar(a:buf, '&modified')\n  let name = bufname(a:buf)\n  let name = empty(name) ? s:tab.s:tab.'[No Name]' : ' '.s:tab.name\n  let active = tabpagewinnr(a:tab) == a:win\n  return (active? s:blue('>', 'Operator') : ' ') . name . s:tab . (modified? s:red(' [+]', 'Exception') : '')\nendfunction\n\nfunction! s:windows_sink(line)\n  let list = matchlist(a:line, '^ *\\([0-9]\\+\\) *\\([0-9]\\+\\)')\n  call s:jump(list[1], list[2])\nendfunction\n\nfunction! fzf#vim#windows(...)\n  let lines = []\n  for t in range(1, tabpagenr('$'))\n    let buffers = tabpagebuflist(t)\n    for w in range(1, len(buffers))\n      call add(lines,\n        \\ printf('%s %s  %s',\n            \\ s:yellow(printf('%3d', t), 'Number'),\n            \\ s:cyan(printf('%3d', w), 'String'),\n            \\ s:format_win(t, w, buffers[w-1])))\n    endfor\n  endfor\n  return s:fzf('windows', {\n  \\ 'source':  extend(['Tab Win     Name'], lines),\n  \\ 'sink':    s:function('s:windows_sink'),\n  \\ 'options': '+m --ansi --tiebreak=begin --header-lines=1 --tabstop=1 -d \"\\t\"'}, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" Commits / BCommits\n\" ------------------------------------------------------------------\nfunction! s:yank_to_register(data)\n  let @\" = a:data\n  silent! let @* = a:data\n  silent! let @+ = a:data\nendfunction\n\nfunction! s:commits_sink(lines)\n  if len(a:lines) < 2\n    return\n  endif\n\n  let pat = '[0-9a-f]\\{7,40}'\n\n  if a:lines[0] == 'ctrl-y'\n    let hashes = join(filter(map(a:lines[1:], 'matchstr(v:val, pat)'), 'len(v:val)'))\n    return s:yank_to_register(hashes)\n  end\n\n  let diff = a:lines[0] == 'ctrl-d'\n  let Cmd = get(get(g:, 'fzf_action', s:default_action), a:lines[0], '')\n  let cmd = type(Cmd) == s:TYPE.string ? Cmd : ''\n\n  let buf = bufnr('')\n  for idx in range(1, len(a:lines) - 1)\n    let sha = matchstr(a:lines[idx], pat)\n    if !empty(sha)\n      if diff\n        if idx > 1\n          execute 'tab sb' buf\n        endif\n        execute 'Gdiff' sha\n      else\n        \" Since fugitive buffers are unlisted, we can't keep using 'e'\n        let c = empty(cmd) ? (idx == 1 ? 'edit' : 'tab split') : cmd\n        execute c FugitiveFind(sha)\n      endif\n    endif\n  endfor\nendfunction\n\nfunction! s:commits(range, buffer_local, args)\n  let s:git_root = s:get_git_root('')\n  if empty(s:git_root)\n    return s:warn('Not in git repository')\n  endif\n\n  let prefix = 'git -C ' . fzf#shellescape(s:git_root) . ' '\n  let source = prefix . 'log '.s:conf('commits_log_options', '--color=always '.fzf#shellescape('--format=%C(auto)%h%d %s %C(green)%cr'))\n  let current = expand('%:p')\n  let managed = 0\n  if !empty(current)\n    call system(prefix . 'show '.fzf#shellescape(current).' 2> '.(s:is_win ? 'nul' : '/dev/null'))\n    let managed = !v:shell_error\n  endif\n\n  let args = copy(a:args)\n  let log_opts = len(args) && type(args[0]) == type('') ? remove(args, 0) : ''\n  let with_preview = !s:is_win && &columns > s:wide\n\n  if len(a:range) || a:buffer_local\n    if !managed\n      return s:warn('The current buffer is not in the working tree')\n    endif\n    if len(a:range)\n      let source .= join([printf(' -L %d,%d:%s --no-patch', a:range[0], a:range[1], fzf#shellescape(current)), log_opts])\n      if with_preview\n        let previewparams = join([printf('log -L %d,%d:%s', a:range[0], a:range[1], fzf#shellescape(current)), log_opts])\n        let previewfilter = \" | awk '/commit {1}/ {flag=1;print;next} /^[^ ]*commit/{flag=0} flag' \"\n        let previewcmd = prefix . previewparams .' --color=always '. previewfilter\n      endif\n    else\n      let source .= join([' --follow', log_opts, fzf#shellescape(current)])\n    endif\n    let command = 'BCommits'\n  else\n    let source .= join([' --graph', log_opts])\n    let command = 'Commits'\n  endif\n\n  let expect_keys = join(keys(get(g:, 'fzf_action', s:default_action)), ',')\n  let options = {\n  \\ 'source':  source,\n  \\ 'sink*':   s:function('s:commits_sink'),\n  \\ 'options': s:reverse_list(['--ansi', '--multi', '--tiebreak=index',\n  \\   '--inline-info', '--prompt', command.'> ', '--bind=ctrl-s:toggle-sort',\n  \\   '--header', ':: Press '.s:magenta('CTRL-S', 'Special').' to toggle sort, '.s:magenta('CTRL-Y', 'Special').' to yank commit hashes',\n  \\   '--expect=ctrl-y,'.expect_keys])\n  \\ }\n\n  if a:buffer_local\n    let options.options[-2] .= ', '.s:magenta('CTRL-D', 'Special').' to diff'\n    let options.options[-1] .= ',ctrl-d'\n  endif\n\n  if with_preview\n    if !len(a:range)\n      let orderfile = tempname()\n      call writefile([current[len(s:git_root)+1:]], orderfile)\n      let previewcmd = 'echo {} | grep -o \"[a-f0-9]\\{7,\\}\" | head -1 | xargs ' . prefix . 'show -O'.fzf#shellescape(orderfile).' --format=format: --color=always '\n    endif\n    let suffix = executable('delta') ? '| delta --width $FZF_PREVIEW_COLUMNS' : ''\n    call extend(options.options, ['--preview', previewcmd . suffix])\n  endif\n\n  return s:fzf(a:buffer_local ? 'bcommits' : 'commits', options, args)\nendfunction\n\n\" Heuristically determine if the user specified a range\nfunction! s:given_range(line1, line2)\n  \" 1. From visual mode\n  \"   :'<,'>Commits\n  \" 2. From command-line\n  \"   :10,20Commits\n  if a:line1 == line(\"'<\") && a:line2 == line(\"'>\") ||\n        \\ (a:line1 != 1 || a:line2 != line('$'))\n    return [a:line1, a:line2]\n  endif\n\n  return []\nendfunction\n\n\" [git-log-args], [spec (dict)], [fullscreen (bool)]\nfunction! fzf#vim#commits(...) range\n  if exists('b:fzf_winview')\n    call winrestview(b:fzf_winview)\n    unlet b:fzf_winview\n  endif\n  return s:commits(s:given_range(a:firstline, a:lastline), 0, a:000)\nendfunction\n\n\" [git-log-args], [spec (dict)], [fullscreen (bool)]\nfunction! fzf#vim#buffer_commits(...) range\n  if exists('b:fzf_winview')\n    call winrestview(b:fzf_winview)\n    unlet b:fzf_winview\n  endif\n  return s:commits(s:given_range(a:firstline, a:lastline), 1, a:000)\nendfunction\n\n\" ------------------------------------------------------------------\n\" fzf#vim#maps(mode, opts[with count and op])\n\" ------------------------------------------------------------------\nfunction! s:align_pairs(list)\n  let maxlen = 0\n  let pairs = []\n  for elem in a:list\n    let match = matchlist(elem, '^\\(\\S*\\)\\s*\\(.*\\)$')\n    let [_, k, v] = match[0:2]\n    let maxlen = max([maxlen, len(k)])\n    call add(pairs, [k, substitute(v, '^\\*\\?[@ ]\\?', '', '')])\n  endfor\n  let maxlen = min([maxlen, 35])\n  return map(pairs, \"printf('%-'.maxlen.'s', v:val[0]).' '.v:val[1]\")\nendfunction\n\nfunction! s:highlight_keys(str)\n  return substitute(\n        \\ substitute(a:str, '<[^ >]\\+>', s:yellow('\\0', 'Special'), 'g'),\n        \\ '<Plug>', s:blue('<Plug>', 'SpecialKey'), 'g')\nendfunction\n\nfunction! s:key_sink(line)\n  let key = matchstr(a:line, '^\\S*')\n  redraw\n  call feedkeys(s:map_gv.s:map_cnt.s:map_reg, 'n')\n  call feedkeys(s:map_op.\n        \\ substitute(key, '<[^ >]\\+>', '\\=eval(\"\\\"\\\\\".submatch(0).\"\\\"\")', 'g'))\nendfunction\n\nfunction! fzf#vim#maps(mode, ...)\n  let s:map_gv  = a:mode == 'x' ? 'gv' : ''\n  let s:map_cnt = v:count == 0 ? '' : v:count\n  let s:map_reg = empty(v:register) ? '' : ('\"'.v:register)\n  let s:map_op  = a:mode == 'o' ? v:operator : ''\n\n  redir => cout\n  silent execute 'verbose' a:mode.'map'\n  redir END\n  let list = []\n  let curr = ''\n  for line in split(cout, \"\\n\")\n    if line =~ \"^\\t\"\n      let src = \"\\t\".substitute(matchstr(line, '/\\zs[^/\\\\]*\\ze$'), ' [^ ]* ', ':', '')\n      call add(list, printf('%s %s', curr, s:green(src, 'Comment')))\n      let curr = ''\n    else\n      if !empty(curr)\n        call add(list, curr)\n      endif\n      let curr = line[3:]\n    endif\n  endfor\n  if !empty(curr)\n    call add(list, curr)\n  endif\n  let aligned = s:align_pairs(list)\n  let sorted  = sort(aligned)\n  let colored = map(sorted, 's:highlight_keys(v:val)')\n  let pcolor  = a:mode == 'x' ? 9 : a:mode == 'o' ? 10 : 12\n  return s:fzf('maps', {\n  \\ 'source':  colored,\n  \\ 'sink':    s:function('s:key_sink'),\n  \\ 'options': '--prompt \"Maps ('.a:mode.')> \" --ansi --no-hscroll --nth 1,.. --color prompt:'.pcolor}, a:000)\nendfunction\n\n\" ----------------------------------------------------------------------------\n\" fzf#vim#complete - completion helper\n\" ----------------------------------------------------------------------------\ninoremap <silent> <Plug>(-fzf-complete-trigger) <c-o>:call <sid>complete_trigger()<cr>\n\nfunction! s:pluck(dict, key, default)\n  return has_key(a:dict, a:key) ? remove(a:dict, a:key) : a:default\nendfunction\n\nfunction! s:complete_trigger()\n  let opts = copy(s:opts)\n  call s:prepend_opts(opts, ['+m', '-q', s:query])\n  let opts['sink*'] = s:function('s:complete_insert')\n  let s:reducer = s:pluck(opts, 'reducer', s:function('s:first_line'))\n  call fzf#run(opts)\nendfunction\n\n\" The default reducer\nfunction! s:first_line(lines)\n  return a:lines[0]\nendfunction\n\nfunction! s:complete_insert(lines)\n  if empty(a:lines)\n    return\n  endif\n\n  let chars = strchars(s:query)\n  if     chars == 0 | let del = ''\n  elseif chars == 1 | let del = '\"_x'\n  else              | let del = (chars - 1).'\"_dvh'\n  endif\n\n  let data = call(s:reducer, [a:lines])\n  let ve = &ve\n  set ve=\n  execute 'normal!' ((s:eol || empty(chars)) ? '' : 'h').del.(s:eol ? 'a': 'i').data\n  let &ve = ve\n  if mode() =~ 't'\n    call feedkeys('a', 'n')\n  elseif has('nvim')\n    execute \"normal! \\<esc>la\"\n  else\n    call feedkeys(\"\\<Plug>(-fzf-complete-finish)\")\n  endif\nendfunction\n\nnnoremap <silent> <Plug>(-fzf-complete-finish) a\ninoremap <silent> <Plug>(-fzf-complete-finish) <c-o>l\n\nfunction! s:eval(dict, key, arg)\n  if has_key(a:dict, a:key) && type(a:dict[a:key]) == s:TYPE.funcref\n    let ret = copy(a:dict)\n    let ret[a:key] = call(a:dict[a:key], [a:arg])\n    return ret\n  endif\n  return a:dict\nendfunction\n\nfunction! fzf#vim#complete(...)\n  if a:0 == 0\n    let s:opts = fzf#wrap()\n  elseif type(a:1) == s:TYPE.dict\n    let s:opts = copy(a:1)\n  elseif type(a:1) == s:TYPE.string\n    let s:opts = extend({'source': a:1}, get(a:000, 1, fzf#wrap()))\n  else\n    echoerr 'Invalid argument: '.string(a:000)\n    return ''\n  endif\n  for s in ['sink', 'sink*']\n    if has_key(s:opts, s)\n      call remove(s:opts, s)\n    endif\n  endfor\n\n  let eol = col('$')\n  let ve = &ve\n  set ve=all\n  let s:eol = col('.') == eol\n  let &ve = ve\n\n  let Prefix = s:pluck(s:opts, 'prefix', '\\k*$')\n  if col('.') == 1\n    let s:query = ''\n  else\n    let full_prefix = getline('.')[0 : col('.')-2]\n    if type(Prefix) == s:TYPE.funcref\n      let s:query = call(Prefix, [full_prefix])\n    else\n      let s:query = matchstr(full_prefix, Prefix)\n    endif\n  endif\n  let s:opts = s:eval(s:opts, 'source', s:query)\n  let s:opts = s:eval(s:opts, 'options', s:query)\n  let s:opts = s:eval(s:opts, 'extra_options', s:query)\n  if has_key(s:opts, 'extra_options')\n    call s:merge_opts(s:opts, remove(s:opts, 'extra_options'))\n  endif\n  if has_key(s:opts, 'options')\n    if type(s:opts.options) == s:TYPE.list\n      call add(s:opts.options, '--no-expect')\n    else\n      let s:opts.options .= ' --no-expect'\n    endif\n  endif\n\n  call feedkeys(\"\\<Plug>(-fzf-complete-trigger)\")\n  return ''\nendfunction\n\n\" ------------------------------------------------------------------\nlet &cpo = s:cpo_save\nunlet s:cpo_save\n"
  },
  {
    "path": "bin/preview.rb",
    "content": "#!/usr/bin/env ruby\n\nputs 'preview.rb is deprecated. Use preview.sh instead.'\n"
  },
  {
    "path": "bin/preview.sh",
    "content": "#!/usr/bin/env bash\n\nREVERSE=\"\\x1b[7m\"\nRESET=\"\\x1b[m\"\n\nif [[ $# -lt 1 ]]; then\n  echo \"usage: $0 [--tag] FILENAME[:LINENO][:IGNORED]\"\n  exit 1\nfi\n\nif [[ $1 = --tag ]]; then\n  shift\n  \"$(dirname \"${BASH_SOURCE[0]}\")/tagpreview.sh\" \"$@\"\n  exit $?\nfi\n\n# Ignore if an empty path is given\n[[ -z $1 ]] && exit\n\nIFS=':' read -r -a INPUT <<< \"$1\"\nFILE=${INPUT[0]}\nCENTER=${INPUT[1]}\n\nif [[ \"$1\" =~ ^[A-Za-z]:\\\\ ]]; then\n  FILE=$FILE:${INPUT[1]}\n  CENTER=${INPUT[2]}\nfi\n\nif [[ -n \"$CENTER\" && ! \"$CENTER\" =~ ^[0-9] ]]; then\n  exit 1\nfi\nCENTER=${CENTER/[^0-9]*/}\n\n# MS Win support\nif [[ \"$FILE\" =~ '\\' ]]; then\n  if [ -z \"$MSWINHOME\" ]; then\n    MSWINHOME=\"$HOMEDRIVE$HOMEPATH\"\n  fi\n  if grep -qEi \"(Microsoft|WSL)\" /proc/version &> /dev/null ; then\n    MSWINHOME=\"${MSWINHOME//\\\\/\\\\\\\\}\"\n    FILE=\"${FILE/#\\~\\\\/$MSWINHOME\\\\}\"\n    FILE=$(wslpath -u \"$FILE\")\n  elif [ -n \"$MSWINHOME\" ]; then\n    FILE=\"${FILE/#\\~\\\\/$MSWINHOME\\\\}\"\n  fi\nfi\n\nFILE=\"${FILE/#\\~\\//$HOME/}\"\nif [ ! -r \"$FILE\" ]; then\n  if [[ \"${INPUT[0]}\" != '[No Name]' ]]; then\n    echo \"File not found ${FILE}\"\n  fi\n  exit 1\nfi\n\nif [ -z \"$CENTER\" ]; then\n  CENTER=0\nfi\n\n# Sometimes bat is installed as batcat.\nif [[ -z \"$BATCAT\" ]]; then\n  if command -v batcat > /dev/null; then\n    BATCAT=\"batcat\"\n  elif command -v bat > /dev/null; then\n    BATCAT=\"bat\"\n  fi\nfi\n\nif [ -z \"$FZF_PREVIEW_COMMAND\" ] && [ \"${BATCAT:+x}\" ] && [[ ! -d \"$FILE\" ]] ; then\n  ${BATCAT} --style=\"${BAT_STYLE:-numbers}\" --color=always --pager=never \\\n      --highlight-line=$CENTER -- \"$FILE\"\n  exit $?\nfi\n\nFILE_LENGTH=${#FILE}\nMIME=$(file --dereference --mime -- \"$FILE\")\nif [[ \"${MIME:FILE_LENGTH}\" =~ binary ]] && [[ ! -d \"$FILE\" ]]; then\n  echo \"$MIME\"\n  exit 0\nfi\n\nDEFAULT_COMMAND=\"highlight -O ansi -l {} || coderay {} || rougify {} || cat {}\"\nif [[ -d \"$FILE\" ]]; then\n  DEFAULT_COMMAND=\"tree -C -L2 {} || ls -l --color=always {}\"\nfi\nCMD=${FZF_PREVIEW_COMMAND:-$DEFAULT_COMMAND}\nCMD=${CMD//{\\}/\"$(printf %q \"$FILE\")\"}\n\neval \"$CMD\" 2> /dev/null | awk \"{ \\\n    if (NR == $CENTER) \\\n        { gsub(/\\x1b[[0-9;]*m/, \\\"&$REVERSE\\\"); printf(\\\"$REVERSE%s\\n$RESET\\\", \\$0); } \\\n    else printf(\\\"$RESET%s\\n\\\", \\$0); \\\n    }\"\n"
  },
  {
    "path": "bin/tagpreview.sh",
    "content": "#!/usr/bin/env bash\n\nREVERSE=\"\\x1b[7m\"\nRESET=\"\\x1b[m\"\n\nif [ -z \"$1\" ]; then\n  echo \"usage: $0 FILENAME:TAGFILE:EXCMD\"\n  exit 1\nfi\n\nIFS=':' read -r FILE TAGFILE EXCMD <<< \"$*\"\n\n# Complete file paths which are relative to the given tag file\nif [ \"${FILE:0:1}\" != \"/\" ]; then\n  FILE=\"$(dirname \"${TAGFILE}\")/${FILE}\"\nfi\n\nif [ ! -r \"$FILE\" ]; then\n  echo \"File not found ${FILE}\"\n  exit 1\nfi\n\n# If users aren't using vim, they are probably using neovim\nif command -v vim > /dev/null; then\n  VIMNAME=\"vim\"\nelif command -v nvim > /dev/null; then\n  VIMNAME=\"nvim\"\nelse\n  echo \"Cannot preview tag: vim or nvim unavailable\"\n  exit 1\nfi\n\nCENTER=\"$(\"${VIMNAME}\" -R -i NONE -u NONE -e -m -s \"${FILE}\" \\\n              -c \"set nomagic\" \\\n              -c \"silent ${EXCMD}\" \\\n              -c 'let l=line(\".\") | new | put =l | print | qa!')\" || exit\n\nSTART_LINE=\"$(( CENTER - FZF_PREVIEW_LINES / 2 ))\"\nif (( START_LINE <= 0 )); then\n    START_LINE=1\nfi\nEND_LINE=\"$(( START_LINE + FZF_PREVIEW_LINES - 1 ))\"\n\n# Sometimes bat is installed as batcat.\nif command -v batcat > /dev/null; then\n  BATNAME=\"batcat\"\nelif command -v bat > /dev/null; then\n  BATNAME=\"bat\"\nfi\n\nif [ -z \"$FZF_PREVIEW_COMMAND\" ] && [ \"${BATNAME:+x}\" ]; then\n  ${BATNAME} --style=\"${BAT_STYLE:-numbers}\" \\\n             --color=always \\\n             --pager=never \\\n             --wrap=never \\\n             --terminal-width=\"${FZF_PREVIEW_COLUMNS}\" \\\n             --line-range=\"${START_LINE}:${END_LINE}\" \\\n             --highlight-line=\"${CENTER}\" \\\n             \"$FILE\"\n  exit $?\nfi\n\nDEFAULT_COMMAND=\"highlight -O ansi -l {} || coderay {} || rougify {} || cat {}\"\nCMD=${FZF_PREVIEW_COMMAND:-$DEFAULT_COMMAND}\nCMD=${CMD//{\\}/$(printf %q \"$FILE\")}\n\neval \"$CMD\" 2> /dev/null | awk \"{ \\\n    if (NR >= $START_LINE && NR <= $END_LINE) { \\\n        if (NR == $CENTER) \\\n            { gsub(/\\x1b[[0-9;]*m/, \\\"&$REVERSE\\\"); printf(\\\"$REVERSE%s\\n$RESET\\\", \\$0); } \\\n        else printf(\\\"$RESET%s\\n\\\", \\$0); \\\n        } \\\n    }\"\n"
  },
  {
    "path": "bin/tags.pl",
    "content": "#!/usr/bin/env perl\n\nuse strict;\n\nmy $prefix = shift @ARGV;\n\nforeach my $file (@ARGV) {\n  my $lines;\n  if ($prefix eq \"\") {\n    open $lines, $file;\n  } else {\n    # https://perldoc.perl.org/perlopentut#Expressing-the-command-as-a-list\n    open $lines, '-|', 'readtags', '-t', $file, '-e', '-p', '-', $prefix;\n  }\n  while (<$lines>) {\n    unless (/^\\!/) {\n      s/^[^\\t]*/sprintf(\"%-24s\", $&)/e;\n      s/$/\\t$file/;\n      print;\n    }\n  }\n  close $lines;\n}\n"
  },
  {
    "path": "doc/fzf-vim.txt",
    "content": "fzf-vim.txt\tfzf-vim\tLast change: June 8 2025\nFZF-VIM - TABLE OF CONTENTS                                *fzf-vim* *fzf-vim-toc*\n==============================================================================\n\n  fzf :heart: vim                                |fzf-vim-fzfheart-vim|\n    Rationale                                    |fzf-vim-rationale|\n    Why you should use fzf on Vim                |fzf-vim-why-you-should-use-fzf-on-vim|\n    Installation                                 |fzf-vim-installation|\n      Using vim-plug                             |fzf-vim-using-vim-plug|\n      Dependencies                               |fzf-vim-dependencies|\n    Commands                                     |fzf-vim-commands|\n    Customization                                |fzf-vim-customization|\n      Configuration options of the base plugin   |fzf-vim-configuration-options-of-the-base-plugin|\n      Configuration options for fzf.vim          |fzf-vim-configuration-options-for-fzf-vim|\n        Preview window                           |fzf-vim-preview-window|\n        Command-level options                    |fzf-vim-command-level-options|\n        Command-level fzf options                |fzf-vim-command-level-fzf-options|\n        List type to handle multiple selections  |fzf-vim-list-type-to-handle-multiple-selections|\n      Advanced customization                     |fzf-vim-advanced-customization|\n        Vim functions                            |fzf-vim-vim-functions|\n        Example: Customizing Files command       |fzf-vim-example-customizing-files-command|\n        Example: git grep wrapper                |fzf-vim-example-git-grep-wrapper|\n    Mappings                                     |fzf-vim-mappings|\n    Completion functions                         |fzf-vim-completion-functions|\n    Custom completion                            |fzf-vim-custom-completion|\n      Reducer example                            |fzf-vim-reducer-example|\n    Status line of terminal buffer               |fzf-vim-status-line-of-terminal-buffer|\n      Hide statusline                            |fzf-vim-hide-statusline|\n      Custom statusline                          |fzf-vim-custom-statusline|\n    License                                      |fzf-vim-license|\n\nFZF :HEART: VIM                                           *fzf-vim-fzfheart-vim*\n==============================================================================\n\nThings you can do with {fzf}{1} and Vim.\n\n                                           {1} https://github.com/junegunn/fzf\n\n\nRATIONALE                                                    *fzf-vim-rationale*\n==============================================================================\n\n{fzf}{1} itself is not a Vim plugin, and the official repository only provides\nthe {basic wrapper function}{2} for Vim. It's up to the users to write their\nown Vim commands with it. However, I've learned that many users of fzf are not\nfamiliar with Vimscript and are looking for the \"default\" implementation of\nthe features they can find in the alternative Vim plugins.\n\n          {1} https://github.com/junegunn/fzf\n          {2} https://github.com/junegunn/fzf/blob/master/README-VIM.md#fzfrun\n\n\nWHY YOU SHOULD USE FZF ON VIM            *fzf-vim-why-you-should-use-fzf-on-vim*\n==============================================================================\n\nBecause you can and you love fzf.\n\nfzf runs asynchronously and can be orders of magnitude faster than similar Vim\nplugins. However, the benefit may not be noticeable if the size of the input\nis small, which is the case for many of the commands provided here.\nNevertheless I wrote them anyway since it's really easy to implement custom\nselector with fzf.\n\n\nINSTALLATION                                              *fzf-vim-installation*\n==============================================================================\n\nfzf.vim depends on the basic Vim plugin of {the main fzf repository}{1}, which\nmeans you need to set up both \"fzf\" and \"fzf.vim\" on Vim. To learn more about\nfzf/Vim integration, see {README-VIM}{3}.\n\n                 {1} https://github.com/junegunn/fzf\n                 {3} https://github.com/junegunn/fzf/blob/master/README-VIM.md\n\n\n< Using vim-plug >____________________________________________________________~\n                                                        *fzf-vim-using-vim-plug*\n>\n    Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }\n    Plug 'junegunn/fzf.vim'\n<\n`fzf#install()` makes sure that you have the latest binary, but it's optional,\nso you can omit it if you use a plugin manager that doesn't support hooks.\n\n\n< Dependencies >______________________________________________________________~\n                                                          *fzf-vim-dependencies*\n\n - {fzf}{1} 0.54.0 or above\n - For syntax-highlighted preview, install {bat}{4}\n - If {delta}{5} is available, `GF?`, `Commits` and `BCommits` will use it to\n   format `git diff` output.\n - `Ag` requires {The Silver Searcher (ag)}{6}\n - `Rg` requires {ripgrep (rg)}{7}\n - `Tags` and `Helptags` require Perl\n - `Tags PREFIX` requires `readtags` command from {Universal Ctags}{8}\n>\n    # Installing dependencies using Homebrew\n    brew install fzf bat ripgrep the_silver_searcher perl universal-ctags\n<\n                             {1} https://github.com/junegunn/fzf\n                             {4} https://github.com/sharkdp/bat\n                             {5} https://github.com/dandavison/delta\n                             {6} https://github.com/ggreer/the_silver_searcher\n                             {7} https://github.com/BurntSushi/ripgrep\n                             {8} https://ctags.io/\n\n\nCOMMANDS                                                      *fzf-vim-commands*\n==============================================================================\n\n       *:Files* *:GFiles* *:Buffers* *:Colors* *:Ag* *:Rg* *:RG* *:Lines* *:BLines* *:Tags* *:BTags*\n   *:Changes* *:Marks* *:BMarks* *:Jumps* *:Windows* *:Locate* *:History* *:Snippets* *:Commits*\n                                *:BCommits* *:Commands* *:Maps* *:Helptags* *:Filetypes*\n\n -----------------------+--------------------------------------------------------------------------------------\n Command                | List                                                                                 ~\n -----------------------+--------------------------------------------------------------------------------------\n  `:Files [PATH]`         | Files (runs  `$FZF_DEFAULT_COMMAND`  if defined)\n  `:GFiles [OPTS]`        | Git files ( `git ls-files` )\n  `:GFiles?`              | Git files ( `git status` )\n  `:Buffers`              | Open buffers\n  `:Colors`               | Color schemes\n  `:Ag [PATTERN]`         | {ag}{6} search result ( `ALT-A`  to select all,  `ALT-D`  to deselect all)\n  `:Rg [PATTERN]`         | {rg}{7} search result ( `ALT-A`  to select all,  `ALT-D`  to deselect all)\n  `:RG [PATTERN]`         | {rg}{7} search result; relaunch ripgrep on every keystroke\n  `:Lines [QUERY]`        | Lines in loaded buffers\n  `:BLines [QUERY]`       | Lines in the current buffer\n  `:Tags [PREFIX]`        | Tags in the project ( `ctags -R` )\n  `:BTags [QUERY]`        | Tags in the current buffer\n  `:Changes`              | Changelist across all open buffers\n  `:Marks`                | Marks\n  `:BMarks`               | Marks in the current buffer\n  `:Jumps`                | Jumps\n  `:Windows`              | Windows\n  `:Locate PATTERN`       |  `locate`  command output\n  `:History`              |  `v:oldfiles`  and open buffers\n  `:History:`             | Command history\n  `:History/`             | Search history\n  `:Snippets`             | Snippets ({UltiSnips}{9})\n  `:Commits [LOG_OPTS]`   | Git commits (requires {fugitive.vim}{10})\n  `:BCommits [LOG_OPTS]`  | Git commits for the current buffer; visual-select lines to track changes in the range\n  `:Commands`             | Commands\n  `:Maps`                 | Normal mode mappings\n  `:Helptags`             | Help tags [1]\n  `:Filetypes`            | File types\n -----------------------+--------------------------------------------------------------------------------------\n\n                                                      *g:fzf_vim.command_prefix*\n\n - Most commands support CTRL-T / CTRL-X / CTRL-V key bindings to open in a new\n   tab, a new split, or in a new vertical split\n - Bang-versions of the commands (e.g. `Ag!`) will open fzf in fullscreen\n - You can set `g:fzf_vim.command_prefix` to give the same prefix to the commands\n   - e.g. `let g:fzf_vim.command_prefix = 'Fzf'` and you have `FzfFiles`, etc.\n\n(1: `Helptags` will shadow the command of the same name from {pathogen}{11}.\nBut its functionality is still available via `call pathogen#helptags()`. [↩])\n\n                             {6} https://github.com/ggreer/the_silver_searcher\n                             {7} https://github.com/BurntSushi/ripgrep\n                             {7} https://github.com/BurntSushi/ripgrep\n                             {9} https://github.com/SirVer/ultisnips\n                             {10} https://github.com/tpope/vim-fugitive\n                             {11} https://github.com/tpope/vim-pathogen\n\n\nCUSTOMIZATION                                            *fzf-vim-customization*\n==============================================================================\n\n\n< Configuration options of the base plugin >__________________________________~\n                              *fzf-vim-configuration-options-of-the-base-plugin*\n\nEvery command in fzf.vim internally calls `fzf#wrap` function of the main\nrepository which supports a set of global option variables. So please read\nthrough {README-VIM}{3} to learn more about them.\n\n                 {3} https://github.com/junegunn/fzf/blob/master/README-VIM.md\n\n\n< Configuration options for fzf.vim >_________________________________________~\n                                     *fzf-vim-configuration-options-for-fzf-vim*\n\n                                                                     *g:fzf_vim*\n\nAll configuration values for this plugin are stored in `g:fzf_vim` dictionary,\nso make sure to initialize it before assigning any configuration values to it.\n>\n    \" Initialize configuration dictionary\n    let g:fzf_vim = {}\n<\n\nPreview window~\n                                                        *fzf-vim-preview-window*\n\n                                                      *g:fzf_vim.preview_window*\n\nSome commands will show the preview window on the right. You can customize the\nbehavior with `g:fzf_vim.preview_window`. Here are some examples:\n\n                                                        *g:fzf_vim.preview_bash*\n>\n    \" This is the default option:\n    \"   - Preview window on the right with 50% width\n    \"   - CTRL-/ will toggle preview window.\n    \" - Note that this array is passed as arguments to fzf#vim#with_preview function.\n    \" - To learn more about preview window options, see `--preview-window` section of `man fzf`.\n    let g:fzf_vim.preview_window = ['right,50%', 'ctrl-/']\n\n    \" Preview window is hidden by default. You can toggle it with ctrl-/.\n    \" It will show on the right with 50% width, but if the width is smaller\n    \" than 70 columns, it will show above the candidate list\n    let g:fzf_vim.preview_window = ['hidden,right,50%,<70(up,40%)', 'ctrl-/']\n\n    \" Empty value to disable preview window altogether\n    let g:fzf_vim.preview_window = []\n\n    \" fzf.vim needs bash to display the preview window.\n    \" On Windows, fzf.vim will first see if bash is in $PATH, then if\n    \" Git bash (C:\\Program Files\\Git\\bin\\bash.exe) is available.\n    \" If you want it to use a different bash, set this variable.\n    \"   let g:fzf_vim = {}\n    \"   let g:fzf_vim.preview_bash = 'C:\\Git\\bin\\bash.exe'\n<\n\nCommand-level options~\n                                                 *fzf-vim-command-level-options*\n\n*g:fzf_vim.commands_expect* *g:fzf_vim.tags_command* *g:fzf_vim.commits_log_options*\n                                                        *g:fzf_vim.buffers_jump*\n>\n    \" [Buffers] Jump to the existing window if possible (default: 0)\n    let g:fzf_vim.buffers_jump = 1\n\n    \" [Ag|Rg|RG] Display path on a separate line for narrow screens (default: 0)\n    \" * Requires Perl and fzf 0.56.0 or later\n    let g:fzf_vim.grep_multi_line = 0\n       \" PATH:LINE:COL:LINE\n    let g:fzf_vim.grep_multi_line = 1\n       \" PATH:LINE:COL:\n       \" LINE\n    let g:fzf_vim.grep_multi_line = 2\n       \" PATH:LINE:COL:\n       \" LINE\n       \" (empty line between items using --gap option)\n\n    \" [[B]Commits] Customize the options used by 'git log':\n    let g:fzf_vim.commits_log_options = '--graph --color=always --format=\"%C(auto)%h%d %s %C(black)%C(bold)%cr\"'\n\n    \" [Tags] Command to generate tags file\n    let g:fzf_vim.tags_command = 'ctags -R'\n\n    \" [Commands] --expect expression for directly executing the command\n    let g:fzf_vim.commands_expect = 'alt-enter,ctrl-x'\n<\n\nCommand-level fzf options~\n                                             *fzf-vim-command-level-fzf-options*\n\nYou can set fzf options for each command by setting\n`g:fzf_vim.{command}_options`.\n>\n    \" In string\n    let g:fzf_vim.buffers_options = '--style full --border-label \" Open Buffers \"'\n\n    \" In list (No need to quote or escape values)\n    let g:fzf_vim.buffers_options = ['--style', 'full', '--border-label', ' Open Buffers ']\n<\n\nList type to handle multiple selections~\n                               *fzf-vim-list-type-to-handle-multiple-selections*\n\nThe following commands will fill the quickfix list when multiple entries are\nselected.\n\n - `Ag`\n - `Rg` / `RG`\n - `Lines` / `BLines`\n - `Tags` / `BTags`\n\n                                                            *g:fzf_vim.listproc*\n\nBy setting `g:fzf_vim.listproc`, you can make them use location list instead.\n>\n    \" Default: Use quickfix list\n    let g:fzf_vim.listproc = { list -> fzf#vim#listproc#quickfix(list) }\n\n    \" Use location list instead of quickfix list\n    let g:fzf_vim.listproc = { list -> fzf#vim#listproc#location(list) }\n<\nYou can customize the list type per command by defining variables named\n`g:fzf_vim.listproc_{command_name_in_lowercase}`.\n\n                                   *g:fzf_vim.listproc_rg* *g:fzf_vim.listproc_ag*\n>\n    \" Command-wise customization\n    let g:fzf_vim.listproc_ag = { list -> fzf#vim#listproc#quickfix(list) }\n    let g:fzf_vim.listproc_rg = { list -> fzf#vim#listproc#location(list) }\n<\nYou can further customize the behavior by providing a custom function to\nprocess the list instead of using the predefined `fzf#vim#listproc#quickfix`\nor `fzf#vim#listproc#location`.\n>\n    \" A customized version of fzf#vim#listproc#quickfix.\n    \" The last two lines are commented out not to move to the first entry.\n    function! g:fzf_vim.listproc(list)\n      call setqflist(a:list)\n      copen\n      wincmd p\n      \" cfirst\n      \" normal! zvzz\n    endfunction\n<\n\n< Advanced customization >____________________________________________________~\n                                                *fzf-vim-advanced-customization*\n\n\nVim functions~\n                                                         *fzf-vim-vim-functions*\n\nEach command in fzf.vim is backed by a Vim function. You can override a\ncommand or define a variation of it by calling its corresponding function.\n\n ----------+---------------------------------------------------------------------------------\n Command   | Vim function                                                                    ~\n ----------+---------------------------------------------------------------------------------\n  `Files`    |  `fzf#vim#files(dir, [spec dict], [fullscreen bool])`\n  `GFiles`   |  `fzf#vim#gitfiles(git_options, [spec dict], [fullscreen bool])`\n  `GFiles?`  |  `fzf#vim#gitfiles('?', [spec dict], [fullscreen bool])`\n  `Buffers`  |  `fzf#vim#buffers([query string], [bufnrs list], [spec dict], [fullscreen bool])`\n  `Colors`   |  `fzf#vim#colors([spec dict], [fullscreen bool])`\n  `Rg`       |  `fzf#vim#grep(command, [spec dict], [fullscreen bool])`\n  `RG`       |  `fzf#vim#grep2(command_prefix, query, [spec dict], [fullscreen bool])`\n ...       | ...\n ----------+---------------------------------------------------------------------------------\n\n(We can see that the last two optional arguments of each function are\nidentical. They are directly passed to `fzf#wrap` function. If you haven't\nread {README-VIM}{3} already, please read it before proceeding.)\n\n                 {3} https://github.com/junegunn/fzf/blob/master/README-VIM.md\n\n\nExample: Customizing Files command~\n                                     *fzf-vim-example-customizing-files-command*\n\nThis is the default definition of `Files` command:\n>\n    command! -bang -nargs=? -complete=dir Files call fzf#vim#files(<q-args>, <bang>0)\n<\nLet's say you want to a variation of it called `ProjectFiles` that only\nsearches inside `~/projects` directory. Then you can do it like this:\n>\n    command! -bang ProjectFiles call fzf#vim#files('~/projects', <bang>0)\n<\nOr, if you want to override the command with different fzf options, just pass\na custom spec to the function.\n>\n    command! -bang -nargs=? -complete=dir Files\n        \\ call fzf#vim#files(<q-args>, {'options': ['--layout=reverse', '--info=inline']}, <bang>0)\n<\nWant a preview window?\n>\n    command! -bang -nargs=? -complete=dir Files\n        \\ call fzf#vim#files(<q-args>, {'options': ['--layout=reverse', '--info=inline', '--preview', 'cat {}']}, <bang>0)\n<\nIt kind of works, but you probably want a nicer previewer program than `cat`.\nfzf.vim ships {a versatile preview script}{12} you can readily use. It\ninternally executes {bat}{4} for syntax highlighting, so make sure to install\nit.\n>\n    command! -bang -nargs=? -complete=dir Files\n        \\ call fzf#vim#files(<q-args>, {'options': ['--layout=reverse', '--info=inline', '--preview', '~/.vim/plugged/fzf.vim/bin/preview.sh {}']}, <bang>0)\n<\nHowever, it's not ideal to hard-code the path to the script which can be\ndifferent in different circumstances. So in order to make it easier to set up\nthe previewer, fzf.vim provides `fzf#vim#with_preview` helper function.\nSimilarly to `fzf#wrap`, it takes a spec dictionary and returns a copy of it\nwith additional preview options.\n>\n    command! -bang -nargs=? -complete=dir Files\n        \\ call fzf#vim#files(<q-args>, fzf#vim#with_preview({'options': ['--layout=reverse', '--info=inline']}), <bang>0)\n<\nYou can just omit the spec argument if you only want the previewer.\n>\n    command! -bang -nargs=? -complete=dir Files\n        \\ call fzf#vim#files(<q-args>, fzf#vim#with_preview(), <bang>0)\n<\n                                            {12} bin/preview.sh\n                                            {4} https://github.com/sharkdp/bat\n\n\nExample: git grep wrapper~\n                                              *fzf-vim-example-git-grep-wrapper*\n\nThe following example implements `GGrep` command that works similarly to\npredefined `Ag` or `Rg` using `fzf#vim#grep`.\n\n - We set the base directory to git root by setting `dir` attribute in spec\n   dictionary.\n - {The preview script}{12} supports `grep` format (`FILE_PATH:LINE_NO:...`), so\n   we can just wrap the spec with `fzf#vim#with_preview` as before to enable\n   previewer.\n>\n    command! -bang -nargs=* GGrep\n      \\ call fzf#vim#grep(\n      \\   'git grep --line-number -- '.fzf#shellescape(<q-args>),\n      \\   fzf#vim#with_preview({'dir': systemlist('git rev-parse --show-toplevel')[0]}), <bang>0)\n<\n                                                           {12} bin/preview.sh\n\n\nMAPPINGS                                                      *fzf-vim-mappings*\n==============================================================================\n\n ---------------------------------+------------------------------------------\n Mapping                          | Description                              ~\n ---------------------------------+------------------------------------------\n <plug>(fzf-maps-n)               | Normal mode mappings\n <plug>(fzf-maps-i)               | Insert mode mappings\n <plug>(fzf-maps-x)               | Visual mode mappings\n <plug>(fzf-maps-o)               | Operator-pending mappings\n <plug>(fzf-complete-word)        |  `cat /usr/share/dict/words`\n <plug>(fzf-complete-path)        | Path completion using  `find`  (file + dir)\n <plug>(fzf-complete-file)        | File completion using  `find`\n <plug>(fzf-complete-line)        | Line completion (all open buffers)\n <plug>(fzf-complete-buffer-line) | Line completion (current buffer only)\n ---------------------------------+------------------------------------------\n>\n    \" Mapping selecting mappings\n    nmap <leader><tab> <plug>(fzf-maps-n)\n    xmap <leader><tab> <plug>(fzf-maps-x)\n    omap <leader><tab> <plug>(fzf-maps-o)\n\n    \" Insert mode completion\n    imap <c-x><c-k> <plug>(fzf-complete-word)\n    imap <c-x><c-f> <plug>(fzf-complete-path)\n    imap <c-x><c-l> <plug>(fzf-complete-line)\n<\n\nCOMPLETION FUNCTIONS                              *fzf-vim-completion-functions*\n==============================================================================\n\n -----------------------------------------+--------------------------------------\n Function                                 | Description                          ~\n -----------------------------------------+--------------------------------------\n  `fzf#vim#complete#path(command, [spec])`  | Path completion\n  `fzf#vim#complete#word([spec])`           | Word completion\n  `fzf#vim#complete#line([spec])`           | Line completion (all open buffers)\n  `fzf#vim#complete#buffer_line([spec])`    | Line completion (current buffer only)\n -----------------------------------------+--------------------------------------\n>\n    \" Path completion with custom source command\n    inoremap <expr> <c-x><c-f> fzf#vim#complete#path('fd')\n    inoremap <expr> <c-x><c-f> fzf#vim#complete#path('rg --files')\n\n    \" Word completion with custom spec with popup layout option\n    inoremap <expr> <c-x><c-k> fzf#vim#complete#word({'window': { 'width': 0.2, 'height': 0.9, 'xoffset': 1 }})\n<\n\nCUSTOM COMPLETION                                    *fzf-vim-custom-completion*\n==============================================================================\n\n`fzf#vim#complete` is a helper function for creating custom fuzzy completion\nusing fzf. If the first parameter is a command string or a Vim list, it will\nbe used as the source.\n>\n    \" Replace the default dictionary completion with fzf-based fuzzy completion\n    inoremap <expr> <c-x><c-k> fzf#vim#complete('cat /usr/share/dict/words')\n<\nFor advanced uses, you can pass an options dictionary to the function. The set\nof options is pretty much identical to that for `fzf#run` only with the\nfollowing exceptions:\n\n - `reducer` (funcref)\n   - Reducer transforms the output lines of fzf into a single string value\n - `prefix` (string or funcref; default: `\\k*$`)\n   - Regular expression pattern to extract the completion prefix\n   - Or a function to extract completion prefix\n - Both `source` and `options` can be given as funcrefs that take the completion\n   prefix as the argument and return the final value\n - `sink` or `sink*` are ignored\n>\n    \" Global line completion (not just open buffers. ripgrep required.)\n    inoremap <expr> <c-x><c-l> fzf#vim#complete(fzf#wrap({\n      \\ 'prefix': '^.*$',\n      \\ 'source': 'rg -n ^ --color always',\n      \\ 'options': '--ansi --delimiter : --nth 3..',\n      \\ 'reducer': { lines -> join(split(lines[0], ':\\zs')[2:], '') }}))\n<\n\n< Reducer example >___________________________________________________________~\n                                                       *fzf-vim-reducer-example*\n>\n    function! s:make_sentence(lines)\n      return substitute(join(a:lines), '^.', '\\=toupper(submatch(0))', '').'.'\n    endfunction\n\n    inoremap <expr> <c-x><c-s> fzf#vim#complete({\n      \\ 'source':  'cat /usr/share/dict/words',\n      \\ 'reducer': function('<sid>make_sentence'),\n      \\ 'options': '--multi --reverse --margin 15%,0',\n      \\ 'left':    20})\n<\n\nSTATUS LINE OF TERMINAL BUFFER          *fzf-vim-status-line-of-terminal-buffer*\n==============================================================================\n\nWhen fzf starts in a terminal buffer (see {fzf/README-VIM.md}{13}), you may\nwant to customize the statusline of the containing buffer.\n\n{13} https://github.com/junegunn/fzf/blob/master/README-VIM.md#fzf-inside-terminal-buffer\n\n\n< Hide statusline >___________________________________________________________~\n                                                       *fzf-vim-hide-statusline*\n>\n    autocmd! FileType fzf set laststatus=0 noshowmode noruler\n      \\| autocmd BufLeave <buffer> set laststatus=2 showmode ruler\n<\n\n< Custom statusline >_________________________________________________________~\n                                                     *fzf-vim-custom-statusline*\n>\n    function! s:fzf_statusline()\n      \" Override statusline as you like\n      highlight fzf1 ctermfg=161 ctermbg=251\n      highlight fzf2 ctermfg=23 ctermbg=251\n      highlight fzf3 ctermfg=237 ctermbg=251\n      setlocal statusline=%#fzf1#\\ >\\ %#fzf2#fz%#fzf3#f\n    endfunction\n\n    autocmd! User FzfStatusLine call <SID>fzf_statusline()\n<\n\nLICENSE                                                        *fzf-vim-license*\n==============================================================================\n\nMIT\n\n\n==============================================================================\nvim:tw=78:sw=2:ts=2:ft=help:norl:nowrap:\n"
  },
  {
    "path": "plugin/fzf.vim",
    "content": "\" Copyright (c) 2015 Junegunn Choi\n\"\n\" MIT License\n\"\n\" Permission is hereby granted, free of charge, to any person obtaining\n\" a copy of this software and associated documentation files (the\n\" \"Software\"), to deal in the Software without restriction, including\n\" without limitation the rights to use, copy, modify, merge, publish,\n\" distribute, sublicense, and/or sell copies of the Software, and to\n\" permit persons to whom the Software is furnished to do so, subject to\n\" the following conditions:\n\"\n\" The above copyright notice and this permission notice shall be\n\" included in all copies or substantial portions of the Software.\n\"\n\" THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n\" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n\" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n\" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n\" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n\" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nif exists('g:loaded_fzf_vim')\n  finish\nendif\nlet g:loaded_fzf_vim = 1\n\nlet s:cpo_save = &cpo\nset cpo&vim\nlet s:is_win = has('win32') || has('win64')\n\nfunction! s:conf(name, default)\n  let conf = get(g:, 'fzf_vim', {})\n  let val = get(conf, a:name, get(g:, 'fzf_' . a:name, a:default))\n  return val\nendfunction\n\nfunction! s:defs(commands)\n  let prefix = s:conf('command_prefix', '')\n  if prefix =~# '^[^A-Z]'\n    echoerr 'g:fzf_command_prefix must start with an uppercase letter'\n    return\n  endif\n  for command in a:commands\n    let name = ':'.prefix.matchstr(command, '\\C[A-Z]\\S\\+')\n    if 2 != exists(name)\n      execute substitute(command, '\\ze\\C[A-Z]', prefix, '')\n    endif\n  endfor\nendfunction\n\ncall s:defs([\n\\'command!      -bang -nargs=? -complete=dir Files              call fzf#vim#files(<q-args>, fzf#vim#with_preview(), <bang>0)',\n\\'command!      -bang -nargs=? GitFiles                         call fzf#vim#gitfiles(<q-args>, fzf#vim#with_preview(<q-args> == \"?\" ? { \"placeholder\": \"\" } : {}), <bang>0)',\n\\'command!      -bang -nargs=? GFiles                           call fzf#vim#gitfiles(<q-args>, fzf#vim#with_preview(<q-args> == \"?\" ? { \"placeholder\": \"\" } : {}), <bang>0)',\n\\'command! -bar -bang -nargs=? -complete=buffer Buffers         call fzf#vim#buffers(<q-args>, fzf#vim#with_preview({ \"placeholder\": \"{1}\" }), <bang>0)',\n\\'command!      -bang -nargs=* Lines                            call fzf#vim#lines(<q-args>, <bang>0)',\n\\'command!      -bang -nargs=* BLines                           call fzf#vim#buffer_lines(<q-args>, <bang>0)',\n\\'command! -bar -bang Colors                                    call fzf#vim#colors(<bang>0)',\n\\'command!      -bang -nargs=+ -complete=dir Locate             call fzf#vim#locate(<q-args>, fzf#vim#with_preview(), <bang>0)',\n\\'command!      -bang -nargs=* Ag                               call fzf#vim#ag(<q-args>, fzf#vim#with_preview(), <bang>0)',\n\\'command!      -bang -nargs=* Rg                               call fzf#vim#grep(\"rg --column --line-number --no-heading --color=always --smart-case -- \".fzf#shellescape(<q-args>), fzf#vim#with_preview(), <bang>0)',\n\\'command!      -bang -nargs=* RG                               call fzf#vim#grep2(\"rg --column --line-number --no-heading --color=always --smart-case -- \", <q-args>, fzf#vim#with_preview(), <bang>0)',\n\\'command!      -bang -nargs=* Tags                             call fzf#vim#tags(<q-args>, fzf#vim#with_preview({ \"placeholder\": \"--tag {2}:{-1}:{3..}\" }), <bang>0)',\n\\'command!      -bang -nargs=* BTags                            call fzf#vim#buffer_tags(<q-args>, fzf#vim#with_preview({ \"placeholder\": \"{2}:{3..}\" }), <bang>0)',\n\\'command! -bar -bang Snippets                                  call fzf#vim#snippets(<bang>0)',\n\\'command! -bar -bang Commands                                  call fzf#vim#commands(<bang>0)',\n\\'command! -bar -bang Jumps                                     call fzf#vim#jumps(fzf#vim#with_preview({ \"placeholder\": \"{2..4}\"}), <bang>0)',\n\\'command! -bar -bang -nargs=* Marks                            call fzf#vim#marks(<q-args>, <bang>0)',\n\\'command! -bar -bang -nargs=* BMarks                           call fzf#vim#marks(\"abcdefghijklmnopqrstuvwxyz\", <bang>0)',\n\\'command! -bar -bang Changes                                   call fzf#vim#changes(<bang>0)',\n\\'command! -bar -bang Helptags                                  call fzf#vim#helptags(fzf#vim#with_preview({ \"placeholder\": \"--tag {2}:{3}:{4}\" }), <bang>0)',\n\\'command! -bar -bang Windows                                   call fzf#vim#windows(fzf#vim#with_preview({ \"placeholder\": \"{2}\" }), <bang>0)',\n\\'command! -bar -bang -nargs=* -range=% -complete=file Commits  let b:fzf_winview = winsaveview() | <line1>,<line2>call fzf#vim#commits(<q-args>, fzf#vim#with_preview({ \"placeholder\": \"\" }), <bang>0)',\n\\'command! -bar -bang -nargs=* -range=% BCommits                let b:fzf_winview = winsaveview() | <line1>,<line2>call fzf#vim#buffer_commits(<q-args>, fzf#vim#with_preview({ \"placeholder\": \"\" }), <bang>0)',\n\\'command! -bar -bang Maps                                      call fzf#vim#maps(\"n\", <bang>0)',\n\\'command! -bar -bang Filetypes                                 call fzf#vim#filetypes(<bang>0)',\n\\'command!      -bang -nargs=* History                          call s:history(<q-args>, fzf#vim#with_preview(), <bang>0)'])\n\nfunction! s:history(arg, extra, bang)\n  let bang = a:bang || a:arg[len(a:arg)-1] == '!'\n  if a:arg[0] == ':'\n    call fzf#vim#command_history(bang)\n  elseif a:arg[0] == '/'\n    call fzf#vim#search_history(bang)\n  else\n    call fzf#vim#history(a:extra, bang)\n  endif\nendfunction\n\nfunction! fzf#complete(...)\n  return call('fzf#vim#complete', a:000)\nendfunction\n\nif (has('nvim') || has('terminal') && has('patch-8.0.995')) && (s:conf('statusline', 1) || s:conf('nvim_statusline', 1))\n  function! s:fzf_restore_colors()\n    if exists('#User#FzfStatusLine')\n      doautocmd User FzfStatusLine\n    else\n      if $TERM !~ \"256color\"\n        highlight default fzf1 ctermfg=1 ctermbg=8 guifg=#E12672 guibg=#565656\n        highlight default fzf2 ctermfg=2 ctermbg=8 guifg=#BCDDBD guibg=#565656\n        highlight default fzf3 ctermfg=7 ctermbg=8 guifg=#D9D9D9 guibg=#565656\n      else\n        highlight default fzf1 ctermfg=161 ctermbg=238 guifg=#E12672 guibg=#565656\n        highlight default fzf2 ctermfg=151 ctermbg=238 guifg=#BCDDBD guibg=#565656\n        highlight default fzf3 ctermfg=252 ctermbg=238 guifg=#D9D9D9 guibg=#565656\n      endif\n      setlocal statusline=%#fzf1#\\ >\\ %#fzf2#fz%#fzf3#f\n    endif\n  endfunction\n\n  function! s:fzf_vim_term()\n    if get(w:, 'airline_active', 0)\n      let w:airline_disabled = 1\n      autocmd BufWinLeave <buffer> let w:airline_disabled = 0\n    endif\n    autocmd WinEnter,ColorScheme <buffer> call s:fzf_restore_colors()\n\n    setlocal nospell\n    call s:fzf_restore_colors()\n  endfunction\n\n  augroup _fzf_statusline\n    autocmd!\n    autocmd FileType fzf call s:fzf_vim_term()\n  augroup END\nendif\n\nif !exists('g:fzf#vim#buffers')\n  let g:fzf#vim#buffers = {}\nendif\n\naugroup fzf_buffers\n  autocmd!\n  if exists('*reltimefloat')\n    autocmd BufWinEnter,WinEnter * let g:fzf#vim#buffers[bufnr('')] = reltimefloat(reltime())\n  else\n    autocmd BufWinEnter,WinEnter * let g:fzf#vim#buffers[bufnr('')] = localtime()\n  endif\n  autocmd BufDelete * silent! call remove(g:fzf#vim#buffers, expand('<abuf>'))\naugroup END\n\ninoremap <expr> <plug>(fzf-complete-word)        fzf#vim#complete#word()\nif s:is_win\n  inoremap <expr> <plug>(fzf-complete-path)      fzf#vim#complete#path('dir /s/b')\n  inoremap <expr> <plug>(fzf-complete-file)      fzf#vim#complete#path('dir /s/b/a:-d')\nelse\n  inoremap <expr> <plug>(fzf-complete-path)      fzf#vim#complete#path(\"find . -path '*/\\.*' -prune -o -print \\| sed '1d;s:^..::'\")\n  inoremap <expr> <plug>(fzf-complete-file)      fzf#vim#complete#path(\"find . -path '*/\\.*' -prune -o -type f -print -o -type l -print \\| sed 's:^..::'\")\nendif\ninoremap <expr> <plug>(fzf-complete-file-ag)     fzf#vim#complete#path('ag -l -g \"\"')\ninoremap <expr> <plug>(fzf-complete-line)        fzf#vim#complete#line()\ninoremap <expr> <plug>(fzf-complete-buffer-line) fzf#vim#complete#buffer_line()\n\nnnoremap <silent> <plug>(fzf-maps-n) :<c-u>call fzf#vim#maps('n', 0)<cr>\ninoremap <silent> <plug>(fzf-maps-i) <c-o>:call fzf#vim#maps('i', 0)<cr>\nxnoremap <silent> <plug>(fzf-maps-x) :<c-u>call fzf#vim#maps('x', 0)<cr>\nonoremap <silent> <plug>(fzf-maps-o) <c-c>:<c-u>call fzf#vim#maps('o', 0)<cr>\n\nlet &cpo = s:cpo_save\nunlet s:cpo_save\n\n"
  }
]