Emacs 24.3いれたけど

24.3でましたね。emacs-jpが発足したりとにわかにEmacs界も盛り上がりを見せてきました。
触発されて設定を根本から整理しはじめる羽目になり、いい時間泥棒になりました。ありがとうございます。

さて、24.3早速試したのですが、結論から言えばとりあえず見送りに。
リリースノートざっくりと読んで、いくつかいいなーと思う物もあったので残念ですが、僕の環境ではどうも安定せず。。

設定の切り分けなど、丁寧な検証はしていないので、設定次第でどうにかなるかもしれませんが、数分に一度くらい数秒フリーズするという現象が発生しています。

数週間前にHEADを試していたときも同様の現象が起きており、24.3で改善しているかと期待したのですが、直りませんでした。
もう少しユーザーが増えてきてから検証も含めて再挑戦しようかなと思っています。

あとHEADではtoggle-fullscreen-frameというコマンドが追加されており、それでフルスクリーンのトグルができたので、フルスクリーンパッチ(ns-toggle-fullscreen)が不要になっていたのですが、24.3では追加されておらず、OS Xネイティブのフルスクリーンに対応はしている物の、あまり使い勝手が良くない状況です。

というか、個人的にネイティブのフルスクリーンに全く魅力を感じないので、ns-toggle-fullscreenのようなフルスクリーンで十分なのですが。

HEADでは、ns-use-native-fullscreenという変数をnilにしておけば、ns-toggle-fullscreenのようなフルスクリーン、non-nilにしておけばネイティブ、という風に切り替えられたので便利でした。

あとはinlineパッチもそのままでは当たらないですね。これはちょっといじれば当たるようにはなりますが、動作的に正しいかどうかはわからず。

とにかく、まだいろいろハードル高いかなぁという印象でした。

MacのEmacsがどうにも重いので設定を見直した

MacEmacs(Cocoa Emacs)はLinuxとかで動かすよりもどうも重く感じる。
特に、普段php書く機会が多いけど、php-modeはひどく重い。(多分、php-modeというよりc-modeじゃないかと思ってる。)
特にスクロール時に突っかかることが多い印象。

とはいえ、我慢できないほどでもないし、一瞬Ubuntuとかに移行することも考えたけど、Macに完全に依存した生活を送っているので、今更メインの環境を移すのはしんどいし、何より、デザインのまねごとをしてたりする身としては、Adobe系がネイティブに動かないのはつらい。
CUI版に移ることも一瞬考えたけどキーマップの関係でそれもつらい。

ということでちゃんと設定を見直すことにした。
といっても、なんでもっと早くにやらなかったんだと思うほど、問題の設定はあっさり見つかり。

結論から言うと、以下の4つの設定が大きく影響していた。

・scroll-bar-mode
・linum-mode
・global-hl-line-mode
・frameのalpha値

まず、scroll-bar-mode。
これが一番大きかった。
こいつが有効になってると、スクロールがめちゃめちゃ重い。
ので、
(scroll-bar-mode -1)
としてやる。
もっとも、人の設定見てるとたいていの人は無効にしてるように思うので、無効にしていなかった自分が特別あほなのかもしれない。
みんな無効にしてるなーとは思ってたけど、パフォーマンスに影響ある物だとは思っていなかったので、気にしていなかった。

次にlinum-mode。
これが重いことは元々わかっていたんだけども、利便性の方が上かと思って有効にしていた。
が、別になくてもいいんじゃないかという気もしてきたので、無効にしてみている。
無効にしないまでも、
http://d.hatena.ne.jp/daimatz/20120215/1329248780
に書いてある対策くらいはしておくべきかと思う。
行番号はネイティブな実装が欲しい。


次、global-hl-line-mode。
カーソルのある行をハイライトするという奴。
これも多少重いのは承知していたけど、別にいらなのではないかと思い直し、これも解除。
代わりに、カーソル位置が目立つようにblinkを有効にしておいた。

(blink-cursor-mode 1)

