見出し画像

Emacsのコマンドやキーバンドは別に覚えなくてもいい

こんにちは、おぎいです。
ナビタイムジャパンで動態管理システムの開発・運用を担当しています。

本記事は先日NAVITIME_Techのnoteで公開されました「Vimの思想を取り入れて開発速度を2倍に」で取り上げられた「Vim」と双璧をなすテキストエディタ、「Emacs」の紹介記事です。
「Vim」と「Emacs」はしばしば対立して語られますが、「Vim」とはまた違った方向性で便利なものであると私は考えています。
「Vim」の記事が公開されたので、「Emacs」についても紹介したいと思い、筆を執らせていただきました!


読んでほしい方

本記事は以下のような方を対象にしています。

 ● 既に「Emacs」を利用していて「Emacs」をもっと便利にしたいという方
 ● 「Emacs」に興味はあるが、難しそうで手を出せていない方

なぜ上記のような方を対象にしているか

「Emacs」は「Vim」のように、思想を取り入れることでどこでも使えるというようなものではないと私は考えています。
もっと言ってしまうと、なにも手を加えていないpureな「Emacs」はとても便利とは言えないですし、私も使いたくはありません。

しかし、以下のような理由から「Emacs」をお勧めしたいです。

● いろんなパッケージがあるので作り込み始めたら便利になるのは確か 
● elispで拡張機能が書けるため、自分好みの新機能を作ることが簡単
● 同様の理由で既存パッケージを自分好みにチューニングすることが可能

「Emacs」の高い拡張性は開発用途に閉じません。下記のような用途にも拡張することができます。

● Trello や Todoist と連携したタスク管理
● メールクライアント
● Slackクライアント
● Twitterクライアント

「Emacs」のあの無骨なウィンドウがTwitterクライアントになると思ったら、ちょっと面白くないですか?


本記事の内容

本記事では「Emacs」を使っていく上でぶつかるであろう2つのハードルを解決してくれるパッケージの紹介をします。

● キーバインド、コマンドが覚えられない
● 設定の仕方がわからない

キーバインド、コマンドが覚えられない

pureな「Emacs」においてコマンドの実行方法は主に2つです。

 ● キーバインドを入力して実行する
 ● M-x(ESCキーを押してからxキーを押す)のあとにコマンドを入力し、Enter押下で実行する

キーバインドやコマンドをすべて覚えるのは難しいと思います。
「Emacs」はelispの実行環境という側面もあると私は考えており、pureな「Emacs」でさえいくつものコマンドを備えています。
自分でパッケージを追加していけば実行できるコマンドはどんどん増えていきます。
この無数にあるコマンドの実行の仕方が簡単になれば「Emacs」はもっと便利になると思います。


M-xで「Emacs」のコマンドを実行することができますが、実行したいコマンドを正確に入力する必要があります。(多少の補完は効きます)
前述の通り「Emacs」には多数のコマンドがあり、よく使うコマンドは何回も実行していれば覚えられるとはいえ毎回入力するのは手間です。


また、新しいパッケージを導入するときにそのパッケージがどんな機能を提供しているのか調べるため、ドキュメントやソースコードを読み込む必要も出てきます。
今自分が使えるコマンドを一覧表示してくれて、その中から適当に検索して目的のコマンドを見つけられるとしたら楽ですね。


counsel.el

counsel.elは「Emacs」の様々な操作を助けてくれます、前述のような問題を華麗に解決してくれます。
counsel.elが提供しているcounsel-M-x関数は、M-xのラッパー関数です。
読み込まれているコマンドを一覧表示してその中からファジー検索を行うことで目的の関数を探索することができます。
また、ivy-richと一緒に使うことで、コマンドの簡単なドキュメントも一緒に参照することが可能です。
今使いたいコマンドを探しながら、新しいコマンドを発見することができます。

コマンド実行以外にも下記のような場面でファジー検索を行うことができます。

● gitリポジトリ内のファイル検索
● ファイル内のインクリメンタルサーチ
● 最近開いたファイル


画面収録 2020-10-01 1.46.13.mov

(counsel.elを使ってすべてのコマンドから「色選択するコマンド」を選択して、実行しています。)


キーバインドはもとから様々なものが設定されています。
キーバインドは主にControlキーとの組み合わせで構築されています。(C-n Controlを押しながらnキーを押す)
一つのキーバインドで処理が実行されるならまだ覚えられますが、
2つ以上(C-c C-k など)のものが設定されているとさすがにすべてを覚えるのは難しいです。
そんなときに使えるのが


which-key.el

