File: pedersen.html

package info (click to toggle)
lg-issue47 3-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 3,776 kB
  • ctags: 237
  • sloc: ansic: 232; sh: 152; makefile: 34; perl: 9
file content (416 lines) | stat: -rw-r--r-- 18,088 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
<!--startcut BEGIN header ==============================================-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>Emacs Macros and the Power-Macros Package LG #47</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!--endcut ============================================================-->

<H4>
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>

<P> <HR> <P> 
<!--===================================================================-->

<center>
<H1><font color="maroon">Emacs Macros and the Power-Macros Package</font></H1>
<H4>By <a href="mailto:blackie@ifad.dk">Jesper Kj&aelig;r Pedersen</a></H4>
</center>
<P> <HR> <P>  

<!-- END header -->




<h2>Abstract</h2>
People sometimes tend to forget that computers are a tool that can make
their life much easier. One of the things computers are especially good at,
and which is easy for you to teach, is monotonic repetitive work. It gets
even better: This kind of work also seems to be the work humans are worst at
doing that is, monotonic repetitive work tends to be very error-prone.<p>

Emacs can eliminate the repetitive work with a very useful concept
called macros. Macros are basically keystrokes that Emacs types for
you.<p>

This article will teach you about Emacs macros and show you a number of
useful examples. Furthermore, it will teach you about an Emacs
package I written called power-macros, which makes it very easy to bind macros to
keys and to save them to a file for use in later Emacs sessions.<p>

<h2>Defining an Emacs macro.</h2>
Defining an Emacs macro is done by pressing <tt>C-x (</tt> (That is press
Ctrl, hold it down and press x, and then release Ctrl and x and press the
opening bracket). The subsequent keystrokes will be part of your
macro that is whenever you ask Emacs to execute your macro, these
keystrokes will <i>be typed for you</i>. When you are done defining the
macro, press <tt>C-x )</tt><p>

When a macro has been defined you may ask Emacs to imitate your
keystrokes as often as you want simply by pressing <tt>C-x e</tt>.<p>

