src/insdel.c (adjust_markers_for_replace): Fix insertion case

test/src/editfns-tests.el (editfns-tests--insert-via-replace): New test
This commit is contained in:
Stefan Monnier 2025-03-29 16:40:19 -04:00
parent 7c82cc8b97
commit 57da44fa70
2 changed files with 27 additions and 6 deletions

View file

@ -348,12 +348,20 @@ adjust_markers_for_replace (ptrdiff_t from, ptrdiff_t from_byte,
ptrdiff_t diff_chars = new_chars - old_chars;
ptrdiff_t diff_bytes = new_bytes - old_bytes;
if (old_chars == 0)
{
/* Just an insertion: markers at FROM may need to move or not depending
on their marker type. Delegate this special case to
'adjust_markers_for_insert' so the loop below can remain oblivious
to marker types. */
adjust_markers_for_insert (from, from_byte,
from + new_chars, from_byte + new_bytes,
false);
return;
}
adjust_suspend_auto_hscroll (from, from + old_chars);
/* FIXME: When OLD_CHARS is 0, this "replacement" is really just an
insertion, but the behavior we provide here in that case is that of
`insert-before-markers` rather than that of `insert`.
Maybe not a bug, but not a feature either. */
for (m = BUF_MARKERS (current_buffer); m; m = m->next)
{
if (m->bytepos >= prev_to_byte)
@ -371,8 +379,7 @@ adjust_markers_for_replace (ptrdiff_t from, ptrdiff_t from_byte,
check_markers ();
adjust_overlays_for_insert (from + old_chars, new_chars, true);
if (old_chars)
adjust_overlays_for_delete (from, old_chars);
adjust_overlays_for_delete (from, old_chars);
}
/* Starting at POS (BYTEPOS), find the byte position corresponding to

View file

@ -357,6 +357,20 @@
(should (= m7a (+ (point-min) 7)))))
(widen)))))
(ert-deftest editfns-tests--insert-via-replace ()
(with-temp-buffer
(insert "bar")
(goto-char (point-min))
;; Check that markers insertion type is respected when an insertion
;; happens via a "replace" operation.
(let ((m1 (copy-marker (point) nil))
(m2 (copy-marker (point) t)))
(looking-at "\\(\\)")
(replace-match "foo")
(should (equal "foobar" (buffer-string)))
(should (= (point-min) m1))
(should (= (+ (point-min) 3) m2)))))
(ert-deftest delete-region-undo-markers-1 ()
"Make sure we don't end up with freed markers reachable from Lisp."
;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=30931#40