るびきちです。
つい最近おもしろいEmacsLispをみつけた。その名も「eev」。
http://angg.twu.net/index.html#eev
eevは大きくわけてふたつの機能がある。
* ハイパーリンク
* region内のスクリプトをセーブ
注目したいのは「ハイパーリンク」。Emacsをひとつの「Lispシステム」とみ
なしてLisp式でハイパーリンクをしてしまっている。とにかくその単純明解か
つ汎用性の高い発想に驚きだ。
その発想の原点となるのが
C-x C-e
で
どのバッファであろうが
Lisp式を評価できるということだ。
emacs-lisp-modeであろうが、text-modeであろうが、perl-modeであろうが、
ruby-modeであろうがなんでもいい。Emacs上にいる以上いつでもどこでも
Lisp式が評価できるということ。
それを逆手に取って
だったらテキストにLisp式を埋め込んでしまえ!
って発想がでた。それがeevの発想。
たとえば、
# (find-file "~/.emacs")
の)の後のカーソルをあわせてC-xC-eすると、バッファが~/.emacsへと変わる。
そんなのは当たり前のことなのだが、ちょっと視点を変えてみたい。
そして、次のコードを.emacsに加えておく。(これはeev配布物には加わってな
い。おれが勝手につくった)
(defun ee-next-sexp ()
(interactive)
(re-search-forward ")$"))
(defun ee-prev-sexp ()
(interactive)
(re-search-backward ")$"))
(global-set-key "\M-p" 'ee-prev-sexp)
(global-set-key "\M-n" 'ee-next-sexp)
そうすると、テキスト内に埋め込まれたLisp式をM-p/M-nでとぶことができる。
で、Lisp式の後にカーソルをあわせて C-x C-e すると実行される。
別にfind-fileに限らない。関数の解説がみたければ describe-function だし
変数ならば describe-variable だ。関数定義にとびたければ find-function。
そういう式を実行すると、所定の場所へジャンプする。これっていってみれば
ハイパーリンク
に他ならない!!!
eevをインストールするとそういうハイパーリンクをもっと便利に使えるよう
にする関数がたくさん登録される。よく使うものとしては
(find-fline filename position)
という関数がある。それはfind-fileの拡張版でpositionに行番号などを入れ
るとその場所へジャンプしてくれるようになる。
(find-fline "~/.emacs" 5)
で~/.emacsの5行目へジャンプするように。
さらに、M-eに end-of-line-then-eval-last-sexp という行頭へ飛んでからそ
の式を評価するコマンドが割り当てられる。M-p/M-nと組み合わせてHTML顔負
けのハイパーリンクができるのがある意味恐しい。どんなファイルを編集して
てもそのハイパーリンクがつかえてしまうのだから!!
スクリプトに使ってもいいし、ChangeLogメモと組み合わせてもいい。
eevを使って以来、拙作clwikiはもう使わなくなった(^^; リンクはeevがある
し、ブロックについてはyardmという「ChangeLog風RDメモ(開発中)」を使って
いるから。RDはほぼフリーフォーマットな上、rd-mode.elが見出しには色をつ
けてくれるから嬉しい。それに階層構造もつくれるし。ChangeLogメモだと先
頭のタブがうざい、clwikiのブロックはclgrepで検索されないなどなど。
さらにbookmark.elとの連携で任意のファイルの位置をLisp式に吐き出すコー
ドを書いてみた。
(defun ee-bookmark (fn pos front rear)
(if fn (find-file fn)
(push-mark))
(goto-char pos)
(if (search-forward front (point-max) t)
(goto-char (match-beginning 0)))
(if (and rear (search-backward rear (point-min) t))
(goto-char (match-end 0))))
(defalias 'pos 'ee-bookmark)
(setq ee-bookmark-tmp nil)
(defun ee-yank (arg)
(interactive "P")
(when ee-bookmark-tmp
(let ((print-escape-newlines t)
(buf (car ee-bookmark-tmp))
(fn (nth 1 ee-bookmark-tmp))
(pos (nth 2 ee-bookmark-tmp))
(front (nth 3 ee-bookmark-tmp))
(rear (nth 4 ee-bookmark-tmp)))
(setq ee-bookmark-tmp nil)
(kill-new (if (eq buf (current-buffer))
(format "(pos nil %d %S %S)" pos front rear)
(format "(pos %S %d %S %S)" fn pos front rear)))))
(call-interactively 'yank))
(global-set-key "\C-y" 'ee-yank)
(defun ee-make-bookmark (arg)
(interactive "P")
(require 'bookmark)
(let* ((bookmark "ee")
(bookmark-alist (list (list bookmark (bookmark-make-cell nil))))
(filename (unless arg (bookmark-get-filename bookmark)))
(front (bookmark-get-front-context-string bookmark))
(rear (bookmark-get-rear-context-string bookmark))
(position (bookmark-get-position bookmark))
)
(setq ee-bookmark-tmp (list (current-buffer) filename position front rear))
(message "stored position at #<buffer %s> to kill-ring." (buffer-name (current-buffer)))))
ここの位置を記録したいと思ったら M-x ee-make-bookmark とする。(当然お
れはキーにわりあてている)それから、貼り付けたい場所で C-y すればその式
がyankされる。
面白いと思ったら是非とも使ってみては?
るびきち☆
http://www.ruby-lang.org/~rubikitch/ ←Ruby大衆化計画(笑)