<h3>Two-cent tip</h3>
If you need to repeat macros several times, then it might be quite annoying
that you need to press two keys to execute the macro defined. (That is, if
you need to execute the macro three times, then you must press C-x e, C-x e,
C-x e). A solution to this may be to bind <i>execute last defined keyboard
macro</i> to a single key press. This way, you may for example bind it to
shift-F1, by inserting the following code into your <tt>.emacs</tt>
file:
<pre>
(global-set-key [(shift f1)] 'call-last-kbd-macro)
</pre>

<h2>Example: Making the current word bold</h2>
That's it now you have learned the basics about Emacs macros, but
I'm pretty sure that you haven't had the feeling yet that this would change
your world much, right? To be honest, I've used Emacs for more than seven
years, but until less than a year ago, I didn't see the light either...
Therefore, here comes a small example to vet your appetite. More will
follow later in the article.<p>

Imagine that you often want to make the current word in boldface (in
HTML documents), you could simply do that by inserting <tt>&lt;b&gt;</tt>
and <tt>&lt;/b&gt;</tt> around the word. That's no big job, but if you are
copy-editing a book, where you need to make words in boldface hundreds
of times each hour, then a macro, that can do this may really spare you a
lot of time.<p>

The macro is easily recorded: Go to the beginning of the word, insert
<tt>&lt;b&gt;</tt>, go to the end of the word, insert <tt>&lt;/b&gt;</tt>,
and there you are!<p>

Ohhh, not so fast! There is one very important point to notice about this
you are not allowed to go to the beginning respectively the end of the word
by pressing the arrow key a number of times! Why not? Well if you do, then
the macro will fail to find the border of the word if your word is of a
different length than the word used when defining the macro. You must
therefore instead use the commands <tt>forward-word</tt> and
<tt>backward-word</tt>. These commands are bound to control and the arrow
keys. Thus to go to the beginning of a word, simply press control and the
left arrow key.<p>

Basically there exist two kinds of macros: those that are used now and again,
and those that are used a number of times in a row and then never used
again. The above is an example of a macro of the first kind. The
description of the second kind is out of the scope for this article, but an
example could be a macro,  that added <tt>/* REMOVE:</tt> to the beginning
of a line, and <tt>*/</tt> to the end of a line. You may use such a macro a
number of times in a row, to comment out a whole function in C for later removal.<p>









<h2>Making macros more general</h2>
In some C++ programs you will often find constructs which resemble the
following:
<pre>
for (bool cont=iterator.First(value); cont; cont=iterator.Next(value)) {
  ...
}
</pre>

The only difference from occasion to occasion is the names <i>cont</i>,
<i>iterator</i>, <i>value</i>, and of course the content in between the
curly brackets.<p>

If you insert the code above often, then you may wish to build a macro,
which will help you with this. Your first attempt may be to define a macro,
which simply inserts:
<pre>
for (bool =.First(); ; =.Next()) {
}
</pre>

That is, a macro that simply leaves out all the parts that may change from
time to time. This is, however, not as useful as it could be, simply
because you would need to type <i>cont</i> three times, and <i>iterator</i>
and <i>value</i> each two times. What you really would need was for Emacs
to ask you about the names to use instead of <i>cont</i>,<i>iterator</i>,
and <i>value</i>.<p>

Guess what? you can do that with macros! The trick is called <tt>recursive
editing</tt>. With recursive editing you tell Emacs to stop at a specific
place in the macro, you do some editing, and when you are done
you tell Emacs to continue with the macro. <p>

When you record the macro, you may tell Emacs to enter recursive editing by
pressing <tt>C-u C-x q</tt>. Then whenever you execute the macro
Emacs will stop macro execution at that point and let you do some editing,
and the macro will first continue when you press C-M-c (That is
control-meta-c, if there is no meta key on your keyboard it is most likely
the alt key instead.).<p> 

While you record the macro, Emacs will also enter recursive editing at that
point. That is, the editing you do from the point you press <tt>C-u C-x
q</tt> and till you press <tt>C-M-c</tt> will <b>not</b> be part of the macro.<p>

Ok, we are almost ready to develop a very neat and useful macro, but first
lets exercise what we've learned above with a simple example. Type the following:
<pre>
C-x ( Type a word ==&gt; C-u C-x q
</pre>

Now type <i>Hello World</i>, and when done, continue typing the following:
<pre>
C-M-c &lt;== C-x )
</pre>

The above inserted the following text into your buffer: <tt>Type a word
==&gt;Hello World&lt;==</tt>. Furthermore it also defined a macro, which
inserts this text except for the words <tt>Hello World</tt>. Whenever you
execute the just defined macro Emacs will pause after having inserted
<tt>Type a word ==&gt;</tt>, and when you press <tt>C-M-c</tt>, it will
continue with the macro, which means that it will insert the text <tt>&lt;==</tt>.<p>

Can you see where we are heading? Now we have the tools to ask the user for
the three names needed, so all we need now is a way to fetch the
information he typed and insert it at the appropriate places.<p>

Fetching the information could be done in several ways. The simplest way
(that is the one, which requires the smallest knowledge about Emacs) would
simply be to switch to a temporary buffer, let the user type in the
information there, and whenever one of the words are needed, simply go to
this buffer, and fetch it there.<p>

A much smarter way is to use <i>registers</i>. A register is a
container where you may save the text of the current region for later
use. To insert text into a register, mark a region, and press
<tt>C-x r s</tt> and a letter (the letter indicates which of the registers
to save the information to) Later you may insert the content of the
register into the buffer  by pressing <tt>C-x r i</tt> and pressing
the letter you typed above.<p>

Now that's it. Below you can see all the keystrokes needed to record this
macro. Text in between quotes should be typed literally, and text in italic
are comments, which you should not type.<p>

It may seem like much to type to obtain this, but on the other hand,
when you are done, you will have a very user friendly interface to
inserting the given for-loops.

<blockquote>
"Bool: " C-space <i>This will set the mark - that is one end of the region</i><br>
C-u C-x q <i>Type the name of the first bool here</i><br>
C-x C-x <i>This will make the region active</i><br>
C-x r s a <i>Copy the just typed word to the register named a</i><br>
C-a C-k <i>Delete the line, as the just inserted text should not be part of the buffer</i><br>
"Iterator: " <i>Now continue as above, and save to register b</i><br>
"Value: " <i>Once again continue and this time save to register c</i><br>
"for (bool " <i>Now we've started to actually type the for-loop</i><br>
C-x r i a <i>Insert the name of the boolean</i><br>
"= " C-x r i b <i>Insert the name of the iterator</i><br>
C-e ".First(" C-x r i c <i>The name of the value</i><br>
C-e "); " C-x r i a C-e "; " C-x r i a C-e " = " C-x r i b C-e ".Next(" C-x
r i c C-e ")) {" Return "}"
</blockquote>



<h1>Power Macros</h1>
Power Macros is an Emacs package, which I developed out of frustration of
not being able to define a macro, bind it to a key, and have it bound there
for future Emacs sessions. (Or rather, not being able to do so very easy).<p>

To use this Emacs package, download the file from its <a
href="http://www.imada.sdu.dk/~blackie/emacs/">home page</a>. Copy the lisp
file to somewhere in your load path, and insert the following into your
<tt>.emacs</tt>file:
<pre>
(require 'power-macros)
(power-macros-mode)
(pm-load)
</pre>

If you do not know what a load path is, or do not have one, then create a
directory called <tt>Emacs</tt>in your home directory, copy the file to
this directory, and insert the following line into your <tt>.emacs</tt>
file before the lines above:
<pre>
(setq load-path (cons "~/Emacs" load-path))
</pre>

When that is done, you may simply press <tt>C-c n</tt>, when you have
defined a macro, and Emacs will ask you the following questions in the
mini-buffer:

<dl>
<dt>Which key to bind the macro to.
<dd>First Emacs must know which key the macro should be bound to. When you
are done answering these questions, then the macro will be available simply
by pressing this key, and you may that way have several macros defined at
the same time.<p>


<dt>How should the macro be accessible.
<dd>With power macros you may make the macro accessible in one of two ways:
1) Global - that is it is accessible in every buffer. 2) As a major mode
specific macro - that is the macro is only accessible in buffers with a
given major mode.<p>

