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