mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 09:14:18 +00:00
delsel.el: Use an overlay to track the replacement text
This patch was sent back in 2014 as part of bug#18886. * lisp/delsel.el (delsel--replace-text-or-position): Delete var. (delete-selection-replacement-face): New defcustom. (delsel--replace-text, delsel--replace-overlay): New vars. (delete-active-region, delete-selection-repeat-replace-region): Use overlay to track replacement text instead of abusing the undo-list; this allows the text to be edited before it is used for substitutions. Add highlight to the replacement text.
This commit is contained in:
parent
4141beb78c
commit
38760d4ba7
1 changed files with 48 additions and 44 deletions
|
|
@ -60,9 +60,24 @@
|
|||
|
||||
;;; Code:
|
||||
|
||||
(defvar delete-selection-save-to-register nil
|
||||
(defcustom delete-selection-save-to-register nil
|
||||
"If non-nil, deleted region text is stored in this register.
|
||||
Value must be the register (key) to use.")
|
||||
Value must be the register (key) to use."
|
||||
:type '(choice
|
||||
(const :tag "None" nil)
|
||||
(character :tag "Register (Key)"))
|
||||
:group 'editing-basics)
|
||||
|
||||
(defcustom delete-selection-replacement-face 'highlight
|
||||
"If non-nil, active region replacement text is shown in this face.
|
||||
The highlighted text is the text that will be inserted by
|
||||
the `delete-selection-repeat-replace-region' command."
|
||||
:type 'face
|
||||
:group 'editing-basics
|
||||
:set (lambda (symbol value)
|
||||
(set-default symbol value)
|
||||
(if delsel--replace-overlay
|
||||
(overlay-put delsel--replace-overlay 'face value))))
|
||||
|
||||
(defcustom delete-selection-temporary-region nil
|
||||
"Whether to delete only temporary regions.
|
||||
|
|
@ -113,7 +128,8 @@ For compatibility with features and packages that are aware of
|
|||
(setq-default delete-selection-mode nil) ; But keep it globally disabled.
|
||||
)))
|
||||
|
||||
(defvar delsel--replace-text-or-position nil)
|
||||
(defvar delsel--replace-overlay nil) ;overlay
|
||||
(defvar delsel--replace-text nil) ;text from overlay
|
||||
|
||||
;;;###autoload
|
||||
(defun delete-active-region (&optional killp)
|
||||
|
|
@ -129,9 +145,14 @@ the active region is killed instead of deleted."
|
|||
(delete-selection-save-to-register
|
||||
(set-register delete-selection-save-to-register
|
||||
(funcall region-extract-function t))
|
||||
(setq delsel--replace-text-or-position
|
||||
(cons (current-buffer)
|
||||
(and (consp buffer-undo-list) (car buffer-undo-list)))))
|
||||
(if delsel--replace-overlay
|
||||
(move-overlay delsel--replace-overlay (point) (point) (current-buffer))
|
||||
(setq delsel--replace-overlay
|
||||
(make-overlay (point) (point) (current-buffer) nil t))
|
||||
(if delete-selection-replacement-face
|
||||
(overlay-put delsel--replace-overlay 'face
|
||||
delete-selection-replacement-face)))
|
||||
(setq delsel--replace-text nil))
|
||||
(t
|
||||
(funcall region-extract-function 'delete-only))))
|
||||
|
||||
|
|
@ -146,47 +167,30 @@ Just `\\[universal-argument]' means repeat until the end of the buffer's accessi
|
|||
(get-register delete-selection-save-to-register)))
|
||||
(count (if (consp arg) (point-max)
|
||||
(prefix-numeric-value current-prefix-arg))))
|
||||
(if (not (and old-text
|
||||
(> (length old-text) 0)
|
||||
(or (stringp delsel--replace-text-or-position)
|
||||
(buffer-live-p (car delsel--replace-text-or-position)))))
|
||||
(if (not (and old-text (> (length old-text) 0)))
|
||||
(message "No known previous replacement")
|
||||
;; If this is the first use after overwriting regions,
|
||||
;; find the replacement text by looking at the undo list.
|
||||
(when (consp delsel--replace-text-or-position)
|
||||
(let ((buffer (car delsel--replace-text-or-position))
|
||||
(elt (cdr delsel--replace-text-or-position)))
|
||||
(setq delsel--replace-text-or-position nil)
|
||||
(with-current-buffer buffer
|
||||
(save-restriction
|
||||
(widen)
|
||||
;; Find the text that replaced the region via the undo list.
|
||||
(let ((ul buffer-undo-list) u s e)
|
||||
(when elt
|
||||
(while (consp ul)
|
||||
(setq u (car ul) ul (cdr ul))
|
||||
(cond
|
||||
((eq u elt) ;; got it
|
||||
(setq ul nil))
|
||||
((and (consp u) (integerp (car u)) (integerp (cdr u)))
|
||||
(if (and s (= (cdr u) s))
|
||||
(setq s (car u))
|
||||
(setq s (car u) e (cdr u)))))))
|
||||
(cond ((and s e (<= s e) (= s (mark t)))
|
||||
(setq delsel--replace-text-or-position
|
||||
(filter-buffer-substring s e))
|
||||
(set-text-properties
|
||||
0 (length delsel--replace-text-or-position)
|
||||
nil delsel--replace-text-or-position))
|
||||
((and (null s) (eq u elt)) ;; Nothing inserted.
|
||||
(setq delsel--replace-text-or-position ""))
|
||||
(t
|
||||
(message "Cannot locate replacement text"))))))))
|
||||
(while (and (> count 0)
|
||||
delsel--replace-text-or-position
|
||||
(search-forward old-text nil t))
|
||||
(replace-match delsel--replace-text-or-position nil t)
|
||||
(setq count (1- count))))))
|
||||
(when (and (null delsel--replace-text)
|
||||
delsel--replace-overlay
|
||||
(buffer-live-p (overlay-buffer delsel--replace-overlay)))
|
||||
(with-current-buffer (overlay-buffer delsel--replace-overlay)
|
||||
(let ((s (overlay-start delsel--replace-overlay))
|
||||
(e (overlay-end delsel--replace-overlay)))
|
||||
(when (/= s e)
|
||||
(setq delsel--replace-text
|
||||
(filter-buffer-substring s e))
|
||||
(set-text-properties
|
||||
0 (length delsel--replace-text)
|
||||
nil delsel--replace-text))))
|
||||
(delete-overlay delsel--replace-overlay))
|
||||
(if delsel--replace-text
|
||||
(while (and (> count 0)
|
||||
delsel--replace-text
|
||||
(search-forward old-text nil t))
|
||||
(replace-match delsel--replace-text nil t)
|
||||
(setq count (1- count)))
|
||||
(message "Cannot locate replacement text")))))
|
||||
|
||||
(defun delete-selection-helper (type)
|
||||
"Delete selection according to TYPE:
|
||||
|
|
|
|||
Loading…
Reference in a new issue