15年目のVim

Vim使用について述べた先の投稿(12)は好評だったこともあり、そろそろ更新が必要になりました。Vim 8には非常に要望の多かった機能がたくさん追加され、VimAwesomeのような新しいコミュニティサイトができたことでプラグイン探しと評価が容易になりました。最近では私もVimで仕事をする機会がとみに増え、ピーク効率に向け自分のワークフローの設定に時間を費やしたりもしています。ですから、この記事は私の現在の状況を写し取ったものです。

大まかには次の内容です。

  • ファイル特定にはfzfとfzf.vim
  • ファイル検索にaはck.vimとag
  • Vim + tmuxが勝利への鍵
  • ALEは新Syntastic。理由はその非同期性
    …などなど多数。ぜひお読みください。


最近のVimセッション

いつものように、私のドットファイルvimrcは公開されています。また、Vimプラグインのアップデートとインストールができる別のインストールスクリプトもあります。

fzf

TextMateとSublime Textは、ファイルを見つける最速の方法はファジー検索であることを示しました。探しているファイル名やパス、タグなどの一部を入力すればよく、文字が隣接していなかったり、誤字脱字があったりもするという意味です。ファジー検索は非常に有用なので、近年のテキストエディタでは標準機能になっています。

長年、Ctrl-Pがファジー検索の王者であり続けてきました。しかし新ツールfzfはより速く、数千の中から1つのファイルやタグを探そうとする時にさらに融通が利きます。Ctrl-Pは私の2013年のMacBook Pro、30,000ファイルのコードベースという状況でうまく機能していたのですが、膨大なタグファイルを検索する間に徐々に速度が落ち始め、今では役に立たなくなりました。一方、fzfならファイルでもタグでも速度に違いはありません。どちらの場合も驚きの速さです。

fzfの導入は簡単です。インストール手順に従い(基本的にmacOSではHomebrewbrew install fzfで行う)、fzf.vim追加プラグインをインストールして軽やかな機能を手に入れましょう。

fzfにはベーシックなVimのプラグインが付いていますが、その機能は最小限です。そこで誰もが期待するような機能を全て満たすためにfzf.vimが作られました。最も使えるコマンドは次のとおりです。:Buffers:Files、そして:Tags。それぞれ、;, t、そして, rとバインドします。

nmap ; :Buffers
nmap t :Files
nmap r :Tags

;のバインドが重要なのは、バッファなしでは息が詰まるからです。私は作業で決してタブを使いません(詳しくは後述)。ですから、思いつくままに様々な作業をしてゆく時に、可能な限り小さな摩擦で切り替えられるようにすることが重要なのです。

