spacemacsについて ~~spacemacsが最強で最高で神エディタであると思い始めた件~~

入門記事を書いています!! その2うpしました!! 

* [Spacemacs入門その1](http://qiita.com/nobkz/items/a0df6c87107401effd4c)
* [Spacemacs入門その2](http://qiita.com/nobkz/items/d1489cd5a3ed457323fb)

# spacemacsについて

最近、**[spacemacs](http://spacemacs.org/)**を使っていて、「これは神じゃね?」とか思っている。それについて書こうと思う。非常に感情的になっているので、注意してほしい。かなり長くなるかもしれないので、それも注意してほしい。ぶっちゃけ**ポエム**である。

spacemacsについては記事がいくつかある。
[Vimも秘伝のタレも飲み込むEmacsの超強力ディストリビューションSpacemacsまとめ](http://qiita.com/ryosukes/items/d0ec5094a9d3d636f7bb)
[6年間使っていたVimからEmacs(Spacemacs)に乗りかえた](http://layzie.hatenablog.com/entry/20160111/1452440731)

しかし、上記の記事では、spacemacsのすばらしさを十分に記述できていないと思ったのだ。


この記事は,**spacemacs**の機能について取り上げたものでは無く、畏れ多くも**spacemacsの僕なりの始めたキッカケの類**を書いたものである。spacemacsの入門については、また別に取り上げたいと思う。しかsi、この記事でもspacemacsの機能のいくつかは紹介するつもりである。

## spacemacsを使う以前

**spacemacs**を使う前、僕は、沢山のエディタを触ってきた。一番最初につかったのは**Emacs**だった。その後、**Vim**、TextMateやSublime、Atom,VSCodeを触ったりした。

### Emacs Lispの高い拡張性

その中で一番しっくり来たのが**Emacs**であった。理由はいくつかあるが、最も重要だと思う点は、**Emacs LispというLispで拡張が書け、そして拡張が容易である** という点である。Emacsは**Emacsコマンド**という命令によって、カーソルを移動したりできるのだが、**Emacs Lispで関数を書くことによって**でそのコマンドが作れるのだ。

たとえば、2文字進むコマンドはこのように書けば良い

```el
(defun forward-2-char ()
  (interactive)
  (forward-char)
  (forward-char))
```

雑な説明なのだが、(interactive)という命令によって、今書いている関数をEmacsコマンドにできる。そして、forward-charという命令を2回すれば良いのだ。非常に簡単である。これを**Emacsで評価**すると、`M-x`からコマンドで呼び出せる。

<img width="582" alt="スクリーンショット 2016-05-22 10.13.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/31381/278766f9-6ace-d363-2002-b57d6327dec0.png">

さて、毎回`M-x`で、Emacsコマンドを呼び出していたら面倒である。であるから、**`keymap`**という、キーとコマンドが対応させてあるEmacs Lispのオブジェクトがあり、それに登録する。

```el
(define-key global-map (kbd "C-f") 'forward-2-char)
```

Emacsは**モード**というものがあり、モードに対応した`keymap`があったりして、それによって`keymap`が多層になっている。上記のemacs lispでは、`global-map`という`keymap`に`C-f`というキー`forward-2-char`が対応させてある。`global-map`は全てのモードに共通してする`keymap`であり、入力したキー他に`keymap`が無ければ`global-map`で対応したEmacsコマンドが実行される。

僕はこのEmacsの高い拡張性に感動していた。さらに僕はプログラミングを始めて直ぐに`Lisp`を書いていたので、Emacs Lispでこどもの玩具のようにEmacs Lispでプログラミングを書いていたのだ。
(そしてほとんどの場合、**先人達のすばらしいEmacs Lisp**によって僕のおもちゃのコードは置き変えられていったのだが。僕はそれによってほとんどのおもちゃのコードを消してしまったのだ!!! 今思えば公開すれば良かったのかもしれない。が当時は公開する価値などなく、非常にはずかしいものだ! と思ったものだ。)


### Emacsその他のアプリケーションを連携、統合するもの

さて、この素晴しい拡張性によって、沢山の拡張が生まれて来た。そして、Emacsはその拡張性において、エディタというテキスト編集機能というものを超えて、emacsでコードをビルドしたりデバッグしたりする**IDE**のようなものになったり、メールを送受信する**メーラー**になったり、**カレンダー**になったり、**ブラウザ**のようなものになったに、更にまた**twitterクライアント**にもなったりもした。

しかし、一部の拡張はすべてEmacs Lispに書かれたものではない。**外部のプログラムを利用する**ことによって、生み出された拡張がある。そもそも、ビルドやコンパイルするためには、その言語のコンパイラを利用しなければならないし、純粋にEmacs lispのみで成り立つものでは無い。(Emacs Lispでコンパイラを書くことは可能だろうが、ほとんどの場合は外部アプリケーションと連携するだろう。) **Slime**や、 **RSense**や、**Ensime**やなどの、プログラミングなどはその例として上げられるだろう。

Emacs Lispは外部プログラムと連携する。とすれば、僕は更にもう一歩勧めて見たい。というのも、**Emacsは、外部プログラムと外部プログラムとの接合点になる**ということである。

たとえば、メールからとあるイベント招待状が来たとすると、それから、カレンダーに日時とイベント名を登録し、そしてtodoリストにイベントで準備するものをリストアップしておくみたいなものである。一般のOSの利用だと、アプリ同士が独立しているため、人の手の作業によって行なわれることが多いだろう。しかし、Emacsは、**OSの独立したアプリケーションを協調し、アプリ間の作業を自動化できる**可能性がある。

この編の話は、詳しくは

[lispを(なるべく)書かないコマンド作成講座(菅原泰樹)](http://dev.ariel-networks.com/articles/emacs/part3/)
[emacsは死んだ](http://cx4a.org/pub/emacs-is-dead.ja.html)
[Emacsで他の言語とRPC](http://qiita.com/kiwanami/items/939fab6ac6588d72edbd)
などの記事を参照すると良いだろう。

### Emacsと拡張とキーバインド

Emacsの魅力を語ってきたのだが、しかし、Emacsにも欠点がある。それは**デフォルトのキーバインドが良くない**のと、**キーバインドがたくさんあって思い出すのが大変**、 **キーの不足問題がある**ということである。

Emacsのカーソル移動のキーは、`C-f`、`C-b`、`C-p`、`C-n`である。これはほどんどの人達にとっては、慣れることが大変である。それぞれのキーがキーボード上では遠い位置になるので、これでカーソル操作というのはなかなか大変であろう。

ただ、フォローしておくと、`C-f`、`C-b`、`C-p`、`C-n`は覚えやすくもあるのだ。たとえば、`f`は`forward`、`b`は`back`、`p`は`previous`、`n`は`next`の頭文字だとすれば、なるほど、思い出すヒントとなる。

拡張も含め他のデフォルト設定のキーバインドも、何かの頭文字でキーバインドが作られていることが多い。なので覚えるヒントにはなる。しかし、**非常にコマンドが多くなり過ぎて、キーバインドが覚えられなくなる**のだ。

そういえば、 `Ctrlキー`を押しまくる問題もあるかもである。しかし、僕としては、その問題はキーボードの本質としては、**キーの不足問題**にあると思っている。というのも、キーボードは沢山のボタンがあるのだが、ほとんどが文字入力に使われてしまい、**文字入力でないことを示すサイン**として`Ctrl`が選ばれた、ということだと思う。

この編の解決として、以前のはてなのブログで書いたことがある。

[キーバインドは覚えるな！(emacs)](http://nobkz.hatenadiary.jp/entry/2013/06/20/163632)

またこれと類似したものとして、このような深町さんが記事を書かれている。

[「Emacsのトラノマキ」連載第16回「元Vimmerが考えるEmacsの再設計」(深町英太郎)](http://dev.ariel-networks.com/wp/documents/aritcles/emacs/part16)

また、更にキーバインドを思い出すものとして [which-key](https://github.com/justbur/emacs-which-key)というemacs拡張が作成されたりしている。

つまり、発想としては、キーバインドの不便さも、キーバインドの再設定や、emacsの拡張によって解決してしまおう!!!ということだ。

そして、これらのキーバインドに問題ついて僕はもっと、よりよりものを探して行った。そして、**Evilを使って、さらにEmacsの拡張をして、もっとよりより体験のためにすばらしいエディタの環境を**作ろうとした。この点について紹介しよう。その前に、**Evil**について、述べておこう。

余談だが、**Emacsは小指が痛くなるみたいな話がよくあるが、その話は糞だと思う**。[emacsで小指を鍛えたみたいなことを誇っているような記事](http://d.hatena.ne.jp/tomoya/20160422/1461275242)が上げられているが、どう考えてもアホである。**そんな記事を書いてなんになるんだ**。(まぁ一般にはネタとしては面白いかもだが) **いままで何やってんだ?** という気分である。というのも、適切にemacsを設定、拡張して、ちゃんと使っていれば**入力するコマンドも少なく最適化されて**、`Ctrl`を押しまくるといった自体にはならない筈である。だから、そうならないのはEmacserとしてそれはどうなんだ? と思うのである。なぜ**自分のEmacsをキチンとデザインしない**のだ? (そもそも、周りの人間でEmacsを勧めて、コマンドの調べ方、拡張の仕方などを教えて使っている人達で小指が痛くなるとかそういうものは見たことが無い)

まぁ、小指問題はEvilを入れてしまうと、一気に解決してしまうことも多い。とりあえず、Evilについて紹介する。

### VimとEvil

EvilはEmacsをVimのように使うものだ。(参考: [EmacsをVimのごとく使う](http://tarao.hatenablog.com/entry/20130303/evil_intro) )

僕はあまり、Vimを書く経験は少ないのだが、Vimも良いエディタと思っている。その魅力としては、やはり、Vimの`モード`という考えである。

Vimの`モード`というのは、Vimがテキストの編集のためのいくつかのキーバインドの状態を持ち、適切な状況に合わせて、エディタの状態を変え、よりよいキーバインドを使おうというものだ。ノーマルモードで、カーソル移動、インサートモードでテキスト入力、ビジュアルモードでテキスト選択、コマンドラインモードによって、Vimのコマンド実行など、ユーザは適切にモードを選択し、それぞれのモードによってテキストを操作して行く。

Vimは、エディタの`モード`によって、エディタの状態を変えながら操作していくため、複雑のように思える。しかし、Vimはそのおかげで、**キーバインドが目的に合わせてグルーピングされ整理される**のだ。**テキストを編集というのは、様々な目的に分割できる**。テキストを選択したり、入力したり、カーソルを移動したり、など。それは、ある**テキストを編集するという目的を、別々のよりシンプル目的へ分割している**という見方ができる。Vimはその小さなシンプルな目的を解決するために、モードを作り、キーバインドすれば良い。

また、モードによって、**文字挿入にキーを取られない**。という利点もある。これによって、**キー不足問題**は解決する。

一方として欠点としては、**いちいちモードを切り変えないといけない**ということである。Emacsの場合は、テキストを入力しつつ、カーソル移動ができるが、Vimの場合は一拍置かないといけない。だから、Emacsを使っていた物からすれば、近いところに移動したいのに、いちいち切り変えるのは面倒なのだ。ただし、Vimの`モード`によって、素早く遠くのところまでカーソルを移動させることができる面は便利ではあるのだ。

Evilは、**上記にVimの利点をすべてEmacsに取り込む**ことができる。Evilでは、Vimの`モード`は、`ステート`になる(既にEmacsでは`モード`は別の概念として存在する)。 つまり、Evilは`ステート`という概念をEmacsに導入し、Emacsに編集状態を作り出すのだ。つまり、カーソルを移動が楽になる、ノーマルステート、テキストを入力するインサートステート、テキストを選択するビジュアルステートなど、が導入されるのだ。


### Evilの拡張

さらに、EvilはEmacsであるため**拡張**することができる。Evilの拡張とは何か? それは、大きく分けて

* 既存のステートにキーバインドを作る
* コマンドラインステートにコマンドを増やす
* 新しいステートを作成する

ということである。

とくに考えなければ、既存のステートにキーバインドを適切に設定するとか、またコマンドラインステートにコマンドを増やす、だろう。そのアプローチでも十分に強力だと思う。

しかし、僕は**新しいステートを作成する**ということに、Evilの魅力を最大限に感じたのだ。そして、いくつかのステートを作ったのだ。たとえば、プログラムをコンパイルや評価をするためのステートや、デバッグのためのステート、通常のカーソル移動を拡張してemacs lispのための移動ステートや、 **paredit**の特殊な操作のためのステートを作ったのだ。

とすると、沢山のステートが存在するようになり、すると、沢山のステート毎の`キーバインド`を覚えなければいけなように思えるだろう。僕はその問題に当たった。その解決のため、僕は、キーマッピングを最初から表示する拡張を作った。`which-key.el`のようなものだ。`which-key.el`の画像を貼っておく。

<img width="743" alt="スクリーンショット 2016-05-22 13.19.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/31381/71a85bbe-57fd-4c79-bb4f-debc16e2c3f9.png">

今はwhich-key.elをそのまま設定して利用している。

### 理想のエディタを構築する

ここまで、僕が、Emacsの設定を弄りを、Evilを導入したり、拡張し続けた。それは、別の見方からすると、**エディタの再設計**であると今にして思う。すると、**理想のエディタ**を構築することに近いのだ。

**僕は、どのようなエディタが欲しいのか?**ってのを常日頃考えている。僕は最近UXデザインを学び、UXなどの勉強をして、「ユーザが何を欲しいか?」ということを考えるようなった。すると**人間は自分が本当に欲しいものを気づくことができないし、説明できない**のということに気づくのだ。だから、いろいろなエディタを触ったり、自分で拡張しながら、それを探すのだ。

そのような仮定において、どのようなエディタを考え、僕はエディタをリデザインしたのだ。拡張したか?ということをまとめみよう。

実は、以前、emacs福岡を開催したときに、自分の環境について発表したことがあるのだが、(そのスライドである : http://slides.com/nobukazuhanada/evil#/8 ) その発表で話たことでもある。

どのようなエディタを僕は考えていたか?である。

まず、**ノーマルステートの拡張**である。ノーマルステートで、カーソルの移動や削除のみならず、コンパイルやファイルオープン、バッファの削除などを設定した。`f`でファイルオープン、`q`でバッファkill、 `c`でコンパイルというキーバインドを設定した。更に、`r`でシェルコマンドを呼び出せるようにした。

さらに、**コマンドラインステート**の拡張である。`:make`で、makeコマンドを呼び出し、`:rgrep`で、ディレクトリの以下の再帰的な検索、`:align`でテキストの整形ができるようにし、`:x`でEmacsの`M-x`と同じ効果にしたのである。

**挿入ステート**は、通常のEmacsのキーバインド設定に似たようなものにした。**auto-complete**や、**yasnippet**、**paredit-mode**などの、キーバインドは変更している。

あと、大きく変更したのは、**テキストの移動や削除、置換の特殊なステート**を作成したことである。ノーマルステートでは`x`と`d`で削除ができるが、これを`d`に統一した。そして、`d`が削除や`hjkl`で移動や`s`で文字置き変えにしたのである。そして、その前に文字の量の単位を設定できるようにし、たとえば、`4d`で4文字削除、`4lj`で4行移動、などというように、移動量や削除量、置換量を設定できるようにした。

ここまでが、spacemacsを出会う前までの設定であった。僕なりに理想を追求したのである。

## Spacemacsの衝撃

ここまで、自分なりに理想のエディタを考えて、設定し、拡張しEmacsを変えていったのだ。とすると、元々の何も設定していない、Emacsとはかなりかけ離れたものになって行くのである。なぜそうなって行くのであろうか? 

僕はなんとなく、**元々の素のEmacsの操作**がやはり良くないのだという思いが生じ始めていた。

「ユーザが拡張できる。拡張しやすさがある。」というのはすごく素晴しい一面がある。しかし、Emacsの場合は、ユーザがそもそも、「**拡張しなれけばらなない状態**」であったのだ。そのようになるというのは、もともとEmacsが**ユーザフレンドリィに、ユーザのため**に考える設計に失敗したのであった。

そう考えていた時、**spacemacs**を紹介されて、触り始めたのであった。そして、僕は衝撃を受けた。僕はすごくすばらしいものだと思ったのだ。そのいくつかを紹介しよう。

### spacemacsはユーザに良く考えられた設計

spacemacsは、EmacsでもVimでも無い。**僕の理想とするエディタに近い**と僕は思う。その理由としては良く**考えられたキーバインド**である。(勿論不満が無いわけでは無いが。)

最初から、**キーバインドが素晴しい**のだ。それは以下の幾つかの点になる。

まず、**スペースキー(`SPC`)を活用した**ということである。[公式のドキュメント](http://spacemacs.org/doc/DOCUMENTATION.html)では`SPC`をevilの`leader key`に設定することにより、`RSI` (Repetitive Strain Injury、反復的なストレスによる障害)を低減したとある。

そして、**キーバインドがとても覚えやすく**設計されているのである。たとえば、ファイル関連の操作であればとりあえず`SPC f`を、バッファ関連であれば`SPC b`を、git関連であれば`SPC g`を押下するれば良いのである。これは、僕のノーマルステートの拡張と似たような発想であって、すごい良いと思ったのである。

そして、**`:`を押すと、Vimのコマンド、`SPC :`を押すとEmacsのコマンドつまり`M-x`を押したのと同じ状態**になるのだ。この点において、僕の以前のEvilの設定`:x`と似たようなもので、非常にマッチする。

僕がSpacemacsに切り変えて、起ったのは**大半のEvilの自作のステートが必要なくなった**ということである。僕はもともと、**ステートを作り過ぎていたのだ**。だから、大半の設定ファイルを捨ててしまった。

そして、**キーバインドがspacemacsでは思い出しやすい**ということがある。それは殆ど`which-key.el`であり、それも僕が設定していた拡張を捨てる動機にもなった。最早、**キーバインドを沢山覚える必要が無い**のである。

### spacemacsのその他の利点

そして、spacemacsは通常のemacsをベースにしているので、もちろんemacsの拡張性はある。そしてさらに、spacemacsはlayerという概念があり、これにより、設定をスッキリされることができる。このことに関しては後日別の記事でまとめよう。

あとこれはどうでも良いが、アイコンがカッチョイイし、見た目が良い。

<img width="1280" alt="スクリーンショット 2016-05-22 14.56.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/31381/dd4a3f8b-65c5-bc4c-cda1-330e3d924a35.png">


### spacemacsは、僕の拡張に近く、さらに超えている面があり、理想に近い

**spacemacsは**上記以外の様々な点で、良く考えられていると思ったのであり、僕の拡張や設定を非常に近いものであった。それ以上に、**spacemacsは僕の拡張を超えている**と思ったこともたくさんあった。

### もちろん不満もある。

もちろん不満もいくつかはある。なので、設定ファイルを弄り続けているのではある。それらの不満は設定の変更や、拡張をすればいいのだ。

## 最後に

長くなって申しわけない。ここまで読んでくれたら幸いである。

以上である。

もし、開発を通して「こうであったらな」とかあれば僕に教えてほしい、そういう議論は大好きだ。もしかしたら、更に寄り良いものができるかもしれない。

今後、spacemacsのlayerや、オススメの設定など晒して行くつもりなので、期待してほしい。