🐱

vfiler.vim ファイラープラグインの紹介

2022/03/30に公開

はじめに

vfiler.vim という、Vim/Neovim 用のファイラープラグインを紹介いたします。
https://github.com/obaland/vfiler.vim
vfiler-demo

この記事では、プラグイン作成の背景や特徴を通じて、作者の考えが少しでもお伝えできればと思います。
拙文ではありますが、お付き合いいただけると幸いです。

背景

プラグイン作成に至った背景を、作者のエディター遍歴にも少し触れながら説明します。

xyzzy エディター

作者が、いわゆるテキストエディターとして初めて触ったのが xyzzy です。
xyzzy は、Windows で動作する Emacs ライクのテキストエディターで、Common Lisp によるカスタマイズが可能な、知る人ぞ知るエディターです。
https://github.com/xyzzy-022/xyzzy
比較的軽量でカスタマイズ性も十分な、とても良いエディターです。特にエディター上から起動できる、2画面ファイラーがシンプル且つ強力なのでとても重宝しておりました。

xyzzy
xyzzy の2画面ファイラー

Vim への移行

しばらく xyzzy でプログラミングをしておりましたが、作業環境が Windows に限らなくなってきたこともあり、本家 Emacs エディターへの移行を考えておりました。
しかしながら、ファイラーがしっくりこないのと、なんか「もっさり」している感じがしたので、悶々とした日々を過ごしておりました。
ある日、友人がテキパキ使いこなしている Vim をみた時に「なんか軽そうだし、慣れれば使いやすそうだな・・・」と感じました。残りの課題はファイラーでしたが、丁度 Shougo さんが公開している vimfiler.vim を見つけて「これでいけそうだぞ」となって、Vim への移行を決めました。
https://github.com/Shougo/vimfiler.vim

自分が求めるファイラーを実現する

vimfiler.vim はキーバインドも自然で、何より2画面ファイラー機能を搭載していたので、基本的には満足していたのですが、他のプラグインに依存している点と、少々動作が重いときがあることが気になり始めます。
解決する手段は色々あったと思いますが、当時は Vim 知識を深めるために Vim script にも多少興味が出始めていたこともあったので、勉強を兼ねて「ファイラープラグインを作ってみよう」ということにしました。

vfiler.vim の経歴

ファイラーを作る決心をしてから、自分勝手に紆余曲折しながらバージョンを重ねてきました。現在に至るまでの経歴を簡単ですが記します。

ver.1.0.0

ファイラーとして(自分にとって)必要な機能が揃い、問題なく実用にも耐えられる状態になったので、満を持して公開しました。

ver.2.0.0

それまで vfiler.vim は、Vim script で実装してきました。
ver.1.0.0 公開時点で、すでに巷では Neovim の RPC を活用したプラグインが出始めました。非同期処理の実現や、何より言語としての処理速度の問題を解消する手段として、とても魅力的に見えました。
RPC を駆使して Python 等で書き直してみようかと検討や実験を繰り返しましたが、以下の理由で断念しました。

  1. (あたりまえですが)プラグイン実行に、その言語の実行環境が必要になる
  2. Nevim と Vim を同じコードで実装するには、Vim 側の実装がかなり面倒くさい
  3. ファイラープラグインとしては、処理速度面で上記の手間に見合う恩恵が少ない

しかしながら、Neovim で Lua がビルドインで動作することに注目しました。
環境が許せば Vim でも動作しますし[1]、処理速度も対 Vim script でかなり有利であることから、Lua をベースに再実装しました。これにより処理速度の面でより快適になりました。
また、併せてオプション等を含めて全体的に設計も見直し、より拡張性を意識したものになっています。

ver.2.5.3 (2022年3月時点)

ver.2.0.0 から

  • プレビューの対応
  • フローティング起動の対応
  • 速度改善
  • バグ修正

を経て、安定動作しております。
途中、Neovim 側だけでも、vim.loop (LibUV API) の非同期処理を駆使した速度改善を試みました。非同期実装にありがちなことですが、やはりオーバーヘッドを含めると、総合的にはむしろ処理速度としての効果は薄く、使う側の快適性が損なわれる可能性があったため止めました。

vfiler.vim について

前置きが長くなりましたが、vfiler.vim について説明していきます。

コンセプト

vfiler.vim に限ったことではありませんが、コンセプトというか大事にしていることは、以下の3点です。

  1. 他プラグインには依存しない
  2. Vim、Neovim の両方で動作する
  3. 軽快に動作する

vfiler.vim の特徴

主な基本機能

  • ツリー表示
  • ファイルオープン (edit, split, vsplit, tab)
  • ソート (名前、ファイル日付、更新日付、拡張子)
  • ファイル内容のプレビュー
  • 隠しファイルの表示切替
  • ディレクトリジャンプ (ルートディレクトリ, ホームディレクトリ, 任意のディレクトリ)
  • パスコピー
  • ブックマーク

