diff src/insdel.c @ 203:850242ba4a81 r20-3b28

Import from CVS: tag r20-3b28
author cvs
date Mon, 13 Aug 2007 10:02:21 +0200
parents 3d6bfa290dbd
children 78478c60bfcd
line wrap: on
line diff
--- a/src/insdel.c	Mon Aug 13 10:01:24 2007 +0200
+++ b/src/insdel.c	Mon Aug 13 10:02:21 2007 +0200
@@ -2802,7 +2802,16 @@
     }
   else
     {
-      /* must implement as deletion followed by insertion. */
+      /*
+       * Must implement as deletion followed by insertion.
+       *
+       * Make a note to move point forward later in the one situation
+       * where it is needed, a delete/insert one position behind
+       * point.  Point will drift backward by one position and stay
+       * there otherwise.
+       */
+      int movepoint = (pos == BUF_PT (b) - 1);
+
       buffer_delete_range (b, pos, pos + 1, 0);
       /* Defensive steps in case the before-change-functions fuck around */
       if (!BUFFER_LIVE_P (b))
@@ -2818,7 +2827,13 @@
       if (pos < BUF_BEGV (b))
 	/* no more characters in buffer! */
 	return;
-      buffer_insert_string_1 (b, pos, newstr, Qnil, 0, newlen, 0);
+      /*
+       * -1 as the pos argument means to move point forward with the
+       * insertion, which we must do if the deletion moved point
+       * backward so that it now equals the insertion point.
+       */
+      buffer_insert_string_1 (b, (movepoint ? -1 : pos),
+			      newstr, Qnil, 0, newlen, 0);
     }
 }