$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

年末emacs設定大掃除をして、これは捨てられないと思った設定書いてく

 ふとemacsの設定どのくらいになっているのかなーと思って行数数えたら

wc -l init.el inits/* | grep total
    2303 total

と、とんでもないことになっていたので、これまでどんな設定してたか思い出すことも兼ねて、emacs設定大掃除をおこなってみました。そこで「これは捨てられないなー」と思った設定を淡々と書いていきます。

ちなみに実際の設定ファイルはhttps://github.com/shibayu36/emacs/tree/master/emacs.d を御覧ください。

init-loader.el

emacsでinit-loaderを導入してみた - $shibayu36->blog; の記事でも書きましたが、init-loaderは便利です。最近の構成としてはinit.elにはinit-loaderの設定だけ書いて、inits以下に全部設定置いています。以下の様な感じで番号振って、十の位に似た設定をまとめています。これがないと設定多い人は死ぬ思いをします。

init.el
inits/
├── 00-init.el
├── 00-util.el
├── 01-display.el
├── 10-dired.el
├── 11-search-buffer.el
├── 12-popwin.el
├── 20-edit-mode-javascript.el
├── 20-edit-mode-lisp.el
├── 20-edit-mode-perl.el
├── 20-edit-mode-ruby.el
├── 20-edit-mode.el
├── 30-anything.el
├── 31-anything-ctags.el
├── 31-anything-git-project.el
├── 31-anything-git.el
├── 31-anything-gtags.el
├── 40-abbrev.el
├── 40-auto-complete.el
├── 40-bm.el
├── 40-dictionary.el
├── 40-direx.el
├── 40-elscreen.el
├── 40-expand-region.el
├── 40-flymake.el
├── 40-fold-dwim.el
├── 40-git.el
├── 40-grep.el
├── 40-migemo.el
├── 40-mode-compile.el
├── 40-org.el
├── 40-recentf.el
├── 40-shell.el
├── 40-slime.el
├── 40-term.el
├── 40-view-mode.el
├── 40-yasnippet.el
├── 60-myfuncs.el
├── 70-mymacros.el
├── 80-other-extension.el
└── 90-keybinds.el

地味だけど便利な設定

file名の補完で大文字小文字を区別しない

意外と重要な設定。file探すときshiftキーとか押したくないですよね。

(setq completion-ignore-case t)

バッファ自動再読み込み

デフォルトでは、emacs以外のものからファイル編集された時にbufferを再読込してくれないので、以下の設定は地味だけど便利です。

(global-auto-revert-mode 1)

同名ファイルのバッファ名の識別文字列を変更する

 デフォルトだと同じファイル名を複数開くと<1>,<2>とかついて全く区別できないので、以下の設定をしておくと便利です。入っているディレクトリ名などで識別してくれます。

(require 'uniquify)
(setq uniquify-buffer-name-style 'post-forward-angle-brackets)

現在行のハイライト

 emacs使っているとよくカーソルを見失います。そこで現在行のハイライトをしておくと便利です。

(defface hlline-face
  '((((class color)
      (background dark))
     (:background "dark slate gray"))
    (((class color)
      (background light))
     (:background  "#98FB98"))
    (t
     ()))
  "*Face used by hl-line.")
(setq hl-line-face 'hlline-face)
(global-hl-line-mode)

 こんなかんじになります。
f:id:shiba_yu36:20121227160108p:plain

ないと困る基本設定

install-elisp

 install-elispがないと、毎回elファイルをダウンロードしてきて配置してみたいなことをしないといけなくて大変です。詳しくはEmacs ビギナーに贈る、これからバリバリ使い隊!!人のための設定講座 その1。 - 日々、とんは語る。 などを参考に入れると良いと思います。

 設定は簡単で以下のようにrequireしてどこに入れるか設定するだけです。

(require 'install-elisp)
(setq install-elisp-repository-directory "~/.emacs.d/elisp/")

あとはM-x install-elispしてURLとか入れるだけでemacs lispをインストールすることができます。

shellenv.el

 emacsを使っていると一度はPATHなどの設定で死ぬ思いをする気がします。そこでshellenv.elを使って、自分の使っているshellのPATHをemacsに引き継ぎましょう。
 詳しくはhttp://d.hatena.ne.jp/syohex/20111117/1321503477 から。

emacs server

 Cocoa Emacsとか使ってて、さらにターミナルでいろいろ操作している時にemacsでファイルを開こうとして、ターミナルでemacsが起動してうざい、みたいなことはemacs serverを使って解決できます。

 以下のコードを設定しておいて

(require 'server)
(unless (server-running-p)
  (server-start))

 あとはemacsclientを使ってファイルを開けば、serverで待ち受けているemacsでファイルを開けます。以下のaliasとか貼っておくといいでしょう。

alias e='/usr/local/bin/emacsclient -n'

ファイル等の操作や編集補助

recentf.el

 最近開いたファイルというのはすぐにアクセスしたいものですよね。recentfを使うとそれが可能です。人は俺を「recentfマスター」と呼ぶ - http://rubikitch.com/に移転しましたを参考に設定すると良さそうです。

 僕の設定はこんな感じ。

(when (require 'recentf nil t)
  (setq recentf-max-saved-items 2000)
  (setq recentf-exclude '(".recentf"))
  (setq recentf-auto-cleanup 10)
  (setq recentf-auto-save-timer
        (run-with-idle-timer 30 t 'recentf-save-list))
  (recentf-mode 1)
  (require 'recentf-ext))

auto-complete.el

 自動補完機能です。これがないとタイプ数が増えて指が痛くなります。詳しくはhttp://cx4a.org/software/auto-complete/manual.ja.htmlをどうぞ。

設定例

(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/.emacs.d/elisp/auto-complete/ac-dict")
(ac-config-default)
(setq ac-use-menu-map t)

undo-tree.el + undo-hist.el

 undo-treeはこれまでの編集をtree上に出してくれてundoとかredoとかできるやつです。下のような感じ。
f:id:shiba_yu36:20121228231746p:plain

 更にundo-histというemacsを閉じてもundoの履歴を残しておいてくれるものを使うと、どこまでもundoできて便利です。

 設定は以下のような感じ。

;; undohistの設定
(when (require 'undohist nil t)
  (undohist-initialize))

;; undo-treeモードの設定
(when (require 'undo-tree nil t)
  (global-undo-tree-mode))

 僕はこの設定でundohistの保存ファイルがぶっ壊れるみたいになってうまく使えなくなって悲しい思いをしています。

smartchr.el

 smartchrというのはあるキーを繰り返し押した時に入力内容を変えてくれるみたいな拡張です。詳しくはsmartchr.el を使って生産性を上げる - KAYAC engineers' blog 辺りを御覧ください。

 僕の場合perlで$とか => とか打ちづらいので以下のように設定してたりします。

(require 'smartchr)
(add-hook 'cperl-mode-hook
          '(lambda ()
             (progn
               (local-set-key (kbd "F") (smartchr '("F" "$")))
               (local-set-key (kbd "H") (smartchr '("H" " => ")))
               (local-set-key (kbd "J") (smartchr '("J" "->")))
               (local-set-key (kbd "M") (smartchr '("M" "my ")))
               )))

migemo.el

 migemoがないと日本語検索の時にいちいちかな入力にしないといけなくて辛い気分になります。詳しくはMigemo: ローマ字のまま日本語をインクリメンタル検索あたりを参照に。使うにはcmigemoが必要です。ただ、辞書ファイルが見つからなかった記憶があるのでそのへんは頑張りましょう。

 僕の設定は下のような感じ。

(when (and (executable-find "cmigemo")
           (require 'migemo nil t))
  ;; cmigemoを使う
  (setq migemo-command "cmigemo")
  ;; migemoのコマンドラインオプション
  (setq migemo-options '("-q" "--emacs" "-i" "\a"))
  ;; migemo辞書の場所
  (setq migemo-dictionary "/usr/local/share/migemo/utf-8/migemo-dict")
  ;; cmigemoで必須の設定
  (setq migemo-user-dictionary nil)
  (setq migemo-regex-dictionary nil)
  ;; キャッシュの設定
  (setq migemo-use-pattern-alist t)
  (setq migemo-use-frequent-pattern-alist t)
  (setq migemo-pattern-alist-length 1000)
  (setq migemo-coding-system 'utf-8-unix)

  ;; migemoを起動する
  (migemo-init))

wgrep.el

 emacs内でgrepした時に一斉置換したい時はよくありますが、wgrep.elを使うとwdiredと同じようなインターフェースで扱えて便利です。wgrep.el が便利 - amari3の日記 あたりを参考に。

 設定は以下のようにするだけ。

(require 'wgrep)
(setq wgrep-enable-key "r")

wdired.el

 diredいじっていて、ファイル名を弄りたくなることはよくあります。そのたびにターミナル開いてmvとか打ってたらつらすぎるのでwdiredを使うと捗ります。

 設定を書いておいたら、dired使っている時にrを押して編集してC-x C-s押したらファイル名とか編集できます。詳しくはEmacs で wdired と moccur-edit を使っていない人は(ry - higepon blogをどうぞ。

(require 'wdired)
(define-key dired-mode-map "r" 'wdired-change-to-wdired-mode)

yasnippet.el

 yasnippet最近使い始めたけど、普通に単なる貼り付け機能としてだけでも便利です。詳しくはyasnippetの見直しをした - $shibayu36->blog;に書いたのでどうぞ。

open-junk-file

 たまにちょっとしたプログラムを試したいとか思った時にopen-junk-fileは便利です。ファイルが出来るディレクトリを指定しておいて、open-junk-fileとかすると試すためのファイルを簡単に作れます。コードはhttp://www.emacswiki.org/emacs/open-junk-file.el をどうぞ。

 僕は以下の様な設定をしています。

(require 'open-junk-file)
(setq open-junk-file-format "~/junk/%Y-%m-%d-%H%M%S.")

window管理

window分割

 window分割するときに毎回C-x 3とか打ってられないし、切り替えの時もC-x oとか打ってられない。しかも、画面が広いんだったら3分割ぐらい一瞬でなってほしい。
 そんな時にそろそろEmacsのウィンドウについて一言いっとくか - http://rubikitch.com/に移転しました をみて、設定したのを更に改良して、emacsのwindow幅に合わせて、分割数を変える - $shibayu36->blog; みたいなのを書きました。C-tですべてやってくれて便利すぎる。

popwin.el

 mode-compileとかで突然windowが開いてこれまでのwindow構成が変わって辛いみたいな経験をしていたら、popwin.elが便利です。詳しくはヘルプバッファや補完バッファをポップアップで表示してくれるpopwin.elをリリースしました - Functional Emacserから。

設定例はこちら。こんなかんじだと、mode-compileとか、補完とか、anythingとかが下からひょこっと出てきて後から消せるので、画面構成が変わらないので便利です。

(setq pop-up-windows nil)
(require 'popwin nil t)
(when (require 'popwin nil t)
  (setq anything-samewindow nil)
  (setq display-buffer-function 'popwin:display-buffer)
  (push '("anything" :regexp t :height 0.5) popwin:special-display-config)
  (push '("*Completions*" :height 0.4) popwin:special-display-config)
  (push '("*compilation*" :height 0.4 :noselect t :stick t) popwin:special-display-config)
  )

elscreen.el

 僕の頭はバッファが少なすぎるので、ウィンドウをscreenみたいな感じで開いておかないと作業ができなくなります。そのためelscreen.elは捨てられません。はてなブログあたりを参考にどうぞ。
 
 普通に導入するだけだったらrequireするだけで大丈夫そうです。

anything関連

 最近はanythingがないとファイルも開けません。anything導入のeverything 〜3分で使えるanything.el〜 - http://rubikitch.com/に移転しました を見て、チュートリアルをしていろいろしましょう。

ファイルをanythingで開く

 最近はanything-filelist+とanything-git-project(後述)を組み合わせたものを登録してファイルを開いています。buffer、projectのファイル、recentfのファイルなどを一度に見れて便利です。

(defun anything-custom-filelist ()
    (interactive)
    (anything-other-buffer
     (append
      '(anything-c-source-ffap-line
        anything-c-source-ffap-guesser
        anything-c-source-buffers+
        )
      (anything-c-sources-git-project-for)
      '(anything-c-source-recentf
        anything-c-source-bookmarks
        anything-c-source-file-cache
        anything-c-source-filelist
        ))
     "*anything file list*"))

kill ringをanythingで使う

 killringに幾つか内容があっても、インターフェースが微妙すぎて使えなかったのがanythingにしたらつかえるようになっています。
 anything-show-kill-ringというコマンド使うだけなので適当にキーバインドに入れています。このコマンドはanything-config.elに入っています。

(global-set-key (kbd "M-y") 'anything-show-kill-ring)

バッファ内を検索ワードで絞り込む

 anything-c-moccur便利です。いわゆるmoccurのanythingインターフェースです。詳しくはanything-c-moccur.elの設定や使い方等のまとめエントリー - IMAKADO::BLOGをどうぞ。
 僕は以下のようにして、C-M-oで絞込みみたいな感じにしています。

(when (require 'anything-c-moccur nil t)
    (setq
     ;; anything-c-moccur用 `anything-idle-delay'
     anything-c-moccur-anything-idle-delay 0.1
     ;; バッファの情報をハイライトする
     anything-c-moccur-higligt-info-line-flag t
     ;; 現在選択中の候補の位置を他のwindowに表示する
     anything-c-moccur-enable-auto-look-flag t
     ;; 起動時にポイントの位置の単語を初期パターンにする
     anything-c-moccur-enable-initial-pattern t))
(global-set-key (kbd "C-M-o")
                'anything-c-moccur-occur-by-moccur)

exuberant-ctagsをanythingから使う

 コードリーディングとかするときに定義された関数にジャンプするときに便利です。これがないともうコード読めないです。詳しくははてなグループの終了日を2020年1月31日(金)に決定しました - はてなの告知をどうぞ。

 まずtagファイルを作っておきます。以下のコマンドをproject rootで実行すると良さげ。

ctags --verbose -R --fields="+afikKlmnsSzt" --langmap=Perl:+.t --exclude=.git

 それで設定を書きます。

(when (require 'anything nil t)
  (require 'anything-exuberant-ctags)
  )

 あとはキーバインド適当にしておきましょう。

(define-key global-map [(control @)] 'anything-exuberant-ctags-select-from-here)

 これで関数名にカーソルを当てておいて、C-@押すと一瞬でジャンプするようになります。複数候補あったらanythingで絞込みできます。便利すぎる。

gitのprojectのファイルをanythingで探す

 projectのファイルを絞り込みたいみたいなことはよくあるのですが、gitを使っていればyaottiさんが作ったanything-git-project.elが便利です。最近はちょっとだけ改良して、file絞込みのsourceに含めてしまっています。詳しくはanything-git-project.elを少し手直ししてみた - $shibayu36->blog;git repositoryじゃない場所でもanything-git-project.elがエラーにならないように - $shibayu36->blog;あたりをどうぞ。

org-mode.el

 org-modeはタスク管理とか文章作成とか、まあとにかくいろいろなことにつかえるモードです。最近は仕事の管理とか日々のアイディアとかこれをつかって貯めています。詳しくはOrg mode for Emacs をどうぞ。

 あ、そういえばorgモードで編集したファイルをDropboxとかにおいておくと便利だったりしました。

programming補助

flymake.el

 flymakeは勝手にコンパイルしてくれてエラーチェックしてくれるやつです。syntax errorに頭を悩ませることがなくなって捗ります。詳しくはEmacsWiki: Fly Makeflymake (いままでこれ無しでどうやってプログラム書いてたんだろう) - にゃあさんの戯言日記 あたりをどうぞ。

 設定すると以下のようにタイポとかしていると赤く表示してくれます。
f:id:shiba_yu36:20121229001348p:plain

 perl用の設定はantipopさんが書いています。http://blog.kentarok.org/entry/20080701/1214838633 。その他の言語はよくわかってない。

perlの便利設定

perlbrew.el

perlbrewをemacsからつかえるようにしたものです。詳しくはemacsで利用するperlを切り替える(perlbrew.elの紹介) - $shibayu36->blog; をどうぞ。

Test::Classの現在編集中テストだけ実行

 perlでテストを書くときはTest::Classを使って書いているのですが、一つのファイルである程度の量のテストを書き出すと、ある特定のメソッドのみのテスト実行をしたくなります。そのたびにTEST_METHOD=hogehoge prove t/... とかやってられないので、mechairoiさんが書いた以下の様なものを使うと便利です。なんかいろいろ付け足したりしたので、環境によってはうまく動かないかも。

(defun run-perl-method-test ()
  (interactive)
  (let (
        (command compile-command)
        (test-method nil))
    (save-excursion
      (when (or
             (re-search-backward "\\bsub\s+\\([_[:alpha:]]+\\)\s*:\s*Test" nil t)
             (re-search-forward "\\bsub\s+\\([_[:alpha:]]+\\)\s*:\s*Test" nil t))
        (setq test-method (match-string 1))))
    (if test-method
        (compile
         (format "cd %s; TEST_METHOD=%s %s -MProject::Libs %s" (replace-regexp-in-string "\n+$" "" (shell-command-to-string "git rev-parse --show-cdup")) test-method (perlbrew-get-current-perl-path) (buffer-file-name (current-buffer))))
        (compile
         (format "cd %s; %s -MProject::Libs %s" (replace-regexp-in-string "\n+$" "" (shell-command-to-string "git rev-parse --show-cdup")) (perlbrew-get-current-perl-path) (buffer-file-name (current-buffer)))))))

 以下のような感じで自分が編集しているmethodだけテストできます。僕はC-c tとかに割り当ててるので、編集 -> テスト実行 -> 編集みたいなのを繰り返しています。

f:id:shiba_yu36:20121229000459p:plain

その他便利機能

htmlize-and-browse-by-safari

プログラミング関係のスライド作成に便利。Emacsでの見た目そのままにソースコードをブラウザで開くコマンドを作った (Kanasansoft Web Lab.) あたりをどうぞ。

最後に

 さて非常に長いエントリになってしまいました。役に立つ設定などありましたでしょうか。

 結局どのくらい設定が掃除できたのか、見てみると...

wc -l init.el inits/* | grep total
    1975 total

 300行しか減らなかった!!!!!まぁ久々にいろんな設定を見れたりしたので良かったです。

 ちなみに今回の設定はほとんど以下の書籍から勉強していろいろ追加しています。emacsに関しては以下の三冊を読めば十分な気がしています。