2015年Emacsパッケージ事情

Emacsは「拡張可能なテキストエディタ」と呼ばれ[^1]、エディタとしての基本的な機能ですらユーザーが柔軟にカスタマイズできます。

最初から同梱されてるライブラリだけではなくWebにあるEmacs Lispパッケージを導入することで、べんりなインターフェイスや強力な編集機能、追加の言語サポートを取り入れることができます。

さて、そのEmacs Lispパッケージの管理方法については大きく変化があるので、この記事では近年の潮流について紹介します。

[^1]: https://packages.debian.org/ja/wheezy/emacs23

## 読むのがめんどくさいひとのために結論

**Emacsを最新版にして、Caskを入れよう！！！！**

* Caskをインストールすると…
  * パッケージリポジトリとして、デフォルトでMELPAが登録されます
  * Palletがインストールされ、<kbd>M-x package-install</kbd>とCaskが統合されます
* この記事にはWindows向けの説明はありませんので気をつけてください
* El-Getも良いものですが、この記事ではpackage.elとCaskの話です
* 有用な新作Emacs Lispパッケージは @rubikitch が[るびきち「日刊Emacs」](http://rubikitch.com/)で紹介してます
* [Ad] 毎週土曜22時から[init.el読書会](http://emacs-jp.github.io/reading-initel.html)に参加しよう

## よびかたについて

先に書いた通り、EmacsはLispと呼ばれるプログラミング言語で記述されたテキストエディタです。ただしLispはシンプルなプログラミング言語なので、いくつもの亜種(方言)があります[^2]。EmacsのLispなので、ふつうは「Emacs Lisp」と呼ばれます。また、縮めて「elisp」と呼ばれることもあります[^3]。

Emacsユーザーによって作成されたプログラム/ライブラリの単位を何と呼称するかは定まって居らず、単に「拡張/extension」や「elisp[^4]」と呼ばれてきました。Emacs 24からは後述する`package.el`が標準機能として同梱されたこともあり、「パッケージ/package」と呼ぶことが定着してきました。

以上のような経緯から、Emacsの拡張プログラムを「プラグイン/plug-in」と呼ぶことは(あまり)ありません。[EmacsWiki: Emacs Plugin](http://www.emacswiki.org/emacs/EmacsPlugin)では、Emacsのコア機能を拡張する(ex. 動画/音声の表示やWebブラウザのレンダリングなど)ための外部プログラムを指して「プラグイン」と呼びます。また、Emacs上に構築されたHelm/AnythingやMagitなどのフレームワークの拡張を指して「プラグイン」とも呼ばれます。

[^2]: 方言とはいっても互換性の差は大きく、ほかの種類のLispで書かれたプログラム/ライブラリをEmacsでそのまま動かすことは困難です。ただし、ほかのLisp方言の特徴や流行は継続的にEmacsに持ち込まれてます。
[^3]: Emacsとは無関係な古い「Elisp」が存在するらしく(伝聞)、プログラミング言語名としては「Emacs Lisp」と呼ぶ方が好まれます。ただし、Emacsのソースコード内でも[「elisp」と記述された箇所は少なくなく](https://github.com/emacs-mirror/emacs/search?utf8=%E2%9C%93&q=%22elisp%22)、この呼び名が誤りであるとも言切れません。
[^4]: [El-Get](https://github.com/dimitri/el-get)の説明文には<q>Manage the *external elisp* bits and pieces upon which you depend!</q>とあります。

## 前史

Emacsの解説書として「Emacsテクニックバイブル」(るびきち著, 2010年)や「Emacs実践入門」(大竹智也著, 2012年)があり、どちらも現在でも通用する内容は多いのですが、パッケージ周りに関しては大きな変化がありました。

後者の出版された記事がEmacs 24の正式リリース直前だったこともあり、Emacs 24の`package.el`の機能についても触れられてます。ただし、当時はまだ主流で環境が整ってなかったため、紹介程度に留められてます。

ちなみに両書籍で紹介された手法は[auto-install.el](http://www.emacswiki.org/emacs/download/auto-install.el)を利用して[EmacsWiki](http://www.emacswiki.org/)からダウンロードする方法でした。

## バージョンについて

最新のEmacsの安定バージョンは2015年4月にリリースされた「24.5」です。また、2016年8月現在の開発版は25.1rc1(リリース候補版)で、次期安定版の正式リリース25.1に向けて目下作業中の段階です。

Emacsは世間で思ひ込まれてるほど枯れて進歩のないソフトウェアではなく、旺盛な進化の途上にあります。

*残念なお知らせ* ですが、Macに最初からインストールされてる`/usr/bin/emacs`は最新のOS X El-Capitanにおいても更新されず2007年にリリースされた22.1.1で、**異常に古い**ままです。古いEmacsは最新のべんり機能やライブラリに対応できないのはもちろんですが、**Unicodeを正しく読み書きできない**などさまざまな問題があります。

Emacs24系であればある程度は問題ありませんが、最新版を導入しましょう。24.4では多くの機能追加があり、MELPAに登録されたパッケージには**24.3以前のバージョンをサポート対象としない**ものが少なからずあります。

> ## El-Get
>
> 本題に入る前にまた話題が逸れるのですが、[El-Get](https://github.com/dimitri/el-get)は公式のパッケージ機能と人気を二分するパッケージマネージャとレシピ集(リポジトリ)です。この記事では詳しくは説明しませんが、標準の`package.el`とは別の実装なので、導入はどちらかにした方が良いでしょう。
>
> 人気を二分するだけあって、El-Getもよくできたパッケージマネージャーなので、興味があれば[Caskはもう古い、これからはEl-Get - いまどきのEmacsパッケージ管理 - 貳佰伍拾陸夜日記](http://d.hatena.ne.jp/tarao/20150221/1424518030)を読んでみるといいでしょう。

## package.elの夜明け

Emacs 24.1がリリースされたのは2012年6月10日でした。Emacs 24でどのような機能が取り入れられたかについては[Emacs24 のインストールと新機能 : 紹介マニア](http://sakito.jp/emacs/emacs24.html#emacs24)に詳しいのですが、この記事の趣旨としての目玉機能はもちろんパッケージ機能です。

<kbd>M-x list-packages</kbd>と打ち込んでみましょう。

![list-packages](https://qiita-image-store.s3.amazonaws.com/0/4121/657bdb98-35b4-56f3-0798-8ede7e1548f5.png)

何も設定をしてない状態でも100超のパッケージがインストールできる状態です。この画面の操作方法などは[package.el - Emacs JP](http://emacs-jp.github.io/packages/package-management/package-el.html)をお読みください。

これは、[GNU Emacs Lisp Package Archive](https://elpa.gnu.org/)(ELPA)だけが登録された状態です。ELPAにパッケージを登録するには書面での手続きが必要など低くない敷居があるため、現在のところ収録数も少なく、更新頻度も低いです。

## MELPA

`package.el`には公式のリポジトリだけではなく、有志が用意したパッケージリポジトリを追加することも可能です。

現在もっとも活発に更新されてるリポジトリは[**MELPA**](http://melpa.org/#/) (Milkypostman’s Emacs Lisp Package Archive) です。このプロジェクトには毎日多くのパッケージが追加・更新されてます。

その特徴は、GitHubやBitbucketなどのGitホスティングサイトと連携されてゐることです。パッケージ開発者はmasterブランチにpushするだけで最新版としてリリースすることができ、ユーザーはすぐさま最新版を利用できます(最新版を利用したくない場合は後述のmelpa-stableが利用できます)。

その更新の活発さはTwitterの[MELPA(@melpa_emacs)](https://twitter.com/melpa_emacs)アカウントの更新通知を見れば一目瞭然です！

MELPAを有効にするには、`~/.emacs.d/init.el`に追加するだけです。ただし、以下に紹介するCaskと併用する場合は、この記述は<u>必要ありません</u>。

```init.el
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/"))
```

最新の導入方法は [Getting Started - MELPA](http://melpa.org/#/getting-started)にあります。また、Webからパッケージを探したいときは[melpa.org](http://melpa.org/)で簡単に絞り込み検索できるので良いです。

自作のEmacs Lispパッケージを公開することに興味のある型は[MELPAにレシピを投稿するには](http://qiita.com/tadsan/items/b74856f555720a5ca2e5)をお読みください。

### melpa-stable

MELPAではmasterにpushされた最新の状態が取得されますが、その裏返しとして正式リリースではない、不安定なバージョンが落ちてくる可能性もあります。

上記に加へて次のコードを足すと、バージョン番号(タグ)が付いた安定バージョンが優先して取得されるようになります。

```init.el
(add-to-list 'package-archives
             '("melpa-stable" . "https://stable.melpa.org/packages/") t)
```

先程書いた通り、以下で紹介するCaskを併用する場合は不要です。

## Cask

[cask/cask](https://github.com/cask/cask)は、ちょうどRubyのBundlerのようなツールです[^5]。

Caskの長所については[package.elから Caskに切り替えました - syohex’s diary](http://syohex.hatenablog.com/entry/20140424/1398310931)に詳しいので、こちらをお読みください。

Caskを利用するには依存するパッケージを`~/.emacs.d/Cask`ファイルに記述することになるので、環境を作り直すときに依存するライブラリを復旧しやすくなるのが非常に大きなメリットです。

```sh
% cd ~/.emacs.d
% cask init
% cask install
```

`Cask`ファイルにはCask作者おすすめのパッケージが最初から登録されてます。また、MELPAも最初から登録されてますが、先程紹介したmelpa-stableを利用したい場合は、ファイル先頭に`(source melpa-stable)`を追加してください。

パッケージのインストール・更新をするときは、必ず`~/.emacs.d`に移動する必要があることに注意してください。

package.elを利用した場合はパッケージは`~/.emacs.d/elpa/`以下にインストールされますが、Caskを利用すると`~/.emacs.d/.cask/`以下に保存されるようになるので気をつけてください。(その点、後述するPalletを組合せるのがオススメです)

`Cask`ファイルの書き型の資料は[Cask Domain Specific Language](http://cask.readthedocs.org/en/latest/guide/dsl.html)にあります
。また、わたしの`Cask`ファイルは[zonuexe/dotfiles:/.emacs.d/Cask](https://github.com/zonuexe/dotfiles/blob/master/.emacs.d/Cask)です。

[^5]: [Homebrew Cask](http://caskroom.io/)とは名前がかぶってますが、無関係な別のツールです。

### Pallet

[rdallasgray/pallet](https://github.com/rdallasgray/pallet)はpackage.elとCaskを統合するライブラリです。

Caskはコマンドラインツールなので単体で利用すると一旦Emacsを終了してから`Cask`ファイルを変更してインストールまたはアップデートしたあと再起動する必要があります。

具体的には、標準機能の<kbd>M-x package-install</kbd>でパッケージをインストールしたときにもインストール先が`~/.emacs.d/.cask/`にまとめられ、また`~/.emacs.d/Cask`ファイルに追記してくれます。

また、コマンドラインを利用せずEmacsから<kbd>M-x pallet-install</kbd>と<kbd>M-x pallet-update</kbd>を利用可能にもなります。

### そのほかのリポジトリ

必要になるまで追加しなくて良いと思ひます。MELPAが定着する前は[Marmalade](https://marmalade-repo.org/)がよく利用されてましたが、わたしは登録したことがありません。

## つまりどうすればいいの？

**Emacsの最新版とCaskを入れよう！！！！**

Caskをインストールし、`cd ~/.emacs.d; cask init; cask install`すると、パッケージリポジトリとしてMELPAが登録され、先に紹介したPalletのほか、人気のあるパッケージがインストールされた状態になります。

わたしは新しいパッケージをインストールするときは<kbd>M-x package-install</kbd>でインストールします。Helmなどを利用してると、パッケージ名の絞り込みができて便利です。

## 今後のメンテナンスについて

気が向いたときに `cd ~/.emacs.d; cask update` すると、パッケージがインストールできます。

ごくまれにパッケージに大きなアップデートがあってEmacs起動時にエラーが出るようになってしまったとき[^6]、`rm -rf ~/.emacs.d/.cask; cask install`すると、クリーンな状態に戻ります。

`~/.emacs.d`ディレクトリはGit管理しておくと良いでしょう。`init.el`や`Cask`がバージョン管理されてあれば、復旧が容易になります。

わたしはGitHubで[.emacs.d](https://github.com/zonuexe/dotfiles/tree/master/.emacs.d)を公開して居ります。バージョン管理の対象外にするファイルなどは[.emacs.d/.gitignore](https://github.com/zonuexe/dotfiles/blob/master/.emacs.d/.gitignore)が参考になるかもしれません。

[^6]: 最近では[Magit](http://magit.vc/)がバージョンアップしたときにありました

## おまけ

### 設定ファイルの書き方

Emacsの設定ファイルは`~/.emacs.d/init.el`に置きます。`~/.emacs`や`~/.emacs.el`は古い形式なので、`init.el`に書いてください。

これは実は最近に限った話ではないのですが、パッケージマネージャーを使ってインストールしたパッケージは基本的に`require`する<u>必要がありません</u>。Emacsにはオートロードの仕組みがあり、パッケージマネージャーはインストール時にソースコードからオートロードに必要なファイルを生成してくれるからです。

初期化ファイルに不必要な`require`を書かないことで、Emacsの起動時間の短縮を期待できます。また、パッケージマネージャー経由でインストールしたパッケージでもお作法に則ってないものに関しては引き続き`require`を書くことになります。

また、`init.el`を書くときには`use-package`を利用すると便利です。詳しくは[use-packageで可読性の高いinit.elを書く](http://qiita.com/kai2nenobu/items/5dfae3767514584f5220)をお読みください。

### Emacsパッケージを書くには

かんたんなEmacsパッケージ(メジャーモード)を書き上げるまでの一連の流れは[pixiv-novel-modeを作った - pixiv inside](http://inside.pixiv.net/entry/2014/12/19/230810)に書きました。

いろいろ書きましたが、Flycheckを利用すると、Emacs Lispの作法に違反した書きかたや抜け漏れを指摘してくれるので、強くオススメします。[Flycheckでモダンなシンタックスチェック - Qiita](http://qiita.com/senda-akiha/items/cddb02cfdbc0c8c7bc2b)に詳しいです。

パッケージを書いたらリポジトリに登録しませう。一通り完成したらMELPAとEl-Getに登録するのがおすすめです。

以下、わたしがいままでに送ったレシピ追加依頼の例。

* [MELPA/pulls author:zonuexe](https://github.com/milkypostman/melpa/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aclosed+author%3Azonuexe+)
* [El-Get/pulls author:zonuexe](https://github.com/dimitri/el-get/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aclosed+author%3Azonuexe+)

雑な英語でも意外にコミュニケーションできる気がする。

MELPAのひとはコーディングスタイルがお作法に則ってるか、ちゃんとレビューしてくれるので、先に送るのがオススメです。

ちなみにわたしが初めて作ったパッケージは[既存のパッケージと完全に機能が重複して下位互換な上にバグってる](https://github.com/milkypostman/melpa/pull/829)との理由で蹴られました ヾ(〃＞＜)ﾉﾞ

### Emacsでわからないことがあったら

日本語で雑に質問できるチャンネルはいろいろあります。

* [emacs-jp slack](http://syohex.hatenablog.com/entry/2016/06/10/004305) **(←最近それなりに活溌)**
* [LingrのEmacs部屋](http://lingr.com/room/emacs/)
* [Emacs JPのIssues](https://github.com/emacs-jp/issues/issues)
* [スタック・オーバーフロー(日本語版)](http://ja.stackoverflow.com/questions/tagged/emacs)

あと、毎週土曜の22時からLingrで[init.el読書会](http://emacs-jp.github.io/reading-initel.html)やってるので気軽に参加してみよう。

## 改版履歴

* 2015年11月2日: 初版公開
* 2016年8月21日: 修正・表現の変更および、現在時点での情報を反映

## 脚注