summaryrefslogtreecommitdiff
path: root/lisp/minibuffer.el
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2010-10-01 01:05:26 +0200
committerStefan Monnier <monnier@iro.umontreal.ca>2010-10-01 01:05:26 +0200
commit55586d2a88c1273958893da1e17979a3e7a89691 (patch)
tree076d73b04841ac6c1e737589eaaf069f6211fab0 /lisp/minibuffer.el
parent39e266f9bb060e76f58e719d6860afb5daed4ece (diff)
downloademacs-55586d2a88c1273958893da1e17979a3e7a89691.tar.gz
* lisp/minibuffer.el (completion--replace): Better preserve markers.
Fixes: debbugs:7138
Diffstat (limited to 'lisp/minibuffer.el')
-rw-r--r--lisp/minibuffer.el22
1 files changed, 21 insertions, 1 deletions
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 93a222053f6..9a477020421 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -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))))