资讯专栏INFORMATION COLUMN

VIM与模糊搜索神器FZF的集成用法 - 从简单到高级

?xiaoxiao, / 2340人阅读

摘要:比如下表是它可用的所有选项是一个函数,用来创建自己的自动补全功能。如果第一个参数是一个命令字符或一个那么它会被用作对于高级用户,可以传入一个字典选项。希望大家可以结合创造出更多的使用方法。

FZF and VIM 前言

fzf本身并不是一个vim 插件,本来作者只提供了基本的wrapper函数(比如fzf#run). 但后来作者发现很多人并不熟悉VIMScript, 所以就创建一个默认的vim plugin.

为什么在VIM里用fzf?

fzf可以异步地运行,不影响vim操作,比同类的其他插件都快得多。

如何安装

有两种安装方式vundle或vim-plug

vundle
set rtp+=/home/harriszh/.fzf/
...
Plugin "junegunn/fzf.vim"
vim-plug
Plug "/usr/local/opt/fzf"
Plug "junegunn/fzf.vim"

如果你希望通过vim-plug来安装fzf, 那么使用下面设置

Plug "junegunn/fzf", { "dir": "~/.fzf", "do": "./install --all" }
Plug "junegunn/fzf.vim"
vim下支持的命令

这些命令都是FZF调用某个工具产生文件,文件内容, tag, comment, command,然后FZF用一个小窗口把它们显示出来,用户就可以用模糊搜索的方式来选择一个或多个选项,按下enter键后就可以用VIM打开它们或跳转到相应的行。
如Files针对的就是文件, GFiles针对的就是git文件

Command List
Files [PATH] 普通文件查找 (similar to :FZF)
GFiles [OPTS] git文件查找 (git ls-files)
GFiles? git文件查找 (git status)
Buffers buffer文件切换
Colors Color schemes
Ag [PATTERN] ag search result (ALT-A to select all, ALT-D to deselect all)
Lines [QUERY] 加载的所有buffer里查找
BLines [QUERY] 在当前buffer里查找包含某关键词的行
Tags [QUERY] 以Tag查找 (ctags -R)
BTags [QUERY] Tags in the current buffer
Marks Marks
Windows Windows
Locate PATTERN locate command output
History v:oldfiles and open buffers
History: 命令历史查找
History/ Search history
Snippets Snippets (UltiSnips)
Commits Git commits (requires fugitive.vim)
BCommits Git commits for the current buffer
Commands Commands
Maps Normal mode mappings
Helptags Help tags 1
Filetypes File types
例子

FilesFZF一样的作用,它会列出所有文件,选中后vim会打开选中的文件

Buffers用于在存在于buffer中的文件间切换

Lines 用于在存在于buffer里的文件中寻找含有某个关键词的行

BLines Lines类似,只不过它只在当前buffer里查找

因为ripgrep是目前性能最好的文本内容搜索工具,所以我们可以自己定义一个命令

command! -bang -nargs=* Rg
   call fzf#vim#grep(
     "rg --column --line-number --no-heading --color=always --smart-case ".shellescape(), 1,
     0 ? fzf#vim#with_preview("up:60%")
             : fzf#vim#with_preview("right:50%:hidden", "?"),
     0)

这样输入:Rg 会调用ripgrep来递归搜索当前目录

定制化 按键绑定

上面的命令都可以通过ctrl-t, ctrl-x, ctrl-v来在new tab, new split, new vsplit窗口打开

" This is the default extra key bindings
let g:fzf_action = {
   "ctrl-t": "tab split",
   "ctrl-x": "split",
   "ctrl-v": "vsplit" }

" Default fzf layout
" - down / up / left / right
let g:fzf_layout = { "down": "~40%" }

" In Neovim, you can set up fzf window using a Vim command
let g:fzf_layout = { "window": "enew" }
let g:fzf_layout = { "window": "-tabnew" }
let g:fzf_layout = { "window": "10split enew" }

" Customize fzf colors to match your color scheme
let g:fzf_colors =
 { "fg":      ["fg", "Normal"],
   "bg":      ["bg", "Normal"],
   "hl":      ["fg", "Comment"],
   "fg+":     ["fg", "CursorLine", "CursorColumn", "Normal"],
   "bg+":     ["bg", "CursorLine", "CursorColumn"],
   "hl+":     ["fg", "Statement"],
   "info":    ["fg", "PreProc"],
   "border":  ["fg", "Ignore"],
   "prompt":  ["fg", "Conditional"],
   "pointer": ["fg", "Exception"],
   "marker":  ["fg", "Keyword"],
   "spinner": ["fg", "Label"],
   "header":  ["fg", "Comment"] }

" Enable per-command history.
" CTRL-N and CTRL-P will be automatically bound to next-history and
" previous-history instead of down and up. If you don"t like the change,
" explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS.

let g:fzf_history_dir = "~/.local/share/fzf-history"
本地设定
" [Buffers] 如果可能跳到已存在窗口
let g:fzf_buffers_jump = 1

" [[B]Commits] 自定义被"git log"使用的选项
let g:fzf_commits_log_options = "--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr""

" [Tags] 定义用来产生tag的命令
let g:fzf_tags_command = "ctags -R"

" [Commands] --expect expression for directly executing the command
let g:fzf_commands_expect = "alt-enter,ctrl-x"
高级定制

也可以使用autoload函数来定义自己的命令

" Command for git grep
" - fzf#vim#grep(command, with_column, [options], [fullscreen])
command! -bang -nargs=* GGrep
   call fzf#vim#grep(
     "git grep --line-number ".shellescape(), 0,
     { "dir": systemlist("git rev-parse --show-toplevel")[0] }, 0)

