1

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?

Please, do not blame me... I'm really trying to find the infos by myself. I've searched in the docs, in the internet and I red the code of undo command but I've not been able to find how to get what I need.

EDIT. I think I shoud 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.

  • 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 '17 at 13:33
  • @Drew I just continued searching for related posts. Thank you. – Gabriele Nicolardi Jun 23 '17 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 '17 at 17:11
1

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
    I've just found this solution by myself. But thank you! This works for me! – Gabriele Nicolardi Jun 23 '17 at 12:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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