1

I would like to have a command that inserts some text at a distance, while keeping the point in place during its own execution and while being undone.

To illustrate the point, consider following example:

(save-excursion (goto-char (point-at-eol)) (insert "test"))

enter Demonstration of point being moved by undo.

As I was writing this, I found a solution through making an invisible change at the original position, at the beginning and at the end of execution. This will ensure that original position is the last position visited by point during undo or redo.

Following solution works, however I would like to apply more conventional approach if one exists:

(atomic-change-group (insert " ") (delete-char -1)
                     (save-excursion (goto-char (point-at-eol))
                                     (insert "test"))
                     (insert " ") (delete-char -1))

2 Answers 2

1

The undo log normally doesn't keep track of point motion (tho it does try to put point back to where it was before a change, it does so under the assumption that point was only moved as a side effect of the changes and doesn't try to handle pointmotions that happened before the buffer modification).

So you'll have to explicitly add an undo entry to put point back to where it was, e.g.:

(save-excursion (if (listp buffer-undo-list)
                    (push (point) buffer-undo-list))
                (goto-char (point-at-eol))
                (insert "test"))
1
  • Thanks, documentation for buffer-undo-list does indeed contain an answer to my question.
    – mpontus
    Apr 10, 2015 at 14:35
1
(save-excursion (undo-boundary) (goto-char (point-at-eol)) (insert "test"))

IOW, tell undo what you want it to do. One way to do that is to use undo-boundary.

If you want more info about what you are calling an "atomic [undo] group", see the Elisp manual, node Undo.

3
  • Hello Drew, thanks for suggestion. However this form doesn't prevent cursor from jumping forward on very first redo.
    – mpontus
    Apr 8, 2015 at 8:14
  • Of course it doesn't. You can fiddle with undo boundaries, putting them wherever you like. And you can group actions on the list, so they are undone (and undone undone) as a group. But unless you remove something (including a group) from the undo list it is there - the history is complete - precisely so that you can undo in both directions. The sexp I showed answers your question as posed, which didn't include anything about undoing undo skipping a position. If you want to remove something from the undo list or to group then the answer is, again, to consult the doc page I pointed you to.
    – Drew
    Apr 8, 2015 at 13:36
  • I apologize for misunderstanding but the point of my question was exactly the opposite.
    – mpontus
    Apr 8, 2015 at 17:12

Your Answer

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

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