Emacs という名前の Vim があるようですね！

[Emacs Advent Calendar 2020](https://qiita.com/advent-calendar/2020/emacs) の 3 日目の記事です。

Vimmer が [Evil](https://github.com/emacs-evil/evil) + Emacs を １からサクッと設定します。丁寧に解説するので、 Evil Emacs を使っていきましょう！

> 付け焼き刃なのはご了承ください。

## Emacs: Become Evil

と思ったのですが、 Emacs は敷居が高かったです。コツを 100 ~ 300 個くらい集めないと入門できませんでした。すべてを書いたら読み切れませんし、情報を絞ると、どこかでハマるのでナンセンスだと思います。

なので、全コミットと解説を GitHub に置き、この記事では余談を書きます。

[evil-emacs-2020](https://github.com/toyboot4e/evil-emacs-2020) (GitHub)

この設定の特徴は、 Vimmer の視点で 1 からコミットを作ってあることです。僕は Emacs master では無いので、究極の設定とは行きませんが、入門には活用できるかもしれません。

> `org-mode` の話なども出ず、多くのコミットが Evil の設定に費やされています。

### 事前知識

この記事は、以下のようなターミナル／ Vim の経験を想定して書かれています:

* [新しいLinuxの教科書](https://www.amazon.co.jp/%E6%96%B0%E3%81%97%E3%81%84Linux%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E4%B8%89%E5%AE%85-%E8%8B%B1%E6%98%8E/dp/4797380942)
* [実践 Vim](https://www.amazon.co.jp/dp/B00HWLJI3U/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
* (Git の本)

### 設定中の方針

`emacs` はターミナル版を使用します (`emacs -nw`) 。方針としては、なるべく初見を想定しました:

* `git` は Emacs から `C-z` を押してターミナルに戻って使用する
* コードの折り畳みを重視する (`zm`, `zr`, `za`) (`hs-minor-mode`)
* ELisp の自動フォーマットを有効にする (4 タブで)
* `K` でヘルプを表示する
* パッケージのリンクをコードに入れる (`gx` で開く)
* ターミナル上での入力 (マウスやクリップボード) のサポートについて言及する
* Evil / Emacs 間の切り替え (を無くす設定) について言及する

などなど……。
知りたいことを知りたい順番に知ることは不可能ですが、少しでも早く理想に近づけましたら幸いです。

Doom Emacs や Spacemacs のような distribution を使わなかったのは、結局、自分で調整する必要が出ると考えたためです。後から Doom Emacs などを導入しても良いと思います。

### リファレンス

『これさえ読めばいい』というものは無さそうです。随時、パッケージのドキュメントや、人の設定ファイルを読んでいきます。

* [Evil - Documentation](https://evil.readthedocs.io/en/latest/index.html): キーマッピングのやり方など
* [evil/evil-maps.el](https://github.com/emacs-evil/evil/blob/master/evil-maps.el): デフォルトのキーマップの確認
* [evil-guide](https://github.com/noctuid/evil-guide): キーマップなど
* [Evil - EmacsWiki](https://www.emacswiki.org/emacs/Evil): オプションなど
* [Evil: EmacsをVimのごとく使う - 導入編](https://tarao.hatenablog.com/entry/20130303/evil_intro): オプションなど
* [Emacsモダン化計画 -かわEmacs編-](https://qiita.com/Ladicle/items/feb5f9dce9adf89652cf): GUI のパッケージなど

入門 GNU Emacs も買ったのですが、 Evil ユーザとしては、あまり読む必要を感じませんでした。 Emacs 自体に詳しくなる必要は無いかもしれません。

[2020年代のEmacs入門](https://emacs-jp.github.io/tips/emacs-in-2020) では、 `use-package` ではなく `leaf.el` を使った Emacs 入門について書いてあります。コピペが辛くなるので `use-package` を使いましたが、 `leaf` は良さそうですね。

## 余談集

### パッケージ紹介

[Centaur Tabs](https://github.com/ema2159/centaur-tabs) は、バッファをグルーピングしてくれるバーです。右画面では Emacs の設定ファイルを開いていますが、左画面のバッファとは別グループとして表示されるため、多少設定ファイルを開いても、タブバーは有用なままです。

![centaur-tabs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/54865703-a405-6d9d-bede-1cfa9ced2dba.png)

[Hydra](https://github.com/abo-abo/hydra) でモードを作ると、設定したヒント (キーマッピング) を表示してくれます。 ↓ は僕が設定した [ウィンドウ操作モード](https://github.com/toyboot4e/evil-emacs-2020/blob/main/elisp/hydra.el) です。モードを脱出するまで、このキー操作を使用できます:

![hydra.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/10769242-ce03-c149-969e-d68d5ec0f057.png)

[Ivy](https://github.com/abo-abo/swiper) が fuzzy finder です。 **プレビュー付きでも軽量** です。プレビューするまでバッファを読み込まないためだと思います。僕は `C-l` でプレビュー、 `C-k` で kill にマッピングしています:

![counsel-rg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/3a540e40-242c-f9b6-8320-2b3c9b4e41d7.png)

[fzf-preview](https://github.com/yuki-ycino/fzf-preview.vim) 並みの検索ができていい感じです。 [ivy-posframe](https://github.com/tumashu/ivy-posframe) を使ったら、 floating window っぽくできると思います。

[magit](https://magit.vc/) は Emacs から interactive に Git を使えるモードです:

![magit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/e383c55c-43c0-d5b2-f8a6-a8d9dfa5919f.png)

Distraction-free モードを hook して中央寄せにして表示しています。使いこなしたら無敵の `rebase` ができるようになるのではないでしょうか。

> 僕はまだ `C-z` を押してコマンドラインから `git` を使っています。

### Emacs のドキュメント文化

Emacs パッケージは、 README が非常に丁寧に書かれてあることが多いです。 Google 検索では見つからない話もドキュメントにはちゃんと書いてあります。素晴らしい！

裏を返せば、じっくり読まないと使用できません。 `Plug "author/package"` でパッケージ追加！　みたいにサクッとは行かず、時間をかける必要があります。

### ハマった話

Evil を入れるだけでは Vim にはならず、僕は 3 回挫折しました。その後も Emacs をメインエディタにするまでの道は長かったです:

* 『Fuzzy finder からファイルのプレビューができない』  
→ できる。ただしドキュメントを丁寧に読む必要がある。
* 『x を "_x にマッピングしたい』  
→ 可能だがイレギュラーなマッピングが必要。
* 『Rust の LSP (`rustic`) がカーソルをファンキーに動かしてしまう』  
→ 事実。ただし `rustic` にフォーマットを任せなければ問題無い。

ドキュメントさえ読めば良い……とも行きません。特に Evil ユーザの場合は、微妙な積み重ねが必要です。

また、マイナ環境のためか、 [明らかに思えたバグ](https://github.com/redguardtoo/evil-matchit/issues/129) に何度か出会いました。その代わり、報告すると 1 日で直してくれました (3 回経験あり) 。大変ありがたいです。

ときどき [Emacs JP](https://emacs-jp.github.io/) の Slack で質問させていただいています。特に『何かができない』という確証を得ることは難しく、最終確認として Emacs マスターに聞けると助かります。僕は 9 割くらい愚かな質問をしてしまいますけれど…… (T^T)

### Emacs のターミナル上の制限

Emacs は、 GUI に比べてターミナルが冷遇されているように見えます:

* アイコン表示は (普通は) できません。
* [Posframe](https://github.com/tumashu/posframe) (floating window に相当する拡張) が使えません。 `popup.el` があるものの、あまり広くサポートされていないと思います。
* Evil のクリップボードのサポートが [怪しい](https://github.com/emacs-evil/evil/issues/380) です (つまり、 `"+d` などができません) 。誰かが解決しているとは思うのですが。

ターミナル特有の問題として、 Vim でも Emacs でも一部のキーマッピングができません (Ctrl+Shift+key, Ctrl+m など) 。 Emacs では Ctrl+Space もマッピングできないと思います。

NeoVim の方はターミナルがメインなのか、アイコン表示、 floating window, クリップボードを完備しています。キーマップの対応範囲も若干広いです。

### Emacs ／ Vim の比較

僕のような浅い Vimmer としては、 Evil Emacs は Vim と大差ありません。

ディテールの違いとしては:

* Vim の方が見た目が良いと思います。配色がビビッドですし、ターミナルでもアイコンを使えます。 Emacs はターミナルだと (24 bit color を有効にしても) 色がおかしくなると思います。また、ターミナル上でのアイコン表示は至難の技です。
* Evil (Emacs) では、『現ディレクトリ位置 = 現ファイルの位置』となり、 `:e` が使いにくいです。替わりにサイドバーや fuzzy finder を使います。
* Emacs の undo, redo は、 (特に設定しないと) マクロじみています。こちらの方が本来のあり方という感じで良いと思います。
* Emacs は **起動後の動作が速い** です。
    * [Goyo.vim](https://github.com/junegunn/goyo.vim) では遅かった distraction-free writing への切り替えも速いです。代わりに、 `gj` や `gk` が崩れます。一長一短ですね。
    * Emacs の fuzzy finder は **preview 付きの検索も非常に速い** です。 Preview キーを押すまでバッファが読み込まれません。 NeoVim の方は、そもそも floating window が重そうです。

### その他エディタの比較

脱線しすぎな気もしますが、他のエディタの感想も書いてみます。

VSCode (CustomizeUI を適用済み); 

![vscode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/c0b945e0-ec38-0763-4b6c-da3f6c67807d.png)

何と言ってもターミナルペインが良いですね。キー 1 発で全画面表示をトグルできますし、ここに `tmux` を呼んでも OK です。 VSCode のターミナルペインに匹敵するプラグインは、他のエディタで見たことがありません。ただ、 VSCode には良い fuzzy finder が見つかりません。ターミナルから grep します。

ターミナル版 Emacs:

![emacs-tui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/72607838-8706-9583-029f-fae489218791.png)

この頃は Evil Emacs のディテールが気に入っています。 NeoVim の設定が悪いのか、重くなってしまったこともあって、当分 Evil Emacs を使います。

GUI 版 Emacs:

![emacs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/bad22653-4875-fcad-96b1-2e82088301ff.png)

検討中です。ボトムバー (modeline) が分厚いのが気になります。タイトルバーは自分でコンパイルしないと消せなさそうです。

NeoVim:

![nvim.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/e0210681-72f4-e72b-ec8c-96e629e5d590.png)

配色はヴィヴィッド、アイコン表示あり、 LSP は VSCode 並み。やはり良いですね。足りないのは[centaur-tabs](https://github.com/ema2159/centaur-tabs) (バッファをグルーピングしたバー) 相当のものかな。 [vim-wintabs](https://github.com/zefei/vim-wintabs) は開発が止まっていますし……。マルチルートディレクトリ対応のサイドバーは、 [fern.vim](https://github.com/lambdalisue/fern.vim) でいけるんでしょうか。最近の NeoVim について行けていません。

一応 Sublime:

![sublime.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/643a54db-91f1-6519-6069-1faab40d76d8.png)

Sublime は origami と FileBrowser, LSP と Rust-enhanced の相性が悪くて止めました。 Terminus でもキーの二重押しが発生して辛かったです。軽量でセンスも良いエディタなだけに、無念です。

### Vanila Emacs

設定ファイルを Emacs 縛りで書いたので、設定無しの Emacs も触れるようになりました。スクロールが半ページ単位だったり、センスの良いデフォルトがあると思います。

Evil 無しでも悪くないですね。バニラ Emacs へ移行するとしても、左手で文字を書くよりは楽な変化だと思います。ただ、単語単位のカーソル移動などで修飾キーを多用するので、そこに不安があります。

## 終わりに

新しい環境へ移行すると、手も足も出ない期間ができて大変です。しかし得るものも多くて良かったです。 Evil Emacs に興味のある Vimmer の方、 Emacs の方は、良かったら [evil-emacs-2020](https://github.com/toyboot4e/evil-emacs-2020) をチェックしてみてください。

今後の展望としては、 AsciiDoc のパッケージを作ってみたいです。また、第 3 の Vim 、第 2 の tmux 、あるいは新たなターミナルの登場も願っています！