# HG changeset patch # User Kim F. Storm # Date 1165019400 0 # Node ID c728cbf657c6e6dad038f021a8e8230930b70b00 # Parent 64e31a523fe210d7415d5c03b39b1b76ccffa263 (cua-toggle-set-mark): Doc fix. (cua-repeat-replace-region): Make M-v more robust. (cua-paste-pop-rotate-temporarily): New defcustom. (cua-paste-pop): Use it. (cua-auto-mark-last-change): New defcustom. (cua-pop-to-last-change): New helper function. (cua-set-mark): Use them. diff -r 64e31a523fe2 -r c728cbf657c6 lisp/emulation/cua-base.el --- a/lisp/emulation/cua-base.el Sat Dec 02 00:29:50 2006 +0000 +++ b/lisp/emulation/cua-base.el Sat Dec 02 00:30:00 2006 +0000 @@ -317,11 +317,19 @@ :group 'cua) (defcustom cua-toggle-set-mark t - "*In non-nil, the `cua-set-mark' command toggles the mark." + "*If non-nil, the `cua-set-mark' command toggles the mark." :type '(choice (const :tag "Disabled" nil) (other :tag "Enabled" t)) :group 'cua) +(defcustom cua-auto-mark-last-change nil + "*If non-nil, set implicit mark at position of last buffer change. +This means that \\[universal-argument] \\[cua-set-mark] will jump to the position +of the last buffer change before jumping to the explicit marks on the mark ring. +See `cua-set-mark' for details." + :type 'boolean + :group 'cua) + (defcustom cua-enable-register-prefix 'not-ctrl-u "*If non-nil, registers are supported via numeric prefix arg. If the value is t, any numeric prefix arg in the range 0 to 9 will be @@ -358,6 +366,15 @@ :type 'boolean :group 'cua) +(defcustom cua-paste-pop-rotate-temporarily nil + "*If non-nil, \\[cua-paste-pop] only rotates the kill-ring temporarily. +This means that \\[cua-paste] always inserts the most recent kill, while one or +more \\[cua-paste-pop]'s immediately following it will replace the previous text +with the next older element on the `kill-ring'. If \\[cua-paste-pop] is used after +any other command, it will insert the same element from the `kill-ring' as last +time it was used." + :type 'boolean + :group 'cua) ;;; Rectangle Customization @@ -912,15 +929,52 @@ (clipboard-yank)) (t (yank arg))))))) + +;; cua-paste-pop-rotate-temporarily == t mechanism: +;; +;; C-y M-y M-y => only rotates kill ring temporarily, +;; so next C-y yanks what previous C-y yanked, +;; +;; But: After another command, M-y remembers the temporary +;; kill-ring position, so +;; M-y => yanks what the last M-y yanked +;; + +(defvar cua-paste-pop-count nil) + (defun cua-paste-pop (arg) "Replace a just-pasted text or rectangle with a different text. -See `yank-pop' for details." +See `yank-pop' for details about the default behaviour. For an alternative +behaviour, see `cua-paste-pop-rotate-temporarily'." (interactive "P") - (if (eq last-command 'cua--paste-rectangle) - (progn - (undo) - (yank arg)) - (yank-pop (prefix-numeric-value arg)))) + (cond + ((eq last-command 'cua--paste-rectangle) + (undo) + (yank arg)) + ((not cua-paste-pop-rotate-temporarily) + (yank-pop (prefix-numeric-value arg))) + (t + (let ((rotate (if (consp arg) 1 (prefix-numeric-value arg)))) + (cond + ((or (null cua-paste-pop-count) + (eq last-command 'yank) + (eq last-command 'cua-paste)) + (setq cua-paste-pop-count rotate) + (setq last-command 'yank) + (yank-pop cua-paste-pop-count)) + ((eq last-command 'cua-paste-pop) + (unless (consp arg) + (setq cua-paste-pop-count (+ cua-paste-pop-count rotate))) + (setq last-command 'yank) + (yank-pop cua-paste-pop-count)) + (t + (setq cua-paste-pop-count (+ cua-paste-pop-count rotate -1)) + (yank (1+ cua-paste-pop-count))))) + ;; Undo rotating the kill-ring, so next C-y will + ;; yank the original head. + (unless (consp arg) + (setq kill-ring-yank-pointer kill-ring)) + (setq this-command 'cua-paste-pop)))) (defun cua-exchange-point-and-mark (arg) "Exchanges point and mark, but don't activate the mark. @@ -961,14 +1015,14 @@ (if (and s (= (cdr u) s)) (setq s (car u)) (setq s (car u) e (cdr u))))))) - (setq cua--repeat-replace-text - (cond ((and s e (<= s e) (= s (mark t))) - (filter-buffer-substring s e nil t)) - ((and (null s) (eq u elt)) ;; nothing inserted - "") - (t - (message "Cannot locate replacement text") - nil)))))) + (cond ((and s e (<= s e) (= s (mark t))) + (setq cua--repeat-replace-text + (filter-buffer-substring s e nil t))) + ((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 @@ -985,6 +1039,28 @@ ;;; Shift activated / extended region +(defun cua-pop-to-last-change () + (let ((undo-list buffer-undo-list) + pos elt) + (while (and (not pos) + (consp undo-list)) + (setq elt (car undo-list) + undo-list (cdr undo-list)) + (cond + ((integerp elt) + (setq pos elt)) + ((not (consp elt))) + ((and (integerp (cdr elt)) + (or (integerp (car elt)) (stringp (car elt)))) + (setq pos (cdr elt))) + ((and (eq (car elt) 'apply) (consp (cdr elt)) (integerp (cadr elt))) + (setq pos (nth 3 elt))))) + (when (and pos + (/= pos (point)) + (>= pos (point-min)) (<= pos (point-max))) + (goto-char pos) + t))) + (defun cua-set-mark (&optional arg) "Set mark at where point is, clear mark, or jump to mark. @@ -993,12 +1069,15 @@ global mark ring if last mark was set in another buffer. With argument, jump to mark, and pop a new position for mark off -the local mark ring \(this does not affect the global mark ring\). +the local mark ring (this does not affect the global mark ring). Use \\[pop-global-mark] to jump to a mark off the global mark ring -\(see `pop-global-mark'\). +\(see `pop-global-mark'). + +If `cua-auto-mark-last-change' is non-nil, this command behaves as if there +was an implicit mark at the position of the last buffer change. Repeating the command without the prefix jumps to the next position -off the local \(or global\) mark ring. +off the local (or global) mark ring. With a double \\[universal-argument] prefix argument, unconditionally set mark." (interactive "P") @@ -1013,7 +1092,9 @@ (pop-global-mark)) (arg (setq this-command 'pop-to-mark-command) - (pop-to-mark-command)) + (or (and cua-auto-mark-last-change + (cua-pop-to-last-change)) + (pop-to-mark-command))) ((and cua-toggle-set-mark mark-active) (cua--deactivate) (message "Mark Cleared"))