summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/emulation/cua-base.el53
-rw-r--r--lisp/kmacro.el50
-rw-r--r--lisp/simple.el80
3 files changed, 117 insertions, 66 deletions
diff --git a/lisp/emulation/cua-base.el b/lisp/emulation/cua-base.el
index e91ce80bbe2..52e1647ede7 100644
--- a/lisp/emulation/cua-base.el
+++ b/lisp/emulation/cua-base.el
@@ -685,7 +685,7 @@ a cons (TYPE . COLOR), then both properties are affected."
(defvar cua--prefix-override-timer nil)
(defvar cua--prefix-override-length nil)
-(defun cua--prefix-override-replay (arg repeat)
+(defun cua--prefix-override-replay (repeat)
(let* ((keys (this-command-keys))
(i (length keys))
(key (aref keys (1- i))))
@@ -705,21 +705,23 @@ a cons (TYPE . COLOR), then both properties are affected."
;; Don't record this command
(setq this-command last-command)
;; Restore the prefix arg
- (setq prefix-arg arg)
- (reset-this-command-lengths)
+ ;; This should make it so that exchange-point-and-mark gets the prefix when
+ ;; you do C-u C-x C-x C-x work (where the C-u is properly passed to the C-x
+ ;; C-x binding after the first C-x C-x was rewritten to just C-x).
+ (prefix-command-preserve-state)
;; Push the key back on the event queue
(setq unread-command-events (cons key unread-command-events))))
-(defun cua--prefix-override-handler (arg)
+(defun cua--prefix-override-handler ()
"Start timer waiting for prefix key to be followed by another key.
Repeating prefix key when region is active works as a single prefix key."
- (interactive "P")
- (cua--prefix-override-replay arg 0))
+ (interactive)
+ (cua--prefix-override-replay 0))
-(defun cua--prefix-repeat-handler (arg)
+(defun cua--prefix-repeat-handler ()
"Repeating prefix key when region is active works as a single prefix key."
- (interactive "P")
- (cua--prefix-override-replay arg 1))
+ (interactive)
+ (cua--prefix-override-replay 1))
(defun cua--prefix-copy-handler (arg)
"Copy region/rectangle, then replay last key."
@@ -742,7 +744,8 @@ Repeating prefix key when region is active works as a single prefix key."
(when (= (length (this-command-keys)) cua--prefix-override-length)
(setq unread-command-events (cons 'timeout unread-command-events))
(if prefix-arg
- (reset-this-command-lengths)
+ nil
+ ;; FIXME: Why?
(setq overriding-terminal-local-map nil))
(cua--select-keymaps)))
@@ -755,8 +758,9 @@ Repeating prefix key when region is active works as a single prefix key."
(call-interactively this-command))
(defun cua--keep-active ()
- (setq mark-active t
- deactivate-mark nil))
+ (when (mark t)
+ (setq mark-active t
+ deactivate-mark nil)))
(defun cua--deactivate (&optional now)
(if (not now)
@@ -944,7 +948,7 @@ See also `exchange-point-and-mark'."
(cond ((null cua-enable-cua-keys)
(exchange-point-and-mark arg))
(arg
- (setq mark-active t))
+ (when (mark t) (setq mark-active t)))
(t
(let (mark-active)
(exchange-point-and-mark)
@@ -1212,25 +1216,28 @@ If ARG is the atom `-', scroll upward by nearly full screen."
(defvar cua--keymaps-initialized nil)
-(defun cua--shift-control-prefix (prefix arg)
+(defun cua--shift-control-prefix (prefix)
;; handle S-C-x and S-C-c by emulating the fast double prefix function.
;; Don't record this command
(setq this-command last-command)
;; Restore the prefix arg
- (setq prefix-arg arg)
- (reset-this-command-lengths)
+ ;; This should make it so that exchange-point-and-mark gets the prefix when
+ ;; you do C-u S-C-x C-x work (where the C-u is properly passed to the C-x
+ ;; C-x binding after the first S-C-x was rewritten to just C-x).
+ (prefix-command-preserve-state)
;; Activate the cua--prefix-repeat-keymap
(setq cua--prefix-override-timer 'shift)
;; Push duplicate keys back on the event queue
- (setq unread-command-events (cons prefix (cons prefix unread-command-events))))
+ (setq unread-command-events
+ (cons prefix (cons prefix unread-command-events))))
-(defun cua--shift-control-c-prefix (arg)
- (interactive "P")
- (cua--shift-control-prefix ?\C-c arg))
+(defun cua--shift-control-c-prefix ()
+ (interactive)
+ (cua--shift-control-prefix ?\C-c))
-(defun cua--shift-control-x-prefix (arg)
- (interactive "P")
- (cua--shift-control-prefix ?\C-x arg))
+(defun cua--shift-control-x-prefix ()
+ (interactive)
+ (cua--shift-control-prefix ?\C-x))
(defun cua--init-keymaps ()
;; Cache actual rectangle modifier key.
diff --git a/lisp/kmacro.el b/lisp/kmacro.el
index 9636a36b1e2..ddf3005bab5 100644
--- a/lisp/kmacro.el
+++ b/lisp/kmacro.el
@@ -941,7 +941,6 @@ without repeating the prefix."
(defvar kmacro-step-edit-inserting) ;; inserting into macro
(defvar kmacro-step-edit-appending) ;; append to end of macro
(defvar kmacro-step-edit-replace) ;; replace orig macro when done
-(defvar kmacro-step-edit-prefix-index) ;; index of first prefix arg key
(defvar kmacro-step-edit-key-index) ;; index of current key
(defvar kmacro-step-edit-action) ;; automatic action on next pre-command hook
(defvar kmacro-step-edit-help) ;; kmacro step edit help enabled
@@ -976,11 +975,6 @@ This keymap is an extension to the `query-replace-map', allowing the
following additional answers: `insert', `insert-1', `replace', `replace-1',
`append', `append-end', `act-repeat', `skip-end', `skip-keep'.")
-(defvar kmacro-step-edit-prefix-commands
- '(universal-argument universal-argument-more universal-argument-minus
- digit-argument negative-argument)
- "Commands which build up a prefix arg for the current command.")
-
(defun kmacro-step-edit-prompt (macro index)
;; Show step-edit prompt
(let ((keys (and (not kmacro-step-edit-appending)
@@ -1084,21 +1078,13 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
;; Handle prefix arg, or query user
(cond
(act act) ;; set above
- ((memq this-command kmacro-step-edit-prefix-commands)
- (unless kmacro-step-edit-prefix-index
- (setq kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
- (setq act 'universal-argument))
- ((eq this-command 'universal-argument-other-key)
- (setq act 'universal-argument))
(t
- (kmacro-step-edit-prompt macro (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
+ (kmacro-step-edit-prompt macro kmacro-step-edit-key-index)
(setq act (lookup-key kmacro-step-edit-map
(vector (with-current-buffer (current-buffer) (read-event))))))))
;; Resume macro execution and perform the action
(cond
- ((eq act 'universal-argument)
- nil)
((cond
((eq act 'act)
t)
@@ -1110,7 +1096,6 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
(setq kmacro-step-edit-active 'ignore)
nil)
((eq act 'skip)
- (setq kmacro-step-edit-prefix-index nil)
nil)
((eq act 'skip-keep)
(setq this-command 'ignore)
@@ -1123,12 +1108,11 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
(setq act t)
t)
((member act '(insert-1 insert))
- (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
+ (setq executing-kbd-macro-index kmacro-step-edit-key-index)
(setq kmacro-step-edit-inserting (if (eq act 'insert-1) 1 t))
nil)
((member act '(replace-1 replace))
(setq kmacro-step-edit-inserting (if (eq act 'replace-1) 1 t))
- (setq kmacro-step-edit-prefix-index nil)
(if (= executing-kbd-macro-index (length executing-kbd-macro))
(setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
kmacro-step-edit-appending t))
@@ -1148,19 +1132,19 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
(setq act t)
t)
((eq act 'help)
- (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
+ (setq executing-kbd-macro-index kmacro-step-edit-key-index)
(setq kmacro-step-edit-help (not kmacro-step-edit-help))
nil)
(t ;; Ignore unknown responses
- (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
+ (setq executing-kbd-macro-index kmacro-step-edit-key-index)
nil))
- (if (> executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
+ (if (> executing-kbd-macro-index kmacro-step-edit-key-index)
(setq kmacro-step-edit-new-macro
(vconcat kmacro-step-edit-new-macro
(substring executing-kbd-macro
- (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index)
- (if (eq act t) nil executing-kbd-macro-index)))
- kmacro-step-edit-prefix-index nil))
+ kmacro-step-edit-key-index
+ (if (eq act t) nil
+ executing-kbd-macro-index)))))
(if restore-index
(setq executing-kbd-macro-index restore-index)))
(t
@@ -1175,12 +1159,10 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
(executing-kbd-macro nil)
(defining-kbd-macro nil)
cmd keys next-index)
- (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index)
- kmacro-step-edit-prefix-index nil)
+ (setq executing-kbd-macro-index kmacro-step-edit-key-index)
(kmacro-step-edit-prompt macro nil)
;; Now, we have read a key sequence from the macro, but we don't want
;; to execute it yet. So push it back and read another sequence.
- (reset-this-command-lengths)
(setq keys (read-key-sequence nil nil nil nil t))
(setq cmd (key-binding keys t nil))
(if (cond
@@ -1201,25 +1183,12 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
unread-command-events nil)))
(setq cmd 'ignore)
nil)
- ((memq cmd kmacro-step-edit-prefix-commands)
- (reset-this-command-lengths)
- nil)
- ((eq cmd 'universal-argument-other-key)
- (setq kmacro-step-edit-action t)
- (reset-this-command-lengths)
- (if (numberp kmacro-step-edit-inserting)
- (setq kmacro-step-edit-inserting nil))
- nil)
((numberp kmacro-step-edit-inserting)
(setq kmacro-step-edit-inserting nil)
nil)
((equal keys "\C-j")
(setq kmacro-step-edit-inserting nil)
(setq kmacro-step-edit-action nil)
- ;; Forget any (partial) prefix arg from next command
- (setq kmacro-step-edit-prefix-index nil)
- (reset-this-command-lengths)
- (setq overriding-terminal-local-map nil)
(setq next-index kmacro-step-edit-key-index)
t)
(t nil))
@@ -1278,7 +1247,6 @@ To customize possible responses, change the \"bindings\" in `kmacro-step-edit-ma
(kmacro-step-edit-inserting nil)
(kmacro-step-edit-appending nil)
(kmacro-step-edit-replace t)
- (kmacro-step-edit-prefix-index nil)
(kmacro-step-edit-key-index 0)
(kmacro-step-edit-action nil)
(kmacro-step-edit-help nil)
diff --git a/lisp/simple.el b/lisp/simple.el
index 6f76d755292..b8d4e741775 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1711,9 +1711,13 @@ The argument SPECIAL, if non-nil, means that this command is executing
a special event, so ignore the prefix argument and don't clear it."
(setq debug-on-next-call nil)
(let ((prefixarg (unless special
+ ;; FIXME: This should probably be done around
+ ;; pre-command-hook rather than here!
(prog1 prefix-arg
(setq current-prefix-arg prefix-arg)
- (setq prefix-arg nil)))))
+ (setq prefix-arg nil)
+ (when current-prefix-arg
+ (prefix-command-update))))))
(if (and (symbolp cmd)
(get cmd 'disabled)
disabled-command-function)
@@ -3626,6 +3630,73 @@ see other processes running on the system, use `list-system-processes'."
(display-buffer buffer)
nil)
+;;;; Prefix commands
+
+(setq prefix-command--needs-update nil)
+(setq prefix-command--last-echo nil)
+
+(defun internal-echo-keystrokes-prefix ()
+ ;; BEWARE: Called directly from the C code.
+ (if (not prefix-command--needs-update)
+ prefix-command--last-echo
+ (setq prefix-command--last-echo
+ (let ((strs nil))
+ (run-hook-wrapped 'prefix-command-echo-keystrokes-functions
+ (lambda (fun) (push (funcall fun) strs)))
+ (setq strs (delq nil strs))
+ (when strs (mapconcat #'identity strs " "))))))
+
+(defvar prefix-command-echo-keystrokes-functions nil
+ "Abnormal hook which constructs the description of the current prefix state.
+Each function is called with no argument, should return a string or nil.")
+
+(defun prefix-command-update ()
+ "Update state of prefix commands.
+Call it whenever you change the \"prefix command state\"."
+ (setq prefix-command--needs-update t))
+
+(defvar prefix-command-preserve-state-hook nil
+ "Normal hook run when a command needs to preserve the prefix.")
+
+(defun prefix-command-preserve-state ()
+ "Pass the current prefix command state to the next command.
+Should be called by all prefix commands.
+Runs `prefix-command-preserve-state-hook'."
+ (run-hooks 'prefix-command-preserve-state-hook)
+ ;; If the current command is a prefix command, we don't want the next (real)
+ ;; command to have `last-command' set to, say, `universal-argument'.
+ (setq this-command last-command)
+ (setq real-this-command real-last-command)
+ (prefix-command-update))
+
+(defun reset-this-command-lengths ()
+ (declare (obsolete prefix-command-preserve-state "25.1"))
+ nil)
+
+;;;;; The main prefix command.
+
+;; FIXME: Declaration of `prefix-arg' should be moved here!?
+
+(add-hook 'prefix-command-echo-keystrokes-functions
+ #'universal-argument--description)
+(defun universal-argument--description ()
+ (when prefix-arg
+ (concat "C-u"
+ (pcase prefix-arg
+ (`(-) " -")
+ (`(,(and (pred integerp) n))
+ (let ((str ""))
+ (while (and (> n 4) (= (mod n 4) 0))
+ (setq str (concat str " C-u"))
+ (setq n (/ n 4)))
+ (if (= n 4) str (format " %s" prefix-arg))))
+ (_ (format " %s" prefix-arg))))))
+
+(add-hook 'prefix-command-preserve-state-hook
+ #'universal-argument--preserve)
+(defun universal-argument--preserve ()
+ (setq prefix-arg current-prefix-arg))
+
(defvar universal-argument-map
(let ((map (make-sparse-keymap))
(universal-argument-minus
@@ -3664,7 +3735,8 @@ see other processes running on the system, use `list-system-processes'."
"Keymap used while processing \\[universal-argument].")
(defun universal-argument--mode ()
- (set-transient-map universal-argument-map))
+ (prefix-command-update)
+ (set-transient-map universal-argument-map nil))
(defun universal-argument ()
"Begin a numeric argument for the following command.
@@ -3677,6 +3749,7 @@ For some commands, just \\[universal-argument] by itself serves as a flag
which is different in effect from any particular numeric argument.
These commands include \\[set-mark-command] and \\[start-kbd-macro]."
(interactive)
+ (prefix-command-preserve-state)
(setq prefix-arg (list 4))
(universal-argument--mode))
@@ -3684,6 +3757,7 @@ These commands include \\[set-mark-command] and \\[start-kbd-macro]."
;; A subsequent C-u means to multiply the factor by 4 if we've typed
;; nothing but C-u's; otherwise it means to terminate the prefix arg.
(interactive "P")
+ (prefix-command-preserve-state)
(setq prefix-arg (if (consp arg)
(list (* 4 (car arg)))
(if (eq arg '-)
@@ -3695,6 +3769,7 @@ These commands include \\[set-mark-command] and \\[start-kbd-macro]."
"Begin a negative numeric argument for the next command.
\\[universal-argument] following digits or minus sign ends the argument."
(interactive "P")
+ (prefix-command-preserve-state)
(setq prefix-arg (cond ((integerp arg) (- arg))
((eq arg '-) nil)
(t '-)))
@@ -3704,6 +3779,7 @@ These commands include \\[set-mark-command] and \\[start-kbd-macro]."
"Part of the numeric argument for the next command.
\\[universal-argument] following digits or minus sign ends the argument."
(interactive "P")
+ (prefix-command-preserve-state)
(let* ((char (if (integerp last-command-event)
last-command-event
(get last-command-event 'ascii-character)))