83 Commits

Author SHA1 Message Date
Junegunn Choi
529894d769 Revert "[GitFiles] Support files with special characters (#500)"
This reverts commit 004af25150.
2017-11-16 19:29:46 +09:00
Michael Budde
004af25150 [GitFiles] Support files with special characters (#500)
By default git will quote filenames that contain special characters.
From the git help on the `core.quotepath` config:

> The commands that output paths (e.g. `ls-files`, `diff`), when not given
> the `-z` option, will quote "unusual" characters in the pathname by
> enclosing the pathname in a double-quote pair and with backslashes the
> same way strings in C source code are quoted. If this variable is set
> to false, the bytes higher than 0x80 are not quoted but output as
> verbatim. Note that double quote, backslash and control characters are
> always quoted without `-z` regardless of the setting of this variable.

This quoting behaviour means that GitFiles cannot be used to open files
that contain any special characters. Fix this by using the `-z` option
to `ls-files` together with the `--read0` option on fzf.
2017-11-16 15:11:27 +09:00
Josh Pencheon
4b9e2a03fe [GFiles] Avoid duplicate entries (#473)
It is presumed that duplicates in `git ls-files` are contiguous.
2017-11-14 12:54:07 +09:00
Michael Kaiser
5c6cee878a [fzf#vim#colors] Pick up colorschemes from opt packages (#489) 2017-11-02 21:35:48 +09:00
Josh Pencheon
f31a2925fe [BCommits] Remove --graph option (#474) 2017-10-25 18:57:27 +09:00
Jan Edmund Lazo
b51382fe9e [fzf#vim#preview] Use ruby in Windows if available (#471)
Close #459
2017-10-22 22:50:12 +09:00
Junegunn Choi
fbfbd04870 Clean up README 2017-10-21 09:27:18 +09:00
Junegunn Choi
852b38db2a Update installation instruction 2017-10-21 09:25:24 +09:00
Junegunn Choi
6ac8d1f742 Update vimdoc and remove duplicate tags
Close #467
2017-10-17 02:21:57 +09:00
Junegunn Choi
121bd70fcf [[B]Commits] Enable preview window by default
Close #461
2017-10-08 03:45:31 +09:00
Junegunn Choi
b24038960e Fix incorrect --query option in completion
s:complete_trigger should prepend the default options instead of
appending them. The bug was introduced in 25ea637.

/tmp/foo<ctrl-x><ctrl-f> should give fzf prompt "/tmp/" and default
query "foo". But it used to give "/tmp//tmp/foo".
2017-09-26 15:20:27 +09:00
Junegunn Choi
36f6e6b5b0 Fix s:wrap for Vim 7.4
Close #446
2017-09-14 19:13:11 +09:00
Jan Edmund Lazo
2fd046fa76 [Files] Port junegunn/fzf/pull/1043 (#442) 2017-09-07 11:03:56 +09:00
Junegunn Choi
e7928d154a [Files] Do not set up lengthy prompt on narrow screen 2017-09-05 18:50:18 +09:00
Jan Edmund Lazo
df79877245 [fzf#vim#preview] works with Windows default command (#441) 2017-09-04 22:50:37 +09:00
Junegunn Choi
0b0d9f0912 [Ag] Print error message when ag is not found on $PATH
Close #440
2017-09-01 11:10:42 +09:00
Junegunn Choi
39f0c2d0a4 Merge pull request #436 from janlazo/Windows_complete
[fzf#vim#complete#path] works in Windows
2017-08-28 22:38:41 +09:00
Jan Edmund Lazo
34ceec14d2 [fzf#vim#complete] append --no-expect to options
Reference: https://github.com/junegunn/fzf.vim/pull/436#discussion_r135379047
2017-08-27 08:50:35 -04:00
Jan Edmund Lazo
b73cec55f0 [fzf#vim#complete#path] works in Windows 2017-08-27 08:50:35 -04:00
Jan Edmund Lazo
25ea6371b2 [s:complete_trigger] use list type for options 2017-08-27 08:50:35 -04:00
Junegunn Choi
4e603e4fab [Commits] Fix formatting of commit log 2017-08-27 05:10:51 +09:00
Junegunn Choi
13b27c45c8 Merge pull request #429 from janlazo/Windows_Ag
[Ag, fzf#vim#grep] works in Windows
2017-08-25 22:57:55 +09:00
Junegunn Choi
e246016844 [History] Remove duplicates and print list in MRU order
Close #434
2017-08-24 02:58:27 +09:00
Jan Edmund Lazo
a4d4986d18 Make 8.3 filename via cmd.exe for Neovim 2017-08-22 06:02:30 -04:00
Jan Edmund Lazo
b0baf7593d [Commits,BCommits] Windows support (#430)
Works only in s:execute of fzf's Vim plugin.
s:execute_term corrupts the output of fzf#shellescape.
2017-08-22 02:13:06 +09:00
Jan Edmund Lazo
dda682ad69 Revert "Run preview script in batchfile for Windows"
The reverted commit is broken.
Keep it simple by sticking with the fnamemodify hack.
Hope that Neovim supports 8.3 filenames
2017-08-20 22:55:47 -04:00
Jan Edmund Lazo
71cc4c5037 Run preview script in batchfile for Windows
Bypasses the following issues in Windows:
1. Neovim does not support 8.3 filenames
   ie. fnamemodify(path, ':8')
2. fzf binary cannot parse output of fzf#shellescape
   It assumes that preview command is run in sh, not cmd.exe
2017-08-20 22:42:45 -04:00
Jan Edmund Lazo
057853a248 [s:fzf] join the option list for preview script check 2017-08-20 21:42:09 -04:00
Jan Edmund Lazo
3334d62749 [fzf#vim#with_preview] works with Ag in Windows
- disabled on Files because the preview scripts cannot resolve the network drive
- use 8.3 filepath for s:bin.preview to bypass escape issues in fzf binary
2017-08-20 21:21:32 -04:00
Jan Edmund Lazo
469ac6bfce [Ag] works in Windows
[fzf#vim#grep] use list type for options
2017-08-20 17:35:28 -04:00
Jan Edmund Lazo
fa91d53f5c [Tags] Support Windows-style absolute filepaths (#428) 2017-08-20 23:14:31 +09:00
Jan Edmund Lazo
1e40de4f2d [Tags, BTags] Windows support (#427) 2017-08-20 22:11:42 +09:00
Jan Edmund Lazo
61bcdb146f [s:q] Use fzf#shellescape for Windows (#425)
Fixes Lines, BLines, Buffers on Windows
2017-08-20 16:59:09 +09:00
Jan Edmund Lazo
d62ec0b113 [GFiles?] Windows suppport: use list type for options (#424)
Requires msysgit or cygwin in Windows
2017-08-20 16:55:15 +09:00
Jan Edmund Lazo
914355df94 [Helptags] Windows support (#423) 2017-08-20 12:26:07 +09:00
Jack O'Connor
7e868c49ac Exclude the current file from History (#422)
Close #367
2017-08-18 02:14:43 +09:00
Jan Edmund Lazo
43a570d6e6 [Files] runs in Windows (#418)
* [Files] runs in Windows

* Use fzf#shellescape() and copy() in s:merge_opts()

* [fzf#vim#preview] uses list type for options

- fixed s:merge_opts for extending the option list

* [fzf#vim#with_preview] no-op in Windows

Reference: https://github.com/junegunn/fzf.vim/pull/418#issuecomment-322645632

* [fzf#vim#with_preview] return passed dict in Windows
2017-08-17 13:12:10 +09:00
Junegunn Choi
b9b275a897 Ignore Funcref actions in g:fzf_action
A Funcref action in g:fzf_action only handles a list of file paths so
they can't be used to open windows.

Related:
- #185
- 2069bbc8b5
2017-08-14 17:42:33 +09:00
Junegunn Choi
d3b9fed9c2 [Ag] Drop --nth to make search faster 2017-07-30 20:14:17 +09:00
Junegunn Choi
685f9aae97 [Tags] Remove --with-nth option to speed up loading 2017-07-24 02:35:21 +09:00
Junegunn Choi
55f6bc8367 [Tags/Helptags] Do not proceed if perl is not found
Related: https://github.com/junegunn/fzf.vim/issues/22#issuecomment-311873515
2017-07-01 01:18:01 +09:00
Junegunn Choi
e1c3bba14b Update README regarding Windows support
Related: #372
2017-06-29 12:35:10 +09:00
Junegunn Choi
348a57a4a4 Allow fzf#complete to take hash argument with sink
This allows us to use the return value of fzf#wrap function with
fzf#complete.

This commit also removes obsolete g:fzf#vim#default_layout and
fzf#vim#layout.
2017-06-28 21:19:11 +09:00
Junegunn Choi
ccc32c3164 Do not depend on fugitive for finding git root
Revert #239
Close #387
2017-06-16 10:39:50 +09:00
Junegunn Choi
cf60e54647 [Commits] Commit hash can be longer 2017-06-10 03:44:52 +09:00
Junegunn Choi
990834ab6c [Helptags] Fix globpath pattern
Close #376
2017-05-22 01:29:48 +09:00
Junegunn Choi
536b6ace35 [[B]Tags] Proceed to the next command if the output is empty
Close #375
2017-05-20 01:52:19 +09:00
Junegunn Choi
d99169da2d Use FZF_PREVIEW_HEIGHT if available. Requires fzf 0.16.7.
Close #361
2017-04-30 12:06:41 +09:00
Junegunn Choi
8ffd3fb0ba [Maps] Fix parse error in non-US locales
Close #324

Caveat: The fix assumes that the paths of Vimscript files do not contain
whitespaces. Maps will report incorrect paths if they do.
2017-04-24 10:48:31 +09:00
Junegunn Choi
f3c3646c81 Fix <plug>(fzf-complete-buffer-line)
Reported by Roland Emmerich
2017-04-24 10:34:40 +09:00
Junegunn Choi
605d9da512 Update documentation 2017-03-18 02:14:43 +09:00
Blaž Hrastnik
4f00962a81 Add support for the rouge highlighter. (#336)
https://github.com/jneen/rouge
2017-03-18 02:07:06 +09:00
Junegunn Choi
2eaff04946 Show how to set up fzf#vim#files with fzf#vim#with_preview 2017-03-13 19:42:16 +09:00
Junegunn Choi
2b69c15226 Fix fzf#vim#with_preview: missing parentheses
Close #334
2017-03-13 19:28:40 +09:00
Junegunn Choi
b7a19efa46 Update .github/ISSUE_TEMPLATE.md
Provide the latest vimrc for testing.

Reference: https://gist.github.com/atenni/5604615
2017-03-13 12:13:25 +09:00
Junegunn Choi
06a8b870c0 [Tags] Support multiple tags files
We also apply --nth 1..2 by default to limit the search scope.

Close #106
Related #5, #329
2017-03-10 17:04:52 +09:00
Junegunn Choi
e4f79f6e98 Use shellescape instead of manual escaping
Close #328
2017-03-07 23:17:04 +09:00
Junegunn Choi
87a910a127 [[B]Commits] Enable sort by default 2017-03-03 12:20:44 +09:00
Junegunn Choi
364fea3ca0 [Tags] Temporarily unset autochdir
Close #269
2017-02-26 00:01:00 +09:00
Junegunn Choi
fcca65bbe5 [BTags] Fix "tag commnads" argument 2017-02-18 13:51:06 +09:00
sangwook
dade777e6d Check for exact command name (#306) 2017-02-08 11:58:58 +09:00
Junegunn Choi
1bf68a978b Do not override existing commands
So that we don't have to use VimEnter autocmd to override the commands
2017-02-07 11:40:31 +09:00
Junegunn Choi
4329721384 [Tags] Fall back to --algo=v1 if tags file is too large (> 200MB) 2017-02-03 12:34:20 +09:00
Junegunn Choi
f77b644797 Revert "Replace --tiebreak=index with --nth 1,.."
The original issue with --tiebreak=begin will be fixed in fzf 0.16.4 so
we should use --tiebreak=begin again to avoid tokenization overhead.
2017-02-03 12:24:27 +09:00
Junegunn Choi
22e59c4da0 Replace --tiebreak=index with --nth 1,..
Currently, --tiebreak=begin does not guarantee the best result due to
performance considerations. But --nth 1,.. works better in these cases
anyway.
2017-01-25 10:17:30 +09:00
Junegunn Choi
51a4d3090f Use 24-bit colors (fzf 0.16.2)
Close https://github.com/junegunn/fzf/issues/789
2017-01-24 01:49:00 +09:00
Junegunn Choi
f54ec7caf1 Do not preview binary files 2017-01-23 10:28:08 +09:00
Theo Belaire
3e8ac82cbb [Buffers] Allow query argument (#286) 2017-01-11 11:24:07 +09:00
Andreas Gerstmayr
bac82a954f [Tags] Add -a option to grep (#284)
Somehow the tags file generated by ctags for the linux kernel, tag
v4.10-rc1 contains non-ASCII characters. grep stops when it detects
non-ASCII characters. This patch adds the -a option to the grep command
to treat the tags file as ASCII text.

Signed-off-by: Andreas Gerstmayr <andreas.gerstmayr@gmail.com>
2017-01-07 10:56:29 +09:00
Matthew Klein
2066643243 [fzf#vim#colors] Remove duplicate colorschemes (#278)
Use s:uniq() instead of uniq() for older versions of Vim.

We don't sort the list before passing it to s:uniq() because
1. s:uniq() can process unsorted lists.
2. And in that way, we can list color schemes from plugins before
   the default ones provided by Vim.
2016-12-25 01:27:53 +09:00
Junegunn Choi
7460b4382c [GFiles?] Apply --tiebreak=index for status code filtering 2016-12-15 10:31:25 +09:00
Oscar Morrison
3d7dfc7068 Change to macOS (#268) 2016-12-11 21:20:59 +09:00
Junegunn Choi
abdf894edf [fzf#vim#with_preview] Expand relative path
Close #261
2016-12-08 13:30:06 +09:00
alex
42086bee57 Add preview.sh for ruby-less previews. (#259) 2016-12-05 02:11:22 +09:00
Junegunn Choi
eb9e5803b1 [Files] Fix path display when cwd is ~ 2016-12-03 01:16:01 +09:00
Junegunn Choi
59eb2b19ac [Files] Display relative path in prompt 2016-12-02 21:07:37 +09:00
Junegunn Choi
eb1f9b02f7 [fzf#vim#with_preview] Escape --bind expression
Close #256
2016-11-27 19:30:28 +09:00
Junegunn Choi
6e50206adf Apply -bar option to commands that do not take arguments 2016-11-26 21:51:24 +09:00
Nate
77db64ef2c Allow restyling of the fzf[123] groups (#254) 2016-11-26 14:59:06 +09:00
Didier Prophete
28a1835ce4 Redirect STDERR of ctags to /dev/null (#252) 2016-11-26 14:17:00 +09:00
Junegunn Choi
9ce2c2179f Add fzf#vim#with_preview function for previewing search result
Close #225
2016-11-26 14:11:27 +09:00
Junegunn Choi
3fbcfdb9ea [Buffers] Ignore quickfix Windows (#249) 2016-11-26 13:00:57 +09:00
Junegunn Choi
dc9364c137 [Tags] Case-insensitive Y/N prompt
Close #247
2016-11-22 12:36:18 +09:00
9 changed files with 588 additions and 217 deletions

View File

@@ -5,7 +5,7 @@
- [ ] Suggestion - [ ] Suggestion
- OS - OS
- [ ] Linux - [ ] Linux
- [ ] Mac OS X - [ ] macOS
- [ ] Windows - [ ] Windows
- [ ] Etc. - [ ] Etc.
- Vim - Vim
@@ -23,7 +23,7 @@ Before submitting
Start Vim with a minimal configuration Start Vim with a minimal configuration
====================================== ======================================
vim -Nu <(curl https://gist.githubusercontent.com/junegunn/6936bf79fedd3a079aeb1dd2f3c81ef5/raw/vimrc) vim -Nu <(curl https://gist.githubusercontent.com/junegunn/6936bf79fedd3a079aeb1dd2f3c81ef5/raw)
--> -->

View File

@@ -29,12 +29,23 @@ selector with fzf.
fzf is an independent command-line program and thus requires an external fzf is an independent command-line program and thus requires an external
terminal emulator when on GVim. You may or may not like the experience. Also terminal emulator when on GVim. You may or may not like the experience. Also
note that fzf currently does not compile on Windows. note that Windows support is experimental at the moment.
Installation Installation
------------ ------------
Using [vim-plug](https://github.com/junegunn/vim-plug): Use [vim-plug](https://github.com/junegunn/vim-plug) or any Vim plugin
manager of your choice.
If you already installed fzf using [Homebrew](https://brew.sh/), the following
should suffice:
```vim
Plug '/usr/local/opt/fzf'
Plug 'junegunn/fzf.vim'
```
But if you want to install fzf as well using vim-plug:
```vim ```vim
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
@@ -43,8 +54,6 @@ Plug 'junegunn/fzf.vim'
- `dir` and `do` options are not mandatory - `dir` and `do` options are not mandatory
- Use `./install --bin` instead if you don't need fzf outside of Vim - Use `./install --bin` instead if you don't need fzf outside of Vim
- If you installed fzf using Homebrew, the following should suffice:
- `Plug '/usr/local/opt/fzf' | Plug 'junegunn/fzf.vim'`
- Make sure to use Vim 7.4 or above - Make sure to use Vim 7.4 or above
Commands Commands
@@ -93,6 +102,10 @@ pathogen#helptags()`. [↩](#a1))
#### Global options #### Global options
See [README-VIM.md][readme-vim] of the main fzf repository for details.
[readme-vim]: https://github.com/junegunn/fzf/blob/master/README-VIM.md#configuration
```vim ```vim
" This is the default extra key bindings " This is the default extra key bindings
let g:fzf_action = { let g:fzf_action = {
@@ -107,6 +120,7 @@ let g:fzf_layout = { 'down': '~40%' }
" In Neovim, you can set up fzf window using a Vim command " In Neovim, you can set up fzf window using a Vim command
let g:fzf_layout = { 'window': 'enew' } let g:fzf_layout = { 'window': 'enew' }
let g:fzf_layout = { 'window': '-tabnew' } let g:fzf_layout = { 'window': '-tabnew' }
let g:fzf_layout = { 'window': '10split enew' }
" Customize fzf colors to match your color scheme " Customize fzf colors to match your color scheme
let g:fzf_colors = let g:fzf_colors =
@@ -117,6 +131,7 @@ let g:fzf_colors =
\ 'bg+': ['bg', 'CursorLine', 'CursorColumn'], \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'],
\ 'hl+': ['fg', 'Statement'], \ 'hl+': ['fg', 'Statement'],
\ 'info': ['fg', 'PreProc'], \ 'info': ['fg', 'PreProc'],
\ 'border': ['fg', 'Ignore'],
\ 'prompt': ['fg', 'Conditional'], \ 'prompt': ['fg', 'Conditional'],
\ 'pointer': ['fg', 'Exception'], \ 'pointer': ['fg', 'Exception'],
\ 'marker': ['fg', 'Keyword'], \ 'marker': ['fg', 'Keyword'],
@@ -133,12 +148,6 @@ let g:fzf_history_dir = '~/.local/share/fzf-history'
#### Command-local options #### Command-local options
```vim ```vim
" [Files] Extra options for fzf
" e.g. File preview using Highlight
" (http://www.andre-simon.de/doku/highlight/en/highlight.html)
let g:fzf_files_options =
\ '--preview "(highlight -O ansi {} || cat {}) 2> /dev/null | head -'.&lines.'"'
" [Buffers] Jump to the existing window if possible " [Buffers] Jump to the existing window if possible
let g:fzf_buffers_jump = 1 let g:fzf_buffers_jump = 1
@@ -152,18 +161,47 @@ let g:fzf_tags_command = 'ctags -R'
let g:fzf_commands_expect = 'alt-enter,ctrl-x' let g:fzf_commands_expect = 'alt-enter,ctrl-x'
``` ```
#### Advanced customization using autoload functions #### Advanced customization
You can use autoload functions to define your own commands. You can use autoload functions to define your own commands.
```vim ```vim
" git grep " Command for git grep
" - fzf#vim#grep(command, with_column, [options], [fullscreen])
command! -bang -nargs=* GGrep command! -bang -nargs=* GGrep
\ call fzf#vim#grep('git grep --line-number '.shellescape(<q-args>), 0, <bang>0) \ call fzf#vim#grep('git grep --line-number '.shellescape(<q-args>), 0, <bang>0)
" We use VimEnter event so that the code is run after fzf.vim is loaded " Override Colors command. You can safely do this in your .vimrc as fzf.vim
autocmd VimEnter * command! Colors " will not override existing commands.
\ call fzf#vim#colors({'left': '15%', 'options': '--reverse --margin 30%,0'}) command! -bang Colors
\ call fzf#vim#colors({'left': '15%', 'options': '--reverse --margin 30%,0'}, <bang>0)
" Augmenting Ag command using fzf#vim#with_preview function
" * fzf#vim#with_preview([[options], preview window, [toggle keys...]])
" * For syntax-highlighting, Ruby and any of the following tools are required:
" - Highlight: http://www.andre-simon.de/doku/highlight/en/highlight.php
" - CodeRay: http://coderay.rubychan.de/
" - Rouge: https://github.com/jneen/rouge
"
" :Ag - Start fzf with hidden preview window that can be enabled with "?" key
" :Ag! - Start fzf in fullscreen and display the preview window above
command! -bang -nargs=* Ag
\ call fzf#vim#ag(<q-args>,
\ <bang>0 ? fzf#vim#with_preview('up:60%')
\ : fzf#vim#with_preview('right:50%:hidden', '?'),
\ <bang>0)
" Similarly, we can apply it to fzf#vim#grep. To use ripgrep instead of ag:
command! -bang -nargs=* Rg
\ call fzf#vim#grep(
\ 'rg --column --line-number --no-heading --color=always '.shellescape(<q-args>), 1,
\ <bang>0 ? fzf#vim#with_preview('up:60%')
\ : fzf#vim#with_preview('right:50%:hidden', '?'),
\ <bang>0)
" Likewise, Files command with preview window
command! -bang -nargs=? -complete=dir Files
\ call fzf#vim#files(<q-args>, fzf#vim#with_preview(), <bang>0)
``` ```
Mappings Mappings
@@ -222,7 +260,7 @@ following exceptions:
- Or a function to extract completion prefix - Or a function to extract completion prefix
- Both `source` and `options` can be given as funcrefs that take the - Both `source` and `options` can be given as funcrefs that take the
completion prefix as the argument and return the final value completion prefix as the argument and return the final value
- `sink` or `sink*` are not allowed - `sink` or `sink*` are ignored
#### Reducer example #### Reducer example

View File

@@ -1,4 +1,4 @@
" Copyright (c) 2016 Junegunn Choi " Copyright (c) 2017 Junegunn Choi
" "
" MIT License " MIT License
" "
@@ -28,10 +28,83 @@ set cpo&vim
" Common " Common
" ------------------------------------------------------------------ " ------------------------------------------------------------------
let s:is_win = has('win32') || has('win64')
let s:layout_keys = ['window', 'up', 'down', 'left', 'right'] let s:layout_keys = ['window', 'up', 'down', 'left', 'right']
let s:TYPE = {'dict': type({}), 'funcref': type(function('call')), 'string': type('')} let s:bin_dir = expand('<sfile>:h:h:h').'/bin/'
let s:bin = {
\ 'preview': s:bin_dir.(executable('ruby') ? 'preview.rb' : 'preview.sh'),
\ 'tags': s:bin_dir.'tags.pl' }
let s:TYPE = {'dict': type({}), 'funcref': type(function('call')), 'string': type(''), 'list': type([])}
if s:is_win
if has('nvim')
let s:bin.preview = split(system('for %A in ("'.s:bin.preview.'") do echo %~sA'), "\n")[1]
else
let s:bin.preview = fnamemodify(s:bin.preview, ':8')
endif
let s:bin.preview = (executable('ruby') ? 'ruby' : 'bash').' '.escape(s:bin.preview, '\')
endif
function s:remove_layout(opts) function! s:extend_opts(dict, eopts, prepend)
if empty(a:eopts)
return
endif
if has_key(a:dict, 'options')
if type(a:dict.options) == s:TYPE.list && type(a:eopts) == s:TYPE.list
if a:prepend
let a:dict.options = extend(copy(a:eopts), a:dict.options)
else
call extend(a:dict.options, a:eopts)
endif
else
let all_opts = a:prepend ? [a:eopts, a:dict.options] : [a:dict.options, a:eopts]
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'))
endif
else
let a:dict.options = a:eopts
endif
endfunction
function! s:merge_opts(dict, eopts)
return s:extend_opts(a:dict, a:eopts, 0)
endfunction
function! s:prepend_opts(dict, eopts)
return s:extend_opts(a:dict, a:eopts, 1)
endfunction
" [[options to wrap], preview window expression, [toggle-preview keys...]]
function! fzf#vim#with_preview(...)
" Default options
let options = {}
let window = 'right'
let args = copy(a:000)
" Options to wrap
if len(args) && type(args[0]) == s:TYPE.dict
let options = copy(args[0])
call remove(args, 0)
endif
" Preview window
if len(args) && type(args[0]) == s:TYPE.string
if args[0] !~# '^\(up\|down\|left\|right\)'
throw 'invalid preview window: '.args[0]
endif
let window = args[0]
call remove(args, 0)
endif
let preview = ['--preview-window', window, '--preview', s:bin.preview.' '.(window =~ 'up\|down' ? '-v' : '').' {}']
if len(args)
call extend(preview, ['--bind', join(map(args, 'v:val.":toggle-preview"'), ',')])
endif
call s:merge_opts(options, preview)
return options
endfunction
function! s:remove_layout(opts)
for key in s:layout_keys for key in s:layout_keys
if has_key(a:opts, key) if has_key(a:opts, key)
call remove(a:opts, key) call remove(a:opts, key)
@@ -45,15 +118,14 @@ function! fzf#vim#wrap(opts)
return fzf#wrap(a:opts) return fzf#wrap(a:opts)
endfunction endfunction
" Deprecated
function! fzf#vim#layout(...)
return (a:0 && a:1) ? {} : copy(get(g:, 'fzf_layout', g:fzf#vim#default_layout))
endfunction
function! s:wrap(name, opts, bang) function! s:wrap(name, opts, bang)
" fzf#wrap does not append --expect if sink or sink* is found " fzf#wrap does not append --expect if sink or sink* is found
let opts = copy(a:opts) let opts = copy(a:opts)
if get(opts, 'options', '') !~ '--expect' && has_key(opts, 'sink*') let options = ''
if has_key(opts, 'options')
let options = type(opts.options) == s:TYPE.list ? join(opts.options) : opts.options
endif
if options !~ '--expect' && has_key(opts, 'sink*')
let Sink = remove(opts, 'sink*') let Sink = remove(opts, 'sink*')
let wrapped = fzf#wrap(a:name, opts, a:bang) let wrapped = fzf#wrap(a:name, opts, a:bang)
let wrapped['sink*'] = Sink let wrapped['sink*'] = Sink
@@ -75,10 +147,6 @@ function! s:escape(path)
return escape(a:path, ' $%#''"\') return escape(a:path, ' $%#''"\')
endfunction endfunction
function! s:q1(str)
return "'".substitute(a:str, "'", "'\\\\''", 'g')."'"
endfunction
if v:version >= 704 if v:version >= 704
function! s:function(name) function! s:function(name)
return function(a:name) return function(a:name)
@@ -91,9 +159,12 @@ else
endif endif
function! s:get_color(attr, ...) function! s:get_color(attr, ...)
let gui = has('termguicolors') && &termguicolors
let fam = gui ? 'gui' : 'cterm'
let pat = gui ? '^#[a-f0-9]\+' : '^[0-9]\+$'
for group in a:000 for group in a:000
let code = synIDattr(synIDtrans(hlID(group)), a:attr, 'cterm') let code = synIDattr(synIDtrans(hlID(group)), a:attr, fam)
if code =~ '^[0-9]\+$' if code =~? pat
return code return code
endif endif
endfor endfor
@@ -102,11 +173,19 @@ endfunction
let s:ansi = {'black': 30, 'red': 31, 'green': 32, 'yellow': 33, 'blue': 34, 'magenta': 35, 'cyan': 36} let s:ansi = {'black': 30, 'red': 31, 'green': 32, 'yellow': 33, 'blue': 34, 'magenta': 35, 'cyan': 36}
function! s:csi(color, fg)
let prefix = a:fg ? '38;' : '48;'
if a:color[0] == '#'
return prefix.'2;'.join(map([a:color[1:2], a:color[3:4], a:color[5:6]], 'str2nr(v:val, 16)'), ';')
endif
return prefix.'5;'.a:color
endfunction
function! s:ansi(str, group, default, ...) function! s:ansi(str, group, default, ...)
let fg = s:get_color('fg', a:group) let fg = s:get_color('fg', a:group)
let bg = s:get_color('bg', a:group) let bg = s:get_color('bg', a:group)
let color = (empty(fg) ? s:ansi[a:default] : ('38;5;'.fg)) . let color = s:csi(empty(fg) ? s:ansi[a:default] : fg, 1) .
\ (empty(bg) ? '' : (';48;5;'.bg)) \ (empty(bg) ? '' : s:csi(bg, 0))
return printf("\x1b[%s%sm%s\x1b[m", color, a:0 ? ';1' : '', a:str) return printf("\x1b[%s%sm%s\x1b[m", color, a:0 ? ';1' : '', a:str)
endfunction endfunction
@@ -117,13 +196,7 @@ for s:color_name in keys(s:ansi)
endfor endfor
function! s:buflisted() function! s:buflisted()
return filter(range(1, bufnr('$')), 'buflisted(v:val)') return filter(range(1, bufnr('$')), 'buflisted(v:val) && getbufvar(v:val, "&filetype") != "qf"')
endfunction
function! s:defaults()
let rules = copy(get(g:, 'fzf_colors', {}))
let colors = join(map(items(filter(map(rules, 'call("s:get_color", v:val)'), '!empty(v:val)')), 'join(v:val, ":")'), ',')
return empty(colors) ? '' : ('--color='.colors)
endfunction endfunction
function! s:fzf(name, opts, extra) function! s:fzf(name, opts, extra)
@@ -143,7 +216,7 @@ function! s:fzf(name, opts, extra)
let eopts = has_key(extra, 'options') ? remove(extra, 'options') : '' let eopts = has_key(extra, 'options') ? remove(extra, 'options') : ''
let merged = extend(copy(a:opts), extra) let merged = extend(copy(a:opts), extra)
let merged.options = join(filter([s:defaults(), get(merged, 'options', ''), eopts], '!empty(v:val)')) call s:merge_opts(merged, eopts)
return fzf#run(s:wrap(a:name, merged, bang)) return fzf#run(s:wrap(a:name, merged, bang))
endfunction endfunction
@@ -152,6 +225,12 @@ let s:default_action = {
\ 'ctrl-x': 'split', \ 'ctrl-x': 'split',
\ 'ctrl-v': 'vsplit' } \ 'ctrl-v': 'vsplit' }
function! s:action_for(key, ...)
let default = a:0 ? a:1 : ''
let Cmd = get(get(g:, 'fzf_action', s:default_action), a:key, default)
return type(Cmd) == s:TYPE.string ? Cmd : default
endfunction
function! s:open(cmd, target) function! s:open(cmd, target)
if stridx('edit', a:cmd) == 0 && fnamemodify(a:target, ':p') ==# expand('%:p') if stridx('edit', a:cmd) == 0 && fnamemodify(a:target, ':p') ==# expand('%:p')
return return
@@ -181,7 +260,7 @@ function! s:warn(message)
return 0 return 0
endfunction endfunction
function! s:uniq(list) function! fzf#vim#_uniq(list)
let visited = {} let visited = {}
let ret = [] let ret = []
for l in a:list for l in a:list
@@ -196,19 +275,30 @@ endfunction
" ------------------------------------------------------------------ " ------------------------------------------------------------------
" Files " Files
" ------------------------------------------------------------------ " ------------------------------------------------------------------
function! s:shortpath()
let short = fnamemodify(getcwd(), ':~:.')
if !has('win32unix')
let short = pathshorten(short)
endif
let slash = (s:is_win && !&shellslash) ? '\' : '/'
return empty(short) ? '~'.slash : short . (short =~ escape(slash, '\').'$' ? '' : slash)
endfunction
function! fzf#vim#files(dir, ...) function! fzf#vim#files(dir, ...)
let args = {'options': '-m '.get(g:, 'fzf_files_options', '')} let args = {}
if !empty(a:dir) if !empty(a:dir)
if !isdirectory(expand(a:dir)) if !isdirectory(expand(a:dir))
return s:warn('Invalid directory') return s:warn('Invalid directory')
endif endif
let dir = substitute(a:dir, '/*$', '/', '') let slash = (s:is_win && !&shellslash) ? '\\' : '/'
let dir = substitute(a:dir, '[/\\]*$', slash, '')
let args.dir = dir let args.dir = dir
let args.options .= ' --prompt '.shellescape(dir)
else else
let args.options .= ' --prompt '.shellescape(pathshorten(getcwd())).'/' let dir = s:shortpath()
endif endif
let args.options = ['-m', '--prompt', strwidth(dir) < &columns / 2 - 20 ? dir : '> ']
call s:merge_opts(args, get(g:, 'fzf_files_options', []))
return s:fzf('files', args, a:000) return s:fzf('files', args, a:000)
endfunction endfunction
@@ -220,7 +310,7 @@ function! s:line_handler(lines)
return return
endif endif
normal! m' normal! m'
let cmd = get(get(g:, 'fzf_action', s:default_action), a:lines[0], '') let cmd = s:action_for(a:lines[0])
if !empty(cmd) && stridx('edit', cmd) < 0 if !empty(cmd) && stridx('edit', cmd) < 0
execute 'silent' cmd execute 'silent' cmd
endif endif
@@ -289,7 +379,7 @@ function! s:buffer_line_handler(lines)
return return
endif endif
normal! m' normal! m'
let cmd = get(get(g:, 'fzf_action', s:default_action), a:lines[0], '') let cmd = s:action_for(a:lines[0])
if !empty(cmd) if !empty(cmd)
execute 'silent' cmd execute 'silent' cmd
endif endif
@@ -317,9 +407,12 @@ endfunction
" Colors " Colors
" ------------------------------------------------------------------ " ------------------------------------------------------------------
function! fzf#vim#colors(...) function! fzf#vim#colors(...)
let colors = split(globpath(&rtp, "colors/*.vim"), "\n")
if has('packages')
let colors += split(globpath(&packpath, "pack/*/opt/*/colors/*.vim"), "\n")
endif
return s:fzf('colors', { return s:fzf('colors', {
\ 'source': map(split(globpath(&rtp, "colors/*.vim"), "\n"), \ 'source': fzf#vim#_uniq(map(colors, "substitute(fnamemodify(v:val, ':t'), '\\..\\{-}$', '', '')")),
\ "substitute(fnamemodify(v:val, ':t'), '\\..\\{-}$', '', '')"),
\ 'sink': 'colo', \ 'sink': 'colo',
\ 'options': '+m --prompt="Colors> "' \ 'options': '+m --prompt="Colors> "'
\}, a:000) \}, a:000)
@@ -339,9 +432,11 @@ endfunction
" History[:/] " History[:/]
" ------------------------------------------------------------------ " ------------------------------------------------------------------
function! s:all_files() function! s:all_files()
return extend( return fzf#vim#_uniq(map(
\ filter(reverse(copy(v:oldfiles)), "filereadable(expand(v:val))"), \ filter([expand('%')], 'len(v:val)')
\ filter(map(s:buflisted(), 'bufname(v:val)'), '!empty(v:val)')) \ + filter(map(s:buflisted_sorted(), 'bufname(v:val)'), 'len(v:val)')
\ + filter(copy(v:oldfiles), "filereadable(expand(v:val))"),
\ 'fnamemodify(v:val, ":~:.")'))
endfunction endfunction
function! s:history_source(type) function! s:history_source(type)
@@ -395,8 +490,8 @@ endfunction
function! fzf#vim#history(...) function! fzf#vim#history(...)
return s:fzf('history-files', { return s:fzf('history-files', {
\ 'source': reverse(s:all_files()), \ 'source': s:all_files(),
\ 'options': '-m --prompt "Hist> "' \ 'options': ['-m', '--header-lines', !empty(expand('%')), '--prompt', 'Hist> ']
\}, a:000) \}, a:000)
endfunction endfunction
@@ -404,14 +499,7 @@ endfunction
" GFiles[?] " GFiles[?]
" ------------------------------------------------------------------ " ------------------------------------------------------------------
" helper function to get the git root. Uses vim-fugitive if available for EXTRA SPEED!
function! s:get_git_root() function! s:get_git_root()
if exists('*fugitive#repo')
try
return fugitive#repo().tree()
catch
endtry
endif
let root = split(system('git rev-parse --show-toplevel'), '\n')[0] let root = split(system('git rev-parse --show-toplevel'), '\n')[0]
return v:shell_error ? '' : root return v:shell_error ? '' : root
endfunction endfunction
@@ -423,7 +511,7 @@ function! fzf#vim#gitfiles(args, ...)
endif endif
if a:args != '?' if a:args != '?'
return s:fzf('gfiles', { return s:fzf('gfiles', {
\ 'source': 'git ls-files '.a:args, \ 'source': 'git ls-files '.a:args.(s:is_win ? '' : ' | uniq'),
\ 'dir': root, \ 'dir': root,
\ 'options': '-m --prompt "GitFiles> "' \ 'options': '-m --prompt "GitFiles> "'
\}, a:000) \}, a:000)
@@ -435,7 +523,7 @@ function! fzf#vim#gitfiles(args, ...)
let wrapped = fzf#wrap({ let wrapped = fzf#wrap({
\ 'source': 'git -c color.status=always status --short --untracked-files=all', \ 'source': 'git -c color.status=always status --short --untracked-files=all',
\ 'dir': root, \ 'dir': root,
\ 'options': '--ansi --multi --nth 2..,.. --prompt "GitFiles?> " --preview ''sh -c "(git diff --color=always -- {-1} | sed 1,4d; cat {-1}) | head -500"''' \ 'options': ['--ansi', '--multi', '--nth', '2..,..', '--tiebreak=index', '--prompt', 'GitFiles?> ', '--preview', 'sh -c "(git diff --color=always -- {-1} | sed 1,4d; cat {-1}) | head -500"']
\}) \})
call s:remove_layout(wrapped) call s:remove_layout(wrapped)
let wrapped.common_sink = remove(wrapped, 'sink*') let wrapped.common_sink = remove(wrapped, 'sink*')
@@ -482,7 +570,7 @@ function! s:bufopen(lines)
return return
endif endif
endif endif
let cmd = get(get(g:, 'fzf_action', s:default_action), a:lines[0], '') let cmd = s:action_for(a:lines[0])
if !empty(cmd) if !empty(cmd)
execute 'silent' cmd execute 'silent' cmd
endif endif
@@ -503,16 +591,21 @@ endfunction
function! s:sort_buffers(...) function! s:sort_buffers(...)
let [b1, b2] = map(copy(a:000), 'get(g:fzf#vim#buffers, v:val, v:val)') let [b1, b2] = map(copy(a:000), 'get(g:fzf#vim#buffers, v:val, v:val)')
" Using minus between a float and a number in a sort function causes an error " Using minus between a float and a number in a sort function causes an error
return b1 > b2 ? 1 : -1 return b1 < b2 ? 1 : -1
endfunction
function! s:buflisted_sorted()
return sort(s:buflisted(), 's:sort_buffers')
endfunction endfunction
function! fzf#vim#buffers(...) function! fzf#vim#buffers(...)
let bufs = map(sort(s:buflisted(), 's:sort_buffers'), 's:format_buffer(v:val)') let [query, args] = (a:0 && type(a:1) == type('')) ?
\ [a:1, a:000[1:]] : ['', a:000]
return s:fzf('buffers', { return s:fzf('buffers', {
\ 'source': reverse(bufs), \ 'source': map(s:buflisted_sorted(), 's:format_buffer(v:val)'),
\ 'sink*': s:function('s:bufopen'), \ 'sink*': s:function('s:bufopen'),
\ 'options': '+m -x --tiebreak=index --header-lines=1 --ansi -d "\t" -n 2,1..2 --prompt="Buf> "', \ 'options': '+m -x --tiebreak=index --header-lines=1 --ansi -d "\t" -n 2,1..2 --prompt="Buf> "'.s:q(query)
\}, a:000) \}, args)
endfunction endfunction
" ------------------------------------------------------------------ " ------------------------------------------------------------------
@@ -533,7 +626,7 @@ function! s:ag_handler(lines, with_column)
return return
endif endif
let cmd = get(get(g:, 'fzf_action', s:default_action), a:lines[0], 'e') let cmd = s:action_for(a:lines[0], 'e')
let list = map(filter(a:lines[1:], 'len(v:val)'), 's:ag_to_qf(v:val, a:with_column)') let list = map(filter(a:lines[1:], 'len(v:val)'), 's:ag_to_qf(v:val, a:with_column)')
if empty(list) if empty(list)
return return
@@ -565,12 +658,15 @@ function! fzf#vim#ag(query, ...)
let query = empty(a:query) ? '^(?=.)' : a:query let query = empty(a:query) ? '^(?=.)' : a:query
let args = copy(a:000) let args = copy(a:000)
let ag_opts = len(args) > 1 && type(args[0]) == s:TYPE.string ? remove(args, 0) : '' let ag_opts = len(args) > 1 && type(args[0]) == s:TYPE.string ? remove(args, 0) : ''
let command = ag_opts . ' ' . s:q1(query) let command = ag_opts . ' ' . fzf#shellescape(query)
return call('fzf#vim#ag_raw', insert(args, command, 0)) return call('fzf#vim#ag_raw', insert(args, command, 0))
endfunction endfunction
" ag command suffix, [options] " ag command suffix, [options]
function! fzf#vim#ag_raw(command_suffix, ...) function! fzf#vim#ag_raw(command_suffix, ...)
if !executable('ag')
return s:warn('ag is not found')
endif
return call('fzf#vim#grep', extend(['ag --nogroup --column --color '.a:command_suffix, 1], a:000)) return call('fzf#vim#grep', extend(['ag --nogroup --column --color '.a:command_suffix, 1], a:000))
endfunction endfunction
@@ -586,13 +682,12 @@ function! fzf#vim#grep(grep_command, with_column, ...)
let words = empty(words) ? ['grep'] : words let words = empty(words) ? ['grep'] : words
let name = join(words, '-') let name = join(words, '-')
let capname = join(map(words, 'toupper(v:val[0]).v:val[1:]'), '') let capname = join(map(words, 'toupper(v:val[0]).v:val[1:]'), '')
let textcol = a:with_column ? '4..' : '3..'
let opts = { let opts = {
\ 'source': a:grep_command, \ 'source': a:grep_command,
\ 'column': a:with_column, \ 'column': a:with_column,
\ 'options': '--ansi --delimiter : --nth '.textcol.',.. --prompt "'.capname.'> " '. \ 'options': ['--ansi', '--prompt', capname.'> ',
\ '--multi --bind alt-a:select-all,alt-d:deselect-all '. \ '--multi', '--bind', 'alt-a:select-all,alt-d:deselect-all',
\ '--color hl:68,hl+:110' \ '--color', 'hl:68,hl+:110']
\} \}
function! opts.sink(lines) function! opts.sink(lines)
return s:ag_handler(a:lines, self.column) return s:ag_handler(a:lines, self.column)
@@ -611,7 +706,7 @@ function! s:btags_source(tag_cmds)
for cmd in a:tag_cmds for cmd in a:tag_cmds
let lines = split(system(cmd), "\n") let lines = split(system(cmd), "\n")
if !v:shell_error if !v:shell_error && len(lines)
break break
endif endif
endfor endfor
@@ -628,7 +723,7 @@ function! s:btags_sink(lines)
return return
endif endif
normal! m' normal! m'
let cmd = get(get(g:, 'fzf_action', s:default_action), a:lines[0], '') let cmd = s:action_for(a:lines[0])
if !empty(cmd) if !empty(cmd)
execute 'silent' cmd '%' execute 'silent' cmd '%'
endif endif
@@ -647,15 +742,20 @@ function! s:btags_sink(lines)
endfunction endfunction
function! s:q(query) function! s:q(query)
return ' --query '.s:q1(a:query) return ' --query '.fzf#shellescape(a:query)
endfunction endfunction
" query, [[tag commands], options] " query, [[tag commands], options]
function! fzf#vim#buffer_tags(query, ...) function! fzf#vim#buffer_tags(query, ...)
let args = copy(a:000) let args = copy(a:000)
let tag_cmds = len(args) > 1 ? remove(args, 0) : [ let escaped = fzf#shellescape(expand('%'))
\ printf('ctags -f - --sort=no --excmd=number --language-force=%s %s', &filetype, expand('%:S')), let null = s:is_win ? 'nul' : '/dev/null'
\ printf('ctags -f - --sort=no --excmd=number %s', expand('%:S'))] let tag_cmds = (len(args) > 1 && type(args[0]) != type({})) ? remove(args, 0) : [
\ printf('ctags -f - --sort=no --excmd=number --language-force=%s %s 2> %s', &filetype, escaped, null),
\ printf('ctags -f - --sort=no --excmd=number %s 2> %s', escaped, null)]
if type(tag_cmds) != type([])
let tag_cmds = [tag_cmds]
endif
try try
return s:fzf('btags', { return s:fzf('btags', {
\ 'source': s:btags_source(tag_cmds), \ 'source': s:btags_source(tag_cmds),
@@ -675,14 +775,17 @@ function! s:tags_sink(lines)
endif endif
normal! m' normal! m'
let qfl = [] let qfl = []
let cmd = get(get(g:, 'fzf_action', s:default_action), a:lines[0], 'e') let cmd = s:action_for(a:lines[0], 'e')
try try
let [magic, &magic, wrapscan, &wrapscan] = [&magic, 0, &wrapscan, 1] let [magic, &magic, wrapscan, &wrapscan, acd, &acd] = [&magic, 0, &wrapscan, 1, &acd, 0]
for line in a:lines[1:] for line in a:lines[1:]
try try
let parts = split(line, '\t\zs') let parts = split(line, '\t\zs')
let excmd = matchstr(join(parts[2:], ''), '^.*\ze;"\t') let excmd = matchstr(join(parts[2:-2], '')[:-2], '^.*\ze;"\t')
call s:open(cmd, parts[1][:-2]) let base = fnamemodify(parts[-1], ':h')
let relpath = parts[1][:-2]
let abspath = relpath =~ (s:is_win ? '^[A-Z]:\' : '^/') ? relpath : join([base, relpath], '/')
call s:open(cmd, expand(abspath, 1))
execute excmd execute excmd
call add(qfl, {'filename': expand('%'), 'lnum': line('.'), 'text': getline('.')}) call add(qfl, {'filename': expand('%'), 'lnum': line('.'), 'text': getline('.')})
catch /^Vim:Interrupt$/ catch /^Vim:Interrupt$/
@@ -692,7 +795,7 @@ function! s:tags_sink(lines)
endtry endtry
endfor endfor
finally finally
let [&magic, &wrapscan] = [magic, wrapscan] let [&magic, &wrapscan, &acd] = [magic, wrapscan, acd]
endtry endtry
if len(qfl) > 1 if len(qfl) > 1
call setqflist(qfl) call setqflist(qfl)
@@ -704,6 +807,9 @@ function! s:tags_sink(lines)
endfunction endfunction
function! fzf#vim#tags(query, ...) function! fzf#vim#tags(query, ...)
if !executable('perl')
return s:warn('Tags command requires perl')
endif
if empty(tagfiles()) if empty(tagfiles())
call inputsave() call inputsave()
echohl WarningMsg echohl WarningMsg
@@ -711,9 +817,9 @@ function! fzf#vim#tags(query, ...)
echohl None echohl None
call inputrestore() call inputrestore()
redraw redraw
if gen =~ '^y' if gen =~? '^y'
call s:warn('Preparing tags') call s:warn('Preparing tags')
call system(get(g:, 'fzf_tags_command', 'ctags -R')) call system(get(g:, 'fzf_tags_command', 'ctags -R'.(s:is_win ? ' --output-format=e-ctags' : '')))
if empty(tagfiles()) if empty(tagfiles())
return s:warn('Failed to create tags') return s:warn('Failed to create tags')
endif endif
@@ -722,21 +828,20 @@ function! fzf#vim#tags(query, ...)
endif endif
endif endif
let tagfile = tagfiles()[0] let tagfiles = tagfiles()
" We don't want to apply --ansi option when tags file is large as it makes let v2_limit = 1024 * 1024 * 200
" processing much slower. for tagfile in tagfiles
if getfsize(tagfile) > 1024 * 1024 * 20 let v2_limit -= getfsize(tagfile)
let proc = 'grep -v ''^\!'' ' if v2_limit < 0
let copt = '' break
else endif
let proc = 'perl -ne ''unless (/^\!/) { s/^(.*?)\t(.*?)\t/'.s:yellow('\1', 'Function').'\t'.s:blue('\2', 'String').'\t/; print }'' ' endfor
let copt = '--ansi ' let opts = v2_limit < 0 ? '--algo=v1 ' : ''
endif
return s:fzf('tags', { return s:fzf('tags', {
\ 'source': proc.shellescape(fnamemodify(tagfile, ':t')), \ 'source': fzf#shellescape(s:bin.tags).' '.join(map(tagfiles, 'fzf#shellescape(fnamemodify(v:val, ":p"))')),
\ 'sink*': s:function('s:tags_sink'), \ 'sink*': s:function('s:tags_sink'),
\ 'dir': fnamemodify(tagfile, ':h'), \ 'options': opts.'--nth 1..2 -m --tiebreak=begin --prompt "Tags> "'.s:q(a:query)}, a:000)
\ 'options': copt.'-m --tiebreak=begin --prompt "Tags> "'.s:q(a:query)}, a:000)
endfunction endfunction
" ------------------------------------------------------------------ " ------------------------------------------------------------------
@@ -839,7 +944,7 @@ function! s:mark_sink(lines)
if len(a:lines) < 2 if len(a:lines) < 2
return return
endif endif
let cmd = get(get(g:, 'fzf_action', s:default_action), a:lines[0], '') let cmd = s:action_for(a:lines[0])
if !empty(cmd) if !empty(cmd)
execute 'silent' cmd execute 'silent' cmd
endif endif
@@ -870,14 +975,22 @@ function! s:helptag_sink(line)
endfunction endfunction
function! fzf#vim#helptags(...) function! fzf#vim#helptags(...)
let sorted = sort(split(globpath(&runtimepath, '**/doc/tags'), '\n')) if !executable('grep') || !executable('perl')
let tags = exists('*uniq') ? uniq(sorted) : s:uniq(sorted) return s:warn('Helptags command requires grep and perl')
endif
let sorted = sort(split(globpath(&runtimepath, 'doc/tags'), '\n'))
let tags = exists('*uniq') ? uniq(sorted) : fzf#vim#_uniq(sorted)
if exists('s:helptags_script')
silent! call delete(s:helptags_script)
endif
let s:helptags_script = tempname()
call writefile(['/('.(s:is_win ? '^[A-Z]:\/.*?[^:]' : '.*?').'):(.*?)\t(.*?)\t/; printf(qq('.s:green('%-40s', 'Label').'\t%s\t%s\n), $2, $3, $1)'], s:helptags_script)
return s:fzf('helptags', { return s:fzf('helptags', {
\ 'source': "grep -H '.*' ".join(map(tags, 'shellescape(v:val)')). \ 'source': 'grep -H ".*" '.join(map(tags, 'fzf#shellescape(v:val)')).
\ "| perl -ne '/(.*?):(.*?)\t(.*?)\t/; printf(qq(".s:green('%-40s', 'Label')."\t%s\t%s\n), $2, $3, $1)' | sort", \ ' | perl -n '.fzf#shellescape(s:helptags_script).' | sort',
\ 'sink': s:function('s:helptag_sink'), \ 'sink': s:function('s:helptag_sink'),
\ 'options': '--ansi +m --tiebreak=begin --with-nth ..-2'}, a:000) \ 'options': ['--ansi', '+m', '--tiebreak=begin', '--with-nth', '..-2']}, a:000)
endfunction endfunction
" ------------------------------------------------------------------ " ------------------------------------------------------------------
@@ -934,12 +1047,13 @@ function! s:commits_sink(lines)
return return
endif endif
let cmd = get(extend({'ctrl-d': ''}, get(g:, 'fzf_action', s:default_action)), a:lines[0], 'e') let diff = a:lines[0] == 'ctrl-d'
let cmd = s:action_for(a:lines[0], 'e')
let buf = bufnr('') let buf = bufnr('')
for idx in range(1, len(a:lines) - 1) for idx in range(1, len(a:lines) - 1)
let sha = matchstr(a:lines[idx], '[0-9a-f]\{7}') let sha = matchstr(a:lines[idx], '[0-9a-f]\{7,9}')
if !empty(sha) if !empty(sha)
if empty(cmd) if diff
if idx > 1 if idx > 1
execute 'tab sb' buf execute 'tab sb' buf
endif endif
@@ -959,11 +1073,11 @@ function! s:commits(buffer_local, args)
return s:warn('Not in git repository') return s:warn('Not in git repository')
endif endif
let source = 'git log '.get(g:, 'fzf_commits_log_options', '--graph --color=always --format="%C(auto)%h%d %s %C(green)%cr"') let source = 'git log '.get(g:, 'fzf_commits_log_options', '--color=always '.fzf#shellescape('--format=%C(auto)%h%d %s %C(green)%cr'))
let current = expand('%:S') let current = expand('%')
let managed = 0 let managed = 0
if !empty(current) if !empty(current)
call system('git show '.current.' 2> /dev/null') call system('git show '.fzf#shellescape(current).' 2> '.(s:is_win ? 'nul' : '/dev/null'))
let managed = !v:shell_error let managed = !v:shell_error
endif endif
@@ -971,7 +1085,9 @@ function! s:commits(buffer_local, args)
if !managed if !managed
return s:warn('The current buffer is not in the working tree') return s:warn('The current buffer is not in the working tree')
endif endif
let source .= ' --follow '.current let source .= ' --follow '.fzf#shellescape(current)
else
let source .= ' --graph'
endif endif
let command = a:buffer_local ? 'BCommits' : 'Commits' let command = a:buffer_local ? 'BCommits' : 'Commits'
@@ -979,15 +1095,20 @@ function! s:commits(buffer_local, args)
let options = { let options = {
\ 'source': source, \ 'source': source,
\ 'sink*': s:function('s:commits_sink'), \ 'sink*': s:function('s:commits_sink'),
\ 'options': '--ansi --multi --no-sort --tiebreak=index --reverse '. \ 'options': ['--ansi', '--multi', '--tiebreak=index', '--reverse',
\ '--inline-info --prompt "'.command.'> " --bind=ctrl-s:toggle-sort '. \ '--inline-info', '--prompt', command.'> ', '--bind=ctrl-s:toggle-sort',
\ '--expect='.expect_keys \ '--header', ':: Press '.s:magenta('CTRL-S', 'Special').' to toggle sort',
\ '--expect='.expect_keys]
\ } \ }
if a:buffer_local if a:buffer_local
let options.options .= ',ctrl-d --header ":: Press '.s:magenta('CTRL-S', 'Special').' to toggle sort, '.s:magenta('CTRL-D', 'Special').' to diff"' let options.options[-2] .= ', '.s:magenta('CTRL-D', 'Special').' to diff'
else let options.options[-1] .= ',ctrl-d'
let options.options .= ' --header ":: Press '.s:magenta('CTRL-S', 'Special').' to toggle sort"' endif
if !s:is_win
call extend(options.options,
\ ['--preview', 'grep -o "[a-f0-9]\{7,\}" <<< {} | xargs git show --format=format: --color=always | head -200'])
endif endif
return s:fzf(a:buffer_local ? 'bcommits' : 'commits', options, a:args) return s:fzf(a:buffer_local ? 'bcommits' : 'commits', options, a:args)
@@ -1043,13 +1164,12 @@ function! fzf#vim#maps(mode, ...)
let list = [] let list = []
let curr = '' let curr = ''
for line in split(cout, "\n") for line in split(cout, "\n")
let src = matchstr(line, 'Last set from \zs.*') if line =~ "^\t"
if empty(src) let src = ' '.join(reverse(reverse(split(split(line)[-1], '/'))[0:2]), '/')
let curr = line[3:]
else
let src = ' '.join(reverse(reverse(split(src, '/'))[0:2]), '/')
call add(list, printf('%s %s', curr, s:green(src, 'Comment'))) call add(list, printf('%s %s', curr, s:green(src, 'Comment')))
let curr = '' let curr = ''
else
let curr = line[3:]
endif endif
endfor endfor
if !empty(curr) if !empty(curr)
@@ -1076,7 +1196,7 @@ endfunction
function! s:complete_trigger() function! s:complete_trigger()
let opts = copy(s:opts) let opts = copy(s:opts)
let opts.options = printf('+m -q %s %s', shellescape(s:query), get(opts, 'options', '')) call s:prepend_opts(opts, ['+m', '-q', s:query])
let opts['sink*'] = s:function('s:complete_insert') let opts['sink*'] = s:function('s:complete_insert')
let s:reducer = s:pluck(opts, 'reducer', s:function('s:first_line')) let s:reducer = s:pluck(opts, 'reducer', s:function('s:first_line'))
call fzf#run(opts) call fzf#run(opts)
@@ -1121,16 +1241,20 @@ endfunction
function! fzf#vim#complete(...) function! fzf#vim#complete(...)
if a:0 == 0 if a:0 == 0
let s:opts = g:fzf#vim#default_layout let s:opts = fzf#wrap()
elseif type(a:1) == s:TYPE.dict elseif type(a:1) == s:TYPE.dict
if has_key(a:1, 'sink') || has_key(a:1, 'sink*')
echoerr 'sink not allowed'
return ''
endif
let s:opts = copy(a:1) let s:opts = copy(a:1)
elseif type(a:1) == s:TYPE.string
let s:opts = extend({'source': a:1}, get(a:000, 1, fzf#wrap()))
else else
let s:opts = extend({'source': a:1}, g:fzf#vim#default_layout) echoerr 'Invalid argument: '.string(a:000)
return ''
endif endif
for s in ['sink', 'sink*']
if has_key(s:opts, s)
call remove(s:opts, s)
endif
endfor
let eol = col('$') let eol = col('$')
let ve = &ve let ve = &ve
@@ -1153,8 +1277,14 @@ function! fzf#vim#complete(...)
let s:opts = s:eval(s:opts, 'options', s:query) let s:opts = s:eval(s:opts, 'options', s:query)
let s:opts = s:eval(s:opts, 'extra_options', s:query) let s:opts = s:eval(s:opts, 'extra_options', s:query)
if has_key(s:opts, 'extra_options') if has_key(s:opts, 'extra_options')
let s:opts.options = call s:merge_opts(s:opts, remove(s:opts, 'extra_options'))
\ join(filter([get(s:opts, 'options', ''), remove(s:opts, 'extra_options')], '!empty(v:val)')) endif
if has_key(s:opts, 'options')
if type(s:opts.options) == s:TYPE.list
call add(s:opts.options, '--no-expect')
else
let s:opts.options .= ' --no-expect'
endif
endif endif
call feedkeys("\<Plug>(-fzf-complete-trigger)") call feedkeys("\<Plug>(-fzf-complete-trigger)")

View File

@@ -23,6 +23,7 @@
let s:cpo_save = &cpo let s:cpo_save = &cpo
set cpo&vim set cpo&vim
let s:is_win = has('win32') || has('win64')
function! s:extend(base, extra) function! s:extend(base, extra)
let base = copy(a:base) let base = copy(a:base)
@@ -48,7 +49,7 @@ endif
function! fzf#vim#complete#word(...) function! fzf#vim#complete#word(...)
return fzf#vim#complete(s:extend({ return fzf#vim#complete(s:extend({
\ 'source': 'cat /usr/share/dict/words'}, \ 'source': 'cat /usr/share/dict/words'},
\ get(a:000, 0, g:fzf#vim#default_layout))) \ get(a:000, 0, fzf#wrap())))
endfunction endfunction
" ---------------------------------------------------------------------------- " ----------------------------------------------------------------------------
@@ -58,25 +59,26 @@ endfunction
" ---------------------------------------------------------------------------- " ----------------------------------------------------------------------------
function! s:file_split_prefix(prefix) function! s:file_split_prefix(prefix)
let expanded = expand(a:prefix) let expanded = expand(a:prefix)
let slash = (s:is_win && !&shellslash) ? '\\' : '/'
return isdirectory(expanded) ? return isdirectory(expanded) ?
\ [expanded, \ [expanded,
\ substitute(a:prefix, '/*$', '/', ''), \ substitute(a:prefix, '[/\\]*$', slash, ''),
\ ''] : \ ''] :
\ [fnamemodify(expanded, ':h'), \ [fnamemodify(expanded, ':h'),
\ substitute(fnamemodify(a:prefix, ':h'), '/*$', '/', ''), \ substitute(fnamemodify(a:prefix, ':h'), '[/\\]*$', slash, ''),
\ fnamemodify(expanded, ':t')] \ fnamemodify(expanded, ':t')]
endfunction endfunction
function! s:file_source(prefix) function! s:file_source(prefix)
let [dir, head, tail] = s:file_split_prefix(a:prefix) let [dir, head, tail] = s:file_split_prefix(a:prefix)
return printf( return printf(
\ "cd %s && ".s:file_cmd." | sed 's:^:%s:'", \ "cd %s && ".s:file_cmd." | sed %s",
\ shellescape(dir), empty(a:prefix) || a:prefix == tail ? '' : head) \ fzf#shellescape(dir), fzf#shellescape('s:^:'.(empty(a:prefix) || a:prefix == tail ? '' : head).':'))
endfunction endfunction
function! s:file_options(prefix) function! s:file_options(prefix)
let [_, head, tail] = s:file_split_prefix(a:prefix) let [_, head, tail] = s:file_split_prefix(a:prefix)
return printf('--prompt %s --query %s', shellescape(head), shellescape(tail)) return ['--prompt', head, '--query', tail]
endfunction endfunction
function! s:fname_prefix(str) function! s:fname_prefix(str)
@@ -128,7 +130,7 @@ function! fzf#vim#complete#path(command, ...)
return fzf#vim#complete(s:extend({ return fzf#vim#complete(s:extend({
\ 'prefix': s:function('s:fname_prefix'), \ 'prefix': s:function('s:fname_prefix'),
\ 'source': s:function('s:file_source'), \ 'source': s:function('s:file_source'),
\ 'options': s:function('s:file_options')}, get(a:000, 0, g:fzf#vim#default_layout))) \ 'options': s:function('s:file_options')}, get(a:000, 0, fzf#wrap())))
endfunction endfunction
" ---------------------------------------------------------------------------- " ----------------------------------------------------------------------------
@@ -147,13 +149,13 @@ function! fzf#vim#complete#line(...)
\ 'prefix': '^.*$', \ 'prefix': '^.*$',
\ 'source': lines, \ 'source': lines,
\ 'options': '--tiebreak=index --ansi --nth '.nth.'.. --tabstop=1', \ 'options': '--tiebreak=index --ansi --nth '.nth.'.. --tabstop=1',
\ 'reducer': s:function('s:reduce_line')}, get(a:000, 0, g:fzf#vim#default_layout))) \ 'reducer': s:function('s:reduce_line')}, get(a:000, 0, fzf#wrap())))
endfunction endfunction
function! fzf#vim#complete#buffer_line(...) function! fzf#vim#complete#buffer_line(...)
call fzf#vim#complete(s:extend({ return fzf#vim#complete(s:extend({
\ 'prefix': '^.*$', \ 'prefix': '^.*$',
\ 'source': s:uniq(getline(1, '$'))}, get(a:000, 0, g:fzf#vim#default_layout))) \ 'source': fzf#vim#_uniq(getline(1, '$'))}, get(a:000, 0, fzf#wrap())))
endfunction endfunction
let &cpo = s:cpo_save let &cpo = s:cpo_save

57
bin/preview.rb Executable file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/env ruby
#
# usage: ./preview.rb [-v] FILENAME[:LINE][:IGNORED]
require 'shellwords'
COMMAND = %[(highlight -O ansi -l {} || coderay {} || rougify {} || cat {}) 2> /dev/null]
ANSI = /\x1b\[[0-9;]*m/
REVERSE = "\x1b[7m"
RESET = "\x1b[m"
split = ARGV.delete('-v')
def usage
puts "usage: #$0 [-v] FILENAME[:LINENO][:IGNORED]"
exit 1
end
usage if ARGV.empty?
file, center, extra = ARGV.first.split(':')
if ARGV.first =~ /^[A-Z]:\\/
file << ':' + center
center = extra
end
usage unless file
path = File.expand_path(file)
unless File.readable? path
puts "File not found: #{file}"
exit 1
end
if `file --mime "#{file}"` =~ /binary/
puts "#{file} is a binary file"
exit 0
end
center = (center || 0).to_i
if ENV['FZF_PREVIEW_HEIGHT']
height = ENV['FZF_PREVIEW_HEIGHT'].to_i
else
height = File.readable?('/dev/tty') ? `stty size < /dev/tty`.split.first.to_i : 40
height /= 2 if split
height -= 2 # preview border
end
offset = [1, center - height / 3].max
IO.popen(['sh', '-c', COMMAND.gsub('{}', Shellwords.shellescape(path))]) do |io|
io.each_line.drop(offset - 1).take(height).each_with_index do |line, lno|
if lno + offset == center
puts REVERSE + line.chomp.gsub(ANSI) { |m| m + REVERSE } + RESET
else
puts line
end
end
end

57
bin/preview.sh Executable file
View File

@@ -0,0 +1,57 @@
#!/bin/bash
REVERSE="\x1b[7m"
RESET="\x1b[m"
if [ "$1" == "-v" ]; then
SPLIT=1
shift
fi
if [ -z "$1" ]; then
echo "usage: $0 [-v] FILENAME[:LINENO][:IGNORED]"
exit 1
fi
IFS=':' read -r -a INPUT <<< "$1"
FILE=${INPUT[0]}
CENTER=${INPUT[1]}
if [[ $1 =~ ^[A-Z]:\\ ]]; then
FILE=$FILE:${INPUT[1]}
CENTER=${INPUT[2]}
fi
if [ ! -r "$FILE" ]; then
echo "File not found ${FILE}"
exit 1
fi
if [[ "$(file --mime "$FILE")" =~ binary ]]; then
echo "$1 is a binary file"
exit 0
fi
if [ -z "$CENTER" ]; then
CENTER=1
fi
if [ -n "$FZF_PREVIEW_HEIGHT" ]; then
LINES=$FZF_PREVIEW_HEIGHT
else
if [ -r /dev/tty ]; then
LINES=$(stty size < /dev/tty | awk '{print $1}')
else
LINES=40
fi
if [ -n "$SPLIT" ]; then
LINES=$(($LINES/2)) # using horizontal split
fi
LINES=$(($LINES-2)) # remove preview border
fi
FIRST=$(($CENTER-$LINES/3))
FIRST=$(($FIRST < 1 ? 1 : $FIRST))
LAST=$((${FIRST}+${LINES}-1))
awk "NR >= $FIRST && NR <= $LAST {if (NR == $CENTER) printf(\"$REVERSE%5d %s\n$RESET\", NR, \$0); else printf(\"%5d %s\n\", NR, \$0)}" $FILE

15
bin/tags.pl Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/env perl
use strict;
foreach my $file (@ARGV) {
open my $lines, $file;
while (<$lines>) {
unless (/^\!/) {
s/^[^\t]*/sprintf("%-24s", $&)/e;
s/$/\t$file/;
print;
}
}
close $lines;
}

View File

@@ -1,4 +1,4 @@
fzf-vim.txt fzf-vim Last change: September 20 2015 fzf-vim.txt fzf-vim Last change: October 21 2017
FZF-VIM - TABLE OF CONTENTS *fzf-vim* *fzf-vim-toc* FZF-VIM - TABLE OF CONTENTS *fzf-vim* *fzf-vim-toc*
============================================================================== ==============================================================================
@@ -8,10 +8,14 @@ FZF-VIM - TABLE OF CONTENTS *fzf-vim* *fzf-vim-to
Installation Installation
Commands Commands
Customization Customization
Global options
Command-local options
Advanced customization
Mappings Mappings
Usage Usage
Completion helper Completion helper
Reducer example Reducer example
Status line (neovim)
License License
FZF :HEART: VIM *fzf-vim-fzf-heart-vim* FZF :HEART: VIM *fzf-vim-fzf-heart-vim*
@@ -53,35 +57,48 @@ selector with fzf.
fzf is an independent command-line program and thus requires an external fzf is an independent command-line program and thus requires an external
terminal emulator when on GVim. You may or may not like the experience. Also terminal emulator when on GVim. You may or may not like the experience. Also
note that fzf currently does not compile on Windows. note that Windows support is experimental at the moment.
INSTALLATION *fzf-vim-installation* INSTALLATION *fzf-vim-installation*
============================================================================== ==============================================================================
Using {vim-plug}{4}: Use {vim-plug}{4} or any Vim plugin manager of your choice.
If you already installed fzf using {Homebrew}{5}, the following should
suffice:
> >
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': 'yes \| ./install' } Plug '/usr/local/opt/fzf'
Plug 'junegunn/fzf.vim' Plug 'junegunn/fzf.vim'
< <
But if you want to install fzf as well using vim-plug:
>
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'
<
- `dir` and `do` options are not mandatory
- Use `./install--bin` instead if you don't need fzf outside of Vim
- Make sure to use Vim 7.4 or above
{4} https://github.com/junegunn/vim-plug {4} https://github.com/junegunn/vim-plug
{5} https://brew.sh/
COMMANDS *fzf-vim-commands* COMMANDS *fzf-vim-commands*
============================================================================== ==============================================================================
-----------------+------------------------------------------------------------------- -----------------+-----------------------------------------------------------------------
Command | List ~ Command | List ~
-----------------+------------------------------------------------------------------- -----------------+-----------------------------------------------------------------------
`Files[PATH]` | Files (similar to `:FZF` ) `Files[PATH]` | Files (similar to `:FZF` )
`GFiles [OPTS]` | Git files (git ls-files) `GFiles[OPTS]` | Git files ( `gitls-files` )
`GFiles?` | Git files (git status) `GFiles?` | Git files ( `gitstatus` )
`Buffers` | Open buffers `Buffers` | Open buffers
`Colors` | Color schemes `Colors` | Color schemes
`Ag[PATTERN]` | {ag}{5} search result (ALT-A to select all, ALT-D to deselect all) `Ag[PATTERN]` | {ag}{6} search result ( `ALT-A` to select all, `ALT-D` to deselect all)
`Lines [QUERY]` | Lines in loaded buffers `Lines[QUERY]` | Lines in loaded buffers
`BLines [QUERY]` | Lines in the current buffer `BLines[QUERY]` | Lines in the current buffer
`Tags[QUERY]` | Tags in the project ( `ctags-R` ) `Tags[QUERY]` | Tags in the project ( `ctags-R` )
`BTags[QUERY]` | Tags in the current buffer `BTags[QUERY]` | Tags in the current buffer
`Marks` | Marks `Marks` | Marks
@@ -90,36 +107,40 @@ COMMANDS *fzf-vim-commands*
`History` | `v:oldfiles` and open buffers `History` | `v:oldfiles` and open buffers
`History:` | Command history `History:` | Command history
`History/` | Search history `History/` | Search history
`Snippets` | Snippets ({UltiSnips}{6}) `Snippets` | Snippets ({UltiSnips}{7})
`Commits` | Git commits (requires {fugitive.vim}{7}) `Commits` | Git commits (requires {fugitive.vim}{8})
`BCommits` | Git commits for the current buffer `BCommits` | Git commits for the current buffer
`Commands` | Commands `Commands` | Commands
`Maps` | Normal mode mappings `Maps` | Normal mode mappings
`Helptags` | Help tags [1] `Helptags` | Help tags [1]
`Filetypes` | File types `Filetypes` | File types
-----------------+------------------------------------------------------------------- -----------------+-----------------------------------------------------------------------
*g:fzf_command_prefix*
- Most commands support CTRL-T / CTRL-X / CTRL-V key bindings to open in a new - Most commands support CTRL-T / CTRL-X / CTRL-V key bindings to open in a new
tab, a new split, or in a new vertical split tab, a new split, or in a new vertical split
- Bang-versions of the commands (e.g. `Ag!`) will open fzf in fullscreen - Bang-versions of the commands (e.g. `Ag!`) will open fzf in fullscreen
- You can set `g:fzf_command_prefix` to give the same prefix to the commands - You can set `g:fzf_command_prefix` to give the same prefix to the commands
- e.g. `let g:fzf_command_prefix = 'Fzf'` and you have `FzfFiles`, etc. - e.g. `letg:fzf_command_prefix='Fzf'` and you have `FzfFiles`, etc.
(1: `Helptags` will shadow the command of the same name from {pathogen}{8}. (1: `Helptags` will shadow the command of the same name from {pathogen}{9}.
But its functionality is still available via `call pathogen#helptags()`.) But its functionality is still available via `call pathogen#helptags()`.)
{5} https://github.com/ggreer/the_silver_searcher {6} https://github.com/ggreer/the_silver_searcher
{6} https://github.com/SirVer/ultisnips {7} https://github.com/SirVer/ultisnips
{7} https://github.com/tpope/vim-fugitive {8} https://github.com/tpope/vim-fugitive
{8} https://github.com/tpope/vim-pathogen {9} https://github.com/tpope/vim-pathogen
< Customization >_____________________________________________________________~ < Customization >_____________________________________________________________~
*fzf-vim-customization* *fzf-vim-customization*
*g:fzf_action* *g:fzf_layout* *g:fzf_colors* *g:fzf_commits_log_options*
Global options~ Global options~
*fzf-vim-global-options*
See {README-VIM.md}{10} of the main fzf repository for details.
> >
" This is the default extra key bindings " This is the default extra key bindings
let g:fzf_action = { let g:fzf_action = {
@@ -134,6 +155,7 @@ Global options~
" In Neovim, you can set up fzf window using a Vim command " In Neovim, you can set up fzf window using a Vim command
let g:fzf_layout = { 'window': 'enew' } let g:fzf_layout = { 'window': 'enew' }
let g:fzf_layout = { 'window': '-tabnew' } let g:fzf_layout = { 'window': '-tabnew' }
let g:fzf_layout = { 'window': '10split enew' }
" Customize fzf colors to match your color scheme " Customize fzf colors to match your color scheme
let g:fzf_colors = let g:fzf_colors =
@@ -144,6 +166,7 @@ Global options~
\ 'bg+': ['bg', 'CursorLine', 'CursorColumn'], \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'],
\ 'hl+': ['fg', 'Statement'], \ 'hl+': ['fg', 'Statement'],
\ 'info': ['fg', 'PreProc'], \ 'info': ['fg', 'PreProc'],
\ 'border': ['fg', 'Ignore'],
\ 'prompt': ['fg', 'Conditional'], \ 'prompt': ['fg', 'Conditional'],
\ 'pointer': ['fg', 'Exception'], \ 'pointer': ['fg', 'Exception'],
\ 'marker': ['fg', 'Keyword'], \ 'marker': ['fg', 'Keyword'],
@@ -156,21 +179,20 @@ Global options~
" explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS. " explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS.
let g:fzf_history_dir = '~/.local/share/fzf-history' let g:fzf_history_dir = '~/.local/share/fzf-history'
< <
{10} https://github.com/junegunn/fzf/blob/master/README-VIM.md#configuration
Command-local options~ Command-local options~
*fzf-vim-command-local-options*
*g:fzf_buffers_jump* *g:fzf_commits_log_options* *g:fzf_tags_command*
*g:fzf_commands_expect*
> >
" [Files] Extra options for fzf
" e.g. File preview using coderay (http://coderay.rubychan.de/)
let g:fzf_files_options =
\ '--preview "(coderay {} || cat {}) 2> /dev/null | head -'.&lines.'"'
" [Buffers] Jump to the existing window if possible " [Buffers] Jump to the existing window if possible
let g:fzf_buffers_jump = 1 let g:fzf_buffers_jump = 1
" [[B]Commits] Customize the options used by 'git log': " [[B]Commits] Customize the options used by 'git log':
let g:fzf_commits_log_options = \ let g:fzf_commits_log_options = '--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"'
'--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"'
" [Tags] Command to generate tags file " [Tags] Command to generate tags file
let g:fzf_tags_command = 'ctags -R' let g:fzf_tags_command = 'ctags -R'
@@ -179,19 +201,48 @@ Command-local options~
let g:fzf_commands_expect = 'alt-enter,ctrl-x' let g:fzf_commands_expect = 'alt-enter,ctrl-x'
< <
Advanced customization using autoload functions~ Advanced customization~
*fzf-vim-advanced-customization*
You can use autoload functions to define your own commands. You can use autoload functions to define your own commands.
> >
" git grep " Command for git grep
" - fzf#vim#grep(command, with_column, [options], [fullscreen])
command! -bang -nargs=* GGrep command! -bang -nargs=* GGrep
\ call fzf#vim#grep('git grep --line-number '.shellescape(<q-args>), 0, <bang>0) \ call fzf#vim#grep('git grep --line-number '.shellescape(<q-args>), 0, <bang>0)
" We use VimEnter event so that the code is run after fzf.vim is loaded " Override Colors command. You can safely do this in your .vimrc as fzf.vim
autocmd VimEnter * command! Colors " will not override existing commands.
\ call fzf#vim#colors({'left': '15%', 'options': '--reverse --margin 30%,0'}) command! -bang Colors
< \ call fzf#vim#colors({'left': '15%', 'options': '--reverse --margin 30%,0'}, <bang>0)
" Augmenting Ag command using fzf#vim#with_preview function
" * fzf#vim#with_preview([[options], preview window, [toggle keys...]])
" * For syntax-highlighting, Ruby and any of the following tools are required:
" - Highlight: http://www.andre-simon.de/doku/highlight/en/highlight.php
" - CodeRay: http://coderay.rubychan.de/
" - Rouge: https://github.com/jneen/rouge
"
" :Ag - Start fzf with hidden preview window that can be enabled with "?" key
" :Ag! - Start fzf in fullscreen and display the preview window above
command! -bang -nargs=* Ag
\ call fzf#vim#ag(<q-args>,
\ <bang>0 ? fzf#vim#with_preview('up:60%')
\ : fzf#vim#with_preview('right:50%:hidden', '?'),
\ <bang>0)
" Similarly, we can apply it to fzf#vim#grep. To use ripgrep instead of ag:
command! -bang -nargs=* Rg
\ call fzf#vim#grep(
\ 'rg --column --line-number --no-heading --color=always '.shellescape(<q-args>), 1,
\ <bang>0 ? fzf#vim#with_preview('up:60%')
\ : fzf#vim#with_preview('right:50%:hidden', '?'),
\ <bang>0)
" Likewise, Files command with preview window
command! -bang -nargs=? -complete=dir Files
\ call fzf#vim#files(<q-args>, fzf#vim#with_preview(), <bang>0)
<
MAPPINGS *fzf-vim-mappings* MAPPINGS *fzf-vim-mappings*
============================================================================== ==============================================================================
@@ -251,7 +302,7 @@ following exceptions:
- Or a function to extract completion prefix - Or a function to extract completion prefix
- Both `source` and `options` can be given as funcrefs that take the completion - Both `source` and `options` can be given as funcrefs that take the completion
prefix as the argument and return the final value prefix as the argument and return the final value
- `sink` or `sink*` are not allowed - `sink` or `sink*` are ignored
Reducer example~ Reducer example~
@@ -268,6 +319,20 @@ Reducer example~
\ 'left': 20}) \ 'left': 20})
< <
STATUS LINE (NEOVIM) *fzf-vim-status-lineneovim*
==============================================================================
>
function! s:fzf_statusline()
" Override statusline as you like
highlight fzf1 ctermfg=161 ctermbg=251
highlight fzf2 ctermfg=23 ctermbg=251
highlight fzf3 ctermfg=237 ctermbg=251
setlocal statusline=%#fzf1#\ >\ %#fzf2#fz%#fzf3#f
endfunction
autocmd! User FzfStatusLine call <SID>fzf_statusline()
<
LICENSE *fzf-vim-license* LICENSE *fzf-vim-license*
============================================================================== ==============================================================================

View File

@@ -23,8 +23,7 @@
let s:cpo_save = &cpo let s:cpo_save = &cpo
set cpo&vim set cpo&vim
let s:is_win = has('win32') || has('win64')
let g:fzf#vim#default_layout = {'down': '~40%'}
function! s:defs(commands) function! s:defs(commands)
let prefix = get(g:, 'fzf_command_prefix', '') let prefix = get(g:, 'fzf_command_prefix', '')
@@ -33,32 +32,35 @@ function! s:defs(commands)
return return
endif endif
for command in a:commands for command in a:commands
execute substitute(command, '\ze\C[A-Z]', prefix, '') let name = ':'.prefix.matchstr(command, '\C[A-Z]\S\+')
if 2 != exists(name)
execute substitute(command, '\ze\C[A-Z]', prefix, '')
endif
endfor endfor
endfunction endfunction
call s:defs([ call s:defs([
\'command! -bang -nargs=? -complete=dir Files call fzf#vim#files(<q-args>, <bang>0)', \'command! -bang -nargs=? -complete=dir Files call fzf#vim#files(<q-args>, <bang>0)',
\'command! -bang -nargs=? GitFiles call fzf#vim#gitfiles(<q-args>, <bang>0)', \'command! -bang -nargs=? GitFiles call fzf#vim#gitfiles(<q-args>, <bang>0)',
\'command! -bang -nargs=? GFiles call fzf#vim#gitfiles(<q-args>, <bang>0)', \'command! -bang -nargs=? GFiles call fzf#vim#gitfiles(<q-args>, <bang>0)',
\'command! -bang Buffers call fzf#vim#buffers(<bang>0)', \'command! -bar -bang -nargs=? -complete=buffer Buffers call fzf#vim#buffers(<q-args>, <bang>0)',
\'command! -bang -nargs=* Lines call fzf#vim#lines(<q-args>, <bang>0)', \'command! -bang -nargs=* Lines call fzf#vim#lines(<q-args>, <bang>0)',
\'command! -bang -nargs=* BLines call fzf#vim#buffer_lines(<q-args>, <bang>0)', \'command! -bang -nargs=* BLines call fzf#vim#buffer_lines(<q-args>, <bang>0)',
\'command! -bang Colors call fzf#vim#colors(<bang>0)', \'command! -bar -bang Colors call fzf#vim#colors(<bang>0)',
\'command! -bang -nargs=+ -complete=dir Locate call fzf#vim#locate(<q-args>, <bang>0)', \'command! -bang -nargs=+ -complete=dir Locate call fzf#vim#locate(<q-args>, <bang>0)',
\'command! -bang -nargs=* Ag call fzf#vim#ag(<q-args>, <bang>0)', \'command! -bang -nargs=* Ag call fzf#vim#ag(<q-args>, <bang>0)',
\'command! -bang -nargs=* Tags call fzf#vim#tags(<q-args>, <bang>0)', \'command! -bang -nargs=* Tags call fzf#vim#tags(<q-args>, <bang>0)',
\'command! -bang -nargs=* BTags call fzf#vim#buffer_tags(<q-args>, <bang>0)', \'command! -bang -nargs=* BTags call fzf#vim#buffer_tags(<q-args>, <bang>0)',
\'command! -bang Snippets call fzf#vim#snippets(<bang>0)', \'command! -bar -bang Snippets call fzf#vim#snippets(<bang>0)',
\'command! -bang Commands call fzf#vim#commands(<bang>0)', \'command! -bar -bang Commands call fzf#vim#commands(<bang>0)',
\'command! -bang Marks call fzf#vim#marks(<bang>0)', \'command! -bar -bang Marks call fzf#vim#marks(<bang>0)',
\'command! -bang Helptags call fzf#vim#helptags(<bang>0)', \'command! -bar -bang Helptags call fzf#vim#helptags(<bang>0)',
\'command! -bang Windows call fzf#vim#windows(<bang>0)', \'command! -bar -bang Windows call fzf#vim#windows(<bang>0)',
\'command! -bang Commits call fzf#vim#commits(<bang>0)', \'command! -bar -bang Commits call fzf#vim#commits(<bang>0)',
\'command! -bang BCommits call fzf#vim#buffer_commits(<bang>0)', \'command! -bar -bang BCommits call fzf#vim#buffer_commits(<bang>0)',
\'command! -bang Maps call fzf#vim#maps("n", <bang>0)', \'command! -bar -bang Maps call fzf#vim#maps("n", <bang>0)',
\'command! -bang Filetypes call fzf#vim#filetypes(<bang>0)', \'command! -bar -bang Filetypes call fzf#vim#filetypes(<bang>0)',
\'command! -bang -nargs=* History call s:history(<q-args>, <bang>0)']) \'command! -bang -nargs=* History call s:history(<q-args>, <bang>0)'])
function! s:history(arg, bang) function! s:history(arg, bang)
let bang = a:bang || a:arg[len(a:arg)-1] == '!' let bang = a:bang || a:arg[len(a:arg)-1] == '!'
@@ -81,13 +83,13 @@ if has('nvim') && get(g:, 'fzf_nvim_statusline', 1)
doautocmd User FzfStatusLine doautocmd User FzfStatusLine
else else
if $TERM !~ "256color" if $TERM !~ "256color"
highlight fzf1 ctermfg=1 ctermbg=8 guifg=#E12672 guibg=#565656 highlight default fzf1 ctermfg=1 ctermbg=8 guifg=#E12672 guibg=#565656
highlight fzf2 ctermfg=2 ctermbg=8 guifg=#BCDDBD guibg=#565656 highlight default fzf2 ctermfg=2 ctermbg=8 guifg=#BCDDBD guibg=#565656
highlight fzf3 ctermfg=7 ctermbg=8 guifg=#D9D9D9 guibg=#565656 highlight default fzf3 ctermfg=7 ctermbg=8 guifg=#D9D9D9 guibg=#565656
else else
highlight fzf1 ctermfg=161 ctermbg=238 guifg=#E12672 guibg=#565656 highlight default fzf1 ctermfg=161 ctermbg=238 guifg=#E12672 guibg=#565656
highlight fzf2 ctermfg=151 ctermbg=238 guifg=#BCDDBD guibg=#565656 highlight default fzf2 ctermfg=151 ctermbg=238 guifg=#BCDDBD guibg=#565656
highlight fzf3 ctermfg=252 ctermbg=238 guifg=#D9D9D9 guibg=#565656 highlight default fzf3 ctermfg=252 ctermbg=238 guifg=#D9D9D9 guibg=#565656
endif endif
setlocal statusline=%#fzf1#\ >\ %#fzf2#fz%#fzf3#f setlocal statusline=%#fzf1#\ >\ %#fzf2#fz%#fzf3#f
endif endif
@@ -122,9 +124,14 @@ augroup fzf_buffers
augroup END augroup END
inoremap <expr> <plug>(fzf-complete-word) fzf#vim#complete#word() inoremap <expr> <plug>(fzf-complete-word) fzf#vim#complete#word()
inoremap <expr> <plug>(fzf-complete-path) fzf#vim#complete#path("find . -path '*/\.*' -prune -o -print \| sed '1d;s:^..::'") if s:is_win
inoremap <expr> <plug>(fzf-complete-file) fzf#vim#complete#path("find . -path '*/\.*' -prune -o -type f -print -o -type l -print \| sed 's:^..::'") inoremap <expr> <plug>(fzf-complete-path) fzf#vim#complete#path('dir /s/b')
inoremap <expr> <plug>(fzf-complete-file-ag) fzf#vim#complete#path("ag -l -g ''") inoremap <expr> <plug>(fzf-complete-file) fzf#vim#complete#path('dir /s/b/a:-d')
else
inoremap <expr> <plug>(fzf-complete-path) fzf#vim#complete#path("find . -path '*/\.*' -prune -o -print \| sed '1d;s:^..::'")
inoremap <expr> <plug>(fzf-complete-file) fzf#vim#complete#path("find . -path '*/\.*' -prune -o -type f -print -o -type l -print \| sed 's:^..::'")
endif
inoremap <expr> <plug>(fzf-complete-file-ag) fzf#vim#complete#path('ag -l -g ""')
inoremap <expr> <plug>(fzf-complete-line) fzf#vim#complete#line() inoremap <expr> <plug>(fzf-complete-line) fzf#vim#complete#line()
inoremap <expr> <plug>(fzf-complete-buffer-line) fzf#vim#complete#buffer_line() inoremap <expr> <plug>(fzf-complete-buffer-line) fzf#vim#complete#buffer_line()