この記事は Vim Advent Calendar 2018 その2 12日目の記事です。
その2と名のつく通りこのアドベントカレンダーの表にはその1があり、そちらでは @deresmosさんが記事を書いていらっしゃると思います。
先日11日目の記事は @yasuo-ozuさんによる [VIM] まだインデントで消耗してるの? 〜スペースインデントでもタブインデントでもない新しいインデント手法〜 - Qiitaです。
Vimその1の記事は@aiya000さんによるfキーをnoremap可能にするfmap.vim - Qiitaです。
概要
最近fzfを使うようになって.vimrcの設定をいじり始めたのですが、fzf.vimからghqのコマンドを叩くスクリプトの参考例を探してみていて意外とありませんでした。
ちょうどいいブログ記事のネタになりそうだと思いましたので、fzfを使ったvimのコマンドを作成する例を紹介します。
fzf.vimについては他にも先行するまとまった記事がありますので、本記事では実際にコマンドを書くところを中心にやってみたいと思います。
fzf
fzfはfuzzy検索が可能なgolang製のコマンドラインツールです。
類似ツールではpeco, percolといったものがあります。
vimとの連携が可能で一旦インストールしておけばvimでもすぐ使えるようになります。
dein.vimでプラグインを管理しているのであれば、
call dein#add('junegunn/fzf',{'build':'./install --all','merged':0})call dein#add('junegunn/fzf.vim',{'depends':'fzf'})
のように書くと実行することができます。
fzf.vim
fzf.vimはVimscriptにあまり慣れていない人でもすぐ使えるようにfzfを使ったコマンドのプリセットを一揃い提供するプラグインです。
汎用的なCommand名が着くのが嫌う場合は、g:fzf_command_prefix
を設定することでprefixを設定できます。
例: let g:fzf_command_prefix = 'Fzf'
と設定すると :Files
のコマンド名が :FzfFiles
になる
Vimscriptのチュートリアル
Examples (vim) · junegunn/fzf Wiki
公式wikiにあるチュートリアルを一部紹介します。
fzfのVim連携は fzf#run
関数が中核となります。この関数はディクショナリ型の単一の引数をとります。ここでは少なくとも sink
オプションを指示する必要があります。
:call fzf#run({'sink':'e'})
この引数に source
オプションがない場合、カレントディレクトリにあるファイルを一覧するのにfindコマンドを使います。
一覧の中からひとつファイルを選択するとそのファイルをsinkで指定した :e
を使って開きます。
findコマンドを使う代わりに、source
を指示することで任意のシェルコマンドを実行することができます。
記事の例はgit管理下にあるファイル一覧を表示することです:
call fzf#run({'source':'git ls-files','sink':'e'})
なお、この操作はfzf.vimでは:GFiles
としてプリセットされています。
他にもオプションは多くあって、tmuxと連携してウインドウを分割して右ペインに一覧を表示するだとか、選択をひとつではなく二個以上選択するなど色々できます。
興味があればチュートリアルの方にまとまっていますのでご参照ください。
ghqの一覧をとって任意のリポジトリディレクトリにcdする
さて、上記の内容からコマンドを自作してみます。
* 単純に一覧のタネとなるsourceに ghq list
を、sinkにcdを指定します。
call fzf#run(fzf#wrap({'source':'ghq list --full-path','sink':'cd'}))
今回は :Fq<CR>
で実行できるようにしたいため、以下のように書くと完成です。
command!-nargs=0 Fq call fzf#run({\'source':'ghq list --full-path',\'sink':'cd'\})
これで、動くようになりました。
その他参考記事
この記事には直接関係しませんが、fzf.vimに関する記事を探した際に見かけたサイトをリンクします。
終わり
以上、fzfを利用して ghq list
の中から選択するコマンドの書き方を紹介しました。
明日の記事の担当は、 Vimその2 @chesscommandsさん、その1 @daisuzuさんです。