Mercurial > hg > xemacs-beta
comparison lisp/prim/macros.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 0293115a14e9 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;; macros.el --- non-primitive commands for keyboard macros. | |
2 | |
3 ;; Copyright (C) 1985, 86, 87, 92, 94, 95 Free Software Foundation, Inc. | |
4 | |
5 ;; Maintainer: FSF | |
6 ;; Keywords: abbrev | |
7 | |
8 ;; This file is part of XEmacs. | |
9 | |
10 ;; XEmacs is free software; you can redistribute it and/or modify it | |
11 ;; under the terms of the GNU General Public License as published by | |
12 ;; the Free Software Foundation; either version 2, or (at your option) | |
13 ;; any later version. | |
14 | |
15 ;; XEmacs is distributed in the hope that it will be useful, but | |
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 ;; General Public License for more details. | |
19 | |
20 ;; You should have received a copy of the GNU General Public License | |
21 ;; along with XEmacs; see the file COPYING. If not, write to the Free | |
22 ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
23 | |
24 ;;; Synched up with: FSF 19.30. | |
25 | |
26 ;;; Commentary: | |
27 | |
28 ;; Extension commands for keyboard macros. These permit you to assign | |
29 ;; a name to the last-defined keyboard macro, expand and insert the | |
30 ;; lisp corresponding to a macro, query the user from within a macro, | |
31 ;; or apply a macro to each line in the reason. | |
32 | |
33 ;;; Code: | |
34 | |
35 ;;;###autoload | |
36 (defun name-last-kbd-macro (symbol) | |
37 "Assign a name to the last keyboard macro defined. | |
38 Argument SYMBOL is the name to define. | |
39 The symbol's function definition becomes the keyboard macro string. | |
40 Such a \"function\" cannot be called from Lisp, but it is a valid | |
41 editor command." | |
42 (interactive "SName for last kbd macro: ") | |
43 (or last-kbd-macro | |
44 (error "No keyboard macro defined")) | |
45 (and (fboundp symbol) | |
46 (not (stringp (symbol-function symbol))) | |
47 (not (vectorp (symbol-function symbol))) | |
48 (error "Function %s is already defined and not a keyboard macro." | |
49 symbol)) | |
50 (fset symbol last-kbd-macro)) | |
51 | |
52 (defun insert-kbd-macro-pretty-string (string) | |
53 ;; Convert control characters to the traditional readable representation: | |
54 ;; put the four characters \M-x in the buffer instead of the one char \370, | |
55 ;; which would deceptively print as `oslash' with the default settings. | |
56 (save-restriction | |
57 (narrow-to-region (point) (point)) | |
58 (prin1 string (current-buffer)) | |
59 (goto-char (1+ (point-min))) | |
60 (while (not (eobp)) | |
61 (cond ((= (following-char) 0) (insert "\\C-@") (delete-char 1)) | |
62 ((= (following-char) ?\n) (insert "\\n") (delete-char 1)) | |
63 ((= (following-char) ?\r) (insert "\\r") (delete-char 1)) | |
64 ((= (following-char) ?\t) (insert "\\t") (delete-char 1)) | |
65 ((= (following-char) ?\e) (insert "\\e") (delete-char 1)) | |
66 ((= (following-char) 127) (insert "\\C-?") (delete-char 1)) | |
67 ((= (following-char) 128) (insert "\\M-\\C-@") (delete-char 1)) | |
68 ((= (following-char) 255) (insert "\\M-\\C-?") (delete-char 1)) | |
69 ((and (> (following-char) 127) (< (following-char) 155)) | |
70 (insert "\\M-\\C-") | |
71 (insert (- (following-char) 32)) | |
72 (delete-char 1) | |
73 (forward-char -1)) | |
74 ((and (>= (following-char) 155) (< (following-char) 160)) | |
75 (insert "\\M-\\C-") | |
76 (insert (- (following-char) 64)) | |
77 (delete-char 1) | |
78 (forward-char -1)) | |
79 ((>= (following-char) 160) | |
80 (insert "\\M-") | |
81 (insert (- (following-char) 128)) | |
82 (delete-char 1) | |
83 (forward-char -1)) | |
84 ((< (following-char) 27) | |
85 ;;(insert "\\^") (insert (+ (following-char) 64)) | |
86 (insert "\\C-") (insert (+ (following-char) 96)) | |
87 (delete-char 1) | |
88 (forward-char -1)) | |
89 ((< (following-char) 32) | |
90 ;;(insert "\\^") (insert (+ (following-char) 64)) | |
91 (insert "\\C-") (insert (+ (following-char) 64)) | |
92 (delete-char 1) | |
93 (forward-char -1)) | |
94 (t | |
95 (forward-char 1)))))) | |
96 | |
97 ;;;###autoload | |
98 (defun insert-kbd-macro (macroname &optional keys) | |
99 "Insert in buffer the definition of kbd macro NAME, as Lisp code. | |
100 Optional second argument KEYS means also record the keys it is on | |
101 \(this is the prefix argument, when calling interactively). | |
102 | |
103 This Lisp code will, when executed, define the kbd macro with the | |
104 same definition it has now. If you say to record the keys, | |
105 the Lisp code will also rebind those keys to the macro. | |
106 Only global key bindings are recorded since executing this Lisp code | |
107 always makes global bindings. | |
108 | |
109 To save a kbd macro, visit a file of Lisp code such as your `~/.emacs', | |
110 use this command, and then save the file." | |
111 (interactive "CInsert kbd macro (name): \nP") | |
112 (let (definition) | |
113 (if (string= (symbol-name macroname) "") | |
114 (progn | |
115 (setq macroname 'last-kbd-macro | |
116 definition last-kbd-macro) | |
117 (insert "(setq ")) | |
118 (progn | |
119 (setq definition (symbol-function macroname)) | |
120 (insert "(fset '"))) | |
121 (prin1 macroname (current-buffer)) | |
122 (insert "\n ") | |
123 (let ((string (events-to-keys definition t))) | |
124 (if (stringp string) | |
125 (insert-kbd-macro-pretty-string string) | |
126 (prin1 string (current-buffer)))) | |
127 (insert ")\n") | |
128 (if keys | |
129 (let ((keys (where-is-internal macroname))) | |
130 (while keys | |
131 (insert "(global-set-key ") | |
132 (prin1 (car keys) (current-buffer)) | |
133 (insert " '") | |
134 (prin1 macroname (current-buffer)) | |
135 (insert ")\n") | |
136 (setq keys (cdr keys))))))) | |
137 | |
138 ;;;###autoload | |
139 (defun kbd-macro-query (flag) | |
140 "Query user during kbd macro execution. | |
141 With prefix argument, enters recursive edit, | |
142 reading keyboard commands even within a kbd macro. | |
143 You can give different commands each time the macro executes. | |
144 Without prefix argument, asks whether to continue running the macro. | |
145 Your options are: \\<query-replace-map> | |
146 \\[act] Finish this iteration normally and continue with the next. | |
147 \\[skip] Skip the rest of this iteration, and start the next. | |
148 \\[exit] Stop the macro entirely right now. | |
149 \\[recenter] Redisplay the frame, then ask again. | |
150 \\[edit] Enter recursive edit; ask again when you exit from that." | |
151 (interactive "P") | |
152 (or executing-macro | |
153 defining-kbd-macro | |
154 (error "Not defining or executing kbd macro")) | |
155 (if flag | |
156 (let (executing-macro defining-kbd-macro) | |
157 (recursive-edit)) | |
158 (if (not executing-macro) | |
159 nil | |
160 (let ((loop t) | |
161 (msg (substitute-command-keys | |
162 "Proceed with macro?\\<query-replace-map>\ | |
163 (\\[act], \\[skip], \\[exit], \\[recenter], \\[edit]) "))) | |
164 (while loop | |
165 (let ((key (let ((executing-macro nil) | |
166 (defining-kbd-macro nil)) | |
167 (message msg) | |
168 (read-char))) | |
169 def) | |
170 (setq key (vector key)) | |
171 (setq def (lookup-key query-replace-map key)) | |
172 (cond ((eq def 'act) | |
173 (setq loop nil)) | |
174 ((eq def 'skip) | |
175 (setq loop nil) | |
176 (setq executing-macro "")) | |
177 ((eq def 'exit) | |
178 (setq loop nil) | |
179 (setq executing-macro t)) | |
180 ((eq def 'recenter) | |
181 (recenter nil)) | |
182 ((eq def 'edit) | |
183 (let (executing-macro defining-kbd-macro) | |
184 (recursive-edit))) | |
185 ((eq def 'quit) | |
186 (setq quit-flag t)) | |
187 (t | |
188 (or (eq def 'help) | |
189 (ding)) | |
190 (with-output-to-temp-buffer "*Help*" | |
191 (princ | |
192 (substitute-command-keys | |
193 "Specify how to proceed with keyboard macro execution. | |
194 Possibilities: \\<query-replace-map> | |
195 \\[act] Finish this iteration normally and continue with the next. | |
196 \\[skip] Skip the rest of this iteration, and start the next. | |
197 \\[exit] Stop the macro entirely right now. | |
198 \\[recenter] Redisplay the frame, then ask again. | |
199 \\[edit] Enter recursive edit; ask again when you exit from that.")) | |
200 (save-excursion | |
201 (set-buffer standard-output) | |
202 (help-mode))))))))))) | |
203 | |
204 ;;;###autoload | |
205 (defun apply-macro-to-region-lines (top bottom &optional macro) | |
206 "For each complete line between point and mark, move to the beginning | |
207 of the line, and run the last keyboard macro. | |
208 | |
209 When called from lisp, this function takes two arguments TOP and | |
210 BOTTOM, describing the current region. TOP must be before BOTTOM. | |
211 The optional third argument MACRO specifies a keyboard macro to | |
212 execute. | |
213 | |
214 This is useful for quoting or unquoting included text, adding and | |
215 removing comments, or producing tables where the entries are regular. | |
216 | |
217 For example, in Usenet articles, sections of text quoted from another | |
218 author are indented, or have each line start with `>'. To quote a | |
219 section of text, define a keyboard macro which inserts `>', put point | |
220 and mark at opposite ends of the quoted section, and use | |
221 `\\[apply-macro-to-region-lines]' to mark the entire section. | |
222 | |
223 Suppose you wanted to build a keyword table in C where each entry | |
224 looked like this: | |
225 | |
226 { \"foo\", foo_data, foo_function }, | |
227 { \"bar\", bar_data, bar_function }, | |
228 { \"baz\", baz_data, baz_function }, | |
229 | |
230 You could enter the names in this format: | |
231 | |
232 foo | |
233 bar | |
234 baz | |
235 | |
236 and write a macro to massage a word into a table entry: | |
237 | |
238 \\C-x ( | |
239 \\M-d { \"\\C-y\", \\C-y_data, \\C-y_function }, | |
240 \\C-x ) | |
241 | |
242 and then select the region of un-tablified names and use | |
243 `\\[apply-macro-to-region-lines]' to build the table from the names. | |
244 " | |
245 (interactive "r") | |
246 (or macro | |
247 (progn | |
248 (if (null last-kbd-macro) | |
249 (error "No keyboard macro has been defined.")) | |
250 (setq macro last-kbd-macro))) | |
251 (save-excursion | |
252 (let ((end-marker (progn | |
253 (goto-char bottom) | |
254 (beginning-of-line) | |
255 (point-marker))) | |
256 next-line-marker) | |
257 (goto-char top) | |
258 (if (not (bolp)) | |
259 (forward-line 1)) | |
260 (setq next-line-marker (point-marker)) | |
261 (while (< next-line-marker end-marker) | |
262 (goto-char next-line-marker) | |
263 (save-excursion | |
264 (forward-line 1) | |
265 (set-marker next-line-marker (point))) | |
266 (save-excursion | |
267 (execute-kbd-macro (or macro last-kbd-macro)))) | |
268 (set-marker end-marker nil) | |
269 (set-marker next-line-marker nil)))) | |
270 | |
271 ;;; macros.el ends here |