「この休みがあればやりたかった事が何でも出来る!」という根拠の無い万能感を抱き休暇へ突入するも、 大して何もできずに終わるというGW恒例現象へのささやかなる抵抗として、まずはfzfによるCUI生活の改善を。
fzfとripgrepのインストール
fzfをインスト-ル。
brew install fzf
ripgrepをインストール。
brew install ripgrep
fzfはパイプ経由で候補リストが渡されなかった場合、カレントディレクトリ配下のファイル一覧が候補リストとなる。
ファイル一覧の作成にはfindコマンドが使用されるが環境変数 FZF_DEFAULT_COMMAND
を設定することで任意のfind代替コマンドを利用することができる。
今回は$XDG_CONFIG_HOME/fish/conf.d/fzf.fish
を作成、以下のように設定し、
set -x FZF_DEFAULT_COMMAND 'rg --files --hidden --follow --glob "!.git/*"'
- ripgrepを利用
- 隠しファイルも対象
- .git配下を無視
- gitignoreに定義済みの対象を無視
- シンボリックリンクを追う
とした。
fzfコマンドを利用する
ファインダーの操作
fzf
コマンドを実行すると候補リスト選択、絞り込みのためのファインダーが表示される。
ファインダーの操作方法は以下の通り。
CTRL-C CTRL-G ESC のいずれで終了。
CTRL-P CTRL-K のいずれかで上へ移動。
CTRL-J CTRL-N のいずれかで下へ移動。
またfzf -m
で複数選択可能とした場合は、
TAB SHIFT-TAB CTRL-I のいずれかで選択していくことができる。
絞り込み検索
またファインダー上でクエリを入力すると候補リストに対して絞り込み検索が行われる。
クエリとして入力した文字列はあいまい検索となるが、以下の記法によってマッチルールを指定することができる。
- 部分完全一致
例:'<文字列>
先頭にシングルクォートを付加することで部分完全一致となる。
この文字列が含まれるものが絞り込まれる。- 前方完全一致
例:^<文字列>
先頭にハットを付加することで前方完全一致となる。
この文字列から始まるものが絞り込まれる。- 後方完全一致
例:<文字列>$
末尾にドルを付加することで後方完全一致となる。
この文字列で終わるものが絞り込まれる。- 否定
例:!<文字列>
先頭に感嘆符を付与することで否定となる。
デフォルトでは部分完全一致の否定となるが、前方完全一致、後方完全一致と組み合わせて使用することもできる。- AND条件
例: '<文字列A> '<文字列B>
複数の条件を空白区切りで指定した場合、AND条件となる。- OR条件
例: '<文字列A> | '<文字列B>
複数の条件をバーティカルバー区切りで指定した場合、OR条件となる。
tmuxとの統合
tmux環境ではfzfに同梱されているfzf-tmux
コマンドを利用することができる。
fzf-tmux
はtmux環境用のfzfコマンドラッパーでオリジナルのfzfの機能に加えて自動的にファインダー用のペインを作成、確定後に自動的に削除するtmux固有の機能が付加されている。
fishから利用する
fishのfzfプラグインをfisherman経由でインストール。
2018/12/23追記:fisherman organaizationは停止し、それぞれのリポジトリで活動を継続することになった模様。
I will dissolve the organization! #446
-
fisherman 改めfisher
https://github.com/jorgebucaran/fisher -
jethrokuan氏のfish fzfプラグイン
https://github.com/jethrokuan/fzf
fisher add jethrokuan/fzf
キーバインド
fzfプラグインは新旧二種類のキーバインドがあり、環境変数FZF_LEGACY_KEYBINDINGS
に0を指定することで新キーバインドが有効となる。
今回は新キーバインドを利用するため$XDG_CONFIG_HOME/fish/conf.d/fzf.fish
に追記する。
set -x FZF_DEFAULT_COMMAND 'rg --files --hidden --follow --glob "!.git/*"'
set -x FZF_LEGACY_KEYBINDINGS 0
また新キーバインドではファイル検索が CTRL-F となっており、自環境ではfishのオートサジェスチョンの受け入れキーマッピングと衝突するため、 サジェスチョンの受け入れキーを CTRL-E へ移動した。
$XDG_CONFIG_HOME/fish/functions/fish_user_key_bindings.fish
function fish_user_key_bindings
for mode in insert default visual
fish_default_key_bindings -M $mode
end
fish_vi_key_bindings --no-erase
bind -M insert -e \ce
bind -M visual -e \ce
bind -M default -e \ce
bind -M insert -e \cf
bind -M insert \ce accept-autosuggestion
### fzf ###
set -q FZF_LEGACY_KEYBINDINGS
or set -l FZF_LEGACY_KEYBINDINGS 1
if test "$FZF_LEGACY_KEYBINDINGS" -eq 1
bind \ct '__fzf_find_file'
bind \cr '__fzf_reverse_isearch'
bind \cx '__fzf_find_and_execute'
bind \ec '__fzf_cd'
bind \eC '__fzf_cd_with_hidden'
if bind -M insert >/dev/null ^/dev/null
bind -M insert \ct '__fzf_find_file'
bind -M insert \cr '__fzf_reverse_isearch'
bind -M insert \cx '__fzf_find_and_execute'
bind -M insert \ec '__fzf_cd'
bind -M insert \eC '__fzf_cd_with_hidden'
end
else
bind \cf '__fzf_find_file'
bind \cr '__fzf_reverse_isearch'
bind \ex '__fzf_find_and_execute'
bind \ed '__fzf_cd'
bind \eD '__fzf_cd_with_hidden'
if bind -M insert >/dev/null ^/dev/null
bind -M insert \cf '__fzf_find_file'
bind -M insert \cr '__fzf_reverse_isearch'
bind -M insert \ex '__fzf_find_and_execute'
bind -M insert \ed '__fzf_cd'
bind -M insert \eD '__fzf_cd_with_hidden'
end
end
### fzf ###
end
ripgrepを利用する
先ほどの環境変数FZF_DEFAULT_COMMAND
の定義によりパイプなしでfzfコマンドを実行した場合ripgrepによるファイル検索が行われるようになっているが、
fishのfzfプラグイン経由でfzfコマンドを実行した場合は常にパイプ経由での利用となり、ファイル検索時はfzfプラグインが自前でfindコマンドを発行し結果をパイプで渡しているため
ripgrepが利用されない。
このためFZF_DEFAULT_COMMAND
とは別にfishのfzfプラグインが利用するfind代替コマンドを指定するための環境変数FZF_FIND_FILE_COMMAND
を定義し
fzfプラグインからもripgrepが使われるようにする。
$XDG_CONFIG_HOME/fish/conf.d/fzf.fish
に追記。
set -x FZF_DEFAULT_COMMAND 'rg --files --hidden --follow --glob "!.git/*"'
set -x FZF_LEGACY_KEYBINDINGS 0
set -x FZF_FIND_FILE_COMMAND $FZF_DEFAULT_COMMAND
入力中のコマンドラインにファイル名を展開する
fishのコマンドライン入力中に CTRL-F でカレントディレクトリ配下のファイル一覧がファインダー表示。
確定後、入力中のコマンドラインのカーソル位置にファイル名が展開される。
コマンド履歴の呼び出し
fishのコマンドライン入力中に CTRL-R でコマンド履歴がファインダー表示。
既にコマンドラインに入力中の文字列がある場合は、その文字列がクエリとなる。
vimから利用する
vim用fzfプラグインfzf.vimを利用する。
今回はneovim & vim-plug の構成で利用。
プラグイン追加
今回fzf本体はHomebrew経由でインストールしているため、init.vim
へのプラグイン定義は以下のようにする。
Plug '/usr/local/opt/fzf'
Plug 'junegunn/fzf.vim'
fzf用キーマップの追加
多用しそうな機能へのキーマップ定義をinit.vim
へ追加する。
let g:mapleader=' '
...
nnoremap [Fzf] <Nop>
nmap <Leader>f [Fzf]
nnoremap [Fzf]f :<C-u>Files<CR>
nnoremap [Fzf]g :<C-u>GFiles<CR>
nnoremap [Fzf]G :<C-u>GFiles?<CR>
nnoremap [Fzf]b :<C-u>Buffers<CR>
vimからファイルを開く
Leader f f でカンレントディレクトリ配下のファイル一覧が候補となる。
絞り込み方はfzf単体で利用する場合とまったく同じだが絞り込み後のアクションをいくつか選択できる。
- タブで開く
- CTRL-T でタブを開く。 単純に ENTER の場合も同じ。
- 水平画面分割で開く
- CTRL-X で水平画面分割で開く。
- 垂直画面分割で開く
- CTRL-V で垂直画面分割で開く。
vimからgit管理のファイルを開く
Leader f g でgitリポジトリ内のファイル一覧が候補となる。
vimからgit管理の変更のあったファイルを開く
Leader f G でgitリポジトリ内の変更のあったファイル一覧が候補となる。
ファインダーでは一覧の他にファイルの差分情報がプレビューされる。
vimからバッファを選択する
Leader f b でvimのバッファ一覧が候補となる。