From 87b60bb133032056fda105e0ce6f5d64436926dd Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Sun, 4 Jun 2023 15:22:13 +0900 Subject: [PATCH] Add :RG command and fzf#vim#grep2 function --- README.md | 38 ++++++++------------ autoload/fzf/vim.vim | 29 ++++++++++++++++ doc/fzf-vim.txt | 83 ++++++++++++++++++++------------------------ plugin/fzf.vim | 1 + 4 files changed, 83 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index 9b05275..7e88eee 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ Commands | `:Colors` | Color schemes | | `:Ag [PATTERN]` | [ag][ag] search result (`ALT-A` to select all, `ALT-D` to deselect all) | | `:Rg [PATTERN]` | [rg][rg] search result (`ALT-A` to select all, `ALT-D` to deselect all) | +| `:RG [PATTERN]` | [rg][rg] search result; relaunch ripgrep on every keystroke | | `:Lines [QUERY]` | Lines in loaded buffers | | `:BLines [QUERY]` | Lines in the current buffer | | `:Tags [QUERY]` | Tags in the project (`ctags -R`) | @@ -164,15 +165,16 @@ let g:fzf_commands_expect = 'alt-enter,ctrl-x' Each command in fzf.vim is backed by a Vim function. You can override a command or define a variation of it by calling its corresponding function. -| Command | Vim function | -| --- | --- | -| `Files` | `fzf#vim#files(dir, [spec dict], [fullscreen bool])` | -| `GFiles` | `fzf#vim#gitfiles(git_options, [spec dict], [fullscreen bool])` | -| `GFiles?` | `fzf#vim#gitfiles('?', [spec dict], [fullscreen bool])` | -| `Buffers` | `fzf#vim#buffers([spec dict], [fullscreen bool])` | -| `Colors` | `fzf#vim#colors([spec dict], [fullscreen bool])` | -| `Rg` | `fzf#vim#grep(command, [has_column bool], [spec dict], [fullscreen bool])` | -| ... | ... | +| Command | Vim function | +| --- | --- | +| `Files` | `fzf#vim#files(dir, [spec dict], [fullscreen bool])` | +| `GFiles` | `fzf#vim#gitfiles(git_options, [spec dict], [fullscreen bool])` | +| `GFiles?` | `fzf#vim#gitfiles('?', [spec dict], [fullscreen bool])` | +| `Buffers` | `fzf#vim#buffers([spec dict], [fullscreen bool])` | +| `Colors` | `fzf#vim#colors([spec dict], [fullscreen bool])` | +| `Rg` | `fzf#vim#grep(command, [has_column bool], [spec dict], [fullscreen bool])` | +| `RG` | `fzf#vim#grep2(command_prefix, query, [has_column bool], [spec dict], [fullscreen bool])` | +| ... | ... | (We can see that the last two optional arguments of each function are identical. They are directly passed to `fzf#wrap` function. If you haven't @@ -256,22 +258,12 @@ command! -bang -nargs=* GGrep \ fzf#vim#with_preview({'dir': systemlist('git rev-parse --show-toplevel')[0]}), 0) ``` -#### Example: `Rg` command with preview window - -You can see the definition of `Rg` command with `:command Rg`. With the -information, you can redefine it with the preview window enabled. In this -case, we're only interested in setting up the preview window, so we will omit -the spec argument to `fzf#vim#preview`. - -```vim -command! -bang -nargs=* Rg - \ call fzf#vim#grep( - \ 'rg --column --line-number --no-heading --color=always --smart-case -- '.shellescape(), 1, - \ fzf#vim#with_preview(), 0) -``` - #### Example: Advanced ripgrep integration +> The example shown here is now available as the `RG` (all uppercase) command +> that uses `fzf#vim#grep2(command_prefix, query, has_column, ...)` function. +> You no longer need to define it in your Vim configuration file. + In the default implementation of `Rg`, ripgrep process starts only once with the initial query (e.g. `:Rg foo`) and fzf filters the output of the process. diff --git a/autoload/fzf/vim.vim b/autoload/fzf/vim.vim index 6eac698..f65ff18 100755 --- a/autoload/fzf/vim.vim +++ b/autoload/fzf/vim.vim @@ -878,6 +878,35 @@ function! fzf#vim#grep(grep_command, has_column, ...) endtry endfunction + +" command_prefix (string), initial_query (string), has_column (bool), [spec (dict)], [fullscreen (bool)] +function! fzf#vim#grep2(command_prefix, query, has_column, ...) + let words = [] + for word in split(a:command_prefix) + if word !~# '^[a-z]' + break + endif + call add(words, word) + endfor + let words = empty(words) ? ['grep'] : words + let name = join(words, '-') + let opts = { + \ 'source': ':', + \ 'column': a:has_column, + \ 'options': ['--ansi', '--prompt', toupper(name).'> ', '--query', a:query, + \ '--disabled', + \ '--bind', 'start:reload:'.a:command_prefix.' '.shellescape(a:query), + \ '--bind', 'change:reload:'.a:command_prefix.' {q} || :', + \ '--multi', '--bind', 'alt-a:select-all,alt-d:deselect-all', + \ '--delimiter', ':', '--preview-window', '+{2}-/2'] + \} + function! opts.sink(lines) + return s:ag_handler(a:lines, self.column) + endfunction + let opts['sink*'] = remove(opts, 'sink') + return s:fzf(name, opts, a:000) +endfunction + " ------------------------------------------------------------------ " BTags " ------------------------------------------------------------------ diff --git a/doc/fzf-vim.txt b/doc/fzf-vim.txt index 8534e4c..147ce9b 100644 --- a/doc/fzf-vim.txt +++ b/doc/fzf-vim.txt @@ -1,32 +1,31 @@ -fzf-vim.txt fzf-vim Last change: January 27 2023 +fzf-vim.txt fzf-vim Last change: June 4 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| - Example: Rg command with preview window |fzf-vim-example-rg-command-with-preview-window| - Example: Advanced ripgrep integration |fzf-vim-example-advanced-ripgrep-integration| - 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 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| + Example: Advanced ripgrep integration |fzf-vim-example-advanced-ripgrep-integration| + 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* ============================================================================== @@ -108,7 +107,7 @@ so you can omit it if you use a plugin manager that doesn't support hooks. COMMANDS *fzf-vim-commands* ============================================================================== - *:Files* *:GFiles* *:Buffers* *:Colors* *:Ag* *:Rg* *:Lines* *:BLines* *:Tags* *:BTags* *:Marks* +*:Files* *:GFiles* *:Buffers* *:Colors* *:Ag* *:Rg* *:RG* *:Lines* *:BLines* *:Tags* *:BTags* *:Marks* *:Windows* *:Locate* *:History* *:Snippets* *:Commits* *:BCommits* *:Commands* *:Maps* *:Helptags* *:Filetypes* @@ -122,6 +121,7 @@ COMMANDS *fzf-vim-commands* `:Colors` | Color schemes `:Ag [PATTERN]` | {ag}{7} search result ( `ALT-A` to select all, `ALT-D` to deselect all) `:Rg [PATTERN]` | {rg}{8} search result ( `ALT-A` to select all, `ALT-D` to deselect all) + `:RG [PATTERN]` | {rg}{8} search result; relaunch ripgrep on every keystroke `:Lines [QUERY]` | Lines in loaded buffers `:BLines [QUERY]` | Lines in the current buffer `:Tags [QUERY]` | Tags in the project ( `ctags -R` ) @@ -180,6 +180,8 @@ 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: + + *g:fzf_preview_bash* > " This is the default option: " - Preview window on the right with 50% width @@ -235,17 +237,18 @@ Vim functions~ Each command in fzf.vim is backed by a Vim function. You can override a command or define a variation of it by calling its corresponding function. - ----------+--------------------------------------------------------------------------- - Command | Vim function ~ - ----------+--------------------------------------------------------------------------- + ----------+------------------------------------------------------------------------------------------ + Command | Vim function ~ + ----------+------------------------------------------------------------------------------------------ `Files` | `fzf#vim#files(dir, [spec dict], [fullscreen bool])` `GFiles` | `fzf#vim#gitfiles(git_options, [spec dict], [fullscreen bool])` `GFiles?` | `fzf#vim#gitfiles('?', [spec dict], [fullscreen bool])` `Buffers` | `fzf#vim#buffers([spec dict], [fullscreen bool])` `Colors` | `fzf#vim#colors([spec dict], [fullscreen bool])` `Rg` | `fzf#vim#grep(command, [has_column bool], [spec dict], [fullscreen bool])` + `RG` | `fzf#vim#grep2(command_prefix, query, [has_column bool], [spec dict], [fullscreen bool])` ... | ... - ----------+--------------------------------------------------------------------------- + ----------+------------------------------------------------------------------------------------------ (We can see that the last two optional arguments of each function are identical. They are directly passed to `fzf#wrap` function. If you haven't @@ -325,23 +328,13 @@ predefined `Ag` or `Rg` using `fzf#vim#grep`. {12} bin/preview.sh -Example: Rg command with preview window~ - *fzf-vim-example-rg-command-with-preview-window* - -You can see the definition of `Rg` command with `:command Rg`. With the -information, you can redefine it with the preview window enabled. In this -case, we're only interested in setting up the preview window, so we will omit -the spec argument to `fzf#vim#preview`. -> - command! -bang -nargs=* Rg - \ call fzf#vim#grep( - \ 'rg --column --line-number --no-heading --color=always --smart-case -- '.shellescape(), 1, - \ fzf#vim#with_preview(), 0) -< - Example: Advanced ripgrep integration~ *fzf-vim-example-advanced-ripgrep-integration* +The example shown here is now available as the `RG` (all uppercase) command +that uses `fzf#vim#grep2(command_prefix, query, has_column, ...)` function. +You no longer need to define it in your Vim configuration file. + In the default implementation of `Rg`, ripgrep process starts only once with the initial query (e.g. `:Rg foo`) and fzf filters the output of the process. diff --git a/plugin/fzf.vim b/plugin/fzf.vim index 971076e..a39cb03 100644 --- a/plugin/fzf.vim +++ b/plugin/fzf.vim @@ -55,6 +55,7 @@ call s:defs([ \'command! -bang -nargs=+ -complete=dir Locate call fzf#vim#locate(, fzf#vim#with_preview(), 0)', \'command! -bang -nargs=* Ag call fzf#vim#ag(, fzf#vim#with_preview(), 0)', \'command! -bang -nargs=* Rg call fzf#vim#grep("rg --column --line-number --no-heading --color=always --smart-case -- ".shellescape(), 1, fzf#vim#with_preview(), 0)', +\'command! -bang -nargs=* RG call fzf#vim#grep2("rg --column --line-number --no-heading --color=always --smart-case -- ", , 1, fzf#vim#with_preview(), 0)', \'command! -bang -nargs=* Tags call fzf#vim#tags(, fzf#vim#with_preview({ "placeholder": "--tag {2}:{-1}:{3..}" }), 0)', \'command! -bang -nargs=* BTags call fzf#vim#buffer_tags(, fzf#vim#with_preview({ "placeholder": "{2}:{3..}" }), 0)', \'command! -bar -bang Snippets call fzf#vim#snippets(0)',