👹

VSCodeライクなVim。Onivim 2でなんちゃってVimmerを超えていけ

commits12 min read 2

onivim 2 logo

はじめに

Atomが死に、VSCodeがモダンエディタ戦争を制して一年[1]
VSCodeでVimキーバインドを使っているなんちゃってVimmerも多いだろう。かくいう私もその一人である。
VSCodeの美しいGUIと強力な拡張機能に日々助けられてはいるものの、あともう少し、ほんの少しだけ、マウスを使う機会を減らしたい。
そんな気持ちを捨てられずにいる。

Onivim 2はそんな諸兄のためのエディタだ。
Vimの思想に基づいて設計され、VSCodeのような美しいGUIとVSCode互換の拡張機能を持つ。
そして、ゴリゴリに練り上げられた.vimrcinit.vimをロードすることができる――将来的には[2]
我々が本当に欲しかったもの、それがOnivim 2なのだ。

ライセンスについて

読み進める前に、ライセンスについて確認しておこう。
Onivim 2はオープンソースではあるが、無償での利用は非商用と教育目的に限られている。
商用目的――つまり、業務でのプログラミングその他の営利目的の作業――で使うためには、ライセンスの購入が必要だ。
記事執筆時点(2021年1月30日)では40ドルだが、これは開発が進むごとに価格が上がっていくそうだ。

業務で使えないならやっぱりVSCodeでいいや、そう思った方もいるだろう。
だが、Onivim 2は"Time delay"デュアルライセンスを採用している。
masterブランチにマージされてから18か月後に、すべてのコミットはMITライセンスとなる[3]
MITライセンスとなったコードは別のリポジトリで管理されている。
つまり、1年半待ちさえすれば商用でもこの素晴らしいエディタを使うことができる、というわけだ。
待ち時間とライセンスフィーを天秤にかけて、どちらを選ぶかを決めればいい。

この記事を読んでOnivim 2をタダで使おうと思ったあなた、会社の敷地内ではVSCodeを使うように。
リモートワークでも駄目だ。いい年をして屁理屈をこねるな。
間違っても私がそそのかしたなどと口を滑らせないでくれ。

分かったら次に進もう。

本記事の構成

まず、Onivim 2の説明を簡単にしてからインストール方法を説明する。
インストール方法だけ知りたい人はこちらを参照

Oni/OniVimとは

Onivim 2の前身として、Oni/OniVimというエディタが開発されていた。
VSCodeやAtomと同じ、Electronで作られたNeoVimベースのGUIエディタだ。
エディタ部分だけでなく、ファイルツリーやコマンドの呼び出し方などもVimと同じようなキーバインドでできる。
もともとはOniVimと呼ばれていたのが、ある時点でただOniというようになったらしい。
今は開発を停止しており、Onivim 2が後継として開発されている。

Onivim2の特徴

OniはReact + TypeScriptで開発されていたようだが、Onivim 2は Revery + Reasonで開発されている。

Reason

https://reasonml.github.io/docs/en/what-and-why

ReasonはOCamlベースのAltJSで、HaskellインスパイアのElmやPureScriptに対してOCamlインスパイアなのがReasonという感じのようだ(詳しくは知らない)。
Reasonで書いたコードはJavaScriptにトランスパイルしてブラウザで動かすこともできるし、ネイティブコードにコンパイルして単体で実行させることもできる、らしい。

Revery

https://github.com/revery-ui/revery

ReveryはElectronインスパイアのGUIフレームワークで、Reasonで書かれている。
Reason + Reveryを使って書かれたGUIアプリはネイティブコードにコンパイルされるので、Electronより速い、らしい。

Vimをモダンエディタで

