diff --git a/README.md b/README.md index 72a8027..a2c68d9 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,8 @@ Commands - 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 - 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 - - e.g. `let g:fzf_command_prefix = 'Fzf'` and you have `FzfFiles`, etc. +- You can set `g:fzf_vim.command_prefix` to give the same prefix to the commands + - e.g. `let g:fzf_vim.command_prefix = 'Fzf'` and you have `FzfFiles`, etc. (1: `Helptags` will shadow the command of the same name from [pathogen][pat]. But its functionality is still available via `call @@ -106,16 +106,27 @@ pathogen#helptags()`. [↩](#a1)) Customization ------------- -### Global options +### Global configuration options for the base plugin 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 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 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 " This is the default option: @@ -123,40 +134,83 @@ behavior with `g:fzf_preview_window`. Here are some examples: " - CTRL-/ will toggle preview window. " - 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`. -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-/. " 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 -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 -let g:fzf_preview_window = [] +let g:fzf_vim.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 " Git bash (C:\Program Files\Git\bin\bash.exe) is available. " 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 - -A few commands in fzf.vim can be customized with global option variables shown -below. +#### Command-level options ```vim " [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': -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 -let g:fzf_tags_command = 'ctags -R' +let g:fzf_vim.tags_command = 'ctags -R' " [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 diff --git a/autoload/fzf/vim.vim b/autoload/fzf/vim.vim index 171aac9..e37901c 100755 --- a/autoload/fzf/vim.vim +++ b/autoload/fzf/vim.vim @@ -1,4 +1,4 @@ -" Copyright (c) 2017 Junegunn Choi +" Copyright (c) 2023 Junegunn Choi " " MIT License " @@ -28,6 +28,11 @@ set cpo&vim " 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 = {} function! s:winpath(path) if has_key(s:winpath, a:path) @@ -166,7 +171,7 @@ function! fzf#vim#with_preview(...) " g:fzf_preview_window if empty(args) - let preview_args = get(g:, 'fzf_preview_window', ['', 'ctrl-/']) + let preview_args = s:conf('preview_window', ['', 'ctrl-/']) if empty(preview_args) let args = ['hidden'] else @@ -338,18 +343,25 @@ let s:default_action = { \ 'ctrl-x': 'split', \ '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 +function! s:execute_silent(cmd) + silent keepjumps keepalt execute a:cmd endfunction -function! s:open(cmd, target) - if stridx('edit', a:cmd) == 0 && fnamemodify(a:target, ':p') ==# expand('%:p') - normal! m' +function! s:action_for(key) + let Cmd = get(get(g:, 'fzf_action', s:default_action), a:key, '') + 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 endif - execute a:cmd s:escape(a:target) + execute 'edit' s:escape(a:target) endfunction function! s:align_lists(lists) @@ -374,15 +386,13 @@ function! s:warn(message) return 0 endfunction -function! s:fill_quickfix(list, ...) +function! s:fill_quickfix(name, list) if len(a:list) > 1 - call setqflist(a:list) - copen - wincmd p - if a:0 - execute a:1 - endif + let Handler = s:conf('listproc_'.a:name, s:conf('listproc', function('fzf#vim#listproc#quickfix'))) + call call(Handler, [a:list], {}) + return 1 endif + return 0 endfunction function! fzf#vim#_uniq(list) @@ -434,12 +444,7 @@ function! s:line_handler(lines) if len(a:lines) < 2 return endif - normal! m' - let cmd = s:action_for(a:lines[0]) - if !empty(cmd) && stridx('edit', cmd) < 0 - execute 'silent' cmd - endif - + call s:action_for(a:lines[0]) let keys = split(a:lines[1], '\t') execute 'buffer' keys[0] execute keys[2] @@ -511,14 +516,10 @@ function! s:buffer_line_handler(lines) let ltxt = join(chunks[1:], "\t") call add(qfl, {'filename': expand('%'), 'lnum': str2nr(ln), 'text': ltxt}) endfor - call s:fill_quickfix(qfl, 'cfirst') - normal! m' - let cmd = s:action_for(a:lines[0]) - if !empty(cmd) - execute 'silent' cmd + call s:action_for(a:lines[0]) + if !s:fill_quickfix('blines', qfl) + execute split(a:lines[1], '\t')[0] endif - - execute split(a:lines[1], '\t')[0] normal! ^zvzz endfunction @@ -740,17 +741,14 @@ function! s:bufopen(lines) return endif 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) if t call s:jump(t, w) return endif endif - let cmd = s:action_for(a:lines[0]) - if !empty(cmd) - execute 'silent' cmd - endif + call s:action_for(a:lines[0]) execute 'buffer' b endfunction @@ -802,20 +800,25 @@ function! s:ag_to_qf(line) return dict endfunction -function! s:ag_handler(lines) +function! s:ag_handler(name, lines) if len(a:lines) < 2 return 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)') if empty(list) return endif + call s:action_for(a:lines[0]) + if s:fill_quickfix(a:name, list) + return + endif + + " Single item selected let first = list[0] try - call s:open(cmd, first.filename) + call s:open(first.filename) execute first.lnum if has_key(first, 'col') call cursor(0, first.col) @@ -823,8 +826,6 @@ function! s:ag_handler(lines) normal! zvzz catch endtry - - call s:fill_quickfix(list) endfunction " query, [ag options], [spec (dict)], [fullscreen (bool)] @@ -869,8 +870,8 @@ function! fzf#vim#grep(grep_command, ...) call remove(args, 0) endif - function! opts.sink(lines) - return s:ag_handler(a:lines) + function! opts.sink(lines) closure + return s:ag_handler(get(opts, 'name', name), a:lines) endfunction let opts['sink*'] = remove(opts, 'sink') try @@ -907,8 +908,8 @@ function! fzf#vim#grep2(command_prefix, query, ...) if len(args) && type(args[0]) == s:TYPE.bool call remove(args, 0) endif - function! opts.sink(lines) - return s:ag_handler(a:lines) + function! opts.sink(lines) closure + return s:ag_handler(name, a:lines) endfunction let opts['sink*'] = remove(opts, 'sink') return s:fzf(name, opts, args) @@ -940,18 +941,21 @@ function! s:btags_sink(lines) if len(a:lines) < 2 return endif - normal! m' - let cmd = s:action_for(a:lines[0]) - if !empty(cmd) - execute 'silent' cmd '%' - endif + call s:action_for(a:lines[0]) let qfl = [] 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('.')}) 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 " query, [tag commands], [spec (dict)], [fullscreen (bool)] @@ -983,9 +987,8 @@ function! s:tags_sink(lines) if len(a:lines) < 2 return endif - normal! m' let qfl = [] - let cmd = s:action_for(a:lines[0], 'e') + call s:action_for(a:lines[0]) try let [magic, &magic, wrapscan, &wrapscan, acd, &acd] = [&magic, 0, &wrapscan, 1, &acd, 0] for line in a:lines[1:] @@ -995,8 +998,8 @@ function! s:tags_sink(lines) 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)) - silent execute excmd + call s:open(expand(abspath, 1)) + call s:execute_silent(excmd) call add(qfl, {'filename': expand('%'), 'lnum': line('.'), 'text': getline('.')}) catch /^Vim:Interrupt$/ break @@ -1007,8 +1010,15 @@ function! s:tags_sink(lines) finally let [&magic, &wrapscan, &acd] = [magic, wrapscan, acd] 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 function! fzf#vim#tags(query, ...) @@ -1024,7 +1034,7 @@ function! fzf#vim#tags(query, ...) redraw if gen =~? '^y' 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()) return s:warn('Failed to create tags') endif @@ -1136,7 +1146,7 @@ function! fzf#vim#commands(...) return s:fzf('commands', { \ 'source': extend(extend(list[0:0], map(list[1:], 's:format_cmd(v:val)')), s:excmds()), \ '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) endfunction @@ -1151,10 +1161,7 @@ function! s:mark_sink(lines) if len(a:lines) < 2 return endif - let cmd = s:action_for(a:lines[0]) - if !empty(cmd) - execute 'silent' cmd - endif + call s:action_for(a:lines[0]) execute 'normal! `'.matchstr(a:lines[1], '\S').'zz' endfunction @@ -1180,10 +1187,7 @@ function! s:jump_sink(lines) if len(a:lines) < 2 return endif - let cmd = s:action_for(a:lines[0]) - if !empty(cmd) - execute 'silent' cmd - endif + call s:action_for(a:lines[0]) let idx = index(s:jumplist, a:lines[1]) if idx == -1 return @@ -1309,7 +1313,7 @@ function! s:commits_sink(lines) end 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('') for idx in range(1, len(a:lines) - 1) let sha = matchstr(a:lines[idx], pat) @@ -1321,7 +1325,7 @@ function! s:commits_sink(lines) execute 'Gdiff' sha else " 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) endif endif @@ -1335,7 +1339,7 @@ function! s:commits(range, buffer_local, args) endif 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 managed = 0 if !empty(current) diff --git a/autoload/fzf/vim/listproc.vim b/autoload/fzf/vim/listproc.vim new file mode 100644 index 0000000..7a1342c --- /dev/null +++ b/autoload/fzf/vim/listproc.vim @@ -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 diff --git a/doc/fzf-vim.txt b/doc/fzf-vim.txt index 6d7b6ae..206d827 100644 --- a/doc/fzf-vim.txt +++ b/doc/fzf-vim.txt @@ -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 :heart: vim |fzf-vim-fzfheart-vim| - Rationale |fzf-vim-rationale| - Why you should use fzf on Vim |fzf-vim-why-you-should-use-fzf-on-vim| - Installation |fzf-vim-installation| - Using vim-plug |fzf-vim-using-vim-plug| - Dependencies |fzf-vim-dependencies| - Commands |fzf-vim-commands| - Customization |fzf-vim-customization| - Global options |fzf-vim-global-options| - Preview window |fzf-vim-preview-window| - Command-local options |fzf-vim-command-local-options| - Advanced customization |fzf-vim-advanced-customization| - Vim functions |fzf-vim-vim-functions| - Example: Customizing Files command |fzf-vim-example-customizing-files-command| - Example: git grep wrapper |fzf-vim-example-git-grep-wrapper| - Mappings |fzf-vim-mappings| - Completion functions |fzf-vim-completion-functions| - Custom completion |fzf-vim-custom-completion| - Reducer example |fzf-vim-reducer-example| - Status line of terminal buffer |fzf-vim-status-line-of-terminal-buffer| - Hide statusline |fzf-vim-hide-statusline| - Custom statusline |fzf-vim-custom-statusline| - License |fzf-vim-license| + fzf :heart: vim |fzf-vim-fzfheart-vim| + Rationale |fzf-vim-rationale| + Why you should use fzf on Vim |fzf-vim-why-you-should-use-fzf-on-vim| + Installation |fzf-vim-installation| + Using vim-plug |fzf-vim-using-vim-plug| + Dependencies |fzf-vim-dependencies| + Commands |fzf-vim-commands| + Customization |fzf-vim-customization| + Global configuration options for the base plugin |fzf-vim-global-configuration-options-for-the-base-plugin| + Configuration options for fzf.vim |fzf-vim-configuration-options-for-fzf-vim| + Preview window |fzf-vim-preview-window| + Command-level options |fzf-vim-command-level-options| + List type to handle multiple selections |fzf-vim-list-type-to-handle-multiple-selections| + Advanced customization |fzf-vim-advanced-customization| + Vim functions |fzf-vim-vim-functions| + Example: Customizing Files command |fzf-vim-example-customizing-files-command| + Example: git grep wrapper |fzf-vim-example-git-grep-wrapper| + Mappings |fzf-vim-mappings| + Completion functions |fzf-vim-completion-functions| + Custom completion |fzf-vim-custom-completion| + Reducer example |fzf-vim-reducer-example| + Status line of terminal buffer |fzf-vim-status-line-of-terminal-buffer| + Hide statusline |fzf-vim-hide-statusline| + Custom statusline |fzf-vim-custom-statusline| + License |fzf-vim-license| FZF :HEART: VIM *fzf-vim-fzfheart-vim* ============================================================================== @@ -140,13 +142,13 @@ COMMANDS *fzf-vim-commands* `: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 tab, a new split, or in a new vertical split - 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 - - e.g. `let g:fzf_command_prefix = 'Fzf'` and you have `FzfFiles`, etc. + - You can set `g:fzf_vim.command_prefix` to give the same prefix to the commands + - e.g. `let g:fzf_vim.command_prefix = 'Fzf'` and you have `FzfFiles`, etc. (1: `Helptags` will shadow the command of the same name from {pathogen}{10}. But its functionality is still available via `call pathogen#helptags()`. [↩]) @@ -163,8 +165,8 @@ 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* 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 @@ -173,58 +175,113 @@ through {README-VIM}{3} to learn more about them. {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~ *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 -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: " - Preview window on the right with 50% width " - CTRL-/ will toggle preview window. " - 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`. - 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-/. " 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 - 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 - let g:fzf_preview_window = [] + let g:fzf_vim.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 " Git bash (C:\Program Files\Git\bin\bash.exe) is available. " 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 >_____________________________________________________~ - *fzf-vim-command-local-options* +Command-level options~ + *fzf-vim-command-level-options* -A few commands in fzf.vim can be customized with global option variables shown -below. - - *g:fzf_commands_expect* *g:fzf_tags_command* *g:fzf_commits_log_options* - *g:fzf_buffers_jump* +*g:fzf_vim.commands_expect* *g:fzf_vim.tags_command* *g:fzf_vim.commits_log_options* + *g:fzf_vim.buffers_jump* > " [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': - 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 - let g:fzf_tags_command = 'ctags -R' + let g:fzf_vim.tags_command = 'ctags -R' " [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 >____________________________________________________~ diff --git a/plugin/fzf.vim b/plugin/fzf.vim index c73931b..600d632 100644 --- a/plugin/fzf.vim +++ b/plugin/fzf.vim @@ -30,8 +30,14 @@ let s:cpo_save = &cpo set cpo&vim 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) - let prefix = get(g:, 'fzf_command_prefix', '') + let prefix = s:conf('command_prefix', '') if prefix =~# '^[^A-Z]' echoerr 'g:fzf_command_prefix must start with an uppercase letter' return @@ -85,7 +91,7 @@ function! fzf#complete(...) return call('fzf#vim#complete', a:000) 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() if exists('#User#FzfStatusLine') doautocmd User FzfStatusLine