ファイル操作機能

  • 新規作成
  • 削除
  • コピー
  • 移動
  • リネーム
  • 一括リネーム

後述の2画面ファイラー上だと、ファイラー間でコピーや移動を便利に行うことができます。
(そうでない場合は、クリップボードを介した挙動になります。)

2画面ファイラー

自分が外せないと思っている機能の一つです。
この機能があることで、基本的なファイル操作のほとんどをエディタ上で快適に行うことができ(ると思って)ます。

2つのディレクトリ構成を比較しながら、ファイルのコピーや移動を行うことができます。
vfiler-multiple-windows

様々な起動方法

vfiler.vimウィンドウスタイルがデフォルトではありますが、IDE のような使い方をしたい場合はエクスプローラースタイルで、編集中にワンポイントで起動したい場合は、フローティングスタイルで、といった、利用シーンに合わせて起動方法を変えることが可能です。
但し、フローティングスタイルは Neovim のみの対応となります。

vfiler-window
ウィンドウスタイル

vfiler-explorer
エクスプローラースタイル

vfiler-floating
フローティングスタイル (Neovim のみ)

多様なカスタマイズ

vfiler.vim は多様なカスタマイズが可能です。
前述の起動方法を始め、キーバインド変更や再設定、表示カラムの変更、細かな挙動の変更を自分好みにカスタマイズすることが可能です。
※詳しくはドキュメントをご覧ください。

vfiler-customize
例:エクスプローラースタイルで、表示するカラムを必要最小限に設定

デフォルトの設定値を変更することも勿論できますが、起動コマンドのオプションで指定することもできるので、ケースバイケースで切り替えることができます。

作者の使い方としては、毎度のオプション指定はさすがに億劫なので、キーに割り当てて使っています。

使用例
function! s:start_exprolorer() abort
" エクスプローラースタイルで起動する
" ※起動時に指定したオプションはデフォルトオプションよりも優先されて起動する
lua <<EOF

local configs = {
  options = {
    auto_cd = true,
    auto_resize = true,
    keep = true,
    name = 'exp',
    layout = 'left',
    width = 36,
    columns = 'indent,devicons,name,git',
    git = {
      enabled = true,
      untracked = true,
      ignored = true,
    },
  },
}

-- 現在開いているファイルのディレクトリを取得する
local path = vim.fn.bufname(vim.fn.bufnr())
if vim.fn.isdirectory(path) ~= 1 then
  path = vim.fn.getcwd()
end
path = vim.fn.fnamemodify(path, ':p:h')

-- Lua 関数による起動
require'vfiler'.start(path, configs)

EOF
endfunction

" エクスプローラースタイルで起動 (関数による起動)
noremap <silent><Leader>e :call <SID>start_exprolorer()<CR>

" フローティングスタイルで起動 (VFiler コマンドからオプション指定で起動)
" ※フローティングスタイルの指定以外は、デフォルトオプション値で起動する
noremap <silent><Leader>E <Cmd>VFiler -layout=floating<CR>

拡張プラグイン

vfiler.vim は拡張を前提にして設計しているので、少ないですが拡張プラグインがあります。これにより、表示カラムやアクションを拡張できます。

vfiler-column-devicons

ファイラー系プラグインでは割と一般的になっている、Nerd Fonts を活用したアイコンカラム拡張プラグインです。nvim-web-devicons を参考にして実装しました。
https://github.com/obaland/vfiler-column-devicons

vfiler-fzf

ファジーファインダーで有名な、fzfvfiler.vim で使えるようにする拡張プラグインです。fzf 用アクションを適当なキーに割り当てて使用します。
当初、あったら便利かもなぐらいで実装したものですが、作者自身が思ったより使っていないのが実情です。
https://github.com/obaland/vfiler-fzf

今後の展望

展望と記載しておいて恐縮ですが、機能面においては、少なくとも自分では及第点の状態なので、基本的には、不具合修正や速度改善、リファクタリングを気づいたタイミングで行っていくつもりです。
勿論、アイディアを思いついたり、何か要望いただいた場合は積極的に対応していきたいと考えております。また、筆者の Vim スキルはまだまだなので、上級者の方々の使い勝手を向上させるような要望や意見をいただけるとうれしいです。

謝辞

このプラグインを作るキッカケを与えてくれた、vimfiler.vim の作者 Shougo さんに、勝手ながら、この場を借りてお礼申し上げます。また、ver.1.0.0 までの間、Vim script による実装についても参考にさせていただきました。

おわりに

自身で初めてつくった Vim/Neovim 用プラグインでもある、vfiler.vim を紹介させていただきました。
実際に使っていただいている方々に感謝すると共に、この記事を機会に「使ってみよう」と思ってくださる方が一人でもいましたら感謝の念に堪えません。

脚注
  1. Lua が有効な状態にする必要があります。 (:echo has("lua")1を返す) ↩︎

Discussion