いきなり非本質的な技術の話から入ってしまった。悪い癖である。
Onivim 2が目指すところはOniと同じ、Vimの思想をモダンエディタで実現することだ。
Vimと同じモーダル(モードを切り替えて使う)テキストエディタであり、キーボードだけで操作できる。それゆえ生産性を最大限に高められる。
まあ、ここでVimの良さを語るのはOnivim 2 を使ってみようなどという奇特な諸兄には釈迦に説法だろう。
藪蛇でマサカリを投げられるのも怖いのでこの辺にしておく。
とにかく、VSCodeっぽいVim――あるいはVimっぽいVSCode――ということだ。
そして、Electronではパフォーマンスに問題があるためReason + Reveryに移行したというわけだ。
英断だと思うし、自分も見習いたい(ほんまか)。

すべてがキーボードで操作可能

ガチのVimmer諸兄はご存じないかもしれないが、自分のようななんちゃってVimmer(あるいはVimキーバインドラバーとでも呼ぶべきか)なら、VSCodeにVimキーバインド拡張を入れてVimライクに使えることを知っているだろう。
ではそれでVimと同じ体験ができるかというと、そうではない。
ファイルツリーでの選択の移動など、Vimとは異なる操作(おおむねマウス操作)を強いられるところは多い。もちろんキーボードショートカットをきっちり設定すればできるはずだが、他の操作とぶつかって謎挙動を見せるなんてこともしょっちゅうだ。
VSCodeにおいては「キーボードのみで操作可能」というのは「できなくはない」というだけであって、そんなことをやろうとする変態はそれなりに労苦を強いられることになるのだ、残念ながら。

それに対してOnivim 2では、「すべての要素がキーボードで操作可能」である。
その思想が結実したのが「Sneak mode(以下スニークモード)」だ。
Ctrl + gを押すだけで画面上のすべての要素[4]にショートカットキーが割り振られる。
「エディタ(の選択)」と「エディタを閉じるボタン」に別々にショートカットキーが割り振られるのだから徹底している。
これだけでもVSCodeから乗り換えたくなったなんちゃってVimmerは多いのではないだろうか。
Vimに限界を感じつつも[5]、「VSCodeはチョットなァ~~」なんて考えているVimmerにもおすすめだ。

VSCodeの拡張機能が(一部)使える

なんと、OniVim 2 ではVSCodeの拡張機能を使うことができる。
とはいえ、すべての拡張機能を使えるわけではない。
VSCodeの拡張機能が配布されている VSCodeマーケットプレイスは実はMicrosoft製品だけに利用が許されている。
VSCode互換のエディタはVSCodiumやEclipse Theiaなどがあるが、それらはMicrosoft製品ではないので、VSCodeマーケットプレイスで配布されている拡張は使えないのだ。

そうした問題意識から、Open VSX Registryでは、こうしたVSCode互換エディタで使用できる拡張機能を配布している。
Onivim 2で使用できるのもこうした拡張機能だ。
つまり、「Open VSXで配布されている、VSCode互換の拡張機能」だけを使用できる。

ちょっとがっかりしただろうか? 私もした。

待ってほしい。ため息をついてブラウザのタブを閉じる前に、Open VSX Registryでいくつかお気に入りの拡張を検索してみるといい。
意外とある。
なんと、Microsoft製のPython拡張もある。Microsoft製なのに!?
GitHubを見れば分かるが、VSCodeのPython拡張はMITライセンスなのだ。ありがとう、Microsoft。

残念ながら、VSCodeの非常に強力な拡張機能であるRemote development(SSH/WSL/Container)はオープンソースではないため、Onivim 2での利用は絶望的だろう、今のところ。Microsoftの懐の深さに期待したい(?)。

Vim/NeoVimの設定は(将来的には)ロードできるようになる

今はまだできない。
FAQによると、ベータ版のマイルストーンに init.vim.vimrcの使用がスケジュールされているらしい。
Vimmer諸兄は首を洗って待っていてほしい。

Windowsでのインストール

ようやくインストールの話だ。お待たせした。いや待っていないかもしれないが。
しかし手順に入るその前に、単にインストールするだけでわざわざ説明がいるのか、という点を説明させてほしい。すまない。

インストールバイナリの配布とアーリーアクセス

