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