Commit | Line | Data |
---|---|---|
c9bba7ed DL |
1 | ;;; autoarg.el --- make digit keys supply prefix args |
2 | ||
acaf905b | 3 | ;; Copyright (C) 1998, 2000-2012 Free Software Foundation, Inc. |
c9bba7ed DL |
4 | |
5 | ;; Author: Dave Love <fx@gnu.org> | |
6 | ;; Created: 1998-09-04 | |
7 | ;; Keywords: abbrev, emulations | |
8 | ||
643c911e DL |
9 | ;; This file is part of GNU Emacs. |
10 | ||
eb3fa2cf | 11 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
c9bba7ed | 12 | ;; it under the terms of the GNU General Public License as published by |
eb3fa2cf GM |
13 | ;; the Free Software Foundation, either version 3 of the License, or |
14 | ;; (at your option) any later version. | |
c9bba7ed | 15 | |
643c911e | 16 | ;; GNU Emacs is distributed in the hope that it will be useful, |
c9bba7ed DL |
17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | ;; GNU General Public License for more details. | |
20 | ||
21 | ;; You should have received a copy of the GNU General Public License | |
eb3fa2cf | 22 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
c9bba7ed DL |
23 | |
24 | ;;; Commentary: | |
25 | ||
26 | ;; This provides `autoarg-mode', a global minor mode meant to emulate | |
27 | ;; a facility reported from Twenex Emacs whereby digit keys supplied | |
28 | ;; prefix args rather than self inserting, with a digit sequence | |
29 | ;; terminated by space acting to insert the digits. | |
30 | ||
31 | ;; The bindings of DIGIT and C-DIGIT are swapped and a command bound | |
32 | ;; to SPC deals with a numeric prefix arg or acts normally without | |
33 | ;; such an arg. (In the absence of a suitable terminal, you'd | |
34 | ;; probably want to swap DIGIT and M-DIGIT.) See the mode doc. | |
35 | ||
36 | ;; You probably don't really want to use this. | |
37 | ||
c3327721 DL |
38 | ;; Also provides `autoarg-kp-mode' which is similar, but leaves the |
39 | ;; digit keys alone and redefines the `keypad' keys, `kp-1' &c as | |
40 | ;; digit arguments. (Use `NumLock' if necessary to generate kp-N.) | |
41 | ;; You're more likely to want to use this. | |
42 | ||
c9bba7ed DL |
43 | ;;; Code: |
44 | ||
c3327721 DL |
45 | (defvar autoarg-mode-map |
46 | (let ((map (make-sparse-keymap))) | |
47 | ;; Loop over digit characters to set up keymap. | |
48 | (dotimes (i 10) | |
49 | (define-key map `[,(+ ?0 i)] 'digit-argument) | |
50 | (define-key map `[(control ,(+ ?0 i))] 'self-insert-command)) | |
51 | (define-key map " " 'autoarg-terminate) | |
52 | map) | |
53 | "Keymap for Autoarg mode.") | |
54 | ||
c9bba7ed DL |
55 | ;; Logical additions: |
56 | ;; (define-key autoarg-mode-map [?-] 'negative-argument) | |
57 | ;; (define-key autoarg-mode-map [(control ?-)] 'self-insert-command) | |
58 | ;; A sensible/addition? | |
59 | ;; (define-key autoarg-mode-map [?\r] 'autoarg-terminate) | |
60 | ||
c3327721 DL |
61 | (defvar autoarg-kp-digits |
62 | (let (alist) | |
63 | (dotimes (i 10 alist) | |
64 | (push (cons (intern (format "kp-%d" i)) i) alist)))) | |
65 | ||
66 | (defun autoarg-kp-digit-argument (arg) | |
67 | "Part of the numeric argument for the next command, like `digit-argument'." | |
68 | (interactive "P") | |
8989a920 | 69 | (let ((digit (cdr (assq last-command-event autoarg-kp-digits)))) |
c3327721 DL |
70 | (cond ((integerp arg) |
71 | (setq prefix-arg (+ (* arg 10) | |
72 | (if (< arg 0) (- digit) digit)))) | |
73 | ((eq arg '-) | |
74 | ;; Treat -0 as just -, so that -01 will work. | |
75 | (setq prefix-arg (if (zerop digit) '- (- digit)))) | |
76 | (t | |
77 | (setq prefix-arg digit)))) | |
78 | (setq universal-argument-num-events (length (this-command-keys))) | |
79 | (setq overriding-terminal-local-map universal-argument-map)) | |
80 | ||
81 | (defvar autoarg-kp-mode-map | |
82 | (let ((map (make-sparse-keymap))) | |
83 | ;; Loop over digit characters to set up keymap. | |
84 | (dotimes (i 10) | |
85 | (let ((sym (intern (format "kp-%d" i)))) | |
86 | (define-key map (vector sym) 'autoarg-kp-digit-argument))) | |
87 | (define-key map [kp-subtract] 'negative-argument) | |
88 | map) | |
89 | "Keymap for Autoarg-KP mode.") | |
90 | ||
c9bba7ed | 91 | ;;;###autoload |
c3327721 | 92 | (define-minor-mode autoarg-mode |
06e21633 CY |
93 | "Toggle Autoarg mode, a global minor mode. |
94 | With a prefix argument ARG, enable Autoarg mode if ARG is | |
95 | positive, and disable it otherwise. If called from Lisp, enable | |
96 | the mode if ARG is omitted or nil. | |
97 | ||
c9bba7ed | 98 | \\<autoarg-mode-map> |
06e21633 CY |
99 | In Autoarg mode, digits are bound to `digit-argument', i.e. they |
100 | supply prefix arguments as C-DIGIT and M-DIGIT normally do. | |
101 | Furthermore, C-DIGIT inserts DIGIT. | |
102 | \\[autoarg-terminate] terminates the prefix sequence and inserts | |
103 | the digits of the autoarg sequence into the buffer. | |
104 | Without a numeric prefix arg, the normal binding of \\[autoarg-terminate] | |
105 | is invoked, i.e. what it would be with Autoarg mode off. | |
c9bba7ed DL |
106 | |
107 | For example: | |
108 | `6 9 \\[autoarg-terminate]' inserts `69' into the buffer, as does `C-6 C-9'. | |
109 | `6 9 a' inserts 69 `a's into the buffer. | |
110 | `6 9 \\[autoarg-terminate] \\[autoarg-terminate]' inserts `69' into the buffer and | |
111 | then invokes the normal binding of \\[autoarg-terminate]. | |
112 | `C-u \\[autoarg-terminate]' invokes the normal binding of \\[autoarg-terminate] four times. | |
113 | ||
114 | \\{autoarg-mode-map}" | |
f1f8542f | 115 | nil " Aarg" autoarg-mode-map :global t :group 'keyboard) |
c9bba7ed | 116 | |
c3327721 DL |
117 | ;;;###autoload |
118 | (define-minor-mode autoarg-kp-mode | |
06e21633 CY |
119 | "Toggle Autoarg-KP mode, a global minor mode. |
120 | With a prefix argument ARG, enable Autoarg-KP mode if ARG is | |
121 | positive, and disable it otherwise. If called from Lisp, enable | |
122 | the mode if ARG is omitted or nil. | |
123 | ||
c3327721 | 124 | \\<autoarg-kp-mode-map> |
06e21633 CY |
125 | This is similar to `autoarg-mode' but rebinds the keypad keys |
126 | `kp-1' etc. to supply digit arguments. | |
c3327721 DL |
127 | |
128 | \\{autoarg-kp-mode-map}" | |
7666b1cb | 129 | nil " Aakp" autoarg-kp-mode-map :global t :group 'keyboard |
c3327721 DL |
130 | (if autoarg-kp-mode |
131 | (dotimes (i 10) | |
132 | (let ((sym (intern (format "kp-%d" i)))) | |
133 | (define-key universal-argument-map (vector sym) | |
134 | 'autoarg-kp-digit-argument))) | |
135 | (dotimes (i 10) | |
136 | (let ((sym (intern (format "kp-%d" i)))) | |
137 | (define-key universal-argument-map (vector sym) nil))))) | |
c9bba7ed DL |
138 | |
139 | (defun autoarg-terminate (n) | |
140 | "Maybe terminate a digit prefix sequence. | |
c9bba7ed DL |
141 | With a non-negative numeric prefix arg, insert the digits comprising |
142 | the arg into the current buffer. Otherwise use the binding of the key | |
143 | which invoked this function, excluding the Autoarg keymap." | |
144 | (interactive "P") | |
145 | (if (numberp n) | |
146 | (insert (number-to-string n)) | |
147 | (let* ((autoarg-mode nil) ; hide the bindings | |
148 | (binding (key-binding (this-single-command-keys)))) | |
149 | (if binding (call-interactively binding))))) | |
150 | ||
151 | (provide 'autoarg) | |
152 | ||
153 | ;;; autoarg.el ends here |