" Override Colors command. You can safely do this in your .vimrc as fzf.vim
" will not override existing commands.
command! -bang Colors
   call fzf#vim#colors({"left": "15%", "options": "--reverse --margin 30%,0"}, 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(,
                   0 ? fzf#vim#with_preview("up:60%")
                           : fzf#vim#with_preview("right:50%:hidden", "?"),
                   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 --smart-case ".shellescape(), 1,
     0 ? fzf#vim#with_preview("up:60%")
             : fzf#vim#with_preview("right:50%:hidden", "?"),
     0)

" Likewise, Files command with preview window
command! -bang -nargs=? -complete=dir Files
   call fzf#vim#files(, fzf#vim#with_preview(), 0)
映射
Mapping Description
(fzf-maps-n) Normal mode mappings
(fzf-maps-i) Insert mode mappings
(fzf-maps-x) Visual mode mappings
(fzf-maps-o) Operator-pending mappings
(fzf-complete-word) cat /usr/share/dict/words
(fzf-complete-path) Path completion using find (file + dir)
(fzf-complete-file) File completion using find
(fzf-complete-file-ag) File completion using ag
(fzf-complete-line) Line completion (all open buffers)
(fzf-complete-buffer-line) Line completion (current buffer only)
映射用法
" Mapping selecting mappings
nmap  (fzf-maps-n)
xmap  (fzf-maps-x)
omap  (fzf-maps-o)

" Insert mode completion
imap  (fzf-complete-word)
imap  (fzf-complete-path)
imap  (fzf-complete-file-ag)
imap  (fzf-complete-line)

" Advanced customization using autoload functions
inoremap   fzf#vim#complete#word({"left": "15%"})
创建自己的插件

fzf#run()是vim集成的核心函数,它接受一个字典变量作为输入, 你至少要通过sink选项来告诉fzf如何处理选中的条目。
比如:

call fzf#run({"sink": "tabedit", "options": "--multi --reverse"})

call fzf#run({"source": "git ls-files", "sink": "e", "right": "40%"})

call fzf#run({"source": map(split(globpath(&rtp, "colors/*.vim")),
                           "fnamemodify(v:val, ":t:r")"),
             "sink": "colo", "left": "25%"})

下表是它可用的所有选项

Option name Type Description
source string External command to generate input to fzf (e.g. find .)
source list Vim list as input to fzf
sink string Vim command to handle the selected item (e.g. e, tabe)
sink funcref Reference to function to process each selected item
sink* funcref Similar to sink, but takes the list of output lines at once
options string Options to fzf
dir string Working directory
up/down/left/right number/string Use tmux pane with the given size (e.g. 20, 50%)
window (Neovim only) string Command to open fzf window (e.g. vertical aboveleft 30new)
launcher string External terminal emulator to start fzf with (GVim only)
launcher funcref Function for generating launcher string (GVim only)
completion helper

fzf#vim#complete是一个helper函数,用来创建自己的自动补全功能。 如果第一个参数是一个命令字符或一个vim list, 那么它会被用作source.

" Replace the default dictionary completion with fzf-based fuzzy completion
inoremap   fzf#vim#complete("cat /usr/share/dict/words")

对于高级用户,可以传入一个字典选项。它的选项和fzf#run是一致的,除了下面几个选项。

reducer (funcref)

把fzf的输出转成单一字符串

prefix (funcref or string; default: k*$)

用于匹配想自动补全字符串的正则表达式

或者是一个函数

sourceoptions可以是一个函数引用, 它用prefix作为输入参数,返回最终的值

sinksink*被忽略

" 全局补全 (不仅仅是buffers. 需要安装ripgrep)
inoremap   fzf#vim#complete(fzf#wrap({
   "prefix": "^.*$",
   "source": "rg -n ^ --color always",
   "options": "--ansi --delimiter : --nth 3..",
   "reducer": { lines -> join(split(lines[0], ":zs")[2:], "") }}))

Reducer例子:

function! s:make_sentence(lines)
return substitute(join(a:lines), "^.", "=toupper(submatch(0))", "")."."
endfunction

inoremap   fzf#vim#complete({
 "source":  "cat /usr/share/dict/words",
 "reducer": function("make_sentence"),
 "options": "--multi --reverse --margin 15%,0",
 "left":    20})
总结

结合FZF,vim可实现快速文件跳转,特别是在结合Rg或ctags或git以后,可以快速地跳转到满足某种条件的文件中。
希望大家可以结合FZF创造出更多的使用方法。有任何好点子,欢迎联系本人

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/25042.html

相关文章

  • 模糊搜索神器fzf

    摘要:让你通过输入模糊的关键词就可以定位文件或文件夹。当你的思维也习惯了模糊匹配后,在工作中可以大幅提高你的工作效率。模糊搜索的概念如下,你记得文件名含有,那么你只需要把所有文件送给然后在窗口里输入就可以了,不管实现名是还是都会匹配上。 前言 fzf是目前最快的fuzzy finder。使用golang编写。结合其他工具(比如ag和fasd)可以完成非常多的工作。让你通过输入模糊的关键词就可...

    miqt 评论0 收藏0
  • Vim模糊文件搜索fzf

    摘要:参考官网参考使用全指南安装直接在插件管理器中其中会把命令行软件安装到本机的目录中,然后在中就可以直接通过执行来使用命令搜索文件了。使用最简单的话,直接在中输入命令就会弹出当前目录下的所有文件列表,然后可以各种模糊搜索,按和上下选择。 不同于Command-T只能用于VIM,大名鼎鼎的fzf是命令行工具,而且只在VIM中使用的话也不需要手动去编译任何依赖,直接用插件管理器安装即可立马使用...

    lavor 评论0 收藏0

发表评论

0条评论

?xiaoxiao,

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<