]> git.eshelyaron.com Git - emacs.git/commitdiff
src/insdel.c (adjust_markers_for_replace): Fix insertion case
authorStefan Monnier <monnier@iro.umontreal.ca>
Sat, 29 Mar 2025 20:40:19 +0000 (16:40 -0400)
committerEshel Yaron <me@eshelyaron.com>
Mon, 31 Mar 2025 08:39:07 +0000 (10:39 +0200)
test/src/editfns-tests.el (editfns-tests--insert-via-replace): New test

(cherry picked from commit 57da44fa702782e19cd9d60ea63ec2fd9ca48521)

src/insdel.c
test/src/editfns-tests.el

index 20267265ab8b9021e8662b99f9c48198dad914f6..053b2d4638059ad2b26d2877f51a9692236a1409 100644 (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
index 3da9d4e8acd0ecc9a0547dbf74a232b7665ce0b4..2553ad3ec2cbc06768bbba61901694baabce97ba 100644 (file)
             (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