fzfを使用する時は、agを使うようにしてください。Silver Searcherと呼ばれるgrep/ackの差し替えです。ag.gitignore.agignorファイルを尊重しますので、vimrc内に巨大なwildignore“`の文字列を保持する必要はなくなります。

fzfはシェル内でも機能するので、Zsh、Bash、Fishシェル用のバインドが付いています。Zshでは、Ctrl-tで、即座に現在のディレクトリ内のファイルをファジー検索できます。agを使えるようfzfを設定したので、.gitignoreで除外されたものは全て無視します。最高です。

これが私の.zshrから取ったスニペットです。FZF環境変数は、fzfがVim内から呼び出された時にも使われます。

# fzf via Homebrew
if [ -e /usr/local/opt/fzf/shell/completion.zsh ]; then
source /usr/local/opt/fzf/shell/key-bindings.zsh
source /usr/local/opt/fzf/shell/completion.zsh
fi

# fzf via local installation
if [ -e ~/.fzf ]; then
_append_to_path ~/.fzf/bin
source ~/.fzf/shell/key-bindings.zsh
source ~/.fzf/shell/completion.zsh
fi

# fzf + ag configuration
if _has fzf && _has ag; then
export FZF_DEFAULT_COMMAND='ag --nocolor -g ""'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_ALT_C_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_DEFAULT_OPTS='
--color fg:242,bg:236,hl:65,fg+:15,bg+:239,hl+:108
--color info:108,prompt:109,spinner:108,pointer:168,marker:168
'
fi

外部コマンドであり、MacVimで使えないことが、いかにfzfの使用を躊躇させるかを書こうとしていたのですが、今では使えます! Vim 8の新ネイティブターミナルの利用で、最近サポートが追加されたのです。ただ、機能に問題はないのですが、大きなコードベースのターミナルに比べるとかなり遅いです(〜1 mファイル)。

余談:ファジー検索

FZF、Ctrl-Pやその他のエディタはパス名のファジー検索をサポートしていますが、誰か、ぜひVimで1番目の文字で検索ができるようにしてくれないでしょうか。例えばIntellijでは、クラスFooFactoryGeneratorBeanを開きたいと思えば、Cmd-oを叩いてF F G B Enterと入力すれば開くことができます(クラス名の各パートの1番目の文字を打つわけです)。どの言語を書いていてもクラス名はキャメルケースにすることが多いので、それができればタグ検索がしやすくなるのに、と思います。アンダースコアの前の文字を1番目の文字として扱い、f b b qと打てばファイルfoo_bar_baz_quux.jsをハイライトしたりできるのではないでしょうか。

検索とQuickFixウィンドウ

agは新たなackです。ackは新たなgrepでした。Vim内でのagの最善の使い方は、ack.vimでしょう。ag.vimは非推奨なので誤解を招いてはいけませんが、ack.vimはackagの両方をサポートしています。

ack.vimでは:Ackコマンドが使えます。コマンドラインでagを実行するのと同様に引数を用います。異なるのはそれが検索結果リストを表示するQuickFixウィンドウを開くことです。

初期設定では、AckはQuickFixのリストの最初の結果にジャンプすることに注意してください。それを望まない場合は、:Ack!を使うか、ドキュメントごとの2つのコマンドの機能を逆にしましょう。

(分かりにくいのは、fzf.wim;Agコマンドを追加することです。それは、agでインタラクティブに検索する際にfzfを使います。私はそれを使ってみるために, aをバインドしました。大して役立つわけではありませんが、ちょっとカッコイイ機能です)

結果がQuickFixウィンドウに入ったら、それを最も直接的に使うには、カーソルをそこへ動かしてEnterキーで結果を開きます。結果リストを上下に動かすには:cnext:cprevコマンドが使えます。その2つのために自分で使いやすいクロスプラットフォームのキーバインドを設定しようとしましたが、ダメでした。そこで見つけたのがunimpaired.vimで、これは:cnext:cprevに、[ q] qをバインドできて便利です。vim-unimpairedには次/前の組に対するバインドが他にもたくさんあります。コンパイラ/リンタのエラーをナビゲートして、行数などの共通のオプションをトグルしたりすることができます。これもVimに内蔵されてほしい機能です。

QuickFixウィンドウを検索結果に利用するのは非常に便利なので、カーソル下に表示されているワードを検索するバインドをいくつか書いてみました。exhuberant-ctagsがRubyやCoffeeScriptでタグを探そうとするのと同じように、表示中のワードを検索したい時に使えます。

nmap :Ack! "\b\b"
nmap k :Ack! "\b\b"
nmap :Ggrep! "\b\b"
nmap K :Ggrep! "\b\b"

最後に、検索とナビゲーションができたら、 xを打ち(:ccloseをバインドしています)、QuickFixウィンドウを閉じます。検索を始める前に見ていたファイルに戻りたいこともあるので、たいていはCtrl-oを何度か打ちます。これで、ブラウザの「戻る」ボタンをクリックするように、ジャンプリストを遡れるのです。時には;でバッファリストを呼び出して、そこから元のファイルを見つけることもあります。今、ちょっと考えてみたのですが、バインドセットを、oなど、私のMeta-kバインドのグローバルマークに修正するのもよいかもしれません。そうすれば' 0で常に最初の地点に戻れるでしょう。

ターミナル、ペイン、多重化

以前、gcim/MacVimはほとんど使わないと言いました。私はターミナルで作業するのがとても好きなのですが、スタンドアロンのVimアプリケーションにも使うに足る理由がいくつかあります。

  1. ターミナル内、tmux内のVimよりも応答が良い。
  2. macOSとWindowsで.txtファイルを開く初期設定アプリケーションとして、TextEditよりも優れている。
  3. 幅広のエディタウィンドウで220番目の列をクリックしても問題が起こらない。
  4. 誤字だらけのブログ記事を書いてもターミナルのVimは下線(または、波線のほうがなじみ深いと言う人もいるかもしれません)を表示しない
  5. 本物のSolarizedカラースキームが使える。Solarizedなら256色が使えるところに、生成された冒涜的なスキームを使う必要がない。

コマンドラインの近接性以外にVimをターミナルで使う大きな理由はtmuxで、これはリモート開発でよく使われていますが、ローカル開発でも便利です。現在のところ、tmuxは私が毎日使っているフルスクリーンの作業環境で、たいていVimがtmuxのペインの1つを占めています。他にいくつかシェル、多くの場合サーバと1つか2つの別のユーティリティペインを開いている間もVimが使えます。時にはVimを一時的にズームのキーバインドでフルスクリーンにすることもあります。

tmuxが特別なのは、別の場所からtmuxペインにキーを送れる機能があるからです。私はtmuxとVimをIDEのように使っています。つまり、1つのペインの中で編集をし、別の場所でコマンドを実行し、エラーが出た時のためにサーバログが見えるようにもしておけるのです。例えば、RESTエンドポイントの作業をしている時、curlでエンドポイントを再テストし、少しキーを打つだけでアウトプットをjqで閲覧することができます。

一般的に、これを行うには、Vim内で変更し、: w Enterを打って保存した後、```h```で左ペイン(はtmuxのプレフィックスキーで、普通はCtrl-aです)tmuxのに移り、それからUp Enterでコマンドを繰り返し、“““ lでVimに戻ります。しかし、次のようにVimのキーバインドを一時的に設定したほうがはるかに速いです。

nmap \r :!tmux send-keys -t 0:0.1 C-p C-j

上記では、tmux send-keysを実行し、セッション、ウィンドウ、そして先にcurlを走らせていたペイン0.0.1にキーを送るように命令しています。すると、Ctrl-pが送られます。これはUpを打つのと同等で、先のコマンドを履歴から引き出します。そしてEnterで実行です。私はこれを、「実行」または「リピート」のように、 rにバインドしました。send-keyの利用について、詳しくはこの記事この記事を参照してください。

この機能を半年間使ってきましたが、目に見えて生産性が上がっています。しかし、今、Vim 8はエディタ内のネイティブターミナルをサポートするようになったことは言っておきましょう。少し使ってみましたが、とてもしっかりしているようです。様々なプラグインがターミナルをVimに統合しようとしては、いまいちな結果を出し続けてきたのですが、新しいネイティブターミナルは速く、Unicodeを認識し、256色が使え、tmuxのようにキー入力を送れる新規のterm_sendkeys()関数もあります。これはほんの数か月前にVimに追加されたばかりなので、実験が必要です。まだ分かりませんが、いずれ、tmuxの:terminalで分割したMacVimを使うようになるのかもしれません。

メモ:macOSのターミナル

私は、覚えている限りずっと、macOSに搭載されているTerminal.appではなくiTerm2を使っています。しかし、最近気づいたのですが、iTerm2上でVimに入力すると、とりわけtmux内の場合、反応が遅いのです。比較のためにXQuartx内のurxvtを使ってみると、ずっと軽く感じられました。明らかに何かがレイテンシを上乗せしているのですが、それでもurxvtをmacOSのプライマリターミナルにしようとは思いません。悲惨なクリップボード、フォーカス問題に加え、XQuartzには高DPIのサポートがないからです。

このことに気づいて数日後、macOSのターミナル間で入力レイテンシを実演し、Terminal.appはiTerm2よりも相当速くなっていると結論づけた記事を読みました。自分でも試してみたところ、キー入力のレイテンシはurxvtとiTerm2の中間くらいだな、と感じました。それで完全にTerminal.appに完全に切り替えたのです。それまで、ファンシーなカスタムiTerm2カラースキームテーマを使っていましたので、Terminal.appに全テーマを移したというプロジェクトを見つけた時は嬉しくなりました。

ただ、iTerm2ではできた垂直分割がないのは残念です。時々、ペイン間で異なるフォントサイズを表示させたい時に使っていたからです。iTerm2ではそれが簡単にできましたし、実際、編集エリアのグリッドが複数あってセルのサイズが固定されているエディタ環境なら実装されているのが普通なのですが、当分はそれなしで我慢します。

Vimで散文を書く

書くことに特化した機能が人気を集めていますが、それも当然、実際に効率が上がるからです。快適な執筆環境を実現した見た目の美しいネイティブアプリケーション、ブラウザベースのアプリケーションは存在しますが、私は書くのもVimでやりたいと思い、ソリューションを考えてみました。

goyo.vimは偉大なプラグインで、バッファに多くの余白を追加し、美しくない要素を隠してくれます。Airline/Powerline/Lightlineというステータスバーを認識し、それも隠します。ほとんどの場合、ですが。さらにいくつかの設定をいじったものを私は「散文モード」と読んでいます。

function! ProseMode()
call goyo#execute(0, [])
set spell noci nosi noai nolist noshowmode noshowcmd
set complete+=s
set bg=light
if !has('gui_running')
let g:solarized_termcolors=256
endif
colors solarized
endfunction

command! ProseMode call ProseMode()
nmap \p :ProseMode

このコマンドは( pにバインドしました)、Goyoを起動し、括弧を入力した際にインデントするようなおかしなソースコードを全て取り除きます。また、カラースキームを、私が普段使っている暗い色のテーマからSolarizedの明るいバージョンに変えます。テーマ分けが大切なのは、自分が「執筆モード」にいることが視覚的に確認できるからです。それに、言葉を生み出すのが最優先事項である時に、余計な作業に邪魔されたくありません。

コマンドには、オートコンプリート機能も含まれており、書くスピードを上げたい時にTabキーを叩けば、類語辞典と辞書から言葉を参照してくれます。まだ開発途中ではありますが、時々便利に使っています。

リンタ

Vimへの追加の中でベストかつ最も待ち望まれていたのは、非同期プロセスの制御でしょう。ついにVimも、バックグラウンドで処理を走らせることができるようになり、優れた新規プラグインALEが、リンタを非同期的に実行できるSyntasticに追いつこうとしています。これからは、ファイルを書くたびにリンタが作業を終えるのを待つ必要はないのです。最近はよくJRubyでRubyを書いていて、リンタの実行に少し時間がかかるので、遅延のためにSyntasticをオフにしていました。ALEがあれば編集中もリンタをオンにしておくことができます。

Lightline、Powerline、Airline、そしてステータスバー

ここ数年はPowerlineを使ってきたのですが、やっと、より軽いAirlineに変えてみました。しかし、このステータスバーの中にある情報とウィジェットは便利というより邪魔な代物です。私には、エンコード中のファイルや構文タイプなど知る必要はありません。加えて、改造フォントにも興味はありません。そこでLightlineに切り替え、少し時間をかけて必要最小限にし、リンタステータスのアイコンを追加しました。

とりわけキーを1つ叩けばターミナルが開く状況で、現在のgitブランチ名をステータスラインに表示する必要はありません。それに、gitブランチをシェルステータスに置くという発想は好きになれません。なぜなら別のシェルからブランチを切り替えるとそれは不正確になるからです。しかし、そういう人はここでは明らかに少数派ですから、何かまだ私が知らないことがあるのかもしれません。

Git

Gitを使っているなら、いくつか重要なプラグインがあります。

vim-gitgutterは、追加、削除、変更された行にマーカーを表示するプラグインです。最近のエディタにはほぼ実装されている機能です。私は、変更箇所には、初期設定の-+の代わりに色付きドット(·)を表示するように変えました。このほうがキレイだと思っています。

vim-gitgutterは、Vim向けGitプラグインの中では最も普及しており、機能も多いようです。私はgit用のシェルエイリアスを山ほど抱えているので、Vimでは:Gblame:Gbrowse以外はほとんど使っていません。しかし、エディタ内蔵のGitツールには他にも期待に応える良い機能が山ほどあります(リポジトリをGitHubでホスティングしている場合、:Gbrowseを動かすにはvim-rhubarbが必要です)。

:Gbrowseには驚嘆しました。リポジトリがGitHubやGitLabなどにミラーされていることを推測し、現在のファイルをブラウザ内のオプションの行選択で開きます。さらに、イシューやプルリクエストの中で使った場合、GitHubが特定のコミットへのリンクと行数をスニペットとして表示するようになったので、それはさらに便利になりました。Shift-vで数行を選択し、:Gbrowseを実行し、開いたURLをコピーしてGitHubコメントにペーストするだけで、次のような結果が得られます。

最初に私は、RootIgnoreがどのように.gitignoreに基づいてwildignoreを自動設定するかを話そうと考えていました。しかし結果としてそれは良くないアイデアでした。パスがwildignoreの中にあると、Vimコマンドラインのタブコンプリートのパスが機能しないのです。さらに悪いことに、展開するように要求したパスが無視されている場合、内蔵のexpand()がnullを戻してきます。.gitignoreを実行した、ホスト固有の.vimlocalファイルが、私がチェックインした.vimrcで基づかない原因を突き止めるのにしばらく時間がかかりました。

バッファ、バッファ、バッファ

私は忠実なバッファユーザです。タブも使おうとしましたが、便利だと思ったことはありませんでした。タブは、情報を隠す追加の方法を作り出すだけであり、さらにそれを使うには別のキーバインドやコマンドを覚えなければなりません。tmuxユーザであるなら、別のペインでVimを開いたほうがずっと簡単です。バッファを使いこなせば、先述のような少しのEZFのキー入力で目当てのファイルに容易に到達できます。

バッファの使用経験がなくても、すぐに理解できるでしょう。Vimをスタートして、開いたり、作成したりしたファイルは名前の付いたバッファになるのです。:buffersコマンドで閲覧でき、:bufで特定のバッファに移動できます。“““にはバッファのファイル名の一部や:buffersで表示される番号を入れましょう。

Vimを、コマンドライン引数として複数のファイルをコマンドラインでスタートしたら、各ファイルは、簡単にアクセスできるようバッファ内で既に開いている状態です。vim-unimpairedをインストールしていれば、[ b] bのキーバインドを使ってファイル間をラクに移動できます。

先に述べたように、私は、;キーをEZFの:Buffersコマンドにバインドし、1度キーを叩けばファジー検索付きのバッファリストが立ち上がるようにして、この処理を大幅にスピードアップさせました。例えば、vim foo.txt bar.txt quux.txtといったコマンドラインで3つのファイルを開いた場合、ただ; q Enterと打つだけで、quux.txtにアクセスできます(そのとおり、:bufに似ているのですが、fzfは、似た名称のファイルが多数開いている時にはライブプレビューを表示してくれます)。

まれに、誤ってバッファを作成してしまうことがあります。:eでファイルを開こうとしてEnterを打つのが速過ぎた時などです。:bdコマンドを使えばバッファを削除し、リストから外すことができますが、Vimウィンドウも閉じてしまったり、バッファがその中で開いている場合は分割してしまったりします。良い解決策は、bufkill.vimで、現在のバッファを削除しつつ、現在のウィンドウを開いたままにする:BDを提供します。よく使うので、私はMeta-wにバインドしています。

ファイル名を変更したり、ファイルをチェンジモード、削除したりする必要がある場合、ターミナルに戻って変更ができますが、そうするとVimバッファが同期しなくなり、「ファイルは利用できません」という煩わしい警告を出してきます。代わりにNERDTreeを使って現在のファイルを:NERDTreeFindでハイライトし、mを叩いて編集し、移動や名前変更などのアクションを選んではどうでしょうか。私の気に入っている解決策はvim-eunuchの利用で、たくさんのコマンドを追加できます。:Chmodは現在のファイルのチェンジモード、:Renameは親ディレクトリのファイル名を変更、:Moveは新規パスへの移動、:Deleteはファイルとバッファの削除です。他にもいくつかコマンドラインがありますが、私が最もよく使うのはこの4つです。

多岐にわたるその他のプラグイン

ある友人vim-polyglotを教えてくれました。これは100以上の構文プラグインを1つのパッケージにバンドルしたもので、オンデマンドでロードできます。非常によく更新されており、オーサーは広く普及している言語をインデントしたり、ハイライトしたりするのに最善の構文プラグインを集めています。

コードのコメントアウトは日常茶飯事なので、様々な言語のコードの行やブロックをコメント化するのにプラグインを使うのは理にかなっています。行のコメントアウトにハッシュを用いるコードを書いているなら、:s/^/#でたいていは切り抜けられますが、私はvim-commentaryプラグインのほうが好きです。どの言語でも、g cだけでコメントアウトとその解除が可能になるからです。

vim-surroundプラグインは便利過ぎるので、Vimに内蔵されるかもしれません。これはあらゆるテキストの囲み文字を追加、削除、変更するキーバインドを追加してくれます。例えば、シングルクォーテーションをダブルクォーテーションや角括弧、丸括弧に変更したりできるのです。残念ながら、.キーは初期設定ではこれらの変更をリピートしないので、それを実装するのはrepeat.vimが必要です。複数の文字列のクォーテーションを変更するには、c S ' "を打つか、1回のコンビネーションを使い、それから.を用いて次の文字列で置換を繰り返します。

エンドブロックのキーワードでRubyやその他の言語を書く場合、たくさんのendを記述することになります。endwiseプラグインはそれらを自動的に挿入してくれて便利です。HTMLやXMLを書く時は、絶対にclosetag.vimプラグインを使うべきです。< /と入力すれば自動的にタグが閉じられます。

元の投稿で私は、様々なタブとスペース変数を用いたコードベースを扱う方法として、タブとスペース調整マクロについて述べました。しかし、sleuth.vimなら、ファイルが開かれた時にスキャンを行い、これらの設定を自動的に検知します。その90%は機能し、私が設定したマクロはほとんど用なしになりました。

プラグインについて思うこと

非同期プロセス制御や、いくつかの必須タイプを始めとするVimとVimLの最近の改良によって、プラグインのエコシステムは進歩しています。新しいプラグインサイト、VimAwesomeのおかげで、人気のプラグインを探すのが簡単になりました。きちんとフォーマット化されたドキュメンテーションとインストール手順も揃っています。

以前の投稿への反応には、Vimにたくさんのプラグインを積むことに対する反発も時折含まれていました。その疑いにも一理あります。ユーザが秩序のないエクステンションを追加して、一貫性なくパッチを当てられるようなシステムは、すぐにメチャクチャになるからです。WordPressを見れば分かるでしょう。あるいは20年前の状況を知っている人なら、Mac OS Classicのエクステンションの恐怖を思い出してください。依存関係を申告する方法がなく、プラグイン間のインタラクションをデバッグすることが日常になっていたものです。

しかし、Vimのプラグインはそれほど悪くありません。プラグインXとYの間のインタラクションのデバッグする際は、たいてい”vim X とY”とgoogle検索しますが、1度か2度の検索で済んでいました。ある時、奇妙なものに行き当たり、昔に遡ってバイナリサーチをして(Conflict Catcherなら20年分)、1つのプラグインの名前を変更し、別のプラグインとのロード順を変える羽目になりました。自慢するわけではありませんが、これまでにひどいプラグインインタラクションに遭遇したのはその一度きりです。

プラグインに対するその他の抵抗は、Vimの機能のコアセット的なものから外れることに対する純粋な敵意のようです。しかし、Vimを使っている人は既に、テキスト編集にスピードと効率を求める集団の一員なのですから、それはオタク同士で誰が最もエキセントリックかを口論しているようなものです。EasyMotionvim-sneakなどのムーブメントプラグインを使っている人々は、vanilla Vimユーザよりも自分たちのほうが効率が良いと主張し、vanilla VimユーザはVim以外のエディタのユーザよりも効率的だと思っている、などなど。いずれにしても、私たちの脳でコンピュータをコントロールできるようになった暁には、その議論は空論になるでしょう。

また、実用性の上でプラグインは避けたいという話も聞きました。プラグインが、RubyやPythonが使える、ナントカがコンパイルされたバージョンのVimを条件にしている、あるいはプラグインそのものをコンパイルする必要がある、といった場合です。Vim 7で不可欠な言語機能が多数追加されたので、多くのプラグインは今では純粋なVimLであり、余分な言語依存を必要としなくなりました。そして、~/.vim/bundle/にある全てをVimのランタイムパスに追加するvim-pathogenと結合したことで、プラグイン追加はgit cloneと同じくらい気軽に行えるものになりました。

私の考えはこうです。Vimに内蔵されていればいいのに、と思う機能をプラグインが提供しているなら、インストールする価値はあります。そうでなければ、プラグインの数は最低限に抑え、インタラクションの問題を避け、Vimをスタートしてファイルを閲覧する時の軽快なパフォーマンスが保たれるようにします。私がここでリストアップしたプラグインと設定は、効率を上げ、必要な成果を得るためのものですが、私の脳の配線を全てつなぎ直す必要がない程度まで、という条件付きです。

Vimだけがエディタではない

4年前と比べると、興味深いエディタがたくさん増えています。AtomとMicrosoftのVisual Studio Codeの登場で、ブラウザベースのネイティブアプリケーションが実用化されました。Sublime Textは今もなお偉大なアプリケーションです。IntelliJ IDEAにはフリーのコミュニティエディションもあります。これらは全てVimと同様のモードをサポートしており、状況によっては使ってみる価値があるものばかりです。

よく新人プログラマにどのエディタを使うべきかと尋ねられるのですが、私はいつも、まずはSublime Textから始めるよう勧めます。なじみやすいインターフェース、最新の構文ハイライト機能を伴った素晴らしいプラグインエコシステムを備えており、macOS、Windows、そしてLinuxでも快適に使えるからです。プログラミングを学んでいるなら、スクリーン上のテキストを移動、編集するだけのために、さらにVimの奇妙で難解な文字の組み合わせと様々な編集モードを覚えるのは避けたいでしょう。そういう人たちの何人かが後にVimを選び、いかに速く強力に感じるかを説き始めたのですが。

JavaのベストなエディタはおそらくIntelliJ IDEAでしょう。Community Editionは無料で使うことができ、モダンJavaやKotlinの開発者なら誰もが欲しがる必須の機能が全て揃っています。Mavenの優れたビルドサポート、確かなGitインテグレーション、衝撃的なリファクタリングサポート、正確なコンプリート、優雅な関数のパラメータヒント、Ctagsを超えるスマートなインデックス、検索機能、そしてインタラクティブのデバッガも不可欠です。実際、Rubyを書いていて、デバッグが必要になり、1つか2つのputsを実行しなければならない時は、IntelliJを立ち上げてデバッガを使っています。Vimが懐かしくなったら、無料のIdeaVIMプラグインでVimのキーバインドが使えて比較的うまく動作します。

Visual Studio Codeを試したことはまだありませんが、TypeScriptを書く時にはぜひ使いたいと思います。どちらもMicrosoftが開発しているので、相性が良さそうです。いくつかGIFも見てきて、その完成度に驚きましたし、それについて書かれたものも読みましたが概ね好意的でした。友人の1人はYouCompleteMe Vimプラグインは、CやC++を書くなら必須だと言っています。TypeScriptのサポートもあるので、これもいつか試すことになりそうです。

NeoVimも面白そうですが、使ってみるつもりはありません。非同期ジョブ制御とネイティブターミナルが売りだと発表されましたが、それらの機能はVimコアに追加されているからです。もし、絶対に使うべき理由があればぜひ教えてください。

まとめ

最近私が注力しているのは、ツールをいじり回すことではなく、仕事を片付けることです。しかし、Vimは昔からずっと、ちょっとした工夫や研究を行うだけの価値があるエディタでした。VimAwesome.comを閲覧したり、ヘルプページを数行読んだりするだけで、効率がグンと向上するからです。プラグインや私が加えた設定の多くは、煩わしさにぶつかるたびに「もっと良い方法があるはずだ」と考えた結果です。

この投稿が役立てば嬉しいです。ぜひご意見をコメントしてください。