このパッケージは複数設定されているキーバインドの一つ目を押したあとに、そのあとに続くキーバンドを画面下部に表示して教えてくれます。
すべてのキーバインドを覚えていなくても、起点となるものだけならなんとか覚えられそうです。
「Emacs」には様々な言語をサポートしてくれるパッケージが存在しており、それらでは言語固有のキーバインドは主に C-c(Controlを押しながらcキーを押す)を起点に設定されています。
また、「Emacs」の基本的な機能はC-xを起点に設定されています。
which-key.elが導入されていればC-c (またはC-x) を入力するだけで、その後にどんなキーバインドが設定されているか確認しながら処理を実行することができます。

画面収録 2020-10-01 1.50.51.mov

(C-c から始まるmarkdown-modeのキーバインドを確認しながら実行しています。タイトルや表組み、リスト表記などたくさんの機能が提供されています。)


設定の仕方がわからない

githubを中心としたOSSコミュニティには多くのelispパッケージがあります。
それらのパッケージの導入、設定の書き方さえ覚えてしまえば自分好みの環境を作り込むことができます。
elispはLisp系のプログラミング言語であり、少々癖のあるものですが、設定ファイルを記述するだけであればそこまで難しいことはしなくてすみます。

「Emacs」のパッケージ導入は基本的には下記のような手順で行います。

1. パッケージソースをローカルにダウンロードする
2. ダウンロードしたパッケージにパスを通す
3. Emacsの設定ファイルでパッケージの設定を記載する

1.2がいかにもめんどくさそうですね。。。
「Emacs」の機能でパスの通ったディレクトリへダウンロードすることもできますが、環境構築の段階ではダウンロード漏れでエラーになってしまうことがよくあります。
設定ファイルを読んだときに足りないパッケージがあったら自動でダウンロードしてくれるようにしたいですね。

straight.el

私も使っているパッケージ管理用パッケージです。
環境の再現性にこだわっており、現在の「Emacs」の環境のスナップショットをとっておいて、PCが変わっても「Emacs」の起動時に常に同じ環境を再現してくれます。

設定ファイルの記載もかんたんで私の設定ファイルを一部紹介すると

(use-package which-key
 :diminish which-key-mode
 :config
 (which-key-mode)
 )

(use-package counsel
 :bind
 (("C-r" . counsel-M-x)
  ("C-x C-f" . counsel-find-file))
 )

(use-package evil
 :custom
 (evil-disable-insert-state-bindings t)
 :config
 (setq evil-cross-lines t)
 (setq evil-search-module 'isearch)
 (evil-mode 1)
 (setq evil-want-fine-undo t)
 (setq evil-esc-delay 0)
 )

上記の例では3つのパッケージの設定が記述されています。
「use-package」というキーワードに続くものがパッケージ名です。
1パッケージ1ブロックのように記載ができるので、とても管理がしやすくなります。

導入の仕方も簡単です。下記のコードを「Emacs」の設定ファイルの先頭に記述するだけです。
その後は上記のように導入したいパッケージごとに設定を記述していきます。 

(defvar bootstrap-version)
(let ((bootstrap-file
     (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
    (bootstrap-version 5))
(unless (file-exists-p bootstrap-file)
  (with-current-buffer
      (url-retrieve-synchronously
       "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
       'silent 'inhibit-cookies)
    (goto-char (point-max))
    (eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))


おまけ

evil

弊社のnoteから「Vim」の記事が出たので、私はすぐさま手を挙げて「Emacs」の記事を書き始めましたが、戦争をしに来たわけではありません!
むしろ私は「Vim」も好きです。
普段の開発では「AndroidStudio」や「IntelliJ IDEA」といったIDEを使っていますが、キーバインドは「Vim」にしています。
もちろん「Emacs」でも「Vim」操作がしたくなりました。

evilを導入することで「Vim」のようなオペレータ+モーション/テキストオブジェクトでの操作や、テキスト入力モードとコマンドモードと言ったモードの概念 (evil上ではステートと呼ばれています) を取り入れることができます。


spacemacs

0から自分の「Emacs」を作り上げていくのはとても大変。。。
という方におすすめしたいのが「spacemacs」です。
これは「Vim」の操作性と「Emacs」の拡張性を両取りした設定ファイル群を提供してくれます。
また、設定ファイルは「Emacs」のままなので、「spacemacs」を起点にして自分だけのエディタを作っていくのもいいと思います


まとめ

本記事では「Emacs」を使っていく上でぶつかるであろう2つのハードルを解決方法を紹介しました。
コマンドやキーバインドを無理に覚えようとせず、補完やファジー検索に頼ることで簡単に「Emacs」の力を引き出すことができます。
実際に私も紹介した機能によって発見したコマンドやキーバインドが数え切れません。

読み込むだけで環境を再現できるような設定ファイルを記述しておけば自分の「Emacs」を持ち運ぶことも容易になります。

「Emacs」を使い始めて6年以上経ちますが、もっともっと上手に使えるようになる気がしています。

ご興味ある方は、ぜひはじめの一歩を踏み出してみてください!