375 lines
17 KiB
HTML
375 lines
17 KiB
HTML
<!--startcut ==========================================================-->
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
|
<HTML>
|
|
<HEAD>
|
|
<title>EMACSulation LG #39</title>
|
|
<link rev="made" href="mailto:emarsden+emacs@laas.fr">
|
|
<meta name="keywords" content="emacs, template, expansions, dmacro">
|
|
<meta name="description" content="Templating mechanisms in Emacs: how
|
|
to use auto-inserted contents and skeletons."
|
|
<meta name="author" content="Eric Marsden">
|
|
<meta name="generator" content="Emacs">
|
|
</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">EMACSulation</font></H1>
|
|
<H4>By <a href="mailto:emarsden@mail.dotcom.fr">Eric Marsden</a></H4>
|
|
</center>
|
|
<P> <HR> <P>
|
|
|
|
<blockquote><small>
|
|
|
|
This column is devoted to making the best use of Emacs, text editor
|
|
extraordinaire. Each issue I plan to present an Emacs extension
|
|
which can improve your productivity, make the sun shine more brightly
|
|
and the grass greener.
|
|
|
|
</small></blockquote>
|
|
|
|
|
|
<h1>Templating</h1>
|
|
|
|
<p> Documents often conform to a boilerplate: a regular structure which is
|
|
boring to type in for each document. Most wordprocessors recognise this
|
|
and allow you to create templates for business letters, technical
|
|
reports, memos etc. Emacs can do one better than these static
|
|
"skeletons", since its templating mechanism allows you to
|
|
insert dynamically generated text, according to the file's name, your
|
|
login, the date, or the results of a shell command.
|
|
|
|
<p> The Emacs auto-insertion mechanism allows you to set up boilerplates
|
|
which will be instanciated upon file creation, based on the new file's
|
|
name or mode. For example, when you create a file called
|
|
<tt>lsys.h</tt>, it will ask you <em>Perform C / C++ header
|
|
auto-insertion?</em>, and if you say yes might insert something like
|
|
</p>
|
|
|
|
<table border="0" bgcolor="#E0E0E0" width="100%">
|
|
<tr><td>
|
|
<pre class="programlisting">
|
|
<font color="#ff0000">
|
|
/**********************************************************************
|
|
* lsys.h
|
|
*
|
|
* Eric Marsden <emarsden@mail.dotcom.fr>
|
|
* Time-stamp: <>
|
|
**********************************************************************/</font>
|
|
#<font color="#5f9ea0">ifndef</font> <font color="#b8860b">_LSYS_H_</font>
|
|
#<font color="#5f9ea0">define</font> <font color="#b8860b">_LSYS_H_</font>
|
|
|
|
|
|
|
|
|
|
#<font color="#5f9ea0">endif</font> <font color="#ff0000">/* _LSYS_H_ */</font>
|
|
</pre>
|
|
</td></tr></table>
|
|
|
|
<p> Note that <tt>#ifdefs</tt> have been generated to protect against
|
|
multiple inclusions of the header. You might want to add additional
|
|
elements such as your company's copyright blabber, skeletal revision
|
|
history comments, or an RCS version $Id. The auto-inserted content
|
|
depends on the major mode: upon creation of a file called
|
|
<tt>lsys.sgml</tt> the auto-inserted text might be </p>
|
|
|
|
<table border="0" bgColor="#E0E0E0" width="100%">
|
|
<tr><td>
|
|
<pre class="programlisting">
|
|
|
|
<<font color="#4682b4">!DOCTYPE</font> ARTICLE PUBLIC <font color="#a0522d">"-//Davenport//DTD DocBook V3.0//EN"</font> [
|
|
]>
|
|
<<font color="#0000cd">article</font>>
|
|
<<font color="#0000cd">artheader</font>>
|
|
<<font color="#0000cd">date</font>>1999-03-01<<font color="#0000cd">/date</font>>
|
|
<<font color="#0000cd">title</font>> <<font color="#0000cd">/title</font>>
|
|
<<font color="#0000cd">subtitle</font>> <<font color="#0000cd">/subtitle</font>>
|
|
<<font color="#0000cd">author</font>>
|
|
<<font color="#0000cd">firstname</font>>Eric<<font color="#0000cd">/firstname</font>>
|
|
<<font color="#0000cd">surname</font>>Marsden<<font color="#0000cd">/surname</font>>
|
|
<<font color="#0000cd">affiliation</font>><<font color="#0000cd">orgname</font>>CULTe<<font color="#0000cd">/orgname</font>><<font color="#0000cd">/affiliation</font>>
|
|
<<font color="#0000cd">/author</font>>
|
|
<<font color="#0000cd">authorinitials</font>>ecm<<font color="#0000cd">/authorinitials</font>>
|
|
<<font color="#0000cd">abstract</font>>
|
|
<<font color="#0000cd">para</font>>
|
|
|
|
<<font color="#0000cd">/para</font>>
|
|
<<font color="#0000cd">/abstract</font>>
|
|
<<font color="#0000cd">/artheader</font>>
|
|
|
|
<<font color="#0000cd">sect1</font>><<font color="#0000cd">title</font>> <<font color="#0000cd">/title</font>>
|
|
<<font color="#0000cd">para</font>>
|
|
|
|
<<font color="#0000cd">/para</font>>
|
|
<<font color="#0000cd">/sect1</font>>
|
|
<<font color="#0000cd">/article</font>>
|
|
</pre>
|
|
</td></tr></table>
|
|
|
|
<p> [These font-enhanced program listings were generated by Hrvoje Niksic's
|
|
excellent <a
|
|
href="http://jagor.srce.hr/~hniksic/htmlize.el">htmlize</a> package,
|
|
which generates HTML renderings of font-locked buffers.] Auto-insertion
|
|
can be activated by saying </p>
|
|
|
|
<table border="0" bgColor="#E0E0E0" width="100%">
|
|
<tr><td>
|
|
<pre>
|
|
|
|
(add-hook 'find-file-hooks 'auto-insert)
|
|
(setq auto-insert-directory (expand-file-name <font color="#a0522d">"~/.autoinsert/"</font>))
|
|
</pre>
|
|
</td></tr></table>
|
|
|
|
<p> The <strong>autoinsert package</strong> (written by Charlie Martin) is
|
|
distributed with default templates for several modes. There are two
|
|
ways of customizing the auto-inserted contents: the simplest (which
|
|
doesn't require any knowledge of elisp) involves placing files in
|
|
the directory <tt>~/.autoinsert/</tt> and registering them with
|
|
autoinsert: </p>
|
|
|
|
<table border="0" bgColor="#E0E0E0" width="100%">
|
|
<tr><td>
|
|
<pre>
|
|
|
|
(define-auto-insert "\\.html\\'" "autoinsert.html")
|
|
</pre>
|
|
</td></tr></table>
|
|
|
|
<p> The <tt>"\\.html\\'"</tt> is a regular expression which
|
|
matches filenames ending in <tt>.html</tt> (note the use of
|
|
<tt>\\'</tt> to match the end of a string, rather than <tt>$</tt> for
|
|
the end of a line, since filenames are allowed to contain newline
|
|
characters). This should lead to the contents of the file
|
|
<tt>~/.autoinsert/autoinsert.html</tt> being inserted automatically
|
|
when you create a file whose name ends in <tt>.html</tt>. This method
|
|
only allows insertion of static content. Insertion of dynamically
|
|
generated content is also possible if you know some Emacs Lisp; here is
|
|
some code which creates skeleton C or C++ headers, as in the first
|
|
example in this article: </p>
|
|
|
|
<table border="0" bgColor="#E0E0E0" width="100%">
|
|
<tr><td>
|
|
<pre class="programlisting">
|
|
<font color="#ff0000">;; autoinsert.el</font>
|
|
(define-auto-insert
|
|
(cons <font color="#a0522d">"\\.\\([Hh]\\)\\'"</font> <font color="#a0522d">"My C / C++ header"</font>)
|
|
'(nil
|
|
<font color="#a0522d">"/*"</font> (make-string 69 ?*) <font color="#a0522d">"\n"</font>
|
|
<font color="#a0522d">" * "</font> (file-name-nondirectory buffer-file-name) <font color="#a0522d">"\n"</font>
|
|
<font color="#a0522d">" *\n"</font>
|
|
<font color="#a0522d">" * "</font> (user-full-name) <font color="#a0522d">" <"</font> user-mail-address <font color="#a0522d">">\n"</font>
|
|
<font color="#a0522d">" * Time-stamp: <>\n"</font>
|
|
<font color="#a0522d">" *"</font> (make-string 69 ?*) <font color="#a0522d">"*/\n"</font>
|
|
(<font color="#4682b4">let*</font> ((noext (substring buffer-file-name 0 (match-beginning 0)))
|
|
(nopath (file-name-nondirectory noext))
|
|
(ident (concat <font color="#a0522d">"_"</font> (upcase nopath) <font color="#a0522d">"_H_"</font>)))
|
|
(concat <font color="#a0522d">"#ifndef "</font> ident <font color="#a0522d">"\n"</font>
|
|
<font color="#a0522d">"#define "</font> ident <font color="#a0522d">"\n\n\n"</font>
|
|
<font color="#a0522d">"\n\n#endif /* "</font> ident <font color="#a0522d">" */\n"</font>))))
|
|
</pre>
|
|
</td></tr></table>
|
|
|
|
<p> How does the autoinsertion work? Each time you open a file in Emacs, it
|
|
runs a special hook called <tt>find-file-hooks</tt>. This is where
|
|
things such as enabling syntactic highlighting or checking whether a
|
|
file is under a version control system (RCS or CVS) occur. The
|
|
<tt>add-hook</tt> line above latches the autoinsertion onto this hook.
|
|
|
|
|
|
<h2>Dmacro</h2>
|
|
|
|
<p> The <strong>Dynamic Macro</strong> package by Wayne Mesard allows you
|
|
to insert structured text at any time, not only at document creation
|
|
time. dmacro provides facilities such as prompting the user for input,
|
|
inserting the contents of a file or the output from a shell command,
|
|
and positioning the cursor or the mark after the insertion. One
|
|
particularly nice feature is the ability to indent autoinserted
|
|
contents according to the current mode. It could be used as a way of
|
|
enforcing (well, encouraging developers to adhere to) coding standards,
|
|
and can reduce development time by preventing typos in repetitive text.
|
|
dmacro is not distributed with Emacs; you will have to <a
|
|
href="ftp://ftp.sgi.com/other/dmacro/dmacro.tar.gz">download</a> and
|
|
install it (which is just a matter of saying <emph>make</emph>). It can
|
|
be activated by saying in your <tt>~/.emacs</tt> (where the
|
|
<tt>.dm</tt> file contains your personal macros; see below for some
|
|
examples): </p>
|
|
|
|
<table border="0" bgColor="#E0E0E0" width="100%">
|
|
<tr><td>
|
|
<pre class="programlisting">
|
|
|
|
(require 'dmacro) <font color="#ff0000">; dynamic macros</font>
|
|
(dmacro-load <font color="#a0522d">"~/elisp/ecm.dm"</font>)
|
|
</pre>
|
|
</td></tr></table>
|
|
|
|
<p> The dmacro package is very well documented, so I will only provide a
|
|
few motivating examples. Here is one which will insert the skeleton of
|
|
a <tt>for</tt> block in C-mode (macros can either be global, or
|
|
specific to a certain major mode): </p>
|
|
|
|
<table border="0" bgColor="#E0E0E0" width="100%">
|
|
<tr><td>
|
|
<pre class="programlisting">
|
|
|
|
# file ~/elisp/ecm.dm
|
|
# ================================== Stuff for C-derived modes =======
|
|
# MODE: c-mode c++-mode java-mode
|
|
ifor indent interactive for statement (prompts for variable name)
|
|
for (~(prompt var "Variable: ") = 0; ~prompt < ~@; ~prompt++)
|
|
{
|
|
~mark
|
|
}
|
|
#
|
|
</pre>
|
|
</td></tr></table>
|
|
|
|
<p> You activate the macro by typing <tt>C-c d ifor</tt> (with tab
|
|
completion on the macro's name). It should prompt you for the name of
|
|
the variable:
|
|
|
|
<p> <img src="./gx/marsden/dmacro1.gif">
|
|
|
|
<p> and the result should look like <a href="./gx/marsden/dmacro2.gif">this</a>. The
|
|
next example demonstrates how to insert a timestamp of the form
|
|
<tt>-ecm1999-02-29</tt> in the current buffer (pet peeve: given the
|
|
value of a uniform, standardized external representation for dates, I
|
|
make a point of systematically using the <a
|
|
href="http://www.cl.cam.ac.uk/~mgk25/iso-time.html">ISO 8601</a>
|
|
format). You invoke this macro by typing <tt>C-c d dstamp</tt>. The
|
|
corresponding code (which also demonstrates the use of an alias to
|
|
factorize out commonly used definitions) is: </p>
|
|
|
|
<table border="0" bgColor="#E0E0E0" width="100%">
|
|
<tr><td>
|
|
<pre class="programlisting">
|
|
|
|
# ALIAS: iso-date (eval (format-time-string "%Y-%m-%d"))
|
|
|
|
# ================================= Stuff for all modes ============
|
|
# MODE: nil
|
|
|
|
dstamp expand user id and date
|
|
-~user-id~(iso-date)
|
|
#
|
|
</pre>
|
|
</td></tr></table>
|
|
|
|
|
|
<h2>Related packages</h2>
|
|
|
|
<p> There are several other packages which provide similar functionality to
|
|
dmacro. <tt>tempo.el</tt> (included with both GNU Emacs and XEmacs) was
|
|
originally written as an adjunct to html-helper-mode, providing
|
|
facilities for inserting balanced bits of HTML markup, but can be used
|
|
for other purposes. It is also possible to extend the standard abbrev
|
|
mechanism to insert dynamically generated text by hacking the
|
|
abbrev-mode-hook, as explained in the <a
|
|
href="http://www.dejanews.com/getdoc.xp?AN=340841733">following
|
|
message</a> posted anonymously to <a
|
|
href="news:gnu.emacs.help">gnu.emacs.help</a>. Finally, there is <a
|
|
href="http://www.fmi.uni-passau.de/~wedler/template/">template.el</a>
|
|
by <a href="mailto:wedler!@!fmi.uni-passau.de">Christoph Wedler</a>
|
|
which seems very comprehensive.
|
|
|
|
|
|
<h2>Feedback</h2>
|
|
|
|
<p> The January 1999 EMACSulation on abbreviation mechanisms had a
|
|
bootstrap problem: I indicated how to create abbreviations and how to
|
|
have them read in automatically when Emacs starts up, but the
|
|
instructions that I gave weren't sufficient to get Emacs to save
|
|
abbrevs automatically when quitting. Thanks to Nat Makarevitch and Dave
|
|
Bennet for pointing this out. Here is a revised version of the code
|
|
that I proposed (the last line is what was missing): </p>
|
|
|
|
<table border="0" bgColor="#E0E0E0" width="100%">
|
|
<tr><td>
|
|
<pre class="programlisting">
|
|
<font color="red">
|
|
;; if there is an abbrev file, read it in</font>
|
|
(if (file-exists-p abbrev-file-name)
|
|
(read-abbrev-file))
|
|
(setq-default save-abbrevs t)
|
|
</pre>
|
|
</td></tr></table>
|
|
|
|
<p> A few European readers also asked about abbreviations containing 8bit,
|
|
non-ASCII characters. In its default state Emacs won't take them into
|
|
account, since it assumes that characters with the 8th bit set are non
|
|
word-constituent. To modify this (to take into account accented
|
|
characters in the iso-8859-1 character map, for example) you need to do
|
|
something like </p>
|
|
|
|
<table border="0" bgColor="#E0E0E0" width="100%">
|
|
<tr><td>
|
|
<pre class="programlisting">
|
|
|
|
(set-language-environment 'Latin-1) <font color="red">; GNU Emacs 20.x</font>
|
|
(require 'iso-syntax) <font color="red">; GNU Emacs 19.x</font>
|
|
</pre>
|
|
</td></tr></table>
|
|
|
|
<p> (there are major differences between the way that GNU Emacs 19.x and
|
|
20.x handle different character encodings; recent versions can handle
|
|
multibyte characters, required for representing asian languages. Rather
|
|
than using <a href="http://www.unicode.org/">Unicode</a>, Emacs uses
|
|
adjustable width characters. For XEmacs this <a
|
|
href="http://www.etl.go.jp/~mule/MulePage.html">MULE</a> (MULtilingual
|
|
enhancements for Emacs) support is a compile-time option in recent
|
|
versions.)
|
|
|
|
|
|
<h2>Next time ...</h2>
|
|
|
|
<p> Next month we'll look at spell checking with Emacs. Thanks to <a
|
|
href="mailto:arnu!@!laas.fr">Jean-Christophe Arnu</a> for commenting on
|
|
a draft of this article. Don't hesitate to contact me with comments,
|
|
corrections or suggestions (what's <em>your</em> favorite
|
|
couldn't-do-without Emacs extension package?). <code>C-u 1000 M-x
|
|
hail-emacs</code> !
|
|
|
|
<p> <strong>PS</strong>: Emacs isn't in any way limited to Linux, since
|
|
implementations exist for many other operating systems (and some
|
|
systems which only halfway operate). However, as one of the leading
|
|
bits of free software, one of the most powerful, complex and
|
|
customizable, I feel it has its place in the <i>Linux Gazette</i>.
|
|
|
|
<!--===================================================================-->
|
|
<P> <HR> <P>
|
|
<A HREF="../issue25/marsden.html">EMACSulation #1: Handling Compressed Files, February 1998</A><BR>
|
|
<A HREF="../issue26/marsden.html">EMACSulation #2: Internet Ready, March 1998</A><BR>
|
|
<A HREF="../issue27/marsden.html">EMACSulation #3: Ediff, April 1998</A><BR>
|
|
<A HREF="../issue29/marsden.html">EMACSulation #4: Emacs as a Server, June 1998</A><BR>
|
|
<A HREF="../issue31/marsden.html">EMACSulation #5: Customizing Emacs, August 1998</A><BR>
|
|
<A HREF="../issue36/marsden.html">EMACSulation #6: Saving Time, January 1999</A>
|
|
|
|
<!--===================================================================-->
|
|
<P> <hr> <P>
|
|
<center><H5>Copyright © 1999, Eric Marsden <BR>
|
|
Published in Issue 39 of <i>Linux Gazette</i>, April 1999</H5></center>
|
|
|
|
<!--===================================================================-->
|
|
<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="./sevenich.html"><IMG SRC="../gx/back2.gif"
|
|
ALT=" Back "></A>
|
|
<A HREF="./pollman.html"><IMG SRC="../gx/fwd.gif" ALT=" Next "></A>
|
|
<P> <hr> <P>
|
|
<!--startcut ==========================================================-->
|
|
</BODY>
|
|
</HTML>
|
|
<!--endcut ============================================================-->
|