Commit | Line | Data |
---|---|---|
c9bba7ed DL |
1 | ;;; autoarg.el --- make digit keys supply prefix args |
2 | ||
73b0cd50 | 3 | ;; Copyright (C) 1998, 2000-2011 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 DL |
92 | (define-minor-mode autoarg-mode |
93 | "Toggle Autoarg minor mode globally. | |
c9bba7ed DL |
94 | With ARG, turn Autoarg mode on if ARG is positive, off otherwise. |
95 | \\<autoarg-mode-map> | |
96 | In Autoarg mode digits are bound to `digit-argument' -- i.e. they | |
97 | supply prefix arguments as C-DIGIT and M-DIGIT normally do -- and | |
98 | C-DIGIT inserts DIGIT. \\[autoarg-terminate] terminates the prefix sequence | |
99 | and inserts the digits of the autoarg sequence into the buffer. | |
100 | Without a numeric prefix arg the normal binding of \\[autoarg-terminate] is | |
101 | invoked, i.e. what it would be with Autoarg mode off. | |
102 | ||
103 | For example: | |
104 | `6 9 \\[autoarg-terminate]' inserts `69' into the buffer, as does `C-6 C-9'. | |
105 | `6 9 a' inserts 69 `a's into the buffer. | |
106 | `6 9 \\[autoarg-terminate] \\[autoarg-terminate]' inserts `69' into the buffer and | |
107 | then invokes the normal binding of \\[autoarg-terminate]. | |
108 | `C-u \\[autoarg-terminate]' invokes the normal binding of \\[autoarg-terminate] four times. | |
109 | ||
110 | \\{autoarg-mode-map}" | |
f1f8542f | 111 | nil " Aarg" autoarg-mode-map :global t :group 'keyboard) |
c9bba7ed | 112 | |
c3327721 DL |
113 | ;;;###autoload |
114 | (define-minor-mode autoarg-kp-mode | |
115 | "Toggle Autoarg-KP minor mode globally. | |
116 | With ARG, turn Autoarg mode on if ARG is positive, off otherwise. | |
117 | \\<autoarg-kp-mode-map> | |
118 | This is similar to \\[autoarg-mode] but rebinds the keypad keys `kp-1' | |
cc0f519f | 119 | etc. to supply digit arguments. |
c3327721 DL |
120 | |
121 | \\{autoarg-kp-mode-map}" | |
7666b1cb | 122 | nil " Aakp" autoarg-kp-mode-map :global t :group 'keyboard |
c3327721 DL |
123 | (if autoarg-kp-mode |
124 | (dotimes (i 10) | |
125 | (let ((sym (intern (format "kp-%d" i)))) | |
126 | (define-key universal-argument-map (vector sym) | |
127 | 'autoarg-kp-digit-argument))) | |
128 | (dotimes (i 10) | |
129 | (let ((sym (intern (format "kp-%d" i)))) | |
130 | (define-key universal-argument-map (vector sym) nil))))) | |
c9bba7ed DL |
131 | |
132 | (defun autoarg-terminate (n) | |
133 | "Maybe terminate a digit prefix sequence. | |
c9bba7ed DL |
134 | With a non-negative numeric prefix arg, insert the digits comprising |
135 | the arg into the current buffer. Otherwise use the binding of the key | |
136 | which invoked this function, excluding the Autoarg keymap." | |
137 | (interactive "P") | |
138 | (if (numberp n) | |
139 | (insert (number-to-string n)) | |
140 | (let* ((autoarg-mode nil) ; hide the bindings | |
141 | (binding (key-binding (this-single-command-keys)))) | |
142 | (if binding (call-interactively binding))))) | |
143 | ||
144 | (provide 'autoarg) | |
145 | ||
146 | ;;; autoarg.el ends here |