From 71477684db6d781a07edda5060a0530da3623d96 Mon Sep 17 00:00:00 2001 From: "Kim F. Storm" Date: Thu, 30 Oct 2014 15:19:49 -0400 Subject: [PATCH] Restore cua-delete-copy-to-register-0 and M-v command. * lisp/delsel.el (delete-selection-save-to-register) (delsel--replace-text-or-position): New vars. (delete-active-region): Use them. (delete-selection-repeat-replace-region): New command, moved from cua-base.el. * lisp/emulation/cua-base.el (cua--repeat-replace-text): Remove var. (cua-repeat-replace-region): Move command to delsel.el. (cua--init-keymaps): Update binding accordingly. (cua-mode): Set delete-selection-save-to-register. Fixes: debbugs:18886 --- lisp/ChangeLog | 14 ++++++++- lisp/delsel.el | 76 +++++++++++++++++++++++++++++++++++++++++++--- lisp/emulation/cua-base.el | 54 ++++++-------------------------- 3 files changed, 94 insertions(+), 50 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 33e0b1c757a..bed0928f68f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,17 @@ -2014-10-30 Stefan Monnier +2014-10-30 Kim F. Storm + + Restore cua-delete-copy-to-register-0 and M-v command (bug#18886). + * delsel.el (delete-selection-save-to-register) + (delsel--replace-text-or-position): New vars. + (delete-active-region): Use them. + (delete-selection-repeat-replace-region): New command, moved from + cua-base.el. + * emulation/cua-base.el (cua--repeat-replace-text): Remove var. + (cua-repeat-replace-region): Move command to delsel.el. + (cua--init-keymaps): Update binding accordingly. + (cua-mode): Set delete-selection-save-to-register. +2014-10-30 Stefan Monnier * progmodes/cc-defs.el (c--macroexpand-all): New function (bug#18845). (c-lang-defconst): diff --git a/lisp/delsel.el b/lisp/delsel.el index 1ada02705fe..96794fce7aa 100644 --- a/lisp/delsel.el +++ b/lisp/delsel.el @@ -54,6 +54,10 @@ ;;; Code: +(defvar 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.") + ;;;###autoload (defalias 'pending-delete-mode 'delete-selection-mode) @@ -72,16 +76,78 @@ point regardless of any selection." (remove-hook 'pre-command-hook 'delete-selection-pre-hook) (add-hook 'pre-command-hook 'delete-selection-pre-hook))) +(defvar delsel--replace-text-or-position nil) + (defun delete-active-region (&optional killp) "Delete the active region. If KILLP in not-nil, the active region is killed instead of deleted." - (if killp - ;; Don't allow `kill-region' to change the value of `this-command'. - (let (this-command) - (kill-region (point) (mark) t)) - (funcall region-extract-function 'delete-only)) + (cond + (killp + ;; Don't allow `kill-region' to change the value of `this-command'. + (let (this-command) + (kill-region (point) (mark) t))) + (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))))) + (t + (funcall region-extract-function 'delete-only))) t) +(defun delete-selection-repeat-replace-region (arg) + "Repeat replacing text of highlighted region with typed text. +Search for the next stretch of text identical to the region last replaced +by typing text over it and replaces it with the same stretch of text. +With ARG, repeat that many times. `C-u' means until end of buffer." + (interactive "P") + (let ((old-text (and delete-selection-save-to-register + (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))))) + (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)))))) + (defun delete-selection-helper (type) "Delete selection according to TYPE: `yank' diff --git a/lisp/emulation/cua-base.el b/lisp/emulation/cua-base.el index 96c9ba1e095..c57188338ce 100644 --- a/lisp/emulation/cua-base.el +++ b/lisp/emulation/cua-base.el @@ -277,7 +277,7 @@ enabled." (defcustom cua-remap-control-v t "If non-nil, C-v binding is used for paste (yank). -Also, M-v is mapped to `cua-repeat-replace-region'." +Also, M-v is mapped to `delete-selection-repeat-replace-region'." :type 'boolean :group 'cua) @@ -350,6 +350,8 @@ interpreted as a register number." :group 'cua) (defcustom cua-delete-copy-to-register-0 t + ;; FIXME: Obey delete-selection-save-to-register rather than hardcoding + ;; register 0. "If non-nil, save last deleted region or rectangle to register 0." :type 'boolean :group 'cua) @@ -958,48 +960,8 @@ See also `exchange-point-and-mark'." (t (let (mark-active) (exchange-point-and-mark) - (if cua--rectangle - (cua--rectangle-corner 0)))))) - -;; Typed text that replaced the highlighted region. -(defvar cua--repeat-replace-text nil) - -(defun cua-repeat-replace-region (arg) - "Repeat replacing text of highlighted region with typed text. -Searches for the next stretch of text identical to the region last -replaced by typing text over it and replaces it with the same stretch -of text." - (interactive "P") - (when cua--last-deleted-region-pos - (with-current-buffer (car cua--last-deleted-region-pos) - (save-restriction - (widen) - ;; Find the text that replaced the region via the undo list. - (let ((ul buffer-undo-list) - (elt (cdr cua--last-deleted-region-pos)) - 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 cua--repeat-replace-text (cua--filter-buffer-noprops s e))) - ((and (null s) (eq u elt)) ;; nothing inserted - (setq cua--repeat-replace-text - "")) - (t - (message "Cannot locate replacement text")))))) - (setq cua--last-deleted-region-pos nil)) - (if (and cua--last-deleted-region-text - cua--repeat-replace-text - (search-forward cua--last-deleted-region-text nil t nil)) - (replace-match cua--repeat-replace-text arg t))) + (if cua--rectangle + (cua--rectangle-corner 0)))))) (defun cua-help-for-region (&optional help) "Show region specific help in echo area." @@ -1333,7 +1295,8 @@ If ARG is the atom `-', scroll upward by nearly full screen." (define-key cua--cua-keys-keymap [(control z)] 'undo)) (when cua-remap-control-v (define-key cua--cua-keys-keymap [(control v)] 'yank) - (define-key cua--cua-keys-keymap [(meta v)] 'cua-repeat-replace-region)) + (define-key cua--cua-keys-keymap [(meta v)] + 'delete-selection-repeat-replace-region)) (define-key cua--prefix-override-keymap [(control x)] 'cua--prefix-override-handler) (define-key cua--prefix-override-keymap [(control c)] 'cua--prefix-override-handler) @@ -1402,6 +1365,7 @@ If ARG is the atom `-', scroll upward by nearly full screen." ;; delete-selection-mode (defvar cua--saved-state nil) +(defvar delete-selection-save-to-register) ;;;###autoload (define-minor-mode cua-mode @@ -1469,6 +1433,8 @@ the prefix fallback behavior." (if (and (boundp 'delete-selection-mode) delete-selection-mode) (delete-selection-mode -1))) (if cua-highlight-region-shift-only (transient-mark-mode -1)) + (if cua-delete-copy-to-register-0 + (setq delete-selection-save-to-register ?0)) (cua--deactivate)) (cua--saved-state (if (nth 0 cua--saved-state) -- 2.11.4.GIT