Personal tools
You are here: Home ブログ matsuyama tokyo-emacs#x02の個人的レポート
Document Actions

tokyo-emacs#x02の個人的レポート

id:hayamizさん主催のtokyo-emacs#02に参加してきました。ミラクルリナックスという魅力的な場所で、Emacsが好きという魅力的な人達が多数参加した、魅力的なイベントでした。イベントに関するレポートは諸処であげられているので、このエントリでは発表されたネタに個人的なツッコミを入れていくだけにします。

kwappaさんの発表

「こういうことできたらいいな」という原始的な視点から、Emacsはカスタマイズしてこそという真理を再確認させてくれた発表でした。kwappaさんはその発表の中で、二つのカスタマイズ例を例示されました。一つは一番下までスクロールしたらバッファの先頭に戻るというカスタマイズで、もう一つはリージョンを選択していない時に C-w すると kill-whole-line の挙動になるというカスタマイズです。個人的には後者はすごくいいアイデアだと思います。同発表で実装を説明されていましたが、添削もかねてちゃんとした実装(*)を公開したいと思います。

(*) 自身があるわけではありませんが少しは綺麗になってるはずです

;; 行をコピーするコマンド
(defun copy-line (&optional arg)
  (interactive "p")
  (copy-region-as-kill
   (line-beginning-position)
   (line-beginning-position (1+ (or arg 1))))
  (message "Line copied"))

;; リージョンを選択していないときに行をキルするコマンド(Emacs 23 and advice版)
(defadvice kill-region (around kill-line-or-kill-region activate)
  (if (and (interactive-p) transient-mark-mode (not mark-active))
      (kill-whole-line)
    ad-do-it))

;; 同上(Emacs 22 or 非advice版)
(defun kill-line-or-region (beg end)
  (interactive (list (point) (mark t)))
  (if (and (interactive-p) transient-mark-mode (not mark-active))
      (kill-whole-line 1)
    (kill-region beg end)))
