资讯专栏INFORMATION COLUMN

模糊搜索神器fzf

miqt / 2660人阅读

摘要:让你通过输入模糊的关键词就可以定位文件或文件夹。当你的思维也习惯了模糊匹配后,在工作中可以大幅提高你的工作效率。模糊搜索的概念如下,你记得文件名含有,那么你只需要把所有文件送给然后在窗口里输入就可以了,不管实现名是还是都会匹配上。

前言

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

安装

使用git

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
升级
cd ~/.fzf && git pull && ./install
原生使用

fzf默认会从STDIN读入数据,然后将结果输出到STDOUT

find * -type f | fzf > selected

上面命令从find的搜索结果中读入,输出到文件selected中

fzf里的快捷键

在finder(输出交换窗口)里,

Ctrl-J/Ctrl-K/Ctrl-N/Ctrlk-N可以用来将光标上下移动

Enter键用来选中条目, Ctrl-C/Ctrl-G/Esc用来退出

在多选模式下(-m), TAB和Shift-TAB用来多选

Mouse: 上下滚动, 选中, 双击; Shift-click或shift-scoll用于多选模式

布局

fzf默认全屏模式,你可以定制高度

vim $(fzf --height 40%)

你可以通过$FZF_DEFAULT_OPTS来设定默认值

export FZF_DEFAULT_OPTS="--height 40% --reverse --border"
搜索语法

fzf默认会以“extened-search"模式启动, 这种模式下你可以输入多个以空格分隔的搜索关键词, 如^music .mp3$, sbtrkt !fire.

Token Match type Description
sbtrkt fuzzy-match 匹配sbtrkt
^music prefix-exact-match 以music开头
.mp3$ suffix-exact-match 以.mp3结尾
"wild exact-match(quoted) 精确包含wild
!fire inverse-exact-match 不包含fire
!.mp3$ inverse-suffix-exact-match 不以.mp3结尾

如果你不想用fuzzy match, 可以用fzf -e做精确匹配
|可以做or匹配, 比如

^core go$|rb$|py$

表示以core开头,以go或rb或py结尾的

环境变量

FZF_DEFAULT_ COMMAND

设定默认输入

比如`export FZF_DEFAULT_ COMMAND="ag -g """

FZF_DEFAULT_OPTS

设定默认选项

比如`export FZF_DEFAULT_OPTS="--reverse --inline-info"

命令行下的快捷键 CTRL-T

在命令行下按下ctrl-t会打开fzf窗口,如果你选中某个条目并按下Enter, 选中的条目会被拷贝到命令行上
如果想同时预览文件内容,可以使用--preview选项

export FZF_CTRL_T_OPTS="--preview "(highlight -O ansi -l {} 2> /dev/null || cat {} || tree -C {}) 2> /dev/null | head -200""

也可以用--select-1--exit-0
前者是如果只有一个条目,那么自动选中并退出fzf
后者是如果条目为空,自动退出
上面两个选项对ALT-C也有用

CTRL-R

在命令行下按下ctrl-r, fzf会列出history命令,选中条目并离开fzf的话, 选中条目会被拷到命令行上
在zsh下可以使用下面的方法来按下C-XC-R来直接执行

fzf-history-widget-accept() {
  fzf-history-widget
  zle accept-line
}
zle    -N    fzf-history-widget-accept
bindkey "^X^R" fzf-history-widget-accept
ALT-C

在命令行上按下alt-c, 会列出当前文件夹下的目录,选中条目会自动进入到相应目录

命令行下的模糊完成

默认可以通过**来触发文件或目录的自动完成

COMMAND [DIRECTORY/][FUZZY_PATTERN]**

比如

vim **
vim ../mult**
cd ~/github/fzf**
预览窗口

如果使用--preview选项, fzf会自动用外部程序打开现在条目的文件, {}会被fzf选中行内容代替

fzf --preview "cat {}"

建议安装rougify(先安装ruby, 然后gem intall rouge)
然后在.zshrc里用函数或别名