現在のところ、Onivim2はアーリーアクセスに参加してnightly development buildをダウンロードするか、ソースコードからビルドするしかない
アーリーアクセスに参加するためには40ドルの支払いが必要だ。ライセンスの説明でも書いたが、この価格は開発が進むごとに値上がりする。
コミュニティを支援するために、Onivim2が気に入った人はいっちょ参加してみてはどうだろうか。

とはいえまずは使ってみないとお話にならない。
ということでソースからビルドしてみよう。
しつこいようだが、利用は非商用または教育目的のみに限る。
分からない人はもう一度ライセンスの章を読み返してほしい。

なお、ここではWindows上でインストールを行う。
筆者はMacを使っていないし、Linuxだったら何の問題もなくビルドできるだろう。
Windowsでのビルドは――多くの人がやりたくないと思うだろう。そこにこの記事の価値がある(ドヤッ)。

ソースからビルド

依存関係のインストール

ビルド手順はここに書かれている。
ターミナルにはGit-bashを使う。
管理者権限で開いておこう。ReasonのパッケージマネージャであるEsyの実行に必要なのだ。
ここでPowershellを選んだり、WSL2を選んだりしてもうまくいくことは保証しない。

とりあえずGit, Nodeはインストールしておこう。
npmが使えるようになったらEsyをインストールする。

$ npm install -g esy@latest

次に、Windows用のビルドツールを入れる。

$ npm install -g windows-build-tools

Linuxの場合はさらに、reveryの依存関係のインストールが必要なのだが、Windowsでは準備はこれでおしまいだ。

次にリポジトリをクローンする。

$ git clone https://github.com/onivim/oni2
$ cd oni2

masterブランチだとやや不安なので、最新のタグを使おう。

$ git tag
0.5.0
v0.5.1
v0.5.2

$ git checkout v0.5.2

oni2ディレクトリ配下で、nodeの依存関係をインストールする。
Nodeバイナリをoni2プロジェクトが提供しているものを使うために、npm installを使わないらしい。

$ npm install -g node-gyp
$ node install-node-deps.js

ちなみに、筆者の環境だとビルドしたOnivim 2でターミナルがうまく動かなかったが、この手順からやり直すとうまくいった。
もし同じ状況になったら試していただきたい。
参考

フロントエンドのビルド

ここからはEsyを使って依存関係のインストールやビルドを行っていく。

$ esy install

$ esy bootstrap

$ esy build

たまに、esy bootstrapのところで以下のようなエラーが出ることがある。

info building @opam/luv@github:bryphe/luv:luv.opam#xxxxxxx@yyyyyyyy: done
error: build failed with exit code: 1
  build log:
    # esy-build-package: building: esy-cmake@0.3.5
    # esy-build-package: pwd: C:\Users\user\.esy\3\b\esy_cmake-0.3.5-5b613289
# esy-build-package: running: "bash" "-c" "./build-windows.sh"
    C:\Users\user\AppData\Local\Temp\__esy-bash__377572354__1__.sh: 行 3: 対応する `"' を探索中に予期しないファイル終了 (EOF) です
    C:\Users\user\AppData\Local\Temp\__esy-bash__377572354__1__.sh: 行 4: 構文エラー: 予期しないファイル終了 (EOF) です
    error: command failed: "bash" "-c" "./build-windows.sh" (exited with 2)
    esy-build-package: exiting with errors above...

  building esy-cmake@0.3.5
esy: exiting due to errors above

原因は不明だが、筆者の環境ではもう一度実行したら成功した(原因を追いかける気力はなかった)。

ビルドが完了したら、esy runでOnivim 2を動かすことができる。
とりあえず使う分にはこれでよいだろう。

ちゃんとインストールするには先に進む。

Onivim 2をインストールする

インストールのためにリリースビルドを作成する。

$ esy '@release' run -f --checkhealth
$ esy '@release' install
$ esy '@release' create

これらのコマンドが成功すると、{projectRoot}/scripts/windows/publish.ps1スクリプトを実行できるようになる。

Powershellを管理者権限で開いて、プロジェクトのルートフォルダまで移動しよう。

PS C:\Users\user\repositories\oni2> .\scripts\windows\publish.ps1`