(global-set-key (kbd "C-w") 'kill-line-or-region)

;; リージョンを選択していないときに行をコピーするコマンド(Emacs 23+advice版)
(defadvice kill-ring-save (around kill-line-save-or-kill-ring-save activate)
  (if (and (interactive-p) transient-mark-mode (not mark-active))
      (copy-line)
    ad-do-it)) 

;; 同上(Emacs 22 or 非advice版)
(defun kill-line-or-region-save (beg end)
 (interactive (list (point) (mark t)))
 (if (and (interactive-p) transient-mark-mode (not mark-active))
     (copy-line)
   (kill-ring-save beg end)))
(global-set-key (kbd "M-w") 'kill-line-or-region-save)

Emacs 23とEmacs 22で微妙に挙動が違う(*)ので、それぞれ別の実装になっています。adviceで簡単に実装できるEmacs 23版のほうがスマートな気がします(*)。

(*) mark-even-if-inactive 変数のデフォルト値。これを t にしてやればEmacs 23の実装でも動くと思います

(*) 一般的にデフォルトのキーバインドに違うコマンド名を割り当てるのはよくない

tokyo-emacsの雑談にもありましたが、上記のようなコードをEmacs 23でもEmacs 22でもポータブルにするには次の関数/変数を使えばよいと思います。

  • emacs-major-version 変数
  • window-system 変数
  • system-type 変数

emacs-major-version 変数にはEmacsのメジャーバージョン番号が数値で入ります。 window-system には使用しているウィンドウシステムの識別子がシンボルで入ります(xやwindows-ntなど)。 system-type 変数にはシステムの識別子がシンボルで入ります(gnu/linuxなど)。

例えば上記のコードをポータブルにすると次のようになります。

;; 行をコピーするコマンド
(defun copy-line (&optional arg)
  (interactive "p")
  (copy-region-as-kill
   (line-beginning-position)
   (line-beginning-position (1+ (or arg 1))))
  (message "Line copied"))

(cond
 ((= emacs-major-version 23)
  ;; リージョンを選択していないときに行をキルするコマンド(Emacs 23 and advice版)
  (defadvice kill-region (around kill-line-or-kill-region activate)
    (if (and (interactive-p) transient-mark-mode (not mark-active))
        (kill-whole-line)
      ad-do-it))
  ;; リージョンを選択していないときに行をコピーするコマンド(Emacs 23+advice版)
  (defadvice kill-ring-save (around kill-line-save-or-kill-ring-save activate)
    (if (and (interactive-p) transient-mark-mode (not mark-active))
        (copy-line)
      ad-do-it))) 
 ((= emacs-major-version 22)
  ;; 同上(Emacs 22 or 非advice版)
  (defun kill-line-or-region (beg end)
    (interactive (list (point) (mark t)))
    (if (and (interactive-p) transient-mark-mode (not mark-active))
        (kill-whole-line 1)
      (kill-region beg end)))
  (global-set-key (kbd "C-w") 'kill-line-or-region)
  ;; 同上(Emacs 22 or 非advice版)
  (defun kill-line-or-region-save (beg end)
    (interactive (list (point) (mark t)))
    (if (and (interactive-p) transient-mark-mode (not mark-active))
        (copy-line)
      (kill-ring-save beg end)))
  (global-set-key (kbd "M-w") 'kill-line-or-region-save)))

id:IMAKADOさんの発表

id:IMAKADOさんは anything-project.el という拡張を発表されました。この拡張はプロジェクト内のファイルを名前で検索したりgrepするためのものです。名前に anything- とありましが、anythingとは独立して使うことも可能らしいです。僕は仕事では基本的にJavaやHTMLを扱うのですが、Javaではパッケージとクラスがディレクトリ構造とファイルに一対一で対応するため、どうしてもディレクトリが深くなってしまい、目的のファイルを開くのに時間がかかるという問題があります。それを解決するため、ずいぶん前から僕はGNU findutilsを使った特殊なハック(*)を使っており、anythingの anything-c-source-locate と併用して解決な環境を実現していました。ただ、ポータビリティと使いやすさという点から考えればこの方法は少々気持ちわるいです。というのもWindowsでこの方法を利用するためにはGNU findutilsをコンパイルしないといけませんし、PATH環境変数に手を加えないといけません。

(*) http://dev.ariel-networks.com/Members/matsuyama/use-gnu-locate

id:IMAKADOさんが示した anything-project.el はある意味理想の実装です。Emacs Lispで実装されているので全てのプラットフォームで実行できます。少し懸念があったのがファイルデータベースの作成のコストなのですが、件のJavaの製品のプロジェクトルートでファイルデータベースを作成しても2.5秒ほどしかかからなかったので、心配するほどのことではありませんでした(*)。

(*) たぶんバイトコンパイルしたらもっと速いと思います

(benchmark-run-compiled (ap:directory-files-recursively ".*" "~/src/myproject"))
(2.463106 1 0.14226200000000055)

個人的には、このようなディレクトリをトラバースする処理は頻繁にやるので次のような関数で提供されているとうれしいです。

(defun walk-directories (directory &optional function)
  ...)

この関数は directory 以下のディレトリやファイルを function で指定された関数にコールバックする関数です。次のように使います。

(walk-directories "~/" (lambda (entry) (message "Found: %s" entry)))

検索オプションなども渡せるといいかもしれません。さらに欲を言うとCコードで実装されてほしいです。というのもシステムによっては効率よくディレクトリをトラバースする関数が容易されているからです。どなたかemacs-develに提案する人がいればいいのですが。

anything-project.el はプロジェクトを管理する拡張ですが、今のところ検索機能だけに限られています。プロジェクト管理の要件を考えると最低限次の機能が必要だと思います。

  1. ファイルデータベースおよび検索機能
  2. ナビゲーション
  3. コーディング規約などを統一する機能(インデントスタイルやCスタイル)
  4. 統一的なビルドシステム
  5. メタ情報データベース

(1)は anything-project.el にすでに実装されています。(2)はEmacs Nav(*)のようなファイルブラウザ機能です。プロジェクト(言語)によってさまざまなディレクトリ構造の慣習があるので、それを吸収するのが目的です。(3)は dirvars.el などで実装できる機能ですが、よりプロジェクトらしく使用できるとよいです。(4)はCのプロジェクトでもJavaのプロジェクトでも関係なくF10でビルドできるような機能です。(5)は他の拡張のために仕様化されたプロジェクトのメタ情報を提供する機能です。例えばflymakeがビルドスクリプトを見つけるのに使ったり、auto-completeがソースファイルを見つけるのに使います。仕様化されていることが大事です。

(*)http://code.google.com/p/emacs-nav/

ともかく anything-project.el は限定的ではありますが、十分利用できるものだと思います。 cl マクロが使われまくってるので、僕にはソースの内容までうまく理解できませんが…

松本智行さんの発表

StumpWMというタイリングウィンドウマネージャの話でした。ご自身ではEmacsと全然関係ないとおっしゃっていましたが、実は関係あるのではないかと思っています。というのもEmacs 23から入った(*)XEmbedという機能を使えば、Emacsでウィンドウマネージャが作れるかもしれないからです。ウィンドウマネージャに関してもXEmbedに関しても全く調べてないので適当なことを言っていますが、将来EmacsがウィンドウマネージャになってログインシェルまでEmacsになったりすると素敵じゃないですか。それだけです。

(*) 厳密には仕様がサポートされただけかもしれません。詳しくは仕様を参照してください http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html

ちなみに松本智行は以前にXMonadを使ってらっしゃったらしいです。僕は現在でもXMonadを使っていますが、もし次にXMonadを設定をいじる必要が発生した場合はおそらくXMonadを捨ててawesomeかStumpWMに以降すると思います。それぐらいXMonadはユーザー泣かせの狂ったソフトウェアなのです。

僕の発表

僕はEmacsのプロファイラに関して発表しました。概要を説明しますと、Emacs標準の benchmark.elelp.el は使いものにならないから、Emacsのネイティブプロファイラを実装したよ、という話です。簡単なデモも行いました。資料は次のURLから見れます(*)。

(*) tokyo-emacsグループにも適宜アップロードします

http://cx4a.org/pub/tokyo-emacs/emacs-native-profiler.pdf

このプロファイラはEmacs本体に手をいれることで実装しています。パッチは次のURLから手に入ります。

http://code.google.com/p/emacs-native-profiler/

特徴は次のようになります。

  • ネイティブプロファイラ
  • 少ないオーバーヘッド
  • コールツリーを見れる
  • 簡単に使える

今のところGNU/Linuxでしか動作確認していません。Mac OS Xだとプロセスの生成時(?)に固まります。

使い方は以下のようになります。

  1. M-x profiler-start
  2. ごにょごにょ
  3. M-x profiler-results
  4. ごにょごにょしたプロファイル結果が見れます

以上です。tokyo-emacs#x02は大変面白かったです。id:hayamizさんに感謝します。そして次回も開催されることを期待しています。

最後に宣伝です。9/29にアリエル・ネットワーク社内でEmacsの勉強会を行います。講師は僕ではありませんが、僕などは及ばなぬ技量の持ち主が講師をやってくれます。参加希望の方はATNDのページから登録してください。参加お待ちしています。

http://atnd.org/events/1467

Category(s)
emacs
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/matsuyama/tokyo-emacs-02/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.