4

I have the following code:

(defun test-save-excursion ()
  (interactive)
  (let ((buffer "*test*")
        (text "Lorem Ipsum is simply dummy text
Lorem Ipsum has |been the industry's standard dummy text
It was popularised in the 1960s"))
    (with-current-buffer buffer
      (erase-buffer)
      (insert text)
      (goto-char 50)
      (save-excursion
        (beginning-of-line)
        (kill-line)
        (kill-line)))))

You can see that point moves to the 50th char (second line of text, where | is located), then I want to save point position while I'm killing the line of text. But point always moves to the beginning of line. Why that happens so? Is it possible to save point position in such case? How?

3
  • 1
    Related mailing list discussion: lists.gnu.org/archive/html/help-gnu-emacs/2008-11/msg00874.html
    – nanny
    Commented Jan 20, 2015 at 17:35
  • You save point, but then you cut the region that point used to be in.
    – Tyler
    Commented Jan 20, 2015 at 17:37
  • @nanny Ha! As I read through the discussion I thought 'this sounds familiar'. That was me 7 years ago.
    – Tyler
    Commented Jan 20, 2015 at 17:43

2 Answers 2

4

Thanks to @nanny!

I found the answer in the mailing list which he mentioned in the comment!

save-excursion stores a marker, not the 'byte' number. When you kill the line where point is, this marker gets replaced to the beginning of the line.

(From: Andreas Politz)

From Elisp Manual [ (info "(elisp)Excursions") ]:

Warning: Ordinary insertion of text adjacent to the saved point value relocates the saved value, just as it relocates all markers. More precisely, the saved value is a marker with insertion type nil. See Marker Insertion Types. Therefore, when the saved point value is restored, it normally comes before the inserted text.

Then another one explanation which makes the answer clearer.

Here's a simple example that may help. Suppose you have a buffer containing:

1 abcdef

2 123456

3 wxyz

and point is on line 2 between 3 and 4. You write a function that uses save-excursion while it deletes line 1. When the save-excursion ends, point will still be between 3 and 4, although this will now be line 1.

The intent is to continue pointing to the same text that it originally pointed to. But if that text itself is deleted, this is obviously not possible. Any markers that were within the deleted text will end up pointing to the place where the text used to be.

(From: Barry Margolin)

Now I see, if I want to put point on the same position as it was before editing I need to save that position and then just execute (goto-char saved-position).

Thank you all!

0
0

The behavior you describe is the standard one. Just replay your functions interactively to see.

I think this thing will do what you want:

(defun test-save-excursion ()
  (interactive)
  (let ((text "Lorem Ipsum is simply dummy text
Lorem Ipsum has |been the industry's standard dummy text
It was popularised in the 1960s"))
    (with-current-buffer "*test*"
      (erase-buffer)
      (insert text)
      (goto-char 50)
      (save-excursion
        (forward-line)
        (delete-region (point) (point-max)))))) 

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.