bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: nesting of unwind-protect and atomic-change-group


From: Roland Winkler
Subject: Re: nesting of unwind-protect and atomic-change-group
Date: Sun, 3 Feb 2008 23:53:15 +0100

On Sat Feb 2 2008 Richard Stallman wrote:
>     When combining unwind-protect and atomic-change-group I found that
>     putting unwind-protect outermost worked for me (i.e., an unwindform
>     moving point to the buffer location where the error occured was
>     obeyed), whereas doing it the other way round didn't work for me
>     (the unwindform was ignored). 
> 
> An unwind-protect will _work_ either inside or outside
> of atomic-change-group.  Whatever problem you encountered
> must be more specific.  I can't guess what it might be.

OK, here is a test case, more or less similar to what I really want
to do, tested with emacs -q for GNU Emacs 22.1.2 (i686-pc-linux-gnu,
X toolkit, Xaw3d scroll bars)

When I run fun1 in a buffer containing the following lines of text

hello world bar
hello world bar
hello world foo
hello world bar
hello world bar

fun1 throws an error and puts point at the buffer location the error
refers to. fun2 does not put point at the buffer location that
corresponds to the error. The only difference between fun1 and fun2
is the order of unwind-protect and atomic-change-group.
(I find it counterintuitive that both functions put the message 
"search "foo"" in the *Messages* buffer before the error message,
but I expect that this has to do with how the error is handled.)

Roland


(defun fun1 ()
  "In current buffer replace word \"bar\" by \"baz\".
Throw error for word \"foo\" and move point to malicious word. Works"
  (interactive)
  (let (error-word)
    ;; `atomic-change-group' inside `unwind-protect'
    (unwind-protect
        (atomic-change-group
          (save-excursion
            (goto-char (point-min))
            (while (re-search-forward "\\<\\w+\\>" nil t)
              (let ((word (match-string 0)))
                (cond ((string= word "foo")
                       (setq error-word word)
                       (error "word \"foo\" in text"))
                      ((string= word "bar")
                       (replace-match "baz")))))))
      (when error-word
        (message "search \"foo\"")
        ;; move point to where error occured
        (goto-char (point-min))
        (re-search-forward "foo")
        (goto-char (match-beginning 0))))))

(defun fun2 ()
  "In current buffer replace word \"bar\" by \"baz\".
Throw error for word \"foo\". Code does not move point to malicious word"
  (interactive)
  (let (error-word)
    ;; `unwind-protect' inside `atomic-change-group'
    (atomic-change-group
      (unwind-protect
          (save-excursion
            (goto-char (point-min))
            (while (re-search-forward "\\<\\w+\\>" nil t)
              (let ((word (match-string 0)))
                (cond ((string= word "foo")
                       (setq error-word word)
                       (error "word \"foo\" in text"))
                      ((string= word "bar")
                       (replace-match "baz"))))))
        (when error-word
          (message "search \"foo\"")
          ;; move point to where error occured
          (goto-char (point-min))
          (re-search-forward "foo")
          (goto-char (match-beginning 0)))))))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]