fzfp() {
fzf --preview "[[ $(file --mime {}) =~ binary ]] && echo {} is a binary file || (rougify {}  || highlight -O ansi -l {} || coderay {} || cat {}) 2> /dev/null | head -500"
alias tt="fzf --preview """""[[ $(file --mime {}) =~ binary ]] && echo {} is a binary file || (rougify {}  || highlight -O ansi -l {} || coderay {} || cat {}) 2> /dev/null | head -500""""

函数是更好的方式, 用alias的话,为了绕开"的问题,需要用一个双引号加一个间引号再加一个双引号才能生成一个单引号

上图左侧是文件列表,右侧是rougify生成的预览窗口,可以用鼠标上下滚动,遗憾的是用键盘没法移动光标到右侧窗口进行上下滚动。

fzf示例 interactive cd

安装

wget https://github.com/changyuheng/zsh-interactive-cd/blob/master/zsh-interactive-cd.plugin.zsh
cp zsh-interactive-cd.plugin.zsh ~/.fzf/shell
echo "source ~/.fzf/shell/zsh-interactive-cd.plugin.zsh" >> ~/.zshrc

cd后按ctrl-i就会打开fzf finder窗口

z
# fasd & fzf change directory - jump using `fasd` if given argument, filter output of `fasd` using `fzf` else
z() {
    [ $# -gt 0 ] && fasd_cd -d "$*" && return
    local dir
    dir="$(fasd -Rdl "$1" | fzf -1 -0 --no-sort +m)" && cd "${dir}" || return 1
}
changing directory
# fd - cd to selected directory
fd() {
  local dir
  dir=$(find ${1:-.} -path "*/.*" -prune 
                  -o -type d -print 2> /dev/null | fzf +m) &&
  cd "$dir"
}
# fda - including hidden directories
fda() {
  local dir
  dir=$(find ${1:-.} -type d 2> /dev/null | fzf +m) && cd "$dir"
}
# fdr - cd to selected parent directory
fdr() {
  local declare dirs=()
  get_parent_dirs() {
    if [[ -d "${1}" ]]; then dirs+=("$1"); else return; fi
    if [[ "${1}" == "/" ]]; then
      for _dir in "${dirs[@]}"; do echo $_dir; done
    else
      get_parent_dirs $(dirname "$1")
    fi
  }
  local DIR=$(get_parent_dirs $(realpath "${1:-$PWD}") | fzf-tmux --tac)
  cd "$DIR"
}
# cf - fuzzy cd from anywhere
# ex: cf word1 word2 ... (even part of a file name)
# zsh autoload function
cf() {
  local file

  file="$(locate -Ai -0 $@ | grep -z -vE "~$" | fzf --read0 -0 -1)"

  if [[ -n $file ]]
  then
    if [[ -d $file ]]
    then
        cd -- $file
    else
        cd -- ${file:h}
    fi
  fi
}
v
# fasd & fzf change directory - open best matched file using `fasd` if given argument, filter output of `fasd` using `fzf` else
v() {
    [ $# -gt 0 ] && fasd -f -e ${EDITOR} "$*" && return
    local file
    file="$(fasd -Rfl "$1" | fzf -1 -0 --no-sort +m)" && vi "${file}" || return 1
}
fzf的vim插件

在.vimrc里用vunble安装

set rtp+=/home/harriszh/.fzf/
...
Plugin "junegunn/fzf.vim"
...

然后FZF等命令就可以使用了
建议要安装ag,并把FZF_DEFAULT_COMMAND改成ag

更多信息

如果对FZF和vim和结合感兴趣可以看: VIM与模糊搜索神器FZF的集成用法 - 从简单到高级
如果对FZF和各种工具的配合使用请看: 模糊搜索神器FZF番外篇

后言

fzf是非常强大的胶水工具,利用它和ag, fasd及shell command可以实现非常绚烂的功能。更多例子见wiki
如果上文有错误的地方,欢迎联系作者

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

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

相关文章

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

    摘要:比如下表是它可用的所有选项是一个函数,用来创建自己的自动补全功能。如果第一个参数是一个命令字符或一个那么它会被用作对于高级用户,可以传入一个字典选项。希望大家可以结合创造出更多的使用方法。 FZF and VIM 前言 fzf本身并不是一个vim 插件,本来作者只提供了基本的wrapper函数(比如fzf#run). 但后来作者发现很多人并不熟悉VIMScript, 所以就创建一个默认...

    ?xiaoxiao, 评论0 收藏0
  • Vim模糊文件搜索fzf

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

    lavor 评论0 收藏0

发表评论

0条评论

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