.emacsの整理をした話 + EmacsとViとShellとLispを悪魔合体させたら超絶便利だった
やや長いタイトルですが・・・年末になって大掃除がやってきましたね。みなさんもそろそろ.emacsの大掃除をしましょう。
私の.emacsは元々1300行ちょいあってEmacsの起動に7~8秒(体感)かかってましたが大掃除&高速化をした結果800行弱、起動に1秒(体感)ほどになったので整理の仕方を共有しますね。
前提ですが、私はinitローダーとかは使ってません。全部init.el
に書いてます。で、機能毎にページを作って(C-q C-l
)ます。ただ、それだけだと視認性が悪いので見出しとしてC-u C-u C-u ;
で;
を64個挿入して次の行にコメントで#
付きのタイトルを付けてます。
具体的には
1 2 3 |
|
こんな感じのものが機能毎に書かれてます。これでC-s
やM-x occur
でハッシュタグのように検索することもC-v
でスクロールしていって目grepすることもC-x ]
で機能毎にジャンプすることもできます。
1. Emacsの最新版を使う
結構重要です。「標準のやつだと欲いこの機能がないから拡張パッケージ入れた」なんてのも最新版では改善されていたりします。例えば私はemacs-w3m
を使っていましたが、Emacsのmasterブランチにはeww
なるEmacs Lisp製のブラウザが入っているのでそれを使うようにしました。
ただ、これが絶対的正義かというとそうでもなく、パッケージで入れてない分
Ubuntuのインプットメソッドとの連携部分がなかったのでuim.el
を入れる
必要が出てきたりと、面倒な部分もありました。Emacs標準のインプットメソッドはどうにも使いものにならず、
ddskk
もuim-skkとコンフリクトする(というかC-j
上書きとかありえない)ので使いません。インプットメソッドの切り替え部分は
1 2 |
|
になりました。
2013-12-16追記
これは私が~/.Xresources
にEmacs*useXIM: false
を書いていたのが原因でした。Emacs*useXIM: true
に書き換え、xrdb ~/.Xresources
すると直りました。
2. 普段使わない設定は全部消す
基本ですね。私はsummary-edit.el
だとかmultiverse.el
だとかるびきちさんの本を読んで便利そうだから入れたものの、結局使わなかったものの設定&elispをごっそり削除。あとかなりの言語に対してデフォルトでauto-mode-alist
が設定されていたのでauto-mode-alist
の設定も全部消して、必要になったら書き足すようにしました。
3. 普段使っていても代替の効くものは削除
これは高速化の意味と自分の環境に依存しない意味があります。最近、自分のラップトップ以外でもEmacsを触ることが多くあって、デフォルトのキーを上書きして使ってる部分で何度も誤操作したのでそれを減らす目的です。bm.el
はC-x r SPC
のregister
系やC-x C-SPC
で対応(registerは覚えれば使い出がありそうなのでいつか解説書くかもです)、open-junk-file.el
は~/tmp
を作って対応、recentf-ext.el
はhelm-file-buffers
だとか。
あと全てhelm.el
に置き換えてhelm.el
とanything.el
が混在してる状態をどうにかしたかったのですが、php-completion.el
かなにかが依存しててトドメを刺せませんでした。
あと、viewer
の代替を探していたらタイトルにあるように悪魔合体が起きたので後で書きますね。
4. できる限り標準のものを使う
標準で提供されているパッケージはautoload
がemacs
バイナリに組込まれてる(と思う)ので起動時のオーバーヘッドはありません。flymake.el
やruby-mode.el
が標準で提供されてるのに気付いたのでそれを使ったりなど。一度(emacsroot)/lisp
以下を眺めてみることをお勧めします。結構発見があるものです。
5.autoload
を使う
autoload
とはファイルの読み込みを必要になるまで遅らせる仕組みです。「必要になる」ってのはそのファイルで定義されている関数が呼ばれたときです。賢いrequire
と思えば良いでしょう。
(autoload #'関数名 "関数が呼ばれたときに読むファイル名" nil interactivep)
みたいに使います。interactivep
の部分はM-x
で呼ぶものならt
、そうでなければnil
です。require
をautoload
で書き換えていけば理論上起動時の読み込み0にできるのでかなり高速化できます。
が、実際は一々autoload
書くのはしんどいので次です。
6.できる限りpackage.el
を使う
package.el
は必要な関数のautoload
を自動生成して読み込んでおいてくれるのでかなりの手間が省けます。そしてautoload
があるのにrequire
してると折角のpackage.el
の配慮が無駄になります。
自動生成されたautoload
はelpa/パッケージのディレクトリ/パッケージ-autoloads.el
にあるので確認しながらinit.el
の邪魔なものを消していきます。これでかなりinit.el
の行数が減ります。今まで無駄な設定していたんだなと気付きます。
7. eval-after-load
を使う
8割程の設定はautoload
で対応できるのですが、踏み込んだ設定をしているとパッケージの内部の関数を使ってしまってどうしてもその式が評価される前にパッケージが読み込まれている必要があることがあります。
そんなときはeval-after-load
を使います。名前のまんま、ロードした後でeval
してくれます。
(eval-after-load 'ファイル名
'式)
の形で使います。複数の式を使いたい場合はprogn
を使って
(eval-after-load 'ファイル名
'(progn
式1
式2...))
のように使います。あるパッケージの拡張パッケージなんかもここで読むと良いかもしれません。
8.その他
メールクライアントを標準のものにしようとしましたが、gnus.el
はちょっと受け付けなくてその他はimapを喋らないので断念。でも色々調べてたらmew
よりwanderlust
の方が良いようなので使い初めました。表示が綺麗で良いですね。HTMLのレンダリングもemacs-w3m
に頼らず標準のshr.el
を使っているのも◎。
同じような経緯でJDEE
をやめてmalabar.el
を使うようにしました。ただ、私はmaven
使いではないので微妙ではあります。まあ、そもそもプロジェクト単位でJavaを書くことがないってのもあるんですが。Androidのスケルトンがantなのでantでできたら嬉しいなーって。
EmacsとViとShellとLispを悪魔合体させた話
私はEmacsの狂信者ですが読み専のときはちょいちょいviを使うこともあります。片手で操作できるのは便利です。Emacsで読み専といえばview-mode
です。そこでもhjklを使うべくview-mode-map
に手を加えてましたが、大掃除ということで全部削除。
その後でemacsroot/lisp/emulate/
以下を読んでいるとなんかviのエミュレーターが3つも見付かりました。vi.el
、vip.el
、viper.el
です。後者になるほどviとの互換性が高くなります。とりあえずはhjkl
が使えれば良いのでvi.el
を使ってみたところ、ん〜…といったところ。vip.el
と試して結局viper.el
に落ち着きました。
(global-set-key (kbd "C-x C-q") #'(lambda ()
(interactive)
(toggle-viper-mode)
(force-mode-line-update)))
設定はこんな感じです。toggle-viper-mode
してもモードラインの表示が変わらないことがあったのでforce-mode-line-update
を加えました。
viper.el
は単なるviのエミュレートだけではなく、Levelに応じて良い感じにemacsと悪魔合体してくれます。私は最高レベルの5にしました。”C-x C-s”など基本的なコマンドはそのまま使えるようになってます。:
で始まるvi(ex)のコマンドも使えます。C-z
でemacs<–>viを切り替えたり。非常に便利です。
尚、私はvi使いであってvim使いではないのでevilは使いません。
もう一つ、shellの話。今まではmultiterm
× zsh
な感じでしたが、「できる限り標準のものを使う」方針でeshell
に切り替えました。eshell
はEmacs Lispで書かれたshellです。これが思った以上に便利です。るびきちさんの本では標準出力とエラー出力の切り分けができてないと書かれてましたがそれは修正されてるようです。
あとは/dev/kill
だとか>>>
だとかバッファへのリダイレクトだとかgrep
の上書きだとか色々楽しい拡張もあるのですが、一番はeshell
がLispであること。eshell
上で任意のEmacs Lisp式を実行できます。最近Emacs LispやLispに精通してきたので非常に有り難いです。
それにファイルを開くときもその後で同じディレクトリのファイルを開くことが多いので一旦 cd
してからfind-file
をするとアクセスし易くて捗ります。もう起動時にeshell
が立ち上がるようにして、基本そこから操作するようにしてます。guakeもそんなに使わなくなりました。他の環境でも使えるので安心して依存できます。
で、ファイルを開くときはどうしてるかというと実はemacsのfind-file
ではなくviの:e file-name
です。Emacs上でLispで出来たShellを使いつつviを動かしてます。かなり人を選びますが「EmacsのヘビーユーザーでLispに精通しててviを便利だと思ってる人」は試してみてはいかがでしょうか。