Emacs Lispに関する質問です。下記のような hoge という関数を実行した直後にundoを実行すると、まず(2)の置換がキャンセルされ、さらにundoすることで(1)の置換がキャンセルされると思います。

これを、一度のundoが 関数hoge() を実行するまえに戻すような関数 hoge() のコードの書き方はできんもんでしょうか。
undoの利用に手を加えるのではなく、hoge() の実装による解決法を求めています。
よろしくお願いします。

---- code ----
(defun hoge()
 (interactive)
 (replace-string "foo" "bar" nil)   ; (1)
 (replace-string "xxx" "yyy" nil)   ; (2)
)

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2008/11/17 21:35:21
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:Mook No.1

回答回数1314ベストアンサー獲得回数393

ポイント30pt

標準機能ではなく拡張になりますが、下記のものを使用してはどうでしょうか。

http://www.bookshelf.jp/soft/meadow_33.html#SEC482


関数を開始する時点で (undo-group-boundary)を実行するようにし、

関数実行後にundo-group で、実行開始時まで戻るかと思います。

id:room661

ありがとうございます。

なるほど、これも一つの手ですね。

2008/11/13 21:29:29
id:pyopyopyo No.2

回答回数377ベストアンサー獲得回数98

ポイント35pt
(defun hoge ()
  (interactive)
  (format-replace-strings
   '(("foo" . "bar")
     ("xxx" . "yyy"))))

とか、如何でしょう?

id:room661

おお、オミゴト。ありがとうございます。

———

では、正規表現による置換に対して同様な書き方はありませんかね?

つまり上記質問文のコードが次のようである場合です。

(defun hoge()
  (interactive)
  (replace-regexp "^foo" "bar" nil)	; (1)
  (replace-regexp "x+" "yyy" nil)	; (2)
)
2008/11/14 01:30:53
id:hujikojp No.3

回答回数101ベストアンサー獲得回数7

ポイント35pt

ちと力業ですが:

(defun remove-undo-boundary (last-boundary)
  (let ((l buffer-undo-list))
    (when (and l (not (eq last-boundary l)))
      (while (and (cdr l) (not (eq last-boundary (cdr l))))
	(if (null (cadr l))
	    (setcdr l (cddr l))
	  (setq l (cdr l)))))))

(defun hoge ()
  (interactive)
  (let ((last-boundary buffer-undo-list))
    (replace-string "foo" "bar" nil); (1)
    (replace-string "xxx" "yyy" nil); (2)
    (remove-undo-boundary last-boundary))
)

多分悪影響はないと思いますが、おそるおそるつかってください。

id:room661

ありがとうございます。これなら正規表現による置換にも使えそう。

buffer-undo-list のしくみがよく分かります。

勉強になります。

2008/11/15 15:23:50

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません