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