最後、frameのalpha値。
元々、
(set-frame-parameter nil 'alpha 95)
とかやって、背景を透過していたのだけど、どうやらこれも重いようだった。
自宅のCore i7-3960Xつんだデスクトップマシン(OSx86)はそんなでもないんだけど、MacBook Pro Retina(i7 2.3GHz)だと結構影響大きかった。
マシンスペックもあるかもしれないけど、Retina特有のスクロールかくつき問題とか、あの解像度に由来する物もあるのかもしれない。
とにかく、
(set-frame-parameter nil 'alpha 100)
のときはスクロールはスムーズなのに、99になるだけで明らかにかくつくようになっていた。

背景透過も好きだったけど、普段は100で、必要なときにショートカットから簡単に透明度の上げ下げができるようにしておいた。


つまり、結論としては、余計な設定するなの一言に尽きる。
とはいえ、背景透過と、scroll-bar-modeは全然想像してなかったので、びっくりした。もともとフォントとかの方を疑っていたので…。

まぁphp-modeもそれなりのスピードで動くようになってきたので、よかったよかった。
たまに膿み出ししないとだめだなぁ・・・。

Homebrewでnginxを入れるときに比較的簡単に--add-moduleする方法

なんかHomebrewなネタが続く。

nginxでサードパーティモジュールを入れるときに

./configure --add-module=/path/to/module1/source

とかすると思うんですが、Homebrewでnginxいれようとすると、あらかじめ定義されたモジュールしか入れられないっぽい。
仕方ないので、普通にFormulaいじるかーと思ったものの一応ぐぐったらすでに汎用的に使えるFormulaを書いてくれてる人がちらほら。
ポリシーに沿わないとかで、残念ながら本流には取り込まれていないようですが、実用に問題はないと思われます。

件のPull Requestは→: Compile nginx w/external modules by kevsmith · Pull Request #6600 · Homebrew/legacy-homebrew · GitHub

そのまま使おうと思ったけど、結構古いFormulaがベースなので、ついでに最近のFormulaをベースにマージしたものを作成してから使うことに。

それがこれ→ [Homebrew] nginx w/external modules · GitHub

こんな感じで使う。今回はHttpHeadersMoreModuleを入れてコンパイルする例。

git clone https://github.com/agentzh/headers-more-nginx-module.git
cd headers-more-nginx-module
brew install https://raw.github.com/gist/3691439/d3588835afe9656dcc7079b07bebcb5b08b1c468/nginx.rb --with-module=`pwd`

そのほかリンカオプションも渡せるみたい。上述のPull Requestのページに例が載ってます。



ところでこのnginxのformulaに--with-passengerなんてオプションがあるけどPATHが引き継がれないからかRVM使ってるとうまくインストールできない。passenger-configみつからないって怒られる。
仕方ないのでこの--with-moduleでrvm環境下のpassengerのパス渡してインストールした。今のところ特に問題なし。

Emacs 24.2がでたので入れてみた

必要に迫られてRuby+RailsObjective-Cを並行して叩き込んでいる最中でてんやわんやな今日この頃。

そんなわけで24.2がなんかリリースされてたので、適当に入れてみました。

といってもbugfixリリースなので、別にそんな大きな違いはないんですがー。
チェンジログ読んでもそんな心の琴線に触れるアレはなかったです。

前書いたHomebrewのFormulaがパッケージだけ差し替えてそのまま使えたので特にトラブルなくアップデート完了。
今のところは特に問題なし。

gist差し替えたので以下の様な感じで行けます。

     $ brew install https://raw.github.com/gist/2874340/d54f23d1e0f1bb700529a47bbb430c284f3e156e/emacs.rb --cocoa --inline
     $ ln -s /usr/local/Cellar/emacs/24.2/Emacs.app /Applications

例よってcpするかlnするかはお好みでどーぞ。

当ててるパッチなどは以前の記事をご参照ください。
http://d.hatena.ne.jp/rkworks/20120605/1338914051

Emacs 24.1正式版 + inline-patchをHomebrewで入れる

追記: インストールバージョンを24.1RCから24.1正式版に差し替えました。再インストールする際はbrew uninstall emacsをしてからで。

24対応のパッチがコミットされていたので適当にFormula作ってインストールした。

Emacs24については
http://sakito.jp/emacs/emacs24.html
が最近更新されててわかりやすい。ありがとうございます。

インストール

環境はMac OSX 10.7.2、Xcode 4.2.1です。Xcode 4.3にしろってHomebrewに怒られます。

     $ brew install https://raw.github.com/gist/2874340/119964669dec039ffe07d9841992df4e024c2ddb/emacs.rb --cocoa --inline
     $ cp -r /usr/local/Cellar/emacs/24.1/Emacs.app /Applications

宗教上の理由でcpしますが、シンボリックリンクはるのでも良いと思います。
ただ、多分Alfredみたいなランチャはシンボリックリンクだと無視してくれたりします。(設定で変えられる?)

基本は以上。多分autoconfが古いと止まるので、2.6.1とかあたりの人は

     $ brew install autoconf
     $ brew ln autoconf

とかなんとかしてやればいいような気がします。追記: 依存関係にautoconf追加したので多分勝手にやってくれるはず。

Formulaについて

当ててるパッチは標準のFormulaでも当てているフルスクリーンパッチと、trunkのインラインパッチと、
http://moimoitei.blogspot.jp/2010/05/fix-cocoa-emacs-23.html
と、
https://raw.github.com/gist/1273211/
です。
ほかにもいくつか入れようとしましたがもう取り込まれてたりとかで、この辺で落ち着きました。

基本的に上記インストールコマンドで叩くこと以外想定してないです。

Emacsで1〜3ストロークで画面上の任意の場所に移動するための設定

タイトルで1〜3と書きましたが、実際は2ストロークが平均的です。運が良ければ1ストローク、たまに3ストローク。4ストローク以上もありえますが、普通のソースコード上ならまず無いです。
ace-jump-modeを使います。
これはvimのEasyMotionというプラグインにインスパイアされて作られたみたいです。どういう機能かというのは
http://d.hatena.ne.jp/syohex/20120304/1330822993
が参考になります。
実際に動いてるデモは公式のものがあります。
http://dl.dropbox.com/u/3254819/AceJumpModeDemo/AceJumpDemo.htm

で、実際便利なのですが、一度ace-jump-modeを起動して、飛びたい文字を指定して、とやるのもなんだか面倒になってきて、あまり使っていませんでした。(ace-jump-modeの起動をC-c SPCに設定していたのもあります。)
そんな中、テスト駆動JavaScriptの著者であるChristian Johansen氏の.emacs.dをGitHubで眺めていると、このace-jump-modeを大胆な設定で使っているのを発見しました。*1
これはいいと思ったので自分ごのみに改変して自分のところにも取り込んで利用しています。 元ネタはこちら

どんなもんかと簡単に説明すると、H-a 〜 H-z, H-0 〜 H-9をすべてace-jump-modeに割り当て、例えばH-c通したら即座に画面上の文字cにジャンプしようとするようにします。画面上に文字cが1つしか現れていなければH-cで即座にジャンプしますし、複数現れていればH-c bみたいな感じで2ストロークで飛べます。候補が多すぎる場合はそれに応じてストローク数は増えますが、大体2-3回です。Hって何って人は後述の修飾キーの説明をどうぞ。

こういう時に便利

例えばこういうソース。

(put 'if-match 'scheme-indent-function 2)
(put 'let*-values 'scheme-indent-function 1)
(put 'let-args 'scheme-indent-function 2)
(put 'let-keywords* 'scheme-indent-function 2)
(put 'let-match 'scheme-indent-function 2)
(put 'let-optionals* 'scheme-indent-function 2)
(put 'let-syntax 'scheme-indent-function 1)
(put 'let-values 'scheme-indent-function 1)
(put 'let/cc 'scheme-indent-function 1)
(put 'let1 'scheme-indent-function 2)
(put 'letrec-syntax 'scheme-indent-function 1)
(put 'make 'scheme-indent-function 1)
(put 'multiple-value-bind 'scheme-indent-function 2)
(put 'match 'scheme-indent-function 1)
(put 'parameterize 'scheme-indent-function 1)
(put 'parse-options 'scheme-indent-function 1)
(put 'receive 'scheme-indent-function 2)
(put 'rxmatch-case 'scheme-indent-function 1)
(put 'rxmatch-cond 'scheme-indent-function 0)
(put 'rxmatch-if  'scheme-indent-function 2)
(put 'rxmatch-let 'scheme-indent-function 2)
(put 'syntax-rules 'scheme-indent-function 1)
(put 'unless 'scheme-indent-function 1)

このうち(put 'parameterize 'scheme-indent-function 1)を(put 'parameterize 'scheme-indent-function 2)に変えたいなーと思ったときにどう移動するか。
多分isearchとか使ってC-s para C-e C-b C-h 2とかですか?(僕はこのへんのキーバインドすら変更しまくっているので一般的なキーバインドがうろ覚えなのですが)
これをace-jump-modeならC-c SPC 1 h C-d 2で出来ます。*2
さらに、今回紹介する設定をすると、H-1 i C-d 2で出来るよ、っていうはなしです。移動までならH-1 iってことですね。慣れれば相当便利です。
isearchを利用した移動はよくやりますが、今回みたいに似たようなワードばかり出るシーンだと時間かかっちゃうことあるんで。。

インストール

普通にhttps://github.com/winterTTr/ace-jump-modeからとってきてパスの通ったところにおいて

(require 'ace-jump-mode)

してください。package.elが使える環境なら、MarmaladeかMELPA経由でも入れられるはずです。ELPAは入れてないので知りません。

設定

本来ならここで

(define-key global-map (kbd "C-c SPC") 'ace-jump-mode)

 とでもしてキーバインドの設定をしておわりなんですが今回はそれはせずに以下の様な設定を足します。

(defun add-keys-to-ace-jump-mode (prefix c &optional mode)
  (define-key global-map
    (read-kbd-macro (concat prefix (string c)))
    `(lambda ()
       (interactive)
       (funcall (if (eq ',mode 'word)
                    #'ace-jump-word-mode
                  #'ace-jump-char-mode) ,c))))

(loop for c from ?0 to ?9 do (add-keys-to-ace-jump-mode "H-" c))
(loop for c from ?a to ?z do (add-keys-to-ace-jump-mode "H-" c))
(loop for c from ?0 to ?9 do (add-keys-to-ace-jump-mode "H-M-" c 'word))
(loop for c from ?a to ?z do (add-keys-to-ace-jump-mode "H-M-" c 'word))

これでH-0〜H-9、H-a〜H-zで任意のところに飛べます。
H-M-a〜zはword移動にしてあるので単語の先頭の文字だけがジャンプ先候補になります。
例えば、global-linum-modeという文字列に対してH-mをおすとglobal-linum-modelがジャンプ先候補になりますが、H-M-mとしたらglobal-linum-modeがジャンプ先候補になります。
僕は単語の先頭かどうかってことをいちいち考えるのが面倒なので、候補数が増えてもいいから基本はjump-char-modeを使うようにしています。
これが合わなければラスト4行を

(loop for c from ?0 to ?9 do (add-keys-to-ace-jump-mode "H-" c 'word))
(loop for c from ?a to ?z do (add-keys-to-ace-jump-mode "H-" c 'word))

とすればH-a〜zもjump-word-modeになります。ちなみに参考元の設定では単語モードのみになっていました。
HyperじゃなくてAltがいいとかなら"H-"を"A-"にすればOKです。
あとはまぁ記号にも飛びたいとかであれば適宜マッピングしてください。
自分は最近記号も飛びたくなってきたので

(loop for c from ?! to ?~ do (add-keys-to-ace-jump-mode "H-" c))
(loop for c from ?! to ?~ do (add-keys-to-ace-jump-mode "H-M-" c 'word))

として主要な記号も含めてほぼすべてマッピングしてしまっています。
どうせほとんどHyper潰しちゃうんだから個人的にはここまでやっちゃっていいんじゃないかなーとおもいます。

おまけ:修飾キーについて

ここではHyperを使っていますが、別に他の修飾キーで構いません。と言ってもControlとMetaを潰す訳にはいかないので、Super, Hyper, Altあたりが候補に上がりますが、Superはすでにそれなりに使うコマンドで予約済みの人も多いはず。
僕はHyperとAltはがら空きだったのでHyperを潰しました。
SuperとかHyperとか何?、AltってMetaじゃないの?って人はこのへんとか。
僕はMacユーザーなので、右コマンドをHyperにしています。デスクトップではKinesisキーボードを使っていて、右のSpaceがそうなるようになっています。ホームポジションで右手の親指が自然にのっかる位置なので非常に押しやすい。
MacBook Airでは右コマンドそのままです。そこそこ押しやすい。
僕の設定は以下の通り。(Lion, Emacs24)

(setq ns-command-modifier (quote meta))
(setq ns-right-command-modifier (quote hyper))
(setq ns-alternate-modifier (quote super))
(setq ns-right-alternate-modifier (quote alt))

あとCentOSを使うこともありますがそれはここを参考に、CapsLockとCtrlを入れ替えたあと、CapsLockにHyperをマッピングしています。

おわりに

なんか大したこと書いてないのに長くなってしまった。
でも久しぶりに使い勝手に大きな変化が現れたので自分の中で相当大きいです。
あとこれ書いてる途中にjaunte.elというのを知りましたけど、あれも便利そうですね。
似てるようで若干違うようですが、複数ウィンドウまたいで飛べるのはいいですね。char-modeでそれやっちゃうとさすがにウィンドウの状況によっては検索候補多すぎるかもしれないけど。。
時間ができたらフォーク版作るのも良いかもしれないなー

Emacsは好きですが、やはりカーソル移動を始めとする編集機能はVimとかに比べると弱いので、こういった改造はすごく魅力的に感じます。
僕はC-n,p,f,bという配置もすごく不満に感じたので、それもリマップしています。このへんはあたらしいelisp入れると設定を上書きされることも多いんで色々面倒なのですが。。まぁこのあたりのネタはそのうち。

*1:ただしこの設定をした人はコミットログを見る限り別の方のようです。というかほとんどのコミットが別の方のようです。Emacs Rockというスクリーンキャストサイトの関係だと思うんですがよくわかりません。

*2:ace-jump-modeの起動をC-c SPCにしている場合