As an example of a mode specific macro, think about the
<i>for-loop</i>-macro from the example above. This macro is only useful
when writing C++ programs. Furthermore you may need a similar macro for
programming Java (which of course use Java syntax rather than C++
syntax). With power-macros you may bind both the macro for C++-mode and the
macro for Java-mode to the same key (say <tt>C-M-f</tt>), and then the
correct one will be used in the given mode.<p>

<dt>Which file should it be saved to.
<dd>By default Emacs saves the macros defined with power-macro to the file
named <tt>~/.power-macros</tt>. If that is Ok for the macro you are
defining, then simply press enter at this question. If you do not want to
save the given macro to a file for future Emacs sessions, then remove the
suggested text (so that you answer the question with an empty
string). Finally you may of course name another file. In the <a
href="#local_file">section below</a>, there is a description of when this
can be of special interest.<p>

<dt>What is its description.
<dd>Finally you have to write a description for the macro just
defined. This will make it much easier for you to identify it later, when
you have forgot which key you have bound it to, or when you are searching
for a key to bind a new macro to.
</dl>

As part of binding the macro to a key, Emacs will also check if the given
binding will override an existing binding. If this is the case it will warn
you about this, and ask you for confirmation to continue the definition. 




<h2><a name="local_file">Local Macros</a></h2>
For some time ago I was going to give a speech on Emacs. I have done that a
number of times before, so I haven't done any special preparation for this
specific speech. When I was driving to the speech (by train) I decided
shortly to go through my presentation anyway. I was terrified to see that the
presentation program suddenly didn't work on my machine.<p>

So there I was, less than an hour to my speech and my presentation program
didn't work! What should I do?! The answer was kind of obvious, why not
make the presentation using Emacs?! Fortunately the input to the other
presentation program was ASCII, and the only construct I used in the
presentation was enumerated lists, so it was very easy to rewrite the
presentation so it looked good in an Emacs buffer (with a slightly enlarged
font). Now there was only one problem: How could I easily go
forward/backward one presentation page?<p>

Can you guess what the answer was? Yes you are right, the answer was to
create two macros. One going forward one page, and another going backward
one page.<p>

