* lisp/minibuffer.el (completion--replace): Better preserve markers.
authorStefan Monnier <monnier@iro.umontreal.ca>
Thu, 30 Sep 2010 23:05:26 +0000 (01:05 +0200)
committerStefan Monnier <monnier@iro.umontreal.ca>
Thu, 30 Sep 2010 23:05:26 +0000 (01:05 +0200)
Fixes: debbugs:7138

lisp/ChangeLog
lisp/minibuffer.el

index 22cc8f3..696941f 100644 (file)
@@ -1,3 +1,8 @@
+2010-09-30  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * minibuffer.el (completion--replace):
+       Better preserve markers (bug#7138).
+
 2010-09-29  Juanma Barranquero  <lekktu@gmail.com>
 
        * server.el (server-process-filter): Doc fix.
@@ -10,8 +15,8 @@
 
        * Makefile.in (ELCFILES): Update.
 
-       * emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Avoid
-       infinite recursion on erroneous lambda form.  (Bug#7114)
+       * emacs-lisp/byte-opt.el (byte-optimize-form-code-walker):
+       Avoid infinite recursion on erroneous lambda form.  (Bug#7114)
 
 2010-09-27  Kenichi Handa  <handa@m17n.org>
 
index 93a2220..9a47702 100644 (file)
@@ -475,10 +475,30 @@ in the last `cdr'."
 (defun completion--replace (beg end newtext)
   "Replace the buffer text between BEG and END with NEWTEXT.
 Moves point to the end of the new text."
-  ;; This should be in subr.el.
+  ;; Maybe this should be in subr.el.
   ;; You'd think this is trivial to do, but details matter if you want
   ;; to keep markers "at the right place" and be robust in the face of
   ;; after-change-functions that may themselves modify the buffer.
+  (let ((prefix-len 0))
+    ;; Don't touch markers in the shared prefix (if any).
+    (while (and (< prefix-len (length newtext))
+                (< (+ beg prefix-len) end)
+                (eq (char-after (+ beg prefix-len))
+                    (aref newtext prefix-len)))
+      (setq prefix-len (1+ prefix-len)))
+    (unless (zerop prefix-len)
+      (setq beg (+ beg prefix-len))
+      (setq newtext (substring newtext prefix-len))))
+  (let ((suffix-len 0))
+    ;; Don't touch markers in the shared suffix (if any).
+    (while (and (< suffix-len (length newtext))
+                (< beg (- end suffix-len))
+                (eq (char-before (- end suffix-len))
+                    (aref newtext (- (length newtext) suffix-len 1))))
+      (setq suffix-len (1+ suffix-len)))
+    (unless (zerop suffix-len)
+      (setq end (- end suffix-len))
+      (setq newtext (substring newtext 0 (- suffix-len)))))
   (goto-char beg)
   (insert newtext)
   (delete-region (point) (+ (point) (- end beg))))