summaryrefslogtreecommitdiff
path: root/lisp/replace.el
diff options
context:
space:
mode:
authorMattias EngdegÄrd <mattiase@acm.org>2021-07-25 11:24:53 +0200
committerMattias EngdegÄrd <mattiase@acm.org>2021-07-25 11:24:53 +0200
commitb0d33d42535cc6aef2c518eba373332de59f210f (patch)
tree329f2c1cf8e5cd4bee0298692531fd9ac185e095 /lisp/replace.el
parentc52e26df30d5679dc2b9b34853a3c2db062524ac (diff)
downloademacs-b0d33d42535cc6aef2c518eba373332de59f210f.tar.gz
emacs-b0d33d42535cc6aef2c518eba373332de59f210f.tar.bz2
emacs-b0d33d42535cc6aef2c518eba373332de59f210f.zip
Don't squash markers in occur-edit-mode
* lisp/replace.el (occur-after-change-function): Instead of replacing the whole line being edited, use shrink-wrapping to replace the smallest interval encompassing the change. That way, we avoid disturbing markers (such as occur highlighting locations) in the line; they would otherwise all be forced to the beginning.
Diffstat (limited to 'lisp/replace.el')
-rw-r--r--lisp/replace.el23
1 files changed, 21 insertions, 2 deletions
diff --git a/lisp/replace.el b/lisp/replace.el
index 24befed2412..09bdf28dbce 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1398,8 +1398,27 @@ To return to ordinary Occur mode, use \\[occur-cease-edit]."
(recenter line)
(if readonly
(message "Buffer `%s' is read only." buf)
- (delete-region (line-beginning-position) (line-end-position))
- (insert text))
+ ;; Replace the line, but make the change as small as
+ ;; possible by shrink-wrapping. That way, we avoid
+ ;; disturbing markers unnecessarily.
+ (let* ((beg-pos (line-beginning-position))
+ (end-pos (line-end-position))
+ (buf-str (buffer-substring-no-properties beg-pos end-pos))
+ (common-prefix
+ (lambda (s1 s2)
+ (let ((c (compare-strings s1 nil nil s2 nil nil)))
+ (if (zerop c)
+ (length s1)
+ (1- (abs c))))))
+ (prefix-len (funcall common-prefix buf-str text))
+ (suffix-len (funcall common-prefix
+ (reverse buf-str) (reverse text))))
+ (setq beg-pos (+ beg-pos prefix-len))
+ (setq end-pos (- end-pos suffix-len))
+ (setq text (substring text prefix-len (- suffix-len)))
+ (delete-region beg-pos end-pos)
+ (goto-char beg-pos)
+ (insert text)))
(move-to-column col)))))))