Going forward one page was done the following way:
<ol>
<li>Search for a line starting with a number of equal signs. This was
namely the second line of each presentation page (Just below the title of
the page).
<li>Press <tt>C-1 C-l</tt> (that is control-one control-el) This would
locate this line as the second line of the screen. And consequently the title
of the page would thus be the first one.
<li>Go to the beginning of the next line. This was necessary so the
subsequent search would not find the current page.
</ol>

The two macros, just defined, is only useful for the given file (and later
to all the files, which contains a presentation made for viewing with
Emacs). Therefore it would be a bit annoying to have these macros defined
and bound to keys all the times, especially given that there might be
several month before my next Emacs presentation.<p>

The two macros should therefore be saved to a separate file, and
whenever needed I could simply load them. Loading a power macro is done by
using the function <tt>pm-load</tt>. Thus I could load the macros by
pressing <tt>M-x</tt> typing pm-load, pressing enter, and typing the name
of the file to load.

Loading the macros for the presentation could be done even more automatic,
by inserting the following lines as the very last lines of the file:

<pre>
Local Variables:
eval: (pm-load "presentation.macro")
End:
</pre>

In the above it is assumed that the name of the file containing the macros
is called <tt>presentation.macro</tt>.<p>

Now Emacs automatically loads the presentation macros whenever the file is opened.

<h2>Managing Power Macros</h2>
When you have defined a number of macros, you might want to do various
managing functions on your macros. This is done by pressing <tt>C-c
m</tt>. This will bring up a buffer as the one you can see below:<p>

<img src="gx/pedersen/manage.jpg" BORDER=1>
<BR CLEAR=all>

What you see in this buffer is your power macros, each separated with a
line of dashes. Many of the keys have special meaning in this buffer (Just
like the keys have special meaning in the buffer managing buffer or in the
dired buffer).<p>

By pressing the enter key on top of one of the fields lets you edit the
given field. Editing a field does in fact mean either to change its
content, or to copy the macro to a new one with the given field changed. You specify
whichever of these meanings you intend, when you have pressed enter on the
field.<p>

Deletion of macros is done in two steps, first you mark the macros which
you want to delete, and next you tell Emacs to actual delete them. If you
know either the buffer managing buffer or dired-mode, then you will be
familiar with this two step process.

<h1>The End</h1>
If your appetite has been vet to learn more about Emacs, then I can inform
you that I'm the author of a book 
on Emacs called "Sams Teach Yourself Emacs in 24 Hours". (ISBN:
0-672-31594-7). To learn more about this book, please visit it's home page
on the URL <a
href="http://www.imada.sdu.dk/~blackie/emacs/">http://www.imada.sdu.dk/~blackie/emacs/</a>.
This is also the page you should visit if you want to download the
power-macro package.<p>


<address><a href="http://www.imada.sdu.dk/~blackie/">Jesper Kj&aelig;r
Pedersen</a> &lt;<a href="mailto:blackie@ifad.dk">blackie@ifad.dk</a>&gt;</address>




<!-- BEGIN copyright ==================================================-->
<P> <hr> <P> 
<H5 ALIGN=center>

Copyright &copy; 1999, Jesper Kj&aelig;r Pedersen<BR> 
Published in Issue 47 of <i>Linux Gazette</i>, November 1999</H5>
<!-- END copyright ===================================================-->





<!--startcut footer ===================================================-->
<P> <hr> <P> 
<A HREF="index.html"><IMG ALIGN=BOTTOM SRC="../gx/indexnew.gif" 
ALT="[ TABLE OF CONTENTS ]"></A>
<A HREF="../index.html"><IMG ALIGN=BOTTOM SRC="../gx/homenew.gif"
ALT="[ FRONT PAGE ]"></A>
<A HREF="nielsen.html"><IMG SRC="../gx/back2.gif"
ALT=" Back "></A>
<A HREF="../faq/index.html"
	><IMG SRC="./../gx/dennis/faq.gif"
              ALT="[ Linux Gazette FAQ ]"></A>
<A HREF="pollman.html"><IMG SRC="../gx/fwd.gif" ALT=" Next "></A>
<P> <hr> <P> 
</BODY></HTML>
<!--endcut ============================================================-->