このスクリプトが終了すると、{projectRoot}/_publishというフォルダが作成され、中にインストーラの実行ファイルが格納されている。
実行してOnivim 2をインストールする。

Onivim 2を使ってみる

インストールが終わったら、エディタを起動してみよう。
起動はスタートメニューからでもよいし、Git-bashからoni2コマンドを実行してもよい。
(Git-bashがコマンドを認識するためには再起動が必要かもしれない。)

以降はOnivim 2に特徴的な機能について感想を述べていく。
VSCode-Vimでもできることには特に言及しない。
VSCodeでできないことが知りたいだろう? そうだろう。

ターミナルの起動

ターミナルの起動はVimと同様、 :termと打ち込む。
VSCodeではコマンドを打ち込む際は Ctrl + Shift + p でコマンドパレットを起動するが、Onivim 2では :と打つだけでコマンドパレットが表示される。

ところで、VSCodeではターミナルのトグルは Ctrl + ` でできる。
Onivim 2ではこのようにターミナルを閉じたり開いたりすることはできないらしい
上記のIssueを読むと、VSCodeではターミナルは基本的に底部のペインに表示されるのに対し、Onivim 2のターミナルは通常のエディタと同様に自由にレイアウトできるためトグルの対象を決められないということのようだ。

VSCodeの統合ターミナルと比べた場合の違いは大きく二つだ。
一つは先ほども言及したように、ターミナルがエディタと同様に自由にレイアウトできること。
もう一つはTerminal Normal modeを備えることだ。
これはVSCode-Vimで満足できなかったVimキーバインドラバー諸氏にはうれしい機能だろう。

Terminal Normal mode

https://onivim.github.io/vid/terminal-normal-mode.mp4
(動画)

ターミナルにフォーカスが当たっている状態で Ctrl + \ Ctrl + nを押すとターミナルが読み取り専用になり、Vimキーバインドで移動・コピーできるようになる。
切り替えの際にテキストの色やフォントが変わってしまうのがつらいところだが、シームレスに移行できればコマンドの修正やコピペがかなり簡単になるのではないだろうか。
aiなどInsertモードに移行すると普通に入力できるようになる。

ただ残念なのが、Shift + iを入力しても行頭にカーソルが飛ばないとか、そもそもInsertモードに戻るとカーソル位置が入力行の行末になってしまうとか、Vimらしくない挙動[^要出典]をする点だ。
ブラッシュアップに期待したい。

ファイルツリーの利用

ファイルツリーはもちろんVimキーバインドで移動することができる。
ちなみにエディタ間の移動は Ctrl + w h/j/k/l だ。

ファイルツリーにフォーカスが当たった状態で、j/kで上下のファイル/ディレクトリに移動できる。h/lはディレクトリ配下のファイルツリーのトグル。
5jと打つと5つ下のファイルに移動できる。ggでファイルツリーの先頭に、Shift + gで末尾に移動だ。素晴らしい。
さらに、Vimの検索機能も使える。/tstsconfigなどにヒットする。これはかなり便利ではないだろうか??

ただし、検索対象は展開されている(つまり表示されている)ファイルツリーのみのようだ。
これは簡易な操作で全展開するか、閉じられたファイルツリー内の検索機能も欲しいところだ。

スニークモード

スニークモードはモーダルエディタだからこそできた革命ともいえるし、GUIエディタでVimの思想を実現するためにひねり出された単なる妥協ともいえるかもしれない。
Vimの持つモードに加えて、モダンなGUIエディタが持つ豊富な画面要素を操作するために用意された新たなるモード、それがスニークモードだ。
Ctrl + g を押すことで、ほとんどどんな時でもスニークモードに移行し、画面のあらゆる要素に2文字のショートカットキーが割り当てられ、それが表示される。
例えばAFがエディタのフォーカス、AGが同じエディタの閉じるボタン、といった具合だ。

The sneak mode of Onivim 2

この機能によって、画面上のどんな要素に対しても3回のキータイプで操作可能になる。
なにより直観的だ。
Vimを数年使いこんだ人でも、画面内の要素に移動するための最少のキータイプを瞬時に把握、打てる人は少数だろう。エディタ間の移動などは頻度が少ないのもあってなおさらだ。
「どうやったらあそこに移動できるんだっけ?」という時、マウスに手を伸ばすのではなくCtrl + gを押せばいい、そうOnivim 2ならね。

ただし、現状ではスニークモードはその理想には程遠いと言わざるを得ない。
例えばファイルツリーへのショートカットキーは、ファイルツリーが閉じていればそれを開いてフォーカスしてくれるのだが、ファイルツリーが開いていた場合、単に閉じてしまうだけなのだ。
これはまったくもってイラつく挙動だ。

さらに、マニュアルに記述がないのでどう呼べばいいのかわからないのだが、Onivim 2にはコード実行時のOutputや静的検査によるエラーを表示するエリアが存在し、それはウィンドウの底部に存在している。
この底部ペインにもスニークモードで移動することができないし、もっと言うとこの底部ペインはマウスを使わないと操作できない。
Vimの理想をGUIエディタで表現するのは大変なようだ。

デバッグモードでの起動

Onivim 2は現時点(v0.5.2)ではまだまだ粗削りなエディタだ。
不具合らしき挙動を見つけたら、デバッグモードで起動してログを見てみよう。
GitHubにバグ報告をする際も、デバッグログがあると解析がスムーズだろう。

デバッグモードでの起動はCLIで行う。

Git-bashなどから

oni2 -f --debug

と打つ。-fはOnivim 2起動中にシェルにデバッグログを出力しつづけるためのオプションだ。
行頭に [ERROR]と出ているログがなければひとまずは大丈夫だろう。

ちなみに筆者が最初にビルドしたときはターミナルの起動に必要な依存関係がインストールされておらず、[ERROR]ログが出ていた。

最後に

さて、いかがだったろうか。
使ってみたくなる機能もあれば、少々がっかりしてしまうところもあったかと思う。

私としてはやはりファイルツリーやターミナルをVimキーバインドで操作できるのがご機嫌だ。
スニークモードもカバー範囲が広がれば相当使いやすいだろう。
一方で、VSCodeと比べて逆にタイプ数が多くてつらいところもある。
例えばエディタ間の移動は、VSCodeだと Ctrl + 数字でできる。
3-4つくらいのエディタならかなり高速に移動することができるので、ぜひOnivim 2にも欲しいところだ。
ターミナルの起動もそうだ。

また、底部ペインは驚くほどキーボードでの操作を受け付けない。
まだ実装されたばかりの機能なのかもしれないが、ここを触るときだけマウスを使わなくてはいけないのはハッキリ言って屈辱だ。

なんといっても致命的なのが、まだ日本語に対応していないことだ(白目)。入力済みの文字の表示自体はできるのだが、IMEがOnの状態ではエディタ上で入力中や変換中の文字が表示されず、確定して初めてエディタに反映する。
これでは日本人や非ASCII文字圏での常用はかなり厳しい。
もちろんこれは商用版では解消されているだろう。期待して待ちたい。

いろいろと文句も書いたが、Onivim2は何といってもまだアルファ版だ。
きっともうすぐベータ版が出るだろう。
その時こそ、我々は真のモダンVimの片鱗を目にするのだ。

😤😤😤 衝戟に備えろ 👹👹👹

脚注
  1. 2019年10月ごろにAtomの更新停止が話題になった。最近は少しコミットが増えている。 ↩︎

  2. beta版で手に入るらしい。 ↩︎

  3. ちなみに、Outrun Labs――Onivim 2の開発会社――の外部からのコントリビューションは、18か月を待たずにMITライセンスとなるらしい。頑張ろう(?)。 ↩︎

  4. すべての要素とは言ってない ↩︎

  5. Vimに限界がある、と言っているわけではない。限界を感じるのは個人の自由である。 ↩︎