aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2025-03-29 16:40:19 -0400
committerStefan Monnier2025-03-29 17:49:49 -0400
commit57da44fa702782e19cd9d60ea63ec2fd9ca48521 (patch)
tree7182b458505348be363d9c0093a98a8b5043fb79
parent7c82cc8b975175aebbad1c43ec1cd98b3232f482 (diff)
downloademacs-57da44fa702782e19cd9d60ea63ec2fd9ca48521.tar.gz
emacs-57da44fa702782e19cd9d60ea63ec2fd9ca48521.zip
src/insdel.c (adjust_markers_for_replace): Fix insertion case
test/src/editfns-tests.el (editfns-tests--insert-via-replace): New test
-rw-r--r--src/insdel.c19
-rw-r--r--test/src/editfns-tests.el14
2 files changed, 27 insertions, 6 deletions
diff --git a/src/insdel.c b/src/insdel.c
index 20267265ab8..053b2d46380 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -348,12 +348,20 @@ adjust_markers_for_replace (ptrdiff_t from, ptrdiff_t from_byte,
348 ptrdiff_t diff_chars = new_chars - old_chars; 348 ptrdiff_t diff_chars = new_chars - old_chars;
349 ptrdiff_t diff_bytes = new_bytes - old_bytes; 349 ptrdiff_t diff_bytes = new_bytes - old_bytes;
350 350
351 if (old_chars == 0)
352 {
353 /* Just an insertion: markers at FROM may need to move or not depending
354 on their marker type. Delegate this special case to
355 'adjust_markers_for_insert' so the loop below can remain oblivious
356 to marker types. */
357 adjust_markers_for_insert (from, from_byte,
358 from + new_chars, from_byte + new_bytes,
359 false);
360 return;
361 }
362
351 adjust_suspend_auto_hscroll (from, from + old_chars); 363 adjust_suspend_auto_hscroll (from, from + old_chars);
352 364
353 /* FIXME: When OLD_CHARS is 0, this "replacement" is really just an
354 insertion, but the behavior we provide here in that case is that of
355 `insert-before-markers` rather than that of `insert`.
356 Maybe not a bug, but not a feature either. */
357 for (m = BUF_MARKERS (current_buffer); m; m = m->next) 365 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
358 { 366 {
359 if (m->bytepos >= prev_to_byte) 367 if (m->bytepos >= prev_to_byte)
@@ -371,8 +379,7 @@ adjust_markers_for_replace (ptrdiff_t from, ptrdiff_t from_byte,
371 check_markers (); 379 check_markers ();
372 380
373 adjust_overlays_for_insert (from + old_chars, new_chars, true); 381 adjust_overlays_for_insert (from + old_chars, new_chars, true);
374 if (old_chars) 382 adjust_overlays_for_delete (from, old_chars);
375 adjust_overlays_for_delete (from, old_chars);
376} 383}
377 384
378/* Starting at POS (BYTEPOS), find the byte position corresponding to 385/* Starting at POS (BYTEPOS), find the byte position corresponding to
diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el
index 3da9d4e8acd..2553ad3ec2c 100644
--- a/test/src/editfns-tests.el
+++ b/test/src/editfns-tests.el
@@ -357,6 +357,20 @@
357 (should (= m7a (+ (point-min) 7))))) 357 (should (= m7a (+ (point-min) 7)))))
358 (widen))))) 358 (widen)))))
359 359
360(ert-deftest editfns-tests--insert-via-replace ()
361 (with-temp-buffer
362 (insert "bar")
363 (goto-char (point-min))
364 ;; Check that markers insertion type is respected when an insertion
365 ;; happens via a "replace" operation.
366 (let ((m1 (copy-marker (point) nil))
367 (m2 (copy-marker (point) t)))
368 (looking-at "\\(\\)")
369 (replace-match "foo")
370 (should (equal "foobar" (buffer-string)))
371 (should (= (point-min) m1))
372 (should (= (+ (point-min) 3) m2)))))
373
360(ert-deftest delete-region-undo-markers-1 () 374(ert-deftest delete-region-undo-markers-1 ()
361 "Make sure we don't end up with freed markers reachable from Lisp." 375 "Make sure we don't end up with freed markers reachable from Lisp."
362 ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=30931#40 376 ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=30931#40