Add option to use location list instead of quickfix list

Close #432
Close #448
Close #846
Close #1095
Close #1500
This commit is contained in:
Junegunn Choi
2023-09-05 21:59:29 +09:00
parent 5ab282c2f4
commit 832a090870
5 changed files with 295 additions and 136 deletions

View File

@@ -93,8 +93,8 @@ Commands
- Most commands support `CTRL-T` / `CTRL-X` / `CTRL-V` key - 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 bindings to open in a new 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_vim.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. `let g:fzf_vim.command_prefix = 'Fzf'` and you have `FzfFiles`, etc.
(<a name="helptags">1</a>: `Helptags` will shadow the command of the same name (<a name="helptags">1</a>: `Helptags` will shadow the command of the same name
from [pathogen][pat]. But its functionality is still available via `call from [pathogen][pat]. But its functionality is still available via `call
@@ -106,16 +106,27 @@ pathogen#helptags()`. [↩](#a1))
Customization Customization
------------- -------------
### Global options ### Global configuration options for the base plugin
Every command in fzf.vim internally calls `fzf#wrap` function of the main Every command in fzf.vim internally calls `fzf#wrap` function of the main
repository which supports a set of global option variables. So please read repository which supports a set of global option variables. So please read
through [README-VIM][README-VIM] to learn more about them. through [README-VIM][README-VIM] to learn more about them.
### Configuration options for fzf.vim
All configuration values for this plugin are stored in `g:fzf_vim` dictionary,
so **make sure to initialize it before assigning any configuration values to
it**.
```vim
" Initialize configuration dictionary
let g:fzf_vim = {}
```
#### Preview window #### Preview window
Some commands will show the preview window on the right. You can customize the Some commands will show the preview window on the right. You can customize the
behavior with `g:fzf_preview_window`. Here are some examples: behavior with `g:fzf_vim.preview_window`. Here are some examples:
```vim ```vim
" This is the default option: " This is the default option:
@@ -123,40 +134,83 @@ behavior with `g:fzf_preview_window`. Here are some examples:
" - CTRL-/ will toggle preview window. " - CTRL-/ will toggle preview window.
" - Note that this array is passed as arguments to fzf#vim#with_preview function. " - Note that this array is passed as arguments to fzf#vim#with_preview function.
" - To learn more about preview window options, see `--preview-window` section of `man fzf`. " - To learn more about preview window options, see `--preview-window` section of `man fzf`.
let g:fzf_preview_window = ['right,50%', 'ctrl-/'] let g:fzf_vim.preview_window = ['right,50%', 'ctrl-/']
" Preview window is hidden by default. You can toggle it with ctrl-/. " Preview window is hidden by default. You can toggle it with ctrl-/.
" It will show on the right with 50% width, but if the width is smaller " It will show on the right with 50% width, but if the width is smaller
" than 70 columns, it will show above the candidate list " than 70 columns, it will show above the candidate list
let g:fzf_preview_window = ['hidden,right,50%,<70(up,40%)', 'ctrl-/'] let g:fzf_vim.preview_window = ['hidden,right,50%,<70(up,40%)', 'ctrl-/']
" Empty value to disable preview window altogether " Empty value to disable preview window altogether
let g:fzf_preview_window = [] let g:fzf_vim.preview_window = []
" fzf.vim needs bash to display the preview window. " fzf.vim needs bash to display the preview window.
" On Windows, fzf.vim will first see if bash is in $PATH, then if " On Windows, fzf.vim will first see if bash is in $PATH, then if
" Git bash (C:\Program Files\Git\bin\bash.exe) is available. " Git bash (C:\Program Files\Git\bin\bash.exe) is available.
" If you want it to use a different bash, set this variable. " If you want it to use a different bash, set this variable.
" let g:fzf_preview_bash = 'C:\Git\bin\bash.exe' " let g:fzf_vim = {}
" let g:fzf_vim.preview_bash = 'C:\Git\bin\bash.exe'
``` ```
### Command-local options #### Command-level options
A few commands in fzf.vim can be customized with global option variables shown
below.
```vim ```vim
" [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_vim.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 = '--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"' let g:fzf_vim.commits_log_options = '--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_vim.tags_command = 'ctags -R'
" [Commands] --expect expression for directly executing the command " [Commands] --expect expression for directly executing the command
let g:fzf_commands_expect = 'alt-enter,ctrl-x' let g:fzf_vim.commands_expect = 'alt-enter,ctrl-x'
```
#### List type to handle multiple selections
The following commands will fill the quickfix list when multiple entries are
selected.
* `Ag`
* `Rg` / `RG`
* `Lines / ``BLines`
* `Tags` / `BTags`
By setting `g:fzf_vim.listproc`, you can make them use location list instead.
```vim
" Default: Use quickfix list
let g:fzf_vim.listproc = { list -> fzf#vim#listproc#quickfix(list) }
" Use location list instead of quickfix list
let g:fzf_vim.listproc = { list -> fzf#vim#listproc#location(list) }
```
You can customize the list type per command by defining variables named
`g:fzf_vim.listproc_{command_name_in_lowercase}`.
```vim
" Command-wise customization
let g:fzf_vim.listproc_ag = { list -> fzf#vim#listproc#quickfix(list) }
let g:fzf_vim.listproc_rg = { list -> fzf#vim#listproc#location(list) }
```
You can further customize the behavior by providing a custom function to
process the list instead of using the predefined `fzf#vim#listproc#quickfix`
or `fzf#vim#listproc#location`.
```vim
" A customized version of fzf#vim#listproc#quickfix.
" The last two lines are commented out not to move to the first entry.
function! g:fzf_vim.listproc(list)
call setqflist(a:list)
copen
wincmd p
" cfirst
" normal! zvzz
endfunction
``` ```
### Advanced customization ### Advanced customization

View File

@@ -1,4 +1,4 @@
" Copyright (c) 2017 Junegunn Choi " Copyright (c) 2023 Junegunn Choi
" "
" MIT License " MIT License
" "
@@ -28,6 +28,11 @@ set cpo&vim
" Common " Common
" ------------------------------------------------------------------ " ------------------------------------------------------------------
function! s:conf(name, default)
let conf = get(g:, 'fzf_vim', {})
return get(conf, a:name, get(g:, 'fzf_' . a:name, a:default))
endfunction
let s:winpath = {} let s:winpath = {}
function! s:winpath(path) function! s:winpath(path)
if has_key(s:winpath, a:path) if has_key(s:winpath, a:path)
@@ -166,7 +171,7 @@ function! fzf#vim#with_preview(...)
" g:fzf_preview_window " g:fzf_preview_window
if empty(args) if empty(args)
let preview_args = get(g:, 'fzf_preview_window', ['', 'ctrl-/']) let preview_args = s:conf('preview_window', ['', 'ctrl-/'])
if empty(preview_args) if empty(preview_args)
let args = ['hidden'] let args = ['hidden']
else else
@@ -338,18 +343,25 @@ let s:default_action = {
\ 'ctrl-x': 'split', \ 'ctrl-x': 'split',
\ 'ctrl-v': 'vsplit' } \ 'ctrl-v': 'vsplit' }
function! s:action_for(key, ...) function! s:execute_silent(cmd)
let default = a:0 ? a:1 : '' silent keepjumps keepalt execute a:cmd
let Cmd = get(get(g:, 'fzf_action', s:default_action), a:key, default)
return type(Cmd) == s:TYPE.string ? Cmd : default
endfunction endfunction
function! s:open(cmd, target) function! s:action_for(key)
if stridx('edit', a:cmd) == 0 && fnamemodify(a:target, ':p') ==# expand('%:p') let Cmd = get(get(g:, 'fzf_action', s:default_action), a:key, '')
normal! m' let cmd = type(Cmd) == s:TYPE.string ? Cmd : ''
normal! m'
if len(cmd)
call s:execute_silent(cmd)
endif
return cmd
endfunction
function! s:open(target)
if fnamemodify(a:target, ':p') ==# expand('%:p')
return return
endif endif
execute a:cmd s:escape(a:target) execute 'edit' s:escape(a:target)
endfunction endfunction
function! s:align_lists(lists) function! s:align_lists(lists)
@@ -374,15 +386,13 @@ function! s:warn(message)
return 0 return 0
endfunction endfunction
function! s:fill_quickfix(list, ...) function! s:fill_quickfix(name, list)
if len(a:list) > 1 if len(a:list) > 1
call setqflist(a:list) let Handler = s:conf('listproc_'.a:name, s:conf('listproc', function('fzf#vim#listproc#quickfix')))
copen call call(Handler, [a:list], {})
wincmd p return 1
if a:0
execute a:1
endif
endif endif
return 0
endfunction endfunction
function! fzf#vim#_uniq(list) function! fzf#vim#_uniq(list)
@@ -434,12 +444,7 @@ function! s:line_handler(lines)
if len(a:lines) < 2 if len(a:lines) < 2
return return
endif endif
normal! m' call s:action_for(a:lines[0])
let cmd = s:action_for(a:lines[0])
if !empty(cmd) && stridx('edit', cmd) < 0
execute 'silent' cmd
endif
let keys = split(a:lines[1], '\t') let keys = split(a:lines[1], '\t')
execute 'buffer' keys[0] execute 'buffer' keys[0]
execute keys[2] execute keys[2]
@@ -511,14 +516,10 @@ function! s:buffer_line_handler(lines)
let ltxt = join(chunks[1:], "\t") let ltxt = join(chunks[1:], "\t")
call add(qfl, {'filename': expand('%'), 'lnum': str2nr(ln), 'text': ltxt}) call add(qfl, {'filename': expand('%'), 'lnum': str2nr(ln), 'text': ltxt})
endfor endfor
call s:fill_quickfix(qfl, 'cfirst') call s:action_for(a:lines[0])
normal! m' if !s:fill_quickfix('blines', qfl)
let cmd = s:action_for(a:lines[0]) execute split(a:lines[1], '\t')[0]
if !empty(cmd)
execute 'silent' cmd
endif endif
execute split(a:lines[1], '\t')[0]
normal! ^zvzz normal! ^zvzz
endfunction endfunction
@@ -740,17 +741,14 @@ function! s:bufopen(lines)
return return
endif endif
let b = matchstr(a:lines[1], '\[\zs[0-9]*\ze\]') let b = matchstr(a:lines[1], '\[\zs[0-9]*\ze\]')
if empty(a:lines[0]) && get(g:, 'fzf_buffers_jump') if empty(a:lines[0]) && s:conf('buffers_jump', 0)
let [t, w] = s:find_open_window(b) let [t, w] = s:find_open_window(b)
if t if t
call s:jump(t, w) call s:jump(t, w)
return return
endif endif
endif endif
let cmd = s:action_for(a:lines[0]) call s:action_for(a:lines[0])
if !empty(cmd)
execute 'silent' cmd
endif
execute 'buffer' b execute 'buffer' b
endfunction endfunction
@@ -802,20 +800,25 @@ function! s:ag_to_qf(line)
return dict return dict
endfunction endfunction
function! s:ag_handler(lines) function! s:ag_handler(name, lines)
if len(a:lines) < 2 if len(a:lines) < 2
return return
endif endif
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)') let list = map(filter(a:lines[1:], 'len(v:val)'), 's:ag_to_qf(v:val)')
if empty(list) if empty(list)
return return
endif endif
call s:action_for(a:lines[0])
if s:fill_quickfix(a:name, list)
return
endif
" Single item selected
let first = list[0] let first = list[0]
try try
call s:open(cmd, first.filename) call s:open(first.filename)
execute first.lnum execute first.lnum
if has_key(first, 'col') if has_key(first, 'col')
call cursor(0, first.col) call cursor(0, first.col)
@@ -823,8 +826,6 @@ function! s:ag_handler(lines)
normal! zvzz normal! zvzz
catch catch
endtry endtry
call s:fill_quickfix(list)
endfunction endfunction
" query, [ag options], [spec (dict)], [fullscreen (bool)] " query, [ag options], [spec (dict)], [fullscreen (bool)]
@@ -869,8 +870,8 @@ function! fzf#vim#grep(grep_command, ...)
call remove(args, 0) call remove(args, 0)
endif endif
function! opts.sink(lines) function! opts.sink(lines) closure
return s:ag_handler(a:lines) return s:ag_handler(get(opts, 'name', name), a:lines)
endfunction endfunction
let opts['sink*'] = remove(opts, 'sink') let opts['sink*'] = remove(opts, 'sink')
try try
@@ -907,8 +908,8 @@ function! fzf#vim#grep2(command_prefix, query, ...)
if len(args) && type(args[0]) == s:TYPE.bool if len(args) && type(args[0]) == s:TYPE.bool
call remove(args, 0) call remove(args, 0)
endif endif
function! opts.sink(lines) function! opts.sink(lines) closure
return s:ag_handler(a:lines) return s:ag_handler(name, a:lines)
endfunction endfunction
let opts['sink*'] = remove(opts, 'sink') let opts['sink*'] = remove(opts, 'sink')
return s:fzf(name, opts, args) return s:fzf(name, opts, args)
@@ -940,18 +941,21 @@ function! s:btags_sink(lines)
if len(a:lines) < 2 if len(a:lines) < 2
return return
endif endif
normal! m' call s:action_for(a:lines[0])
let cmd = s:action_for(a:lines[0])
if !empty(cmd)
execute 'silent' cmd '%'
endif
let qfl = [] let qfl = []
for line in a:lines[1:] for line in a:lines[1:]
execute split(line, "\t")[2] call s:execute_silent(split(line, "\t")[2])
call add(qfl, {'filename': expand('%'), 'lnum': line('.'), 'text': getline('.')}) call add(qfl, {'filename': expand('%'), 'lnum': line('.'), 'text': getline('.')})
endfor endfor
call s:fill_quickfix(qfl, 'cfirst')
normal! zvzz if len(qfl) > 1
" Go back to the original position
normal! g`'
" Because 'listproc' will use 'cfirst' to go to the first item in the list
call s:fill_quickfix('btags', qfl)
else
normal! zvzz
endif
endfunction endfunction
" query, [tag commands], [spec (dict)], [fullscreen (bool)] " query, [tag commands], [spec (dict)], [fullscreen (bool)]
@@ -983,9 +987,8 @@ function! s:tags_sink(lines)
if len(a:lines) < 2 if len(a:lines) < 2
return return
endif endif
normal! m'
let qfl = [] let qfl = []
let cmd = s:action_for(a:lines[0], 'e') call s:action_for(a:lines[0])
try try
let [magic, &magic, wrapscan, &wrapscan, acd, &acd] = [&magic, 0, &wrapscan, 1, &acd, 0] 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:]
@@ -995,8 +998,8 @@ function! s:tags_sink(lines)
let base = fnamemodify(parts[-1], ':h') let base = fnamemodify(parts[-1], ':h')
let relpath = parts[1][:-2] let relpath = parts[1][:-2]
let abspath = relpath =~ (s:is_win ? '^[A-Z]:\' : '^/') ? relpath : join([base, relpath], '/') let abspath = relpath =~ (s:is_win ? '^[A-Z]:\' : '^/') ? relpath : join([base, relpath], '/')
call s:open(cmd, expand(abspath, 1)) call s:open(expand(abspath, 1))
silent execute excmd call s:execute_silent(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$/
break break
@@ -1007,8 +1010,15 @@ function! s:tags_sink(lines)
finally finally
let [&magic, &wrapscan, &acd] = [magic, wrapscan, acd] let [&magic, &wrapscan, &acd] = [magic, wrapscan, acd]
endtry endtry
call s:fill_quickfix(qfl, 'clast')
normal! zvzz if len(qfl) > 1
" Go back to the original position
normal! g`'
" Because 'listproc' will use 'cfirst' to go to the first item in the list
call s:fill_quickfix('tags', qfl)
else
normal! zvzz
endif
endfunction endfunction
function! fzf#vim#tags(query, ...) function! fzf#vim#tags(query, ...)
@@ -1024,7 +1034,7 @@ function! fzf#vim#tags(query, ...)
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'.(s:is_win ? ' --output-format=e-ctags' : ''))) call system(s:conf('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
@@ -1136,7 +1146,7 @@ function! fzf#vim#commands(...)
return s:fzf('commands', { return s:fzf('commands', {
\ 'source': extend(extend(list[0:0], map(list[1:], 's:format_cmd(v:val)')), s:excmds()), \ 'source': extend(extend(list[0:0], map(list[1:], 's:format_cmd(v:val)')), s:excmds()),
\ 'sink*': s:function('s:command_sink'), \ 'sink*': s:function('s:command_sink'),
\ 'options': '--ansi --expect '.get(g:, 'fzf_commands_expect', 'ctrl-x'). \ 'options': '--ansi --expect '.s:conf('commands_expect', 'ctrl-x').
\ ' --tiebreak=index --header-lines 1 -x --prompt "Commands> " -n2,3,2..3 -d'.s:nbs}, a:000) \ ' --tiebreak=index --header-lines 1 -x --prompt "Commands> " -n2,3,2..3 -d'.s:nbs}, a:000)
endfunction endfunction
@@ -1151,10 +1161,7 @@ function! s:mark_sink(lines)
if len(a:lines) < 2 if len(a:lines) < 2
return return
endif endif
let cmd = s:action_for(a:lines[0]) call s:action_for(a:lines[0])
if !empty(cmd)
execute 'silent' cmd
endif
execute 'normal! `'.matchstr(a:lines[1], '\S').'zz' execute 'normal! `'.matchstr(a:lines[1], '\S').'zz'
endfunction endfunction
@@ -1180,10 +1187,7 @@ function! s:jump_sink(lines)
if len(a:lines) < 2 if len(a:lines) < 2
return return
endif endif
let cmd = s:action_for(a:lines[0]) call s:action_for(a:lines[0])
if !empty(cmd)
execute 'silent' cmd
endif
let idx = index(s:jumplist, a:lines[1]) let idx = index(s:jumplist, a:lines[1])
if idx == -1 if idx == -1
return return
@@ -1309,7 +1313,7 @@ function! s:commits_sink(lines)
end end
let diff = a:lines[0] == 'ctrl-d' let diff = a:lines[0] == 'ctrl-d'
let cmd = s:action_for(a:lines[0], 'e') let cmd = s:action_for(a:lines[0])
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], pat) let sha = matchstr(a:lines[idx], pat)
@@ -1321,7 +1325,7 @@ function! s:commits_sink(lines)
execute 'Gdiff' sha execute 'Gdiff' sha
else else
" Since fugitive buffers are unlisted, we can't keep using 'e' " Since fugitive buffers are unlisted, we can't keep using 'e'
let c = (cmd == 'e' && idx > 1) ? 'tab split' : cmd let c = empty(cmd) ? (idx == 1 ? 'edit' : 'tab split') : cmd
execute c FugitiveFind(sha) execute c FugitiveFind(sha)
endif endif
endif endif
@@ -1335,7 +1339,7 @@ function! s:commits(range, buffer_local, args)
endif endif
let prefix = 'git -C ' . fzf#shellescape(s:git_root) . ' ' let prefix = 'git -C ' . fzf#shellescape(s:git_root) . ' '
let source = prefix . 'log '.get(g:, 'fzf_commits_log_options', '--color=always '.fzf#shellescape('--format=%C(auto)%h%d %s %C(green)%cr')) let source = prefix . 'log '.s:conf('commits_log_options', '--color=always '.fzf#shellescape('--format=%C(auto)%h%d %s %C(green)%cr'))
let current = expand('%:p') let current = expand('%:p')
let managed = 0 let managed = 0
if !empty(current) if !empty(current)

View File

@@ -0,0 +1,38 @@
" Copyright (c) 2023 Junegunn Choi
"
" MIT License
"
" Permission is hereby granted, free of charge, to any person obtaining
" a copy of this software and associated documentation files (the
" "Software"), to deal in the Software without restriction, including
" without limitation the rights to use, copy, modify, merge, publish,
" distribute, sublicense, and/or sell copies of the Software, and to
" permit persons to whom the Software is furnished to do so, subject to
" the following conditions:
"
" The above copyright notice and this permission notice shall be
" included in all copies or substantial portions of the Software.
"
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
function! fzf#vim#listproc#quickfix(list)
call setqflist(a:list)
copen
wincmd p
cfirst
normal! zvzz
endfunction
function! fzf#vim#listproc#location(list)
call setloclist(0, a:list)
lopen
wincmd p
lfirst
normal! zvzz
endfunction

View File

@@ -1,30 +1,32 @@
fzf-vim.txt fzf-vim Last change: June 4 2023 fzf-vim.txt fzf-vim Last change: September 6 2023
FZF-VIM - TABLE OF CONTENTS *fzf-vim* *fzf-vim-toc* FZF-VIM - TABLE OF CONTENTS *fzf-vim* *fzf-vim-toc*
============================================================================== ==============================================================================
fzf :heart: vim |fzf-vim-fzfheart-vim| fzf :heart: vim |fzf-vim-fzfheart-vim|
Rationale |fzf-vim-rationale| Rationale |fzf-vim-rationale|
Why you should use fzf on Vim |fzf-vim-why-you-should-use-fzf-on-vim| Why you should use fzf on Vim |fzf-vim-why-you-should-use-fzf-on-vim|
Installation |fzf-vim-installation| Installation |fzf-vim-installation|
Using vim-plug |fzf-vim-using-vim-plug| Using vim-plug |fzf-vim-using-vim-plug|
Dependencies |fzf-vim-dependencies| Dependencies |fzf-vim-dependencies|
Commands |fzf-vim-commands| Commands |fzf-vim-commands|
Customization |fzf-vim-customization| Customization |fzf-vim-customization|
Global options |fzf-vim-global-options| Global configuration options for the base plugin |fzf-vim-global-configuration-options-for-the-base-plugin|
Preview window |fzf-vim-preview-window| Configuration options for fzf.vim |fzf-vim-configuration-options-for-fzf-vim|
Command-local options |fzf-vim-command-local-options| Preview window |fzf-vim-preview-window|
Advanced customization |fzf-vim-advanced-customization| Command-level options |fzf-vim-command-level-options|
Vim functions |fzf-vim-vim-functions| List type to handle multiple selections |fzf-vim-list-type-to-handle-multiple-selections|
Example: Customizing Files command |fzf-vim-example-customizing-files-command| Advanced customization |fzf-vim-advanced-customization|
Example: git grep wrapper |fzf-vim-example-git-grep-wrapper| Vim functions |fzf-vim-vim-functions|
Mappings |fzf-vim-mappings| Example: Customizing Files command |fzf-vim-example-customizing-files-command|
Completion functions |fzf-vim-completion-functions| Example: git grep wrapper |fzf-vim-example-git-grep-wrapper|
Custom completion |fzf-vim-custom-completion| Mappings |fzf-vim-mappings|
Reducer example |fzf-vim-reducer-example| Completion functions |fzf-vim-completion-functions|
Status line of terminal buffer |fzf-vim-status-line-of-terminal-buffer| Custom completion |fzf-vim-custom-completion|
Hide statusline |fzf-vim-hide-statusline| Reducer example |fzf-vim-reducer-example|
Custom statusline |fzf-vim-custom-statusline| Status line of terminal buffer |fzf-vim-status-line-of-terminal-buffer|
License |fzf-vim-license| Hide statusline |fzf-vim-hide-statusline|
Custom statusline |fzf-vim-custom-statusline|
License |fzf-vim-license|
FZF :HEART: VIM *fzf-vim-fzfheart-vim* FZF :HEART: VIM *fzf-vim-fzfheart-vim*
============================================================================== ==============================================================================
@@ -140,13 +142,13 @@ COMMANDS *fzf-vim-commands*
`:Filetypes` | File types `:Filetypes` | File types
-----------------------+-------------------------------------------------------------------------------------- -----------------------+--------------------------------------------------------------------------------------
*g:fzf_command_prefix* *g:fzf_vim.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_vim.command_prefix` to give the same prefix to the commands
- e.g. `letg:fzf_command_prefix='Fzf'` and you have `FzfFiles`, etc. - e.g. `letg:fzf_vim.command_prefix='Fzf'` and you have `FzfFiles`, etc.
(1: `Helptags` will shadow the command of the same name from {pathogen}{10}. (1: `Helptags` will shadow the command of the same name from {pathogen}{10}.
But its functionality is still available via `call pathogen#helptags()`. [↩]) But its functionality is still available via `call pathogen#helptags()`. [↩])
@@ -163,8 +165,8 @@ CUSTOMIZATION *fzf-vim-customization*
============================================================================== ==============================================================================
< Global options >____________________________________________________________~ < Global configuration options for the base plugin >__________________________~
*fzf-vim-global-options* *fzf-vim-global-configuration-options-for-the-base-plugin*
Every command in fzf.vim internally calls `fzf#wrap` function of the main Every command in fzf.vim internally calls `fzf#wrap` function of the main
repository which supports a set of global option variables. So please read repository which supports a set of global option variables. So please read
@@ -173,58 +175,113 @@ through {README-VIM}{3} to learn more about them.
{3} https://github.com/junegunn/fzf/blob/master/README-VIM.md {3} https://github.com/junegunn/fzf/blob/master/README-VIM.md
< Configuration options for fzf.vim >_________________________________________~
*fzf-vim-configuration-options-for-fzf-vim*
*g:fzf_vim*
All configuration values for this plugin are stored in `g:fzf_vim` dictionary,
so make sure to initialize it before assigning any configuration values to it.
>
" Initialize configuration dictionary
let g:fzf_vim = {}
<
Preview window~ Preview window~
*fzf-vim-preview-window* *fzf-vim-preview-window*
*g:fzf_preview_window* *g:fzf_vim.preview_window*
Some commands will show the preview window on the right. You can customize the Some commands will show the preview window on the right. You can customize the
behavior with `g:fzf_preview_window`. Here are some examples: behavior with `g:fzf_vim.preview_window`. Here are some examples:
*g:fzf_preview_bash* *g:fzf_vim.preview_bash*
> >
" This is the default option: " This is the default option:
" - Preview window on the right with 50% width " - Preview window on the right with 50% width
" - CTRL-/ will toggle preview window. " - CTRL-/ will toggle preview window.
" - Note that this array is passed as arguments to fzf#vim#with_preview function. " - Note that this array is passed as arguments to fzf#vim#with_preview function.
" - To learn more about preview window options, see `--preview-window` section of `man fzf`. " - To learn more about preview window options, see `--preview-window` section of `man fzf`.
let g:fzf_preview_window = ['right,50%', 'ctrl-/'] let g:fzf_vim.preview_window = ['right,50%', 'ctrl-/']
" Preview window is hidden by default. You can toggle it with ctrl-/. " Preview window is hidden by default. You can toggle it with ctrl-/.
" It will show on the right with 50% width, but if the width is smaller " It will show on the right with 50% width, but if the width is smaller
" than 70 columns, it will show above the candidate list " than 70 columns, it will show above the candidate list
let g:fzf_preview_window = ['hidden,right,50%,<70(up,40%)', 'ctrl-/'] let g:fzf_vim.preview_window = ['hidden,right,50%,<70(up,40%)', 'ctrl-/']
" Empty value to disable preview window altogether " Empty value to disable preview window altogether
let g:fzf_preview_window = [] let g:fzf_vim.preview_window = []
" fzf.vim needs bash to display the preview window. " fzf.vim needs bash to display the preview window.
" On Windows, fzf.vim will first see if bash is in $PATH, then if " On Windows, fzf.vim will first see if bash is in $PATH, then if
" Git bash (C:\Program Files\Git\bin\bash.exe) is available. " Git bash (C:\Program Files\Git\bin\bash.exe) is available.
" If you want it to use a different bash, set this variable. " If you want it to use a different bash, set this variable.
" let g:fzf_preview_bash = 'C:\Git\bin\bash.exe' " let g:fzf_vim = {}
" let g:fzf_vim.preview_bash = 'C:\Git\bin\bash.exe'
< <
< Command-local options >_____________________________________________________~ Command-level options~
*fzf-vim-command-local-options* *fzf-vim-command-level-options*
A few commands in fzf.vim can be customized with global option variables shown *g:fzf_vim.commands_expect* *g:fzf_vim.tags_command* *g:fzf_vim.commits_log_options*
below. *g:fzf_vim.buffers_jump*
*g:fzf_commands_expect* *g:fzf_tags_command* *g:fzf_commits_log_options*
*g:fzf_buffers_jump*
> >
" [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_vim.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 = '--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"' let g:fzf_vim.commits_log_options = '--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_vim.tags_command = 'ctags -R'
" [Commands] --expect expression for directly executing the command " [Commands] --expect expression for directly executing the command
let g:fzf_commands_expect = 'alt-enter,ctrl-x' let g:fzf_vim.commands_expect = 'alt-enter,ctrl-x'
<
List type to handle multiple selections~
*fzf-vim-list-type-to-handle-multiple-selections*
The following commands will fill the quickfix list when multiple entries are
selected.
- `Ag`
- `Rg` / `RG`
- `Lines/``BLines`
- `Tags` / `BTags`
*g:fzf_vim.listproc*
By setting `g:fzf_vim.listproc`, you can make them use location list instead.
>
" Default: Use quickfix list
let g:fzf_vim.listproc = { list -> fzf#vim#listproc#quickfix(list) }
" Use location list instead of quickfix list
let g:fzf_vim.listproc = { list -> fzf#vim#listproc#location(list) }
<
You can customize the list type per command by defining variables named
`g:fzf_vim.listproc_{command_name_in_lowercase}`.
*g:fzf_vim.listproc_rg* *g:fzf_vim.listproc_ag*
>
" Command-wise customization
let g:fzf_vim.listproc_ag = { list -> fzf#vim#listproc#quickfix(list) }
let g:fzf_vim.listproc_rg = { list -> fzf#vim#listproc#location(list) }
<
You can further customize the behavior by providing a custom function to
process the list instead of using the predefined `fzf#vim#listproc#quickfix`
or `fzf#vim#listproc#location`.
>
" A customized version of fzf#vim#listproc#quickfix.
" The last two lines are commented out not to move to the first entry.
function! g:fzf_vim.listproc(list)
call setqflist(a:list)
copen
wincmd p
" cfirst
" normal! zvzz
endfunction
< <
< Advanced customization >____________________________________________________~ < Advanced customization >____________________________________________________~

View File

@@ -30,8 +30,14 @@ let s:cpo_save = &cpo
set cpo&vim set cpo&vim
let s:is_win = has('win32') || has('win64') let s:is_win = has('win32') || has('win64')
function! s:conf(name, default)
let conf = get(g:, 'fzf_vim', {})
let val = get(conf, a:name, get(g:, 'fzf_' . a:name, a:default))
return val
endfunction
function! s:defs(commands) function! s:defs(commands)
let prefix = get(g:, 'fzf_command_prefix', '') let prefix = s:conf('command_prefix', '')
if prefix =~# '^[^A-Z]' if prefix =~# '^[^A-Z]'
echoerr 'g:fzf_command_prefix must start with an uppercase letter' echoerr 'g:fzf_command_prefix must start with an uppercase letter'
return return
@@ -85,7 +91,7 @@ function! fzf#complete(...)
return call('fzf#vim#complete', a:000) return call('fzf#vim#complete', a:000)
endfunction endfunction
if (has('nvim') || has('terminal') && has('patch-8.0.995')) && (get(g:, 'fzf_statusline', 1) || get(g:, 'fzf_nvim_statusline', 1)) if (has('nvim') || has('terminal') && has('patch-8.0.995')) && (s:conf('statusline', 1) || s:conf('nvim_statusline', 1))
function! s:fzf_restore_colors() function! s:fzf_restore_colors()
if exists('#User#FzfStatusLine') if exists('#User#FzfStatusLine')
doautocmd User FzfStatusLine doautocmd User FzfStatusLine