2

I have this loop:

(catch 'QUIT
  (while 
      (search-forward-regexp "\\([^\n\\]\\(?:\\\\\\\\\\)*\\|^\\(?:\\\\\\\\\\)+\\)%.*\n"
                 nil t)
    (save-excursion
          (let ((b (make-marker))
        (e (make-marker))
        MatchedStringOverlay
        ACTION)
        (set-marker b (match-beginning 0))
        (set-marker e (point))

        (setq MatchedStringOverlay (make-overlay b e))
        (unwind-protect 
        (progn
          (overlay-put MatchedStringOverlay 'face '(:background "OliveDrab1"))
          (setq ACTION (read-char "Options:
- [y] erase string and the corresponding \"newline\"
- [l] erase string keeping the corresponding \"newline\"
- [n] skip
- [q] quit:
"))
          (cond 
           ((char-equal ACTION ?y)
            (replace-match "\\1"))
           ((char-equal ACTION ?l)
            (replace-match "\\1\n"))
           ((char-equal ACTION ?n)
            nil)
           ((char-equal ACTION ?q)
            (throw 'QUIT nil))
           )
          )
          (remove-overlays b e))
        )))
  )

that performs some interactive replacements on buffer.

Now it happens that when I do undo after the loop, the command "undoes" all the replacements I made within the loop. How can I make each replacement a "single item" in buffer-undo-list?

I've searched in the docs, in the internet and I read the code of undo command but I've not been able to find how to get what I need.

I think I should add a nil in buffer-undo-list to mark the boundary between two change groups (see here). So I tried

(add-to-list 'buffer-undo-list nil)

just before the first cond group but it does not work.

3
  • 1
    +1 for trying and succeeding to find the answer yourself. You might consider adding here how you found it - that info might help others, along with your question.
    – Drew
    Jun 23, 2017 at 13:33
  • @Drew I just continued searching for related posts. Thank you.
    – Gabriele
    Jun 23, 2017 at 15:28
  • 1
    OK; thx. Next time, you might also consider asking Emacs: As @phils suggested. C-h i, choose the Elisp manual, then i undo TAB. (On the web, the doc you want is here.)
    – Drew
    Jun 23, 2017 at 17:11

1 Answer 1

2

You're looking for undo-boundary:

undo-boundary is a built-in function in ‘src/undo.c’.

(undo-boundary)

Mark a boundary between units of undo.
An undo command will stop at this point,
but another undo command will undo to the previous boundary.

See also C-hig (elisp)Undo RET

1
  • 1
    I've just found this solution by myself. But thank you! This works for me!
    – Gabriele
    Jun 23, 2017 at 12:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.