aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorStefan Monnier2015-09-01 21:14:18 -0400
committerStefan Monnier2015-09-01 21:14:18 -0400
commit5dc644a6b01e2cf950ff617ab15be4bf1917c38c (patch)
treef5572fd4d2c5cc68ac54e48fbd7541bd8043fadc /lisp
parentafe1cf00713847c1d8f3a9d95d4980d705ec39f1 (diff)
downloademacs-5dc644a6b01e2cf950ff617ab15be4bf1917c38c.tar.gz
emacs-5dc644a6b01e2cf950ff617ab15be4bf1917c38c.zip
Generalize the prefix-command machinery of C-u
* lisp/simple.el (prefix-command-echo-keystrokes-functions) (prefix-command-preserve-state-hook): New hooks. (internal-echo-keystrokes-prefix): New function. (prefix-command--needs-update, prefix-command--last-echo): New vars. (prefix-command-update, prefix-command-preserve): New functions. (reset-this-command-lengths): New compatibility definition. (universal-argument--mode): Call prefix-command-update. (universal-argument, universal-argument-more, negative-argument) (digit-argument): Call prefix-command-preserve-state. * src/keyboard.c: Call internal-echo-keystrokes-prefix to build the "prefix argument" to echo. (this_command_key_count_reset, before_command_key_count) (before_command_echo_length): Delete variables. (echo_add_key): Always add a space. (echo_char): Remove. (echo_dash): Don't give up when this_command_key_count is 0, since that is now the case after a prefix command. (echo_update): New function, extracted from echo_now. (echo_now): Use it. (add_command_key, read_char, record_menu_key): Remove old disabled code. (command_loop_1): Don't refrain from pushing an undo boundary when prefix-arg is set. Remove other prefix-arg special case, now handled directly in the prefix commands instead. But call echo_now if there's a prefix state to echo. (read_char, record_menu_key): Use echo_update instead of echo_char. (read_key_sequence): Use echo_now rather than echo_dash/echo_char. (Freset_this_command_lengths): Delete function. (syms_of_keyboard): Define Qinternal_echo_keystrokes_prefix. (syms_of_keyboard): Don't defsubr Sreset_this_command_lengths. * lisp/simple.el: Use those new hooks for C-u. (universal-argument--description): New function. (prefix-command-echo-keystrokes-functions): Use it. (universal-argument--preserve): New function. (prefix-command-preserve-state-hook): Use it. (command-execute): Call prefix-command-update if needed. * lisp/kmacro.el (kmacro-step-edit-prefix-commands) (kmacro-step-edit-prefix-index): Delete variables. (kmacro-step-edit-query, kmacro-step-edit-insert): Remove ad-hoc support for prefix arg commands. (kmacro-step-edit-macro): Don't bind kmacro-step-edit-prefix-index. * lisp/emulation/cua-base.el (cua--prefix-override-replay) (cua--shift-control-prefix): Use prefix-command-preserve-state. Remove now unused arg `arg'. (cua--prefix-override-handler, cua--prefix-repeat-handler) (cua--shift-control-c-prefix, cua--shift-control-x-prefix): Update accordingly. (cua--prefix-override-timeout): Don't call reset-this-command-lengths any more. (cua--keep-active, cua-exchange-point-and-mark): Don't set mark-active if the mark is not set.
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."
685(defvar cua--prefix-override-timer nil) 685(defvar cua--prefix-override-timer nil)
686(defvar cua--prefix-override-length nil) 686(defvar cua--prefix-override-length nil)
687 687
688(defun cua--prefix-override-replay (arg repeat) 688(defun cua--prefix-override-replay (repeat)
689 (let* ((keys (this-command-keys)) 689 (let* ((keys (this-command-keys))
690 (i (length keys)) 690 (i (length keys))
691 (key (aref keys (1- i)))) 691 (key (aref keys (1- i))))
@@ -705,21 +705,23 @@ a cons (TYPE . COLOR), then both properties are affected."
705 ;; Don't record this command 705 ;; Don't record this command
706 (setq this-command last-command) 706 (setq this-command last-command)
707 ;; Restore the prefix arg 707 ;; Restore the prefix arg
708 (setq prefix-arg arg) 708 ;; This should make it so that exchange-point-and-mark gets the prefix when
709 (reset-this-command-lengths) 709 ;; you do C-u C-x C-x C-x work (where the C-u is properly passed to the C-x
710 ;; C-x binding after the first C-x C-x was rewritten to just C-x).
711 (prefix-command-preserve-state)
710 ;; Push the key back on the event queue 712 ;; Push the key back on the event queue
711 (setq unread-command-events (cons key unread-command-events)))) 713 (setq unread-command-events (cons key unread-command-events))))
712 714
713(defun cua--prefix-override-handler (arg) 715(defun cua--prefix-override-handler ()
714 "Start timer waiting for prefix key to be followed by another key. 716 "Start timer waiting for prefix key to be followed by another key.
715Repeating prefix key when region is active works as a single prefix key." 717Repeating prefix key when region is active works as a single prefix key."
716 (interactive "P") 718 (interactive)
717 (cua--prefix-override-replay arg 0)) 719 (cua--prefix-override-replay 0))
718 720
719(defun cua--prefix-repeat-handler (arg) 721(defun cua--prefix-repeat-handler ()
720 "Repeating prefix key when region is active works as a single prefix key." 722 "Repeating prefix key when region is active works as a single prefix key."
721 (interactive "P") 723 (interactive)
722 (cua--prefix-override-replay arg 1)) 724 (cua--prefix-override-replay 1))
723 725
724(defun cua--prefix-copy-handler (arg) 726(defun cua--prefix-copy-handler (arg)
725 "Copy region/rectangle, then replay last key." 727 "Copy region/rectangle, then replay last key."
@@ -742,7 +744,8 @@ Repeating prefix key when region is active works as a single prefix key."
742 (when (= (length (this-command-keys)) cua--prefix-override-length) 744 (when (= (length (this-command-keys)) cua--prefix-override-length)
743 (setq unread-command-events (cons 'timeout unread-command-events)) 745 (setq unread-command-events (cons 'timeout unread-command-events))
744 (if prefix-arg 746 (if prefix-arg
745 (reset-this-command-lengths) 747 nil
748 ;; FIXME: Why?
746 (setq overriding-terminal-local-map nil)) 749 (setq overriding-terminal-local-map nil))
747 (cua--select-keymaps))) 750 (cua--select-keymaps)))
748 751
@@ -755,8 +758,9 @@ Repeating prefix key when region is active works as a single prefix key."
755 (call-interactively this-command)) 758 (call-interactively this-command))
756 759
757(defun cua--keep-active () 760(defun cua--keep-active ()
758 (setq mark-active t 761 (when (mark t)
759 deactivate-mark nil)) 762 (setq mark-active t
763 deactivate-mark nil)))
760 764
761(defun cua--deactivate (&optional now) 765(defun cua--deactivate (&optional now)
762 (if (not now) 766 (if (not now)
@@ -944,7 +948,7 @@ See also `exchange-point-and-mark'."
944 (cond ((null cua-enable-cua-keys) 948 (cond ((null cua-enable-cua-keys)
945 (exchange-point-and-mark arg)) 949 (exchange-point-and-mark arg))
946 (arg 950 (arg
947 (setq mark-active t)) 951 (when (mark t) (setq mark-active t)))
948 (t 952 (t
949 (let (mark-active) 953 (let (mark-active)
950 (exchange-point-and-mark) 954 (exchange-point-and-mark)
@@ -1212,25 +1216,28 @@ If ARG is the atom `-', scroll upward by nearly full screen."
1212 1216
1213(defvar cua--keymaps-initialized nil) 1217(defvar cua--keymaps-initialized nil)
1214 1218
1215(defun cua--shift-control-prefix (prefix arg) 1219(defun cua--shift-control-prefix (prefix)
1216 ;; handle S-C-x and S-C-c by emulating the fast double prefix function. 1220 ;; handle S-C-x and S-C-c by emulating the fast double prefix function.
1217 ;; Don't record this command 1221 ;; Don't record this command
1218 (setq this-command last-command) 1222 (setq this-command last-command)
1219 ;; Restore the prefix arg 1223 ;; Restore the prefix arg
1220 (setq prefix-arg arg) 1224 ;; This should make it so that exchange-point-and-mark gets the prefix when
1221 (reset-this-command-lengths) 1225 ;; you do C-u S-C-x C-x work (where the C-u is properly passed to the C-x
1226 ;; C-x binding after the first S-C-x was rewritten to just C-x).
1227 (prefix-command-preserve-state)
1222 ;; Activate the cua--prefix-repeat-keymap 1228 ;; Activate the cua--prefix-repeat-keymap
1223 (setq cua--prefix-override-timer 'shift) 1229 (setq cua--prefix-override-timer 'shift)
1224 ;; Push duplicate keys back on the event queue 1230 ;; Push duplicate keys back on the event queue
1225 (setq unread-command-events (cons prefix (cons prefix unread-command-events)))) 1231 (setq unread-command-events
1232 (cons prefix (cons prefix unread-command-events))))
1226 1233
1227(defun cua--shift-control-c-prefix (arg) 1234(defun cua--shift-control-c-prefix ()
1228 (interactive "P") 1235 (interactive)
1229 (cua--shift-control-prefix ?\C-c arg)) 1236 (cua--shift-control-prefix ?\C-c))
1230 1237
1231(defun cua--shift-control-x-prefix (arg) 1238(defun cua--shift-control-x-prefix ()
1232 (interactive "P") 1239 (interactive)
1233 (cua--shift-control-prefix ?\C-x arg)) 1240 (cua--shift-control-prefix ?\C-x))
1234 1241
1235(defun cua--init-keymaps () 1242(defun cua--init-keymaps ()
1236 ;; Cache actual rectangle modifier key. 1243 ;; 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."
941(defvar kmacro-step-edit-inserting) ;; inserting into macro 941(defvar kmacro-step-edit-inserting) ;; inserting into macro
942(defvar kmacro-step-edit-appending) ;; append to end of macro 942(defvar kmacro-step-edit-appending) ;; append to end of macro
943(defvar kmacro-step-edit-replace) ;; replace orig macro when done 943(defvar kmacro-step-edit-replace) ;; replace orig macro when done
944(defvar kmacro-step-edit-prefix-index) ;; index of first prefix arg key
945(defvar kmacro-step-edit-key-index) ;; index of current key 944(defvar kmacro-step-edit-key-index) ;; index of current key
946(defvar kmacro-step-edit-action) ;; automatic action on next pre-command hook 945(defvar kmacro-step-edit-action) ;; automatic action on next pre-command hook
947(defvar kmacro-step-edit-help) ;; kmacro step edit help enabled 946(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
976following additional answers: `insert', `insert-1', `replace', `replace-1', 975following additional answers: `insert', `insert-1', `replace', `replace-1',
977`append', `append-end', `act-repeat', `skip-end', `skip-keep'.") 976`append', `append-end', `act-repeat', `skip-end', `skip-keep'.")
978 977
979(defvar kmacro-step-edit-prefix-commands
980 '(universal-argument universal-argument-more universal-argument-minus
981 digit-argument negative-argument)
982 "Commands which build up a prefix arg for the current command.")
983
984(defun kmacro-step-edit-prompt (macro index) 978(defun kmacro-step-edit-prompt (macro index)
985 ;; Show step-edit prompt 979 ;; Show step-edit prompt
986 (let ((keys (and (not kmacro-step-edit-appending) 980 (let ((keys (and (not kmacro-step-edit-appending)
@@ -1084,21 +1078,13 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
1084 ;; Handle prefix arg, or query user 1078 ;; Handle prefix arg, or query user
1085 (cond 1079 (cond
1086 (act act) ;; set above 1080 (act act) ;; set above
1087 ((memq this-command kmacro-step-edit-prefix-commands)
1088 (unless kmacro-step-edit-prefix-index
1089 (setq kmacro-step-edit-prefix-index kmacro-step-edit-key-index))
1090 (setq act 'universal-argument))
1091 ((eq this-command 'universal-argument-other-key)
1092 (setq act 'universal-argument))
1093 (t 1081 (t
1094 (kmacro-step-edit-prompt macro (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index)) 1082 (kmacro-step-edit-prompt macro kmacro-step-edit-key-index)
1095 (setq act (lookup-key kmacro-step-edit-map 1083 (setq act (lookup-key kmacro-step-edit-map
1096 (vector (with-current-buffer (current-buffer) (read-event)))))))) 1084 (vector (with-current-buffer (current-buffer) (read-event))))))))
1097 1085
1098 ;; Resume macro execution and perform the action 1086 ;; Resume macro execution and perform the action
1099 (cond 1087 (cond
1100 ((eq act 'universal-argument)
1101 nil)
1102 ((cond 1088 ((cond
1103 ((eq act 'act) 1089 ((eq act 'act)
1104 t) 1090 t)
@@ -1110,7 +1096,6 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
1110 (setq kmacro-step-edit-active 'ignore) 1096 (setq kmacro-step-edit-active 'ignore)
1111 nil) 1097 nil)
1112 ((eq act 'skip) 1098 ((eq act 'skip)
1113 (setq kmacro-step-edit-prefix-index nil)
1114 nil) 1099 nil)
1115 ((eq act 'skip-keep) 1100 ((eq act 'skip-keep)
1116 (setq this-command 'ignore) 1101 (setq this-command 'ignore)
@@ -1123,12 +1108,11 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
1123 (setq act t) 1108 (setq act t)
1124 t) 1109 t)
1125 ((member act '(insert-1 insert)) 1110 ((member act '(insert-1 insert))
1126 (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index)) 1111 (setq executing-kbd-macro-index kmacro-step-edit-key-index)
1127 (setq kmacro-step-edit-inserting (if (eq act 'insert-1) 1 t)) 1112 (setq kmacro-step-edit-inserting (if (eq act 'insert-1) 1 t))
1128 nil) 1113 nil)
1129 ((member act '(replace-1 replace)) 1114 ((member act '(replace-1 replace))
1130 (setq kmacro-step-edit-inserting (if (eq act 'replace-1) 1 t)) 1115 (setq kmacro-step-edit-inserting (if (eq act 'replace-1) 1 t))
1131 (setq kmacro-step-edit-prefix-index nil)
1132 (if (= executing-kbd-macro-index (length executing-kbd-macro)) 1116 (if (= executing-kbd-macro-index (length executing-kbd-macro))
1133 (setq executing-kbd-macro (vconcat executing-kbd-macro [nil]) 1117 (setq executing-kbd-macro (vconcat executing-kbd-macro [nil])
1134 kmacro-step-edit-appending t)) 1118 kmacro-step-edit-appending t))
@@ -1148,19 +1132,19 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
1148 (setq act t) 1132 (setq act t)
1149 t) 1133 t)
1150 ((eq act 'help) 1134 ((eq act 'help)
1151 (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index)) 1135 (setq executing-kbd-macro-index kmacro-step-edit-key-index)
1152 (setq kmacro-step-edit-help (not kmacro-step-edit-help)) 1136 (setq kmacro-step-edit-help (not kmacro-step-edit-help))
1153 nil) 1137 nil)
1154 (t ;; Ignore unknown responses 1138 (t ;; Ignore unknown responses
1155 (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index)) 1139 (setq executing-kbd-macro-index kmacro-step-edit-key-index)
1156 nil)) 1140 nil))
1157 (if (> executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index)) 1141 (if (> executing-kbd-macro-index kmacro-step-edit-key-index)
1158 (setq kmacro-step-edit-new-macro 1142 (setq kmacro-step-edit-new-macro
1159 (vconcat kmacro-step-edit-new-macro 1143 (vconcat kmacro-step-edit-new-macro
1160 (substring executing-kbd-macro 1144 (substring executing-kbd-macro
1161 (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index) 1145 kmacro-step-edit-key-index
1162 (if (eq act t) nil executing-kbd-macro-index))) 1146 (if (eq act t) nil
1163 kmacro-step-edit-prefix-index nil)) 1147 executing-kbd-macro-index)))))
1164 (if restore-index 1148 (if restore-index
1165 (setq executing-kbd-macro-index restore-index))) 1149 (setq executing-kbd-macro-index restore-index)))
1166 (t 1150 (t
@@ -1175,12 +1159,10 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
1175 (executing-kbd-macro nil) 1159 (executing-kbd-macro nil)
1176 (defining-kbd-macro nil) 1160 (defining-kbd-macro nil)
1177 cmd keys next-index) 1161 cmd keys next-index)
1178 (setq executing-kbd-macro-index (or kmacro-step-edit-prefix-index kmacro-step-edit-key-index) 1162 (setq executing-kbd-macro-index kmacro-step-edit-key-index)
1179 kmacro-step-edit-prefix-index nil)
1180 (kmacro-step-edit-prompt macro nil) 1163 (kmacro-step-edit-prompt macro nil)
1181 ;; Now, we have read a key sequence from the macro, but we don't want 1164 ;; Now, we have read a key sequence from the macro, but we don't want
1182 ;; to execute it yet. So push it back and read another sequence. 1165 ;; to execute it yet. So push it back and read another sequence.
1183 (reset-this-command-lengths)
1184 (setq keys (read-key-sequence nil nil nil nil t)) 1166 (setq keys (read-key-sequence nil nil nil nil t))
1185 (setq cmd (key-binding keys t nil)) 1167 (setq cmd (key-binding keys t nil))
1186 (if (cond 1168 (if (cond
@@ -1201,25 +1183,12 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
1201 unread-command-events nil))) 1183 unread-command-events nil)))
1202 (setq cmd 'ignore) 1184 (setq cmd 'ignore)
1203 nil) 1185 nil)
1204 ((memq cmd kmacro-step-edit-prefix-commands)
1205 (reset-this-command-lengths)
1206 nil)
1207 ((eq cmd 'universal-argument-other-key)
1208 (setq kmacro-step-edit-action t)
1209 (reset-this-command-lengths)
1210 (if (numberp kmacro-step-edit-inserting)
1211 (setq kmacro-step-edit-inserting nil))
1212 nil)
1213 ((numberp kmacro-step-edit-inserting) 1186 ((numberp kmacro-step-edit-inserting)
1214 (setq kmacro-step-edit-inserting nil) 1187 (setq kmacro-step-edit-inserting nil)
1215 nil) 1188 nil)
1216 ((equal keys "\C-j") 1189 ((equal keys "\C-j")
1217 (setq kmacro-step-edit-inserting nil) 1190 (setq kmacro-step-edit-inserting nil)
1218 (setq kmacro-step-edit-action nil) 1191 (setq kmacro-step-edit-action nil)
1219 ;; Forget any (partial) prefix arg from next command
1220 (setq kmacro-step-edit-prefix-index nil)
1221 (reset-this-command-lengths)
1222 (setq overriding-terminal-local-map nil)
1223 (setq next-index kmacro-step-edit-key-index) 1192 (setq next-index kmacro-step-edit-key-index)
1224 t) 1193 t)
1225 (t nil)) 1194 (t nil))
@@ -1278,7 +1247,6 @@ To customize possible responses, change the \"bindings\" in `kmacro-step-edit-ma
1278 (kmacro-step-edit-inserting nil) 1247 (kmacro-step-edit-inserting nil)
1279 (kmacro-step-edit-appending nil) 1248 (kmacro-step-edit-appending nil)
1280 (kmacro-step-edit-replace t) 1249 (kmacro-step-edit-replace t)
1281 (kmacro-step-edit-prefix-index nil)
1282 (kmacro-step-edit-key-index 0) 1250 (kmacro-step-edit-key-index 0)
1283 (kmacro-step-edit-action nil) 1251 (kmacro-step-edit-action nil)
1284 (kmacro-step-edit-help nil) 1252 (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
1711a special event, so ignore the prefix argument and don't clear it." 1711a special event, so ignore the prefix argument and don't clear it."
1712 (setq debug-on-next-call nil) 1712 (setq debug-on-next-call nil)
1713 (let ((prefixarg (unless special 1713 (let ((prefixarg (unless special
1714 ;; FIXME: This should probably be done around
1715 ;; pre-command-hook rather than here!
1714 (prog1 prefix-arg 1716 (prog1 prefix-arg
1715 (setq current-prefix-arg prefix-arg) 1717 (setq current-prefix-arg prefix-arg)
1716 (setq prefix-arg nil))))) 1718 (setq prefix-arg nil)
1719 (when current-prefix-arg
1720 (prefix-command-update))))))
1717 (if (and (symbolp cmd) 1721 (if (and (symbolp cmd)
1718 (get cmd 'disabled) 1722 (get cmd 'disabled)
1719 disabled-command-function) 1723 disabled-command-function)
@@ -3626,6 +3630,73 @@ see other processes running on the system, use `list-system-processes'."
3626 (display-buffer buffer) 3630 (display-buffer buffer)
3627 nil) 3631 nil)
3628 3632
3633;;;; Prefix commands
3634
3635(setq prefix-command--needs-update nil)
3636(setq prefix-command--last-echo nil)
3637
3638(defun internal-echo-keystrokes-prefix ()
3639 ;; BEWARE: Called directly from the C code.
3640 (if (not prefix-command--needs-update)
3641 prefix-command--last-echo
3642 (setq prefix-command--last-echo
3643 (let ((strs nil))
3644 (run-hook-wrapped 'prefix-command-echo-keystrokes-functions
3645 (lambda (fun) (push (funcall fun) strs)))
3646 (setq strs (delq nil strs))
3647 (when strs (mapconcat #'identity strs " "))))))
3648
3649(defvar prefix-command-echo-keystrokes-functions nil
3650 "Abnormal hook which constructs the description of the current prefix state.
3651Each function is called with no argument, should return a string or nil.")
3652
3653(defun prefix-command-update ()
3654 "Update state of prefix commands.
3655Call it whenever you change the \"prefix command state\"."
3656 (setq prefix-command--needs-update t))
3657
3658(defvar prefix-command-preserve-state-hook nil
3659 "Normal hook run when a command needs to preserve the prefix.")
3660
3661(defun prefix-command-preserve-state ()
3662 "Pass the current prefix command state to the next command.
3663Should be called by all prefix commands.
3664Runs `prefix-command-preserve-state-hook'."
3665 (run-hooks 'prefix-command-preserve-state-hook)
3666 ;; If the current command is a prefix command, we don't want the next (real)
3667 ;; command to have `last-command' set to, say, `universal-argument'.
3668 (setq this-command last-command)
3669 (setq real-this-command real-last-command)
3670 (prefix-command-update))
3671
3672(defun reset-this-command-lengths ()
3673 (declare (obsolete prefix-command-preserve-state "25.1"))
3674 nil)
3675
3676;;;;; The main prefix command.
3677
3678;; FIXME: Declaration of `prefix-arg' should be moved here!?
3679
3680(add-hook 'prefix-command-echo-keystrokes-functions
3681 #'universal-argument--description)
3682(defun universal-argument--description ()
3683 (when prefix-arg
3684 (concat "C-u"
3685 (pcase prefix-arg
3686 (`(-) " -")
3687 (`(,(and (pred integerp) n))
3688 (let ((str ""))
3689 (while (and (> n 4) (= (mod n 4) 0))
3690 (setq str (concat str " C-u"))
3691 (setq n (/ n 4)))
3692 (if (= n 4) str (format " %s" prefix-arg))))
3693 (_ (format " %s" prefix-arg))))))
3694
3695(add-hook 'prefix-command-preserve-state-hook
3696 #'universal-argument--preserve)
3697(defun universal-argument--preserve ()
3698 (setq prefix-arg current-prefix-arg))
3699
3629(defvar universal-argument-map 3700(defvar universal-argument-map
3630 (let ((map (make-sparse-keymap)) 3701 (let ((map (make-sparse-keymap))
3631 (universal-argument-minus 3702 (universal-argument-minus
@@ -3664,7 +3735,8 @@ see other processes running on the system, use `list-system-processes'."
3664 "Keymap used while processing \\[universal-argument].") 3735 "Keymap used while processing \\[universal-argument].")
3665 3736
3666(defun universal-argument--mode () 3737(defun universal-argument--mode ()
3667 (set-transient-map universal-argument-map)) 3738 (prefix-command-update)
3739 (set-transient-map universal-argument-map nil))
3668 3740
3669(defun universal-argument () 3741(defun universal-argument ()
3670 "Begin a numeric argument for the following command. 3742 "Begin a numeric argument for the following command.
@@ -3677,6 +3749,7 @@ For some commands, just \\[universal-argument] by itself serves as a flag
3677which is different in effect from any particular numeric argument. 3749which is different in effect from any particular numeric argument.
3678These commands include \\[set-mark-command] and \\[start-kbd-macro]." 3750These commands include \\[set-mark-command] and \\[start-kbd-macro]."
3679 (interactive) 3751 (interactive)
3752 (prefix-command-preserve-state)
3680 (setq prefix-arg (list 4)) 3753 (setq prefix-arg (list 4))
3681 (universal-argument--mode)) 3754 (universal-argument--mode))
3682 3755
@@ -3684,6 +3757,7 @@ These commands include \\[set-mark-command] and \\[start-kbd-macro]."
3684 ;; A subsequent C-u means to multiply the factor by 4 if we've typed 3757 ;; A subsequent C-u means to multiply the factor by 4 if we've typed
3685 ;; nothing but C-u's; otherwise it means to terminate the prefix arg. 3758 ;; nothing but C-u's; otherwise it means to terminate the prefix arg.
3686 (interactive "P") 3759 (interactive "P")
3760 (prefix-command-preserve-state)
3687 (setq prefix-arg (if (consp arg) 3761 (setq prefix-arg (if (consp arg)
3688 (list (* 4 (car arg))) 3762 (list (* 4 (car arg)))
3689 (if (eq arg '-) 3763 (if (eq arg '-)
@@ -3695,6 +3769,7 @@ These commands include \\[set-mark-command] and \\[start-kbd-macro]."
3695 "Begin a negative numeric argument for the next command. 3769 "Begin a negative numeric argument for the next command.
3696\\[universal-argument] following digits or minus sign ends the argument." 3770\\[universal-argument] following digits or minus sign ends the argument."
3697 (interactive "P") 3771 (interactive "P")
3772 (prefix-command-preserve-state)
3698 (setq prefix-arg (cond ((integerp arg) (- arg)) 3773 (setq prefix-arg (cond ((integerp arg) (- arg))
3699 ((eq arg '-) nil) 3774 ((eq arg '-) nil)
3700 (t '-))) 3775 (t '-)))
@@ -3704,6 +3779,7 @@ These commands include \\[set-mark-command] and \\[start-kbd-macro]."
3704 "Part of the numeric argument for the next command. 3779 "Part of the numeric argument for the next command.
3705\\[universal-argument] following digits or minus sign ends the argument." 3780\\[universal-argument] following digits or minus sign ends the argument."
3706 (interactive "P") 3781 (interactive "P")
3782 (prefix-command-preserve-state)
3707 (let* ((char (if (integerp last-command-event) 3783 (let* ((char (if (integerp last-command-event)
3708 last-command-event 3784 last-command-event
3709 (get last-command-event 'ascii-character))) 3785 (get last-command-event 'ascii-character)))