ぼくの.emacs 2013

12月がはじまりました。アドベントカレンダーの季節です。

はじめに
--------

筆者は仕事でRubyやPHPを書いたりしてます。ふだんはUbuntu 12.04 LTSで[ppa:cassou/emacs](https://launchpad.net/~cassou/+archive/emacs)のEmacsをデスクトップで使用してますが、Ubuntu 12.10以降には[emacs24](http://packages.ubuntu.com/quantal/emacs24)パッケージもあります。

個人的な文章やプログラムはMacBook Airで[Emacs24-with-inline-patch - MacEmacs JP](http://sourceforge.jp/projects/macemacsjp/releases/?package_id=13490)のパッケージでインストールしたものをターミナルから起動するようにしてます。

現在仕事で利用してる現行の`.emacs`は[gist:zonuexe/3696989](https://gist.github.com/zonuexe/3696989)ですが、今回紹介する`.emacs`は移行作業中の[zonuexe/.emacs.d](https://github.com/zonuexe/.emacs.d)です。

セットアップ
------------

Emacs24が利用できる環境では`git clone`してEmacsを起動するだけで準備完了します。そのために、`init.el`は以下のようになってます。

```el:init.el
(load (locate-user-emacs-file "./macros"))
(load (locate-user-emacs-file "./packages"))

;;; load config files
(pkg-sync 'init-loader require
          (init-loader-load (locate-user-emacs-file "./conf")))
```

`pkg-sync`は指定したパッケージがインストールされてなければ`pakcage.el`で自動インストールされるようになってます。

パッケージの導入時には`M-x package-install`して… と説明されることが多いですが、そのでは別の環境で再セットアップをする際の手順がとても複雑になるので筆者は設定ファイルに直接書き込む方法が好きです。

ただし現状では、セットアップのために初回起動時のみ2度ほどEmacsを再起動する必要はあります。また、パッケージが勝手に最新にアップデートされたりはしないので、更新頻度の高いものはたまに更新してやってください。

package.elの使用方法、パッケージのアップグレードのしかたなどは[package.el - Emacs JP](http://emacs-jp.github.io/packages/package-management/package-el.html)に日本語で情報がまとまってます。

### pakcage.el VS El-Get

`package.el`はEmacs24に標準添付の機能ですが、競合するパッケージ管理の仕組には[El-Get](https://github.com/dimitri/el-get)があります。El-Getでも対話的なインストール(`M-x el-get-install`)を利用することができますが、以下のようにも書くことができます。

```el:helm.el
(el-get 'sync 'helm)
(helm-mode t)
```

このようにすることで、依存するパッケージの管理と必要な設定を接近して書くことができるので筆者は好きです。

`el-get 'sync`のこの記法にインスパイヤされて作ったのが`pkg-sync`で、このように書くことができるようになります。

```el
(pkg-sync 'helm require)
(helm-mode t)
```

`package.el`とEl-Getのどちらが良いのか筆者はまだ結論を出せてません。なので、いまはまだEmacs23の頃からよく慣れたEl-Getを使用することが多いです。

UI要素
------

意外にこの設定をしてないひとが多い気がするのですが、Emacsのツールバー(アイコンが並んだ領域)とメニューバー(文字が並んだ領域)は隠すことができます。

MacやUbuntu(Unity)のようにシステムのメニューバーとアプリケーションのメニューバー・タイトルバーが統合されたデスクトップ環境以外ではメニューバーがほぼ一行ぶんの画面領域を占有してますが、これを非表示にすることで表示できる文字数が増えます。

```el
(cond
 (window-system (tool-bar-mode -1))
 (t             (menu-bar-mode -1)))
```

### 端末とマウス

ちなみに端末で使用中にメニューバーが表示されるのは決して飾りではありません。

`xterm-mouse-mode`を有効することで、メニューバーをクリックするとその要素に直接アクセスできるようになります。便利… かなあ? 標準的なアクセス方法としては``M-```でメニューバーの機能を利用することができます。

メニューバーは不必要な存在ではありますが、`xterm-mouse-mode`は便利かもしれないし、便利ではないかもしれません。筆者は好きです。

Magit
-----

[magit](https://github.com/magit/magit)はEmacsから利用できるGitのインターフェイスです。Magitを使用するために標準添付のvc-gitは不必要になるので無効化しておきます。

```el:vc.el
(setq vc-handled-backends '())
(eval-after-load "vc"
  '(remove-hook 'find-file-hooks 'vc-find-file-hook))

(el-get 'sync 'magit)
(require 'magit)
(eval-after-load 'magit
  '(progn
     (set-face-foreground 'magit-diff-add "green3")
     (set-face-foreground 'magit-diff-del "red3")
     (when (not window-system)
       (set-face-background 'magit-item-highlight "white"))))
(global-set-key (kbd "C-x m") 'magit-status)
```

筆者はEmacsで電子メールを使用することはないので、`C-x m`でMagitを利用するようにしました。

### 参考

 * [git - How to Use Magit Even More Effectively? - Stack Overflow](http://stackoverflow.com/questions/5676977/how-to-use-magit-even-more-effectively)
 * [How does one disable vc-git in emacs? - Stack Overflow](http://stackoverflow.com/questions/5748814/how-does-one-disable-vc-git-in-emacs)

ParEdit
-------

[ParEdit](http://www.emacswiki.org/emacs/ParEdit)はLisp系のプログラミング言語を編集する際にとても便利なマイナーモードです。当然Emacs Lispを含むので、Emacsの設定ファイルを書くためだけに入れても便利です。

```el:20-lisp.el
(el-get 'sync 'paredit)
(add-hook 'emacs-lisp-mode-hook 'enable-paredit-mode)
```

フォント設定
------------

フォントは無料で見やすい **Migu 2M** を利用してます。

 * [Miguフォント : M+とIPAの合成フォント](http://mix-mplus-ipa.sourceforge.jp/migu/)

Ubuntu 12.10以降では`apt-get`で[fonts-migmix](http://packages.ubuntu.com/saucy/fonts-migmix)パッケージをインストールすることでも導入可能です。

```el:fonts.el
;; -*- Mode: Emacs-Lisp ; Coding: utf-8 -*-
;;; いろはにほへと　ちりぬるを
;;; わかよたれそ　　つねならむ
;;; うゐのおくやま　けふこえて
;;; あさきゆめみし　ゑひもせす
(when window-system
  (set-face-attribute 'default nil
		      :family "Migu 2M"
		      :height 120))
```

Ruby開発のための設定
--------------------

筆者は長い引数列は横幅が長くならないように浅く改行するのが好きなので `(setq ruby-deep-indent-paren-style nil)` のように設定します。

```el:ruby.el
(el-get 'sync '(ruby-mode rcodetools))
(when (require 'ruby-mode nil t)
  (defun my/ruby-mode-hook-function ()
    (setq ruby-deep-indent-paren-style nil)
    (make-local-variable 'ac-omni-completion-sources)
    (make-local-variable 'ac-ignore-case)
    (setq ac-ignore-case nil)
    (setq ac-omni-completion-sources '(("\\.\\=" . (ac-source-rcodetools))))
    t)
  (add-hook 'ruby-mode-hook 'my/ruby-mode-hook-function))
```

PHP開発のための設定
--------------------

PHPは配列を作るリテラルが`array()`と、ほかの言語から来た身にはたいへんつらい仕様なので、`[`だけで入力できるようにします。

```el:php.el
(el-get 'sync 'smartchr)
(el-get 'sync '(php-mode php-completion php-eldoc))
(when (require 'php-mode nil t)
  (defun my/php-mode-hook-function ()
    (when (require 'php-completion nil t)
      (php-completion-mode t))
    (define-key php-mode-map (kbd "C-o") 'phpcmp-complete)
    (define-key php-mode-map (kbd "[") (smartchr "[]" "array()" "[[]]"))
    (define-key php-mode-map (kbd "]") (smartchr "array " "]" "]]"))
    (let ((my/php-offset 4))
      (setq tab-width my/php-offset
            c-basic-offset my/php-offset
            indent-tabs-mode nil)
      (c-set-offset 'case-label' my/php-offset)
      (c-set-offset 'arglist-intro' my/php-offset)
      (c-set-offset 'arglist-cont-nonempty' my/php-offset)
      (c-set-offset 'arglist-close' 0))
    t)
  (add-hook 'php-mode-hook 'my/php-mode-hook-function))
```

過去の記事から
--------------

### カーソルキーで分割ウィンドウ移動

筆者がEmacsなどのスクリーンエディタを使用する強い動機のひとつは画面分割があることなのですが、ほかのウィンドウに移動するときにいちいち`C-x o`と押すのは、特に3つ以上に分割したときに煩しく感じます。

 * [Emacsの分割ウィンドウを←↓↑→で移動 - Qiita [キータ]](http://qiita.com/tadsan/items/114ffe6bb645551268dd)

矢印キーは使用しない派閥のひとも多いですが、筆者は積極的に活用します。

### ESC連打

うっかり`ESC`キーを複数回打ってしまったときに慌てなくなるための設定です。

[Emacs - ESCを連打したときにclose-other-windowsされたくない - Qiita [キータ]](http://qiita.com/tadsan/items/e7557c8db33a3c590fec)

### auto-completeで大文字小文字を区別

オブジェクト指向のようなスタイルでコードを書くときに `book = Book.new ` のようなコードが頻発すると補完の先頭文字列が大文字小文字を混同されると意図通りにならなくて苛立つことがあります。

* [Emacs - auto-complete環境で補完の大文字小文字を区別する - Qiita [キータ]](http://qiita.com/tadsan/items/ab3c3b594b5bf6203f02)

しれっと上記のRuby設定の中にも書かれてます。

さいごに
--------

[.emacs Advent Calendar 2013](http://qiita.com/advent-calendar/2013/dot-emacs)の2日めは、べんりなEmacs Lispを開発・紹介していらっしゃいます @syohex@github さん([Life is very short](http://d.hatena.ne.jp/syohex/))です。

この記事の半分ほどは某卓球ハウスで鍋を御馳走になりながら書いてました。カレー鍋とてもおいしうございました。