Oniで作るNeoGvim


***18/06/28 追記***
*Oni 0.3.6 に対応しました。*
*参考: [What's New in Oni](https://github.com/onivim/oni/wiki/Whats-New-in-Oni)*

-----

NeovimはVimとは異なりGUI版が提供されないため、[多くの実装](https://github.com/neovim/neovim/wiki/Related-projects#user-content-gui)が第三者によって作られています。
今回はその中の[Oni](https://github.com/onivim/oni)を使って**「どこでも使えるGvim的なNeovim」**を仕上げてみようと思います。  

## Oniとは
みんな大好きElectronをベースにしたNeovimフロントエンドのひとつです。開発が活発なので将来性もありますし、Electronベースなので表示が大変綺麗な上にマルチプラットフォームです。
しかしVim/Neovimを常用していないユーザーもターゲットにしているためか、提供される便利機能がかなり多いです。

ちなみに競合アプリの[Nyaovim](https://github.com/rhysd/NyaoVim)は無効化する親切機能がないため、よりGvim化に適していると思います。今回は解説しませんが、割とうまくいきました。


## どうなるのか
- 見た目はGvimそのもの
- ライブラリ特有のGUI、Oniの親切機能がNeovimのあらゆる機能を阻害しない

![Screenshot-0.3.2@Antergos](https://qiita-image-store.s3.amazonaws.com/0/205011/89bf53c5-7e1a-b885-1fde-5f6f94860a4d.png)



## まずは導入
[公式情報](https://github.com/onivim/oni/wiki/Installation-Guide)を元に導入してください。Windowsは非公式ながら[Scoop](http://scoop.sh/)の[extras bucket](https://github.com/lukesampson/scoop-extras)からもインストールできます。
なおLinux(Ubuntu/Debian/Fedora/CentOS/ArchLinux および派生ディストリビューション)ではバージョン0.2.1以上のneovimを事前に導入する必要があります。


## さっそく設定してみる
以下、Gvimっぽくなる設定の例。
設定ファイルはOniメニューバーから *Oni* → *Preferences*  → *Edit Oni Config* の順にクリックすることで編集できます。

参考: [Configuration](https://github.com/onivim/oni/wiki/Configuration)

```typescript:~/.config/oni/config.tsx
// PATHは適宜自身の環境のものに置き換えてください。
import * as React from "path/to/react"
import * as Oni from "path/to/oni-api"

export const activate = (oni: Oni.Plugin.Api) => {
    oni.input.unbind("<C-p>")
    oni.input.unbind("<S-C-p>")
    const isNormalMode =
        () => oni.editors.activeEditor.mode === "normal"
    oni.input.bind("<C-:>", "commands.show", isNormalMode)
}

export const configration = {
    activate,
    "autoClosingPairs.enabled": false,
    "commandline.mode": false,
    "editor.errors.slideOnForce": false,
    "editor.fontFamily": "Cica, Dejavu Sans Mono, Consolas",
    "editor.fontLigatures": false,
    "editor.fontSize": "11px",
    "editor.fontWeight": "normal",
    "editor.linePadding": 1,
    "editor.quickInfo.enabled": false,
    "editor.scrollBar.visible": false,
    "oni.loadInitVim": true,
    "oni.hideMenu": true,
    "oni.useDefaultConfig": false,
    "sidebar.enabled": false,
    "statusbar.enabled": false,
    "tabs.mode": "native",
    "ui.animations.enabled": true,
    "ui.colorscheme": "onedark",
    "ui.fontSmoothing": "auto",
}
```
※**「config.jsが出てくるよ」**という元Oniユーザーの方は、config.jsをリネーム/削除すれば上記手順でtsx版が開けます。
参考: [Migrating Configration to TypeScript](https://github.com/onivim/oni/wiki/Migrating-Configuration-to-TypeScript)

※ **「config.tsxが反映されなくなった」**という方はconfig.tsxの保存場所を確認してください。現行バージョン(0.3.6)では`$HOME/.config/oni`もしくは`%APPDATA%/oni`になります。

以下、各機能の簡単な解説。

### activate
起動時の諸々の設定が行えるらしいです。
「Oni側のキーバインド設定はここで行なえ」とのことなので、上記コードではCtrlPユーザーにとって不要な[FuzzyFinder](https://github.com/onivim/oni/wiki/Features#fuzzy-finder)の無効化とたまに欲しくなるCommandPaletteのリマップを行いました。
もしOniの機能をほとんど使わないのであれば`oni.input.unbindAll()`を使えば完全に素のNeovimにできます。対していくつかのマッピング(Alt-F4など)を残しておきたい場合は、[ソースコード](https://github.com/onivim/oni/blob/master/browser/src/Input/KeyBindings.ts)よりデフォルトのキーバインドを確認し不要なものだけ無効化します。

### autoClosingPairs.enabled
なんとOniではデフォルトで[勝手に括弧を閉じてくれる](https://github.com/onivim/oni/wiki/Language-Support#auto-closing-pairs)らしいです。もちろん拡張可能。つよい。
なお同様の機能をもつプラグインを既に当てている場合は挙動がおかしくなるので、無効化して下さい。

### commandline.mode
Oniのデフォルト設定ではコマンドモードの入力をSublimeTextやElectron系エディタでお馴染みのコマンドパレットに似たUIで行うことになります。
画面上部に出るので大変見やすいですが、置換のようにテキストを見つつ作業したいときなんかは邪魔になるので、致し方なく無効にしておきましょう。

### editor.errors.slideOnForce
エラー箇所にカーソルがあるとき、その内容を表示するかを決めることができます。
限られたいくつかの言語でしか使えない上に、プラグインやQuickFixでなんとかなりそうなので、無効化。

### editor.fontFamily / fontSize
フォント設定。Gvimのようにエスケープを入れたりしなくていいのは嬉しいポイント。
ちなみに最近は[Cica](https://github.com/miiton/Cica)フォントを愛用しています。この場をお借りしてひっそりと感謝の言葉を送らせていただきます。

### editor.fontLigatures
フォントの[リガチャ(合字)](https://ja.wikipedia.org/wiki/%E5%90%88%E5%AD%97)を使うかどうかを決めることができます。リガチャ対応フォントを使っているけどリガチャが嫌い、という変なお方でない限りは無縁な設定だとは思いますが、念の為ご紹介(ちなみに初期値は`true`)。

### editor.fontWeight
**※バージョン0.3.6以降のみ**
フォントの太さ(ウェイト)を指定できます。既定値は`normal`です。

### editor.linePadding
行間の空白をピクセル単位で指定できます。デフォルトは 2 ですが、詰めている方が好きな方は 1 にしてもいいでしょう。なお非整数値の場合は(環境にもよるとは思いますが)一部表示がおかしくなるのでオススメはしません。

### editor.quickInfo.enabled
[QuickInfo](https://github.com/onivim/oni/wiki/Features#quick-info)(カーソル位置にある変数や関数の情報を表示する機能)の有効化ができます。
とても綺麗かつ便利な反面、こいつも限られたいくつかの言語でしか利用できない制限があるので、ここはなくなく無効化。

### editor.scrollBar.visible
スクロールバーの表示設定です。`editor.scrollBar.cursorTick.visible`が有効であればファイル全体に対する相対的なカーソル位置と現在画面表示している領域がスクロールバー上に重ねて表示されます。
完全なるGvim化を目指すなら`false`にしておきましょう。

### oni.loadInitVim
ユーザー定義のinit.vimを読み込むかを設定します。
これがfalseだとターミナルNeovimでは読み込むのにOniでは……となってしまうのでかならず`true`に。

### oni.hideMenu
起動直後にタイトルバー直下のメニューバーを表示するかを決めます。
表示スペースを確保したいので`true`に。必要になったら他のElectron系エディタ同様、Altキーを押せばまた出てきます。

### oni.useDefaultConfig
Oni側が用意してくれたinit.vimを読み込むかを決めます。
思わぬところで機能が上書きされたりすると困るので、無効化。

### sidebar.enabled
VisualStudioCodeのようなカッコいいサイドバーを表示するかを決めます。
私はファイラーもgrepもプラグインに任せているので、無効化。

### statusbar.enabled
エディタ下部に独自の[ステータスバー](https://github.com/onivim/oni/wiki/Features#status-bar)を表示するかを決めます。これもかっこいい。
ちなみに表示内容はPowerline系プラグインで事足りるものばかりですが、カレントディレクトリやGitリポジトリの情報などをプロポーショナルフォントで表示できるという特徴があります。今後の進展次第では併用推奨になるかも。

### tabs.mode
タブの表示形式を決めます。デフォルトではAtomに似たグラフィカルなタブを出してくれます。
大変かっこいいのですが、私はタブバーにファイル情報とかも表示させる派なのでNeovim本来のCUI形式にしています。これは`native`を指定することで実現できます。

### ui.animations.enabled
エラー時のポップアップなどのアニメーション設定を決めます。
ここはお好みでどうぞ。

### ui.colorscheme
Neovimのカラースキーマを上書きすることができます。
ここはかならずinit.vimに書いてあるスキーマと同じものを設定しましょう。指定しない場合はデフォルト設定である[Nord](https://github.com/arcticicestudio/nord-vim)へと上書きされます。

### ui.fontSmoothing 
フォントのアンチエイリアス設定です。GvimではKaoriyaさんのパッチで提供されているようなアレですかね(あそこまで詳細には決められないけど)。
とりあえず`auto`にしておくといいのではないでしょうか。

## 雑感
私はOniを使い始めてからも様々な機能や設定が追加されてきました。その中でもVSCode風のサイドバーの追加やOni独自のプラグインに関する指針などを見ていると、このプロジェクトはより**「すべてのVimキーバインドが使えるモダンエディタ」**という方向に向かって進化しているように思えます。これは公式WikiからGvim化の記事が削除されたことや、各種設定やプラグインにVimScriptを使わないことを宣言していることからも容易に推察できます。

そのため、このような記事を書いておいてアレなのですが、どちらかというとOniはNeoGvimに向いていないと逆説的に言えることになります。無効化しなきゃいけない設定は多いしdotfilesとして管理もしにくいという問題があります。対して冒頭に書いたNyaovimは簡単なHTMLを書けばすぐにGvim化できますし、Electron製ではないですがNeovim-qtに至っては`--no-ext-tabline`オプションを付けて起動するだけで済みます。正直な話、NeoGvimが欲しいのであればこれら2つを使うことをオススメします。

それでもOniは現時点(2018/06/28)では押下キーのプレビューやプラグインなしで括弧補完やインデントライン表示をしてくれるという他のフロントエンドではあまり見ない特徴を有していますので、これらが必要な人はあえてOniをNeoGvimにしておくのも悪くはないと思います。

対して、JS用モダンエディタのとしてのOniはなかなかに魅力的です。現時点ではプラグインの利用環境すら作られていないため、ある程度充実させたかったらまだVimScriptの力を借りなければいけないし、Oniの提供する機能との競合に気を配らなきゃいけないという厄介な点も残ってはいます。
しかしAtomやVSCodeと違ってすべてのVimのキーバインドがプラグインなしで誤作動なく使えますし、ここ最近のアップデートからOni独自のVimキーバインドに関するチュートリアルも追加されてきています。他にもJavaScriptやTypeScriptなどは補完に関する設定も充実し始めてきています。そういった点を踏まえると、いわゆる思考の速度での編集を可能とするVimキーバインドに魅力を感じる人にとってはひとつの候補になるのではないでしょうか。

-----

以上、とりあえずGvimっぽい見た目と挙動にする記事でした。
ルールとマナーを守って楽しくNeovim!!