axiom-developer
[Top][All Lists]

[Axiom-developer] [Axiom In Emacs]

 From: kai Kaminski Subject: [Axiom-developer] [Axiom In Emacs] Date: Wed, 07 Sep 2005 10:47:23 -0500

Changes http://www.axiom-developer.org/zope/mathaction/AxiomInEmacs/diff
--

??changed:
-<h3>Editing Axiom's Source Code</h3>
-
-Emacs can be configured to make editing Axiom's source code much easier. First
of all you have to put <a href="boot-mode.el"><tt>boot-mode.el</tt></a> and
<tt>noweb-mode.el</tt> (included in the noweb distribution, which in turn is
-
<h3>Editing Pamphlets</h3>

All of Axiom's source files are pamphlets now, which means they
are <a href="http://literateprogramming.com";>literate programs</a> as
understood
by <a href="http://www.eecs.harvard.edu/~nr/noweb/";>Noweb</a>. This is
a collection of Elisp code and tips to make editing pamphlets with
Emacs less painful.

The first step is to put <tt>noweb-mode.el</tt>, which is contained in

??changed:
-
'(".*\\.pamphlet" . noweb-mode))
</pre>

Noweb mode not only offers functions to deal with chunks, like killing
chunks, but also lets the user specify a major mode for the code and
documentation chunks. The standard documentation mode is LaTeX and the
standard code mode is Fundamental. While LaTeX is the right choice for
all files in Axiom so far, Fundamental is not a good choice as code
mode in general and there are several ways to change it.

First of all you can use the Emacs command <tt>noweb-set-code-mode</tt>, which
prompts you for a major mode.

You can also
use <a
href="http://www.gnu.org/software/emacs/manual/html_node/File-Variables.html";>file
variables</a>. The easiest way to do this is to open the file in question, go
to the beginning of the file and
call <tt>noweb-insert-mode-line</tt> (a misnomer). It will insert a
new line containing all the necessary incantations. The other option
is to insert the same text manually. A file with code chunks
containing lisp code, for example, should have the following first line:
<pre>
% -*- mode: Noweb; noweb-code-mode: lisp-mode -*-
</pre>

Unfortunately, most files in the Axiom distribution do not contain
file variables to set the code mode and it is unclear if that is
desirable in the first place, since not everyone is using
Emacs. Luckily, many of the pamphlet files have names of the form
<tt>foo.ext.pamphlet</tt>, where <tt>ext</tt> indicates the type of
the code chunks. For example, <tt>foo.lisp.pamphlet</tt> would contain Lisp
simple form of auto detection. Simply add the following to
<pre>

??changed:
-
</pre>
This code does not override file variables. It uses
the <tt>auto-mode-alist</tt>-mechanism to choose the code mode and
uses Fundamental mode, if that fails.

It should be mentioned that Emacs 22 will feature yet another way to
detect the right major mode for a file by examining the file's
content. Maybe this can be adapted to look at the content of the code

Especially when dealing with Axiom's existing code base one often
finds oneself in a situation, where a pamphlet looks like this:
<pre>
\documentclass{article}
\usepackage{noweb}

\begin{document}
\title{DWIM.BOOT.PAMPHLET}
\author{John Doe}
\maketitle

<<*>>=
source code
@
</pre>
The pamphlet doesn't contain any documentation and just one big code
chunk. Usually that means that the original author didn't use
literate programming and that the source code was just transformed
to a pamphlet in the obvious - and useless - way. If you want to
transform it into a true literate program you'll often want to take
a consecutive region of code, replace it with a chunk marker,
say <tt>&lt;&lt;foo&gt;&gt;</tt>, and add a new chunk containing
the replaced code somewhere else in the file. This is made somewhat
easier by the following two Elisp functions:

<pre>
(defun kai:noweb-extract-chunk (chunk-name start end)
(interactive "sChunk name: \nr")
(let* ((chunk (delete-and-extract-region start end)))
(kill-new (concat "<<" chunk-name ">>=\n" chunk "address@hidden"))
(save-excursion
(goto-char start)
(insert (concat "<<" chunk-name ">>\n"))))
(noweb-update-chunk-vector))

(defun kai:noweb-yank (&rest args)
(interactive "")
(apply 'yank args)
(noweb-update-chunk-vector))

(lambda ()
(global-set-key [(control ?c) ?x] 'kai:noweb-extract-chunk)
(global-set-key [(control ?c) ?y] 'kai:noweb-yank)))
</pre>

To use them, just mark a region of code and press <tt>C-c
x</tt>. You'll be prompted for a chunk name. Then go to the point
where you want the new chunk to reside and press <tt>C-c y</tt>.

It would be nicer, if one could bind <tt>kai:noweb-yank</tt>
to <tt>C-y</tt> instead. Unfortunately that doesn't work. The problem
seems to be that whenever the Noweb mode changes major modes, because
you left/entered a chunk, the new major mode as well as the Noweb mode
reinstall their key bindings and restore the original binding
for <tt>C-y</tt>. I'm not sure if this explanation is accurate,
though.

<h3>Editing BOOT code</h3>

To simplify editing BOOT code
put <a href="boot-mode.el"><tt>boot-mode.el</tt></a> into
<pre>

??changed:
-
-;; AUTO-MODE-ALIST
-
-(setq auto-mode-alist
-      (list*
-       '(".*\\.pamphlet" . noweb-mode)
-       '(".*\\.boot" . boot-mode)
-       '(".*\\.lisp" . lisp-mode)
-       '(".*\\.c" . c-mode)
-       auto-mode-alist))
'(".*\\.boot" . boot-mode))

??changed:
-This code tries to automatically set the code mode in noweb, which only works
for files with names of the form <tt>file.ext.pamphlet</tt>, where <tt>ext</tt>
indicates the code mode. For example, <tt>sockio.lisp.pamphlet</tt> would have
its code mode set to <tt>lisp-mode</tt> and <tt>nci.boot.pamphlet</tt> to
<tt>boot-mode</tt>. If the auto-detection can't decide on a mode it uses
<tt>fundamental-mode</tt>.
Currently this mode doesn't do anything beyond very rudimentary syntax
high-lighting and making <tt>comment-region</tt> work.

--