emacsとxyzzyの違い

http://d.hatena.ne.jp/trotr/20080728の続き
今思いついたのは以下の3つです。

  • (defun (beg end) (interactive "r")の挙動
  • listの要素の比較の方法
  • replace-(string|regexp)-region

(defun (beg end) (interactive "r")の挙動

  • emacsはpointの値がbeg < endになる。
  • xyzzyは(beg <- region-beging),(end <- region-end)という感じ

xyzzyの場合は、sortしてからじゃないと使えないみたいです。*1

listの要素の比較の方法

  • schemeでもmemq,memv,member
  • emacsではmemq,memv,member
  • xyzzylispではmemberのみが提供されていてoptionで比較関数を渡す。

M-xdescribe-function memberの結果

member: a built-in function.

member ITEM LIST &key :TEST :TEST-NOT :KEY

not documented.

「:TEST」とともに比較関数を渡せるみたいです。
xyzzylispのバグなのか関数の使い方を勘違いしているのか分からないのですが、optionのTESTの部分を小文字のtestにしないとうまく比較関数が渡されません。
実行結果

	(member "a" '("a" "aa") :test #'equal) ;=> ("a" "aa")
	(member "a" '("a" "aa") :TEST #'equal) ;=> nil
;;何も比較関数を渡さない時は、多分eqで比較される
	(member "a" '("a" "aa")) ;=> nil

replace-(string|regexp)-region

  • 範囲
    • emacsはdefaultで選択したregion内だけで置換を行う。
    • xyzzyはバッファ内のすべてを対象に置換を行う。
  • 履歴
    • emacsは一つ前の設定が使用できる。
    • xyzzyは常に真っ白

そんな訳で,replace-(string|regexp)-regionの作成。

(defvar replace-region-last-from "")
(defvar replace-region-last-to "") 

(defmacro replace-region-maker (name &optional op)
  `(defun ,name (beg end from to) (interactive "r\nstarget:\nswith:" :default1 replace-region-last-from :default2 replace-region-last-to)
     (setf replace-region-last-to to)
     (setf replace-region-last-from from)
     (sort-beg-end beg end)     
     (save-excursion     
       (goto-char beg)
       (while  (scan-buffer from ,@op :no-dup nil :tail t :limit end)
	 (replace-match to)))))

(replace-region-maker replace-string-region)
(replace-region-maker replace-regexp-region (:regexp t))

xyzzyにしかないscan-bufferは便利。
(あとで追加する。たぶん。)

*1:下から上という感じにregionを選択したときに思わぬ動作をしてしまう。