如何与VIM交互搜索/ grep?


12

有什么方法可以配置VIM以便在每个文件中交互式搜索整个项目?

通过交互式,我的意思是更新每个按键。

类似于Emacs counsel-git-grep,请参见:示例演示


我个人没有使用它,所以我不是100%确定,但是我认为ctrl-p您正在寻找类似的插件。请注意,它unite.vim也应该能够执行此操作,但我不建议这样做,因为在我看来,这是一个非常繁琐且易于创建错误的插件。
statox

是否ctrl-p有办法交互式搜索的文件内容是什么?我只用它来基于文件名交互式搜索文件。
ideaman42 '16

我认为这是可能的,但是正如我所说,我不使用它,所以也许我错了
statox

Answers:


14

我不确定这是您要寻找的东西,但是也许您可以尝试fzffzf.vim

如果您将vim-plug用作插件管理器,则安装它们所需要做的就是在您的中添加以下行vimrc

Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'

...在两行之间的某处:

call plug#begin('~/.vim/plugged')

和:

call plug#end()

然后执行:PlugInstall


在提供的各种命令和映射中fzf.vim(其唯一目的似乎是安装要求fzf通过预定义源进行模糊搜索的映射和命令),其中包含command :Ag

为了能够使用它,您需要安装shell命令ag。在基于debian的发行版中,可以使用以下命令来完成:

apt-get install silversearcher-ag

github上的项目说明了如何在MacOS上安装它:

brew install the_silver_searcher

:Ag是的包装$ ag,可以让您在当前目录(键入时显示的文件)中模糊搜索模式:pwd。每次击键后比赛都会更新。

您可以:

  • 在与C-n和的比赛中前后循环C-p
  • 选择当前的匹配,并移动到下一个/上一个带Tab/S-Tab
  • 使用M-a或选择或取消选择所有匹配项M-d

如果选择一个或多个匹配项,则按Enter键后,它们将填充快速修复列表。从那里,您可以使用默认的Vim命令/映射(例如:cnext和)在它们之间导航:cprevious

在此处输入图片说明

如果您想为所安装的所有命令添加前缀fzf.vim,并避免覆盖现有命令,则可以在vimrc

let g:fzf_command_prefix = 'your_prefix'

我将其Fzf用作前缀,这就是为什么我没有输入:Agbut 的原因:FzfAg


如果您喜欢使用git grep而不是ag,则可以在其周围安装自己的自定义包装:GGrep,如下所示:

command! -bang -nargs=* GGrep
  \ call fzf#vim#grep('git grep --line-number '.shellescape(<q-args>), 0, <bang>0)

在中进行了说明:h fzf-vim-customization

此外,如果fzf打开了TMUX一个窗格,您希望它需要整个屏幕,而不是,您可以附加一个爆炸到所有的命令(:Ag!:GGrep!,...)。


正如您在最后一条评论中所说,默认情况下会fzf更改外壳程序的配置。例如,如果您使用bash,它将在您的中添加以下行~/.bashrc

[ -f ~/.fzf.bash ] && source ~/.fzf.bash

这将获取文件~/.fzf.bash。后者包含一些代码:

# Setup fzf
# ---------
if [[ ! "$PATH" == */home/user/.fzf/bin* ]]; then
  export PATH="$PATH:/home/user/.fzf/bin"
fi

# Auto-completion
# ---------------
[[ $- == *i* ]] && source "/home/user/.fzf/shell/completion.bash" 2> /dev/null

# Key bindings
# ------------
source "/home/user/.fzf/shell/key-bindings.bash"

此代码将路径附加到环境变量$PATH/home/user/.fzf/bin; 这是包含fzf程序的文件夹。

它还提供其他2个文件:

/home/user/.fzf/shell/completion.bash
/home/user/.fzf/shell/key-bindings.bash

第一个似乎定义了完成功能,而第二个安装了键绑定。

不幸的是,按键绑定可能会覆盖默认readline功能。
例如,fzf将函数绑定fzf-file-widgetC-t。readline通常使用此键来执行该transpose-chars功能。

如果您不希望这样做,一种可能的解决方案是~/.bashrcfzf获取其配置的源之后,还原其中的键绑定。例如,如果要C-t保留其旧的行为,即将光标周围的2个字符换行并绑定fzf-file-widget到另一个键,例如C-x C-t,可以在以下行末添加这些行~/.bashrc

bind -x '"\C-x\C-t": fzf-file-widget'
bind '"\C-t": transpose-chars'

同样的道理也适用于zsh外壳,但语法安装一键绑定有一点不同:

bindkey '^X^T' fzf-file-widget
bindkey '^T' transpose-chars

如果您曾经习惯的其中一个外壳键绑定已被覆盖fzf,您想恢复它,但不知道所执行函数的确切名称是什么,则可以尝试以下操作。

首先,在您的内~/.bashrc,暂时注释掉提供fzf配置的行。然后,重新打开一个终端,然后查看bind -P命令的输出,您可以在Vim缓冲区中读取该命令的输出:

bind -P | vim -R -

我不确定,但是我认为它应该显示大多数或所有readline键绑定。如果要查找绑定到C-t键的readline函数的名称,请在Vim缓冲区中搜索\\C-t。如果您要查找的是M-c(meta / alt键)绑定的键,则将进行搜索\\ec\e代表转义键,它似乎M-c产生与相同的键码escape + c)。

您可以zsh通过查看bindkey命令的输出来执行相同的操作。但是这一次,它^[代表meta / alt修饰键,而单个插入号(^)字符代表控制键。


目前,我发现4个键绑定执行fzf了名称中包含关键字的函数。他们使用键序列C-i(与,和相同Tab)。它们绑定到以下功能:C-rC-tM-c

C-i    fzf-completion
C-r    fzf-history-widget
C-t    fzf-file-widget
M-c    fzf-cd-widget

在我的系统上,最初,readline(用于bash编辑命令行的库)将这些键绑定到以下功能:

C-i     complete
C-r     reverse-search-history
C-t     transpose-chars
M-c     capitalize-word

并且zle(由所使用的行编辑器zsh)将它们绑定到:

C-i     expand-or-complete
C-r     history-incremental-search-backward
C-t     transpose-chars
M-c     capitalize-word

1
是否ag需要单独安装插件/工具?
ideaman42 '16

@ ideasman42是的,对此感到抱歉,我忘记了shell命令ag也是必需的。我更新了答案。
user9433424 '16

1
可能值得一提的是,这些工具非常具有侵入性,默认情况下会替换bash和zsh配置。
ideaman42

@ ideasman42是的,我更新了答案以提及此问题。
user9433424
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.