]=] .. "\n" -- (find-angg "LUA/texinfo.lua" "prefix") -- (find-angg "LUA/texinfo.lua" "preproc") -- (find-angg "LUA/texinfo.lua" "output")

-- (find-node "(texinfo)Command Syntax")

-- (find-node "(texinfo)Conventions" "doubled single-quote") -- (find-node "(texinfo)Conventions" "`@', `{', and `}'") -- (find-node "(texinfo)emph & strong") -- (find-node "(texinfo)Block Enclosing Commands") -- (find-node "(texinfo)code") -- (find-node "(texinfo)noindent") -- (find-node "(texinfo)Predefined Indices") -- (find-node "(texinfo)Indexing Commands") -- (find-node "(texinfo)code" "shell command names such as `ls'") -- (find-node "(texinfo)kbd")

-- (find-node "(texinfo)exampleindent") -- (find-es "texinfo" "texinfoizing-eev-article") -- http://lists.gnu.org/archive/html/bug-texinfo/2006-06/msg00049.html

-- Mnemonics: --   bendblock: begin/end block (actually "\nbody\n foo") --   qsc:       quote special chars ("/" become "@/{/}") --   ol:        one-line-ify (change newlines to spaces) bendblock = function (tag, body) return "\n..tag.."\n"..body.."\n "..tag.."\n" end qsc = function (str) return (string.gsub(str, "[{]", "%0")) end ol = function (str) return (string.gsub(str, "\n", " ")) end

-- DQ:    wrap in double quotes
-- SQ:    wrap in single quotes (rare)
-- CIND:  an entry for the Concept Index
-- LFIND: an entry for the Lisp Functions Index
-- LVIND: an entry for the Lisp Variables Index
-- ENVIND: an entry for the Environment Variables Index
-- KIND:  an entry for the Key Index
-- IT:    put in italics
-- QQ:    `\tt foo'
-- QK:    quote key
-- QFN:   quote a file name
-- QLF:   quote a lisp function name
-- QLV:   quote a lisp variable name
-- QLC:   quote a lisp constant (e.g. nil and t)
-- QLA:   quote a lisp argument name
-- QGL:   quote (the image of) a glyph
-- QMOD:  quote the name of module (e.g.: eev-compose)
-- QSTR:  quote a string (e.g.: \QSTR\n#\n)
-- QLINE: quote a line for F8/F9 (e.g.: \QLINE# Listen...)
-- QCP:   quote a compose pair (e.g.: <<)
-- QLFACE: quote a lisp face name
-- QSEXP: quote a sexp
-- QSH:   quote a shell command
-- QENV:  quote an environment variable
-- QSC:   quote the special chars "{" (low-level)
-- EX:    an example block
-- UEX:   an example block, unindented
-- LNEX:  a QQQ block with line numbers

OptNL = lpeg.S" \t" ^0 * lpeg.P"\n" ^-1

cmddef("DQ", Curly1, function (str) return "``"..str.."''" end) cmddef("SQ", Curly1, function (str) return "`"..str.."'" end) cmddef("IT", Curly1, function (str) return ""..str.."" end) cmddef("QQ", Curly1, function (str) return ""..str.."" end) cmddef("QK", Curly1, function (str) return ""..str.."" end) cmddef("QFN", Curly1, function (str) return ""..str.."" end) cmddef("QLF", Curly1, function (str) return ""..str.."" end) cmddef("QLV", Curly1, function (str) return ""..str.."" end) cmddef("QLC", Curly1, function (str) return ""..str.."" end) cmddef("QLFACE", Curly1, function (str) return ""..str.."" end) cmddef("QSH", Curly1, function (str) return ""..qsc(str).."" end) cmddef("QGL", Curly1, function (str) return ""..qsc(str).."" end) cmddef("QENV", Curly1, function (str) return ""..str.."" end) cmddef("QMOD", Curly1, function (str) return ""..str.."" end) cmddef("QSTR", Curly1, function (str) return ""..str.."" end) cmddef("QLINE", Curly1, function (str) return ""..str.."" end) cmddef("QCP",  Curly1, function (str) return ""..str.."" end) cmddef("QSEXP", Curly1, function (str) return ""..str.."" end) cmddef("QSC", Curly1, function (str) return qsc(str) end) cmddef("SEE", Curly1, function (str) return bendblock("verbatim", pb(str)) end) cmddef("SEE", Curly1, function (str) return bendblock("example", "[See:]\n"..pb(qsc(str))) end) cmddef("EX",  Curly1,function (str) return bendblock("example",psb(qsc(str))) end) cmddef("UEX", Curly1,function (str) return bendblock("verbatim",psb(str)) end) cmddef("LNEX",Curly1,function (str) return bendblock("example",psb(qsc(str))) end) cmddef("NI", lpeg.P"", function () return "" end) cmddef("CIND",  Curly1*OptNL, function (str) return " "..ol(pb(str)).."\n" end) cmddef("LFIND", Curly1*OptNL, function (str) return " "..ol(pb(str)).."\n" end) cmddef("LVIND", Curly1*OptNL, function (str) return " "..ol(pb(str)).."\n" end) cmddef("ENVIND", Curly1*OptNL, function (str) return " $"..ol(pb(str)).."\n" end) cmddef("KIND",  Curly1*OptNL, function (str) return " "..ol(pb(str)).."\n" end) cmddef("SCREENSHOT",  Curly3, function (a, b, asciiscreen) return bendblock("verbatim", psb(asciiscreen)) end)

preproctexi("eev.texi", [=[

-- (find-eevtexinode "Top") -- (find-angg "LUA/texinfo.lua" "preproc" "TOP_1")

\TOP \SEE (find-eevtexinode "sending commands")

-- «installation»  (to ".installation") \CHAPTER  installation   Installation \SEE (find-eev "INSTALL") (find-eev "README") (find-eev "eev-rctool")

\CIND  environment variables \CIND  eev block \ENVIND  EE \ENVIND  EEVTMPDIR

\CHAPTER  introduction   Introduction (See the sections)

-- «abstract»  (to ".abstract") -- (find-TH "eev-article" "abstract") \SECTION  abstract   Abstract

Interacting with programs with command-line interfaces always involves a bit of line editing, and each CLI program tends to implement independently its own minimalistic editing features. We show a way of centralizing these editing tasks by making these programs receive commands that are prepared, and sent from, Emacs.  The resulting system is a kind of Emacs- and Emacs Lisp-based \DQuniversal scripting language in which commands can be sent to both external programs and to Emacs itself either in blocks or step-by-step under very fine control from the user.

-- «three-kinds-of-interfaces»  (to ".three-kinds-of-interfaces") -- (find-TH "eev-article" "three-kinds-of-interfaces") \SECTION  three interfaces   Three kinds of interfaces

Interactive programs in a Un*x system(1) can have basically three kinds of interfaces: they can be mouse-oriented, like most programs with graphical interfaces nowadays, in which commands are given by clicking with the mouse; they can be character-oriented, like most editors and mail readers, in which most commands are single keys or short sequences of keys; and they can be line-oriented, as, for example, shells are: in a shell commands are given by editing a full line and then typing \DQenter to process that line.

It is commonplace to classify computer users in a spectrum where the \DQusers are in one extreme and the \DQprogrammers are in the other; the \DQusers tend to use only mouse-oriented and character-oriented programs, and the \DQprogrammers only character-oriented and line-oriented programs.

In this paper we will show a way to \DQautomate interactions with line-oriented programs, and, but not so well, to character-oriented programs; more precisely, it is a way to edit commands for these programs in a single central place --- Emacs --- and then send them to the programs; re-sending the same commands afterwards, with or without modifications, then becomes very easy.

This way (\DQe-scripts) can not be used to send commands to mouse-oriented programs --- at least not without introducing several new tricks. But \DQprogrammers using Un*x systems usually see most mouse-oriented programs --- except for a few that are \ITintrinsically mouse-oriented, like drawing programs --- as being just wrappers around line-oriented programs than perform the same tasks with different interfaces; and so, most mouse-oriented programs \DQdo not matter, and our method of automating interactions using e-scripts can be used to automate \DQalmost everything; hence the title of the paper.

(1): Actually we are more interested in GNU systems than in \DQreal Unix systems; the reasons will become clear in the section nnn. By the way: the term \DQUnix is Copyright (C) Bell Labs.

-- «one-thing-well»  (to ".one-thing-well") -- (find-TH "eev-article" "one-thing-well") -- (find-eevtexinode "one thing well") \SECTION  one thing well   \DQMake each program do one thing well

One of the tenets of the Unix philosophy is that each program should do one thing, and do it well; this is a good design rule for Unix programs because the system makes it easy to invoke external programs to perform tasks, and to connect programs.

Some of parts of a Unix system are more like \DQmeta-programs or \DQsub-programs than like self-contained programs that do some clearly useful task by themselves. Shells, for example, are meta-programs: their main function is to allow users to invoke \DQreal programs and to connect these programs using pipes, redirections, control structures (\QQif, \QQfor, etc) and Unix \DQsignals. On the other hand, libraries are sub-programs: for example, on GNU systems there's a library called GNU readline that line-oriented programs can use to get input; if a program, say, \QQbc (a calculator) gets its input by calling \QQreadline(...) instead of using the more basic function \QQfgets(...) then its line-oriented interface will have a little more functionality: it will allow the user to do some minimal editing in the current line, and also to recall, edit and issue again some of the latest commands given.

-- «making-progs-receive-cmds»  (to ".making-progs-receive-cmds") -- (find-TH "eev-article" "making-progs-receive-cmds") -- (find-eevtexinode "making progs receive cmds") \SECTION  making progs receive cmds   Making programs receive commands \SEE (find-eev "eev.el") (find-eev "eev-mini.el" "find-fline") (find-eev "INSTALL") (find-eev "eev-rctool")

\CINDtemporary script file \CINDee \CIND.bashrc \CIND.zshrc \ENVINDEE \ENVINDEEVTMPDIR

Many line-oriented programs allow \DQscripting, which means executing commands from a file. For example, in most shells we can say \QQsource ~/ee.sh, and the shell will then execute the commands in the file \QQ~/ee.sh. There are other ways of executing commands from a file --- like \QQsh ~/ee.sh --- but the one with \QQsource is the one that we'll be more interested in, because it is closer to running the commands in \QQ~/ee.sh one by one by hand: for example, with \QQsource ~/ee.sh the commands that change parameters of the shell --- like the current directory and the environment variables --- will work in the obvious way, while with \QQsh ~/ee.sh they would only change the parameters of a temporary sub-shell; the current directory and the environment variables of the present shell would be \DQprotected.

So, it is possible to prepare commands for a shell (or for scriptable line-oriented programs; for arbitrary line-oriented programs see the section nnn) in several ways: by typing them at the shell's interface --- and if the shell uses readline its interface can be reasonably friendly --- or, alternatively, by using a text editor to edit a file, say, \QQ~/ee.sh, and by then \DQexecuting that file with \QQsource ~/ee.sh. \QQsource ~/ee.sh is a lot of keystrokes, but that can be shortened if we can define a shell function: by putting

\EX function ee ()  source ~/ee.sh;

\NI in the shell's initialization file (\QQ~/.bashrc, \QQ~/.zshrc, ...) we can reduce \QQsource ~/ee.sh to just \QQee: \QKe, \QKe, \QKenter --- three keystrokes.

We just saw how a shell --- or, by the way, any line-oriented program in which we can define an \QQee function like we did for the shell --- can receive commands prepared in an external editor and stored in a certain file; let's refer to that file, \QQ~/ee.sh, as a \ITtemporary script file. Now it remains to see how an external text editor can \DQsend commands to the shell, i.e., how to make the editor save some commands in a temporary script file in a convenient way, that is, without using too many keystrokes...

-- «sending-commands»  (to ".sending-commands") -- (find-TH "eev-article" "sending-commands") \SECTION  sending commands   Sending Commands

\CIND  Lisp \LFIND  eev \KIND  M-x eev \CIND  mark \CIND  verbose mode

GNU Emacs, \DQthe extensible, self-documenting text-editor ([Stallman79]), does at least two things very well: one is to edit text, and so it can be used to edit temporary scripts, and thus to send commands to shells and to line-oriented programs with \QQee functions; and the other one is to run Lisp. Lisp is a powerful programming language, and (at least in principle!) any action or series of actions can be expressed as a program in Lisp; the first thing that we want to do is a way to mark a region of a text and \DQsend it as commands to a shell, by saving it in a temporary script file. We implement that in two ways:

\LNEX
1: (defun ee (s e)
2:   "Save the region in a temporary script"
3:   (interactive "r")
4:   (write-region s e "~/ee.sh"))
5:
6: (defun eev (s e)
7:   "Like `ee', but the script executes in verbose mode"
8:   (interactive "r")
9:   (write-region
10:    (concat "set -v\n" (buffer-substring s e)
11:            "\nset+v")
12:    nil "~/ee.sh"))

\QQee (the name stands for something like \SQemacs-execute) just saves the currently-marked region of text to \QQ~/ee.sh; \QQeev (for something like \SQemacs-execute-verbose) does the same but adding to the beginning of the temporary script a command to put the shell in \DQverbose mode, where each command is displayed before being executed, and also adding at the end an command to leave verbose mode.

We can now use \QQee and \QQeev to send a block of commands to a shell: just select a region and then run \QQee or \QQeev. More precisely: mark a region, that is, put the cursor at one of the extremities of the region, then type \QKC-SPC to set Emacs's \DQmark to that position, then go to other extremity of the region and type \QKM-x eev (\QKC-SPC and \QKM-x are Emacs's notations for Control-Space and Alt-x, a.k.a. \DQMeta-x). After doing that, go to a shell and make it \DQreceive these commands, by typing \QQee.

-- «hyperlinks»  (to ".hyperlinks") -- (find-TH "eev-article" "hyperlinks") \SECTION  hyperlinks   Hyperlinks

\SEE (find-eev "eev.el"      "find-fline") (find-eev "eev-mini.el" "find-fline")

\LFIND find-file \LFIND find-fline \LFIND find-node \LFIND ee-goto-position

When we are using a system like *NIX, in a part of the time we are using programs with which we are perfectly familiar, and in the rest of the time we are using things that we don't understand completely and that make us have to access the documentation from time to time. In a GNU system the documentation is all on-line, and the steps needed to access any piece of documentation can be automated. We can use Emacs Lisp \DQone-liners to create \DQhyperlinks to files:

\LNEX A: (info "(emacs)Lisp Eval") B: (find-file "~/usrc/busybox-1.00/shell/ash.c") C: (find-file "/usr/share/emacs/21.4/lisp/info.el")

\NI These expressions, when executed --- which is done by placing the cursor after them and then typing \QKC-x C-e, or, equivalently, \QKM-x eval-last-sexp --- will (A) open a page of Emacs manual (the manual is a set of files in \DQInfo format), (B) open the source file \QFNshell/ash.c of a program called busybox, and (C) open the file \QFNinfo.el from the Emacs sources, respectively. As some of these files and pages can be very big, these hyperlinks are not yet very satisfactory: we want ways to not only open these files and pages but also to \DQpoint to specific positions, i.e., to make the cursor go to these positions automatically. We can do that by defining some new hyperlink functions, that are invoked like this:

\LNEX A': (find-node "(emacs)Lisp Eval" "C-x C-e") B': (find-fline "~/usrc/busybox-1.00/shell/ash.c" "void\nevalpipe") C': (find-fline "/usr/share/emacs/21.4/lisp/info.el" "defun info")

The convention is that these \DQextended hyperlink functions have names like \QLFfind-xxxnode, \QLFfind-xxxfile, or \QLFfind-xxxyyy; as the name \QLFfind-file was already taken by a standard Emacs function we had to use \QLFfind-fline for ours.

Here are the definitions of \QLFfind-node and \QLFfind-fline:

\LNEX
14: (defun ee-goto-position (&optional pos-spec)
15:   "If POS-SPEC is a string search for its first
16:    occurrence in the file; if it is a number go to the
17:    POS-SPECth line; if it is nil, don't move."
18:   (cond ((null pos-spec))
19:         ((numberp pos-spec)
20:          (goto-char (point-min))
21:          (forward-line (1- pos-spec)))
22:         ((stringp pos-spec)
23:          (goto-char (point-min))
24:          (search-forward pos-spec))
25:         (t (error "Invalid pos-spec: %S" pos-spec))))
26:
27: (defun find-fline (fname &optional pos-spec)
28:   "Like (find-file FNAME), but accepts a POS-SPEC"
29:   (find-file fname)
20:   (ee-goto-position pos-spec))
31:
32: (defun find-node (node &optional pos-spec)
33:   "Like (info NODE), but accepts a POS-SPEC"
34:   (info node)
35:   (ee-goto-position pos-spec)))

Now consider what happens when we send to a shell a sequence of commands like this one:

\EX # (find-node "(gawk)Fields") seq 4 9 | gawk 'print $1, $1*$1'

\NI the shell ignores the first line because of the \QQ#, that makes the shell treat that line as a comment; but when we are editing that in Emacs we can execute the `\QSEXP(find-node ...) with \QKC-x C-e. Hyperlinks can be mixed with shell code --- they just need to be marked as comments.

Note: the actual definitions of \QLFeev, \QLFee-goto-position, \QLFfind-fline and \QLFfind-node in eev's source code are a bit more complex than the code in the listings above (lines 6--12 in the previous section and 14--35 in the current section). In all the (few) occasions in this paper where we will present the source code of eev's functions what will be shown are versions that implement only the \DQessence of those functions, stripped down of all extra functionality. The point that we wanted to stress with those listings is how natural it is to use Emacs in a certain way, as an editor for commands for external programs, and with these plain-text hyperlinks that can be put almost anywhere: the essence of that idea can be implemented in 30 lines of Lisp and one or two lines of shell code.

(See also: the section about [_ e-scripts]).

-- «shorter-hyperlinks»  (to ".shorter-hyperlinks") -- (find-TH "eev-article" "shorter-hyperlinks") \SECTION  shorter hyperlinks   Shorter Hyperlinks

\SEE (find-eev "eev.el"      "code-c-d") (find-eev "eev-mini.el" "code-c-d")

The hyperlinks in lines \QQA'', \QQB'' and \QQC'', below,

\LNEX A'': (find-enode "Lisp Eval" "C-x C-e") B'': (find-busyboxfile "shell/ash.c" "void\nevalpipe") C'': (find-efile "info.el" "defun info")

\NI are equivalent to the ones labeled \QQA', \QQB', \QQC' in Section 5, but are a bit shorter, and they hide details like Emacs's path and the version of BusyBox; if we switch to newer versions of Emacs and BusyBox we only need to change the definitions of \QLFfind-busyboxfile and \QLFfind-efile to update the hyperlinks. Usually not many things change from one version of a package to another, so most hyperlinks continue to work after the update.

Eev defines a function called \QLFcode-c-d that makes defining functions like \QLFfind-enode, \QLFfind-busyboxfile and \QLFfind-efile much easier:

\EX (code-c-d "busybox" "~/usrc/busybox-1.00/") (code-c-d "e" "/usr/share/emacs/21.4/lisp/" "emacs")

The arguments for \QLFcode-c-d are (1) a \DQcode (the \DQxxx in a \QLFfind-xxxfile), (2) a directory, and optionally (3) the name of a manual in Info format. The definition of \QLFcode-c-d is not very interesting, so we won't show it here.

-- «forward-and-back»  (to ".forward-and-back") -- (find-TH "eev-article" "forward-and-back") \SECTION  forward and back   Keys for following hyperlinks and for going back

\KIND  M-k \KIND  M-K \KIND  C-x C-e \KIND  M-e \KIND  M-E \CIND  following hyperlinks \CIND  returning from hyperlinks \CIND  hyperlinks, following \CIND  hyperlinks, returning from \CIND  prefix arguments

Lisp hyperlinks usually extend from a certain position in a line --- usually after a comment sign --- to the end of the line, like this:

\EX # (find-bashnode "Comments" "`#'")

;; (find-elnode  "Comments" "`;'") ;; (find-elnode  "Comment Tips" "`;;'")

The obvious way to follow a hyperlinks like the above is with \QKC-e C-x C-e (\QLFmove-end-of-line, then \QLFeval-last-sexp), but this is so common an operation that eev implements a shortcut for it: when eev-mode is active the effect of typing \QKM-e (\QLFeek-eval-sexp-eol) is roughly the same as \QKC-e C-x C-e.

The main difference between \QKM-e and \QKC-e C-x C-e is how they behave when called with numeric \DQprefix arguments: for example, \QKM-0 M-e highlights temporarily the Lisp expression instead of executing it and \QKM-4 M-e executes it with some debugging flags turned on, while \QKC-x C-e when called with any prefix argument inserts the result of the expression at the cursor instead of showing it at the echo area.

The key \QKM-E (\QLFeek-eval-last-sexp) is like \QKM-e, but it doesn't move to the end of line; it executes the sexp ending just before point with the same behavior on prefix arguments as \QKM-e.

So, \QKM-e and \QKM-E and keys for following hyperlinks. Usually following a hyperlink creates a new buffer, and we can \DQgo back by deleting this new buffer or by just returning to the previous buffer. Eev-mode defines two keys for that: \QKM-k (\QLFee-kill-this-buffer) and \QKM-K (\QLFbury-buffer).

-- (Rewrite this; mention \QKM-k, \QKM-K, \QLFto and the (disabled) -- stubs to implement a `back' command) -- -- It is so common to have Lisp hyperlinks that extend from some position -- in a line --- usually after a comment sign --- to the end of the line -- that eev implements a special key for executing these hyperlinks: the -- effect of typing \QKM-e (when eev is installed and \DQeev mode is -- on) is roughly the same of first going to the end of the line and then -- typing \QKC-x C-e; that is, M-e does the same as the key sequence -- \QKC-e C-x C-e(1). -- -- (There are many other kinds of hyperlinks. Examples?) -- -- (1) The main difference between \QKM-e and \QKC-e C-x C-e is how -- they behave when called with numeric \DQprefix arguments: for -- example, \QKM-0 M-e highlights temporarily the Lisp expression -- instead of executing it and \QKM-4 M-e executes it with some -- debugging flags turned on, while \QKC-x C-e when called with any -- prefix argument inserts the result of the expression at the cursor -- instead of just showing it at the echo area.

-- «dangerous-hyperlinks»  (to ".dangerous-hyperlinks") -- (find-TH "eev-article" "dangerous-hyperlinks") \SECTION  dangerous hyperlinks   Dangerous hyperlinks

\SEE (find-eev "eev.el" "find-sh") (find-eev "eev-mini.el" "find-sh")

\CIND  Forth

Note that these \DQhyperlinks can do very dangerous things. If we start to execute blindly every Lisp expression we see just because it can do something interesting or take us to an interesting place then we can end up running something like:

\EX (shell-c_ommand "rm -Rf ~")

\NI which destroy all files in our home directory; not a good idea. Hyperlinks ought to be safer than that...

The modern approach to safety in hyperlinks --- the one found in web browsers, for example --- is that following a hyperlink can execute only a few kinds of actions, all known to be safe; the \DQtarget of a hyperlink is something of the form \QQhttp://..., \QQftp://..., \QQfile://..., \QQinfo://..., \QQmailto:... or at worst like \QQjavascript:...; none of these kinds of actions can even erase our files. That approach limits a lot what hyperlinks can do, but makes it harmless to hide the hyperlink action and display only some descriptive text.

Eev's approach is the opposite of that. I wrote the first functions of eev in my first weeks after installing GNU/Linux in my home machine and starting using GNU Emacs, in 1994; before that I was using mostly Forth (on MS-DOS), and I hadn't had a lot of exposure to *NIX systems by then --- in particular, I had tried to understand *NIX's notions of user IDs and file ownerships and permissions, and I felt that they were a thick layer of complexity that I wasn't being able to get through.

Forth's attitude is more like ``the user knows what he's doing''; the system is kept very simple, so that understanding all the consequences of an action is not very hard. If the user wants to change a byte in a critical memory position and crash the machine he can do that, and partly because of that simplicity bringing the machine up again didn't use to take more than one minute (in the good old days, of course). Forth people developed good backup strategies to cope with the insecurities, and --- as strange as that might sound nowadays, where all machines are connected and multi-user and crackers abound --- using the system in the Forth way was productive and fun.

*NIX systems are not like Forth, but when I started using them I was accustomed to this idea of achieving simplicity through the lack of safeguards, and eev reflects that. The only thing that keeps eev's hyperlinks reasonably safe is \DQtransparency: the code that a hyperlink executes is so visible that it is hard to mistake a dangerous Lisp expression for a \DQreal hyperlink. Also, all the safe hyperlink functions implemented by eev start with \QLFfind-, and all the \QLFfind- functions in eev are safe, except for those with names like \QLFfind-xxxsh and \QLFfind-xxxsh0: for example,

\EX (find-sh "wget --help" "recursive download")

\NI executes \QSHwget --help, puts the output of that in an Emacs buffer and then jumps to the first occurrence of the string \QQrecursive download there; other \QLFfind-xxxsh functions are variations on that that execute some extra shell commands before executing the first argument --- typically either switching to another directory or loading an initialization file, like \QFN~/.bashrc or \QFN~/.zshrc. The \QFNfind-xxxsh0 functions are similar to their \QFNfind-xxxsh counterparts, but instead of creating a buffer with their output they just show it at Emacs's echo area and they use only the first argument and ignore the others (the pos-spec).

-- «generating-hyperlinks»  (to ".generating-hyperlinks") -- (find-TH "eev-article" "generating-hyperlinks") \SECTION  generating hyperlinks   Generating Hyperlinks

\SEE (find-eev "eev-insert.el") (find-eevfile "article/ss-m-h.png") (find-eevex "screenshots.e" "fisl-screenshots-M-h") (find-eev "eev-mini-steps.el" "eek")

\CIND  eek

Do we need to remember the names of all hyperlinks functions, like \QLFfind-fline and \QLFfind-node? Do we need to type the code for each hyperlink in full by hand? The answers are \DQno and \DQno.

Eev implements several functions that create temporary buffers containing hyperlinks, that can then be cut and pasted to other buffers. For example, \QKM-h M-f creates links about an Emacs Lisp function: typing \QKM-h M-f displays a prompt in a minibuffer asking for the name of an Elisp function; if we type, say, \QLFfind-file there (note: name completion with the TAB key works in that prompt) we get a buffer like the one in figure 1.

\SCREENSHOT
_________________________________________________________
|# (find-efunction-links 'find-file)                      |
|                                                         |
|# (where-is 'find-file)                                  |
|# (describe-function 'find-file)                         |
|# (find-efunctiondescr 'find-file)                       |
|# (find-efunction 'find-file)                            |
|# (find-efunctionpp 'find-file)                          |
|# (find-efunctiond 'find-file)                           |
|# (find-eCfunction 'find-file)                           |
|# (find-estring (documentation 'find-file))              |
|# (find-estring (documentation 'find-file t))            |
|                                                         |
|# (Info-goto-emacs-command-node 'find-file)              |
|# (find-enode "Command Index" "* find-file:")            |
|# (find-elnode "Index" "* find-file:")                   |
|                                                         |
|                                                         |
|                                                         |
|--:**  *Elisp hyperlinks*   All L18    (Fundamental)-----|
|_________________________________________________________|

Figure 1: the result of typing M-h M-f find-file

The first line of that buffer is a hyperlink to that dynamically-generated page of hyperlinks. Its function --- \QLFfind-efunction-links --- has a long name that is hard to remember, but there's a shorter link that will do the same job:

\EX (eek "M-h M-f find-file")

The argument to \QLFeek is a string describing a sequence of keys in a certain verbose format, and the effect of running, say, \QSEXP(eek "M-h M-f find-file") is the same as of typing \QKM-h M-f find-file.

(\QKM-h is a prefix; \QSEXP(eek "M-h C-h") shows all the sequences with the same prefix.)

(Exceptions: \QKM-h M-c, \QKM-h M-2, \QKM-h M-y. Show examples of how to edit hyperlinks with \QKM-h M-2 and \QKM-h M-y.)

(Mention hyperlinks about a key sequence? \QSEXP(eek "M-h M-k C-x C-f"))

(Mention hyperlinks about a Debian package? \QSEXP(eek "M-h M-d bash"))

-- «returning»  (to ".returning") -- (find-TH "eev-article" "returning") \SECTION  returning   Returning from hyperlinks

((Mention M-k to kill the current buffer, and how Emacs asks for confirmation when it's a file and it's modified))

((Mention M-K for burying the current buffer))

((Mention what to do in the cases where a hyperlink points to the current buffer (section 16); there used to be an \QLFee-back function bound to \QKM-B, but to reactivate it I would have to add back some ugly code to `to'... (by the way, that included Rubikitch's contributions)))

((Web browsers have a way to \DQreturn from hyperlinks: the \DQback button... In eev we have many kinds of hyperlinks, including some that are unsafe and irreversible, but we have a few kinds of \DQbacks that work... 1) if the hyperlink opened a new file or buffer, then to kill the file or buffer, use \QKM-k (an eev binding for \QLFkill-this-buffer; note that it asks for a confirmation when the buffer is associated to a file and it has been modified --- or we can use bury-buffer; \QKM-K is an eev binding for \QLFbury-buffer. ((explain how emacs keeps a list of buffers?)) Note: if the buffer contains, say, a manpage, or an html page rendered by w3m, which take a significant time to generate, then \QKM-K is better is than \QKM-k. 2) if the hyperlink was a \QLFto then it jumped to another position in the same file... it is possible to keep a list of previous positions in a buffer and to create an \QLFee-back function (suggestion: bind it to \QKM-B but I haver never been satisfied with the implementations that I did so we're only keeping a hook in \QLFto for a function that saves the current position before the jump))

((dto recommended \QLFwinner-undo))

-- «local-copies»  (to ".local-copies") -- (find-TH "eev-article" "local-copies") \SECTION  local copies   Local copies of files from the internet

\SEE (find-eev "rcfiles/.bashrc-psne") (find-eev "rcfiles/.zshrc-psne") (find-eev "eev-rctool" "new_block_bashrc") http://lists.gnu.org/archive/html/eev/2005-06/msg00000.html http://article.gmane.org/gmane.emacs.eev.devel/9

\CIND  psne \ENVIND  S

Emacs knows how to fetch files from the internet, but for most purposes it is better to use local copies. Suppose that the environment variable \QENV$S is set to \QFN~/snarf/; then running this on a shell

\EX mkdir -p $S/http/www.gnu.org/software/emacs/ cd       $S/http/www.gnu.org/software/emacs/ wget http://www.gnu.org/software/emacs/emacs-paper.html

# (find-fline "$S/http/www.gnu.org/software/emacs/emacs-paper.html") # (find-w3m   "$S/http/www.gnu.org/software/emacs/emacs-paper.html")

\NI creates a local copy of \QFNemacs-paper.html inside \QFN~/snarf/http/. The two last lines are hyperlinks to the local copy; \QLFfind-w3m opens it \DQas HTML, using a web browser called w3m that can be run either in standalone mode or inside Emacs; \QLFfind-w3m uses w3m's Emacs interface, and it accepts extra arguments, which are treated as a pos-spec-list.

Instead of running the \QSHmkdir, \QSHcd and \QSHwget lines above we can run a single command that does everything:

\EX psne http://www.gnu.org/software/emacs/emacs-paper.html

\NI which also adds a line with that URL to a log file (usually \QFN~/.psne.log). It is more convenient to have a \QSHpsne that changes the current directory of the shell than one that doesn't, and for that it must be defined as a shell function.

-- «rcfiles»  (to ".rcfiles") -- (find-TH "eev-article" "rcfiles")

\SECTION  rcfiles   rcfiles

\SEE
(find-eev "INSTALL")
(find-eev "eev-rctool")
(find-eevsh "./eev-rctool notes")
(find-eev     "eev-rctool" "notes")
(find-eev     "eev-rctool"     "new_block_emacs")
(find-eev     "eev-rctool"     "new_block_emacs")
(find-eev     "eev-rctool" "current_block_gdbinit")

Eev comes with an installer script, called \QSHeev-rctool, that can help in adding the definitions for eev (like the \QSHfunction ee ()  source ~/ee.sh; of section 3) to initialization files like \QFN~/.bashrc (such initialization files are termed \DQrcfiles). Eev-rctool does \ITnot add by default the definitions for \QSHpsne and for \QENV$S to rcfiles; however, it adds commented-out lines with instructions, which might be something like:

\EX # To define $S and psne uncomment this: #   . $EEVTMPDIR/psne.sh # (find-eevtmpfile "psne.sh")

-- «glyphs»  (to ".glyphs") -- (find-TH "eev-article" "glyphs") \SECTION  glyphs   Glyphs

\SEE (find-eev "eev-glyphs.el") (find-eev "eev-math-glyphs.el") (find-eev "eev-mini.el" nil "eev-glyph-face-red") (find-eev "eev-sshot.el") http://angg.twu.net/flipbooks/ee-glyph.html

Emacs allows redefining how characters are displayed, and one of the modules of eev --- eev-glyphs --- uses that to make some characters stand out. Character 15, for example, is displayed on the screen by default as \QK^O (two characters, suggesting \DQcontrol-O), sometimes in a different color from normal text(3).]

Eev changes the appearance of char 15 to make it be displayed as a red star. Here is how: Emacs has some structures called \DQfaces that store font and color information, and \QLFACEeeglyphs-face-red is a face that says \DQuse the default font and the default background color, but a red foreground; eev's initialization code runs this,

\EX (eev-set-glyph 15 ?* 'eev-glyph-face-red)

\NI which sets the representation of char 15 to the \DQglyph made of a star in the face \QLFACEeeglyphs-face-red.

For this article, as red doesn't print well in black and white, we used this instead:

\EX (eev-set-glyph 15 342434)

\NI this made occurrences of char 15 appear as the character 342434, \QGL (note that this is outside of the ascii range), using the default face, i.e., the default font and color.

Eev also sets a few other glyphs with non-standard faces. The most important of those are \QGL« and \QGL», which are set to appear in green against the default background, with:

\EX (eev-set-glyph 171 171 'eev-glyph-face-green) (eev-set-glyph 187 187 'eev-glyph-face-green)

There's a technical point to be raised here. Emacs can use several \DQencodings for files and buffers, and \QGL« and \QGL» only have character codes 171 and 187 in a few cases, mainly in the \SQraw-text encoding and in \DQunibyte buffers; in most other encodings they have other char codes, usually above 255, and when they have these other codes Emacs considers that they are other characters for which no special glyphs were set and shows them in the default face. This visual distinction between the below-255 \QGL« and \QGL» and the other \QGL« and \QGL»s is deliberate --- it helps preventing some subtle bugs involving the anchor functions of section [anchors].

(3). Determined by the \DQface \QLFACEescape-glyph-face, introduced in GNU Emacs in late 2004.

-- «compose-pairs»  (to ".compose-pairs") -- (find-TH "eev-article" "compose-pairs") \SECTION  compose pairs   Compose Pairs

\SEE (find-eev "eev-compose.el")

To insert a \QGL in a text we type \QKC-q C-o --- \QKC-q \DQquotes the next key that Emacs receives, and \QKC-q C-o inserts a \DQliteral C-o, which is a char 15. Typing \QGL« and \QGL»s --- and other non-standard glyphs, if we decide to define our own --- involves using another module of eev: \QMODeev-compose.

Eev-compose defines a few variables that hold tables of \DQcompose pairs, which map pairs of characters that are easy to type into other, weirder characters; for example, \QLVeev-composes-otheriso says that the pair \QCP<< is mapped to \QGL« and that \QCP>> is mapped to \QGL», among others. When we are in \DQeev mode the prefix \QKM-, can be used to perform the translation: typing \QKM-, < < enters \QGL«, and typing \QKM-, > > enters \QGL».

The variable \QLVeev-composes-accents holds mappings for accented chars, like \QCP'a to \QGLá and \QCPcc to \QGLç; \QLVeev-composes-otheriso takes care of the other mappings that still concern characters found in the ISO8859-1 character set, like \QGL« and \QGL» as above, \QCP_a to \QGLª, \QCPxx to \QGL×, and a few others; \QLVeev-composes-globalmath and \QLVeev-composes-localmath are initially empty and are meant to be used for used-defined glyphs. The suffix \QLVmath in their names is a relic: Emacs implements its own ways to enter special characters, which support several languages and character encodings, but their code is quite complex and they are difficult to extend; the code that implements eev's \QKM-,, on the other hand, takes about just 10 lines of Lisp (excluding the tables of compose pairs) and it is trivial to understand and to change its tables of pairs. \QKM-, was created originally to enter special glyphs for editing mathematical texts in TeX, but it turned out to be a convenient hack, and it stuck.

-- «delimited-regions»  (to ".delimited-regions") -- (find-TH "eev-article" "delimited-regions") \SECTION  delimited regions   Delimited regions

\SEE (find-eev "eev-bounded.el") (find-eev "eev-mini.el" "eeb-default") (find-eev "doc/shot-f3.png") (find-eev "anim/gdb.anim")

\LFIND  eev-bounded \LFIND  eelatex \LFIND  eelatex-bounded \LFIND  eeb-define \LFIND  ee-once \LVIND  ee-delimiter-hash \LVIND  ee-delimiter-percent \LVIND  eeb-defaults \CIND  highlighting \CIND  flashing

Sometimes it happens that we need to run a certain (long) series of commands over and over again, maybe with some changes from one run to the next; then having to mark the block all the time becomes a hassle.

One alternative to that is using a variaton on \QKM-x eev: \QKM-x eev-bounded. It saves the region around the cursor up to certain delimiters instead of saving what's between Emacs's \DQpoint and \DQmark.

The original definition of eev-bounded was something like this:

\EX (defun eev-bounded () (interactive) (eev (ee-search-backwards "\n#\n") (ee-search-forward   "\n#\n")))

\NI the call to \QLFee-search-backwards searches for the first occurrence of the string \QSTR\n#\n (newline, hash sign, control-O, newline) before the cursor and returns the position after the \QSTR\n#\n, without moving the cursor; the call to \QLFee-search-forward does something similar with a forward search. As the arguments to \QLFeev indicate the extremities of the region to be saved into the temporary script, this saves the region between the first \QSTR\n#\n backwards from the cursor to the first \QSTR\n#\n after the cursor.

The actual definition of \QLFeev-bounded includes some extra code to highlight temporarily the region that was used; see [Figure F3]. Normally the highlighting lasts for less than one second, but here we have set its duration to several seconds to produce a more interesting screenshot.

\SCREENSHOT
____________________ emacs _______________________
|                                                _________ xterm __________
|#                                             |/home/edrx(edrx)# ee      |
|# Global variables                             |# Global variables        |
|lua50 -e '                                     |lua50 -e '                |
|  print(print)                                 |  print(print)            |
|  print(_G["print"])                           |  print(_G["print"])      |
|  print(_G.print)                              |  print(_G.print)         |
|  print(_G)                                    |  print(_G)               |
|  print(_G._G)                                 |  print(_G._G)            |
|'                                              |'                         |
|#                                             |function: 0x804dfc0       |
|# Capture of local variables                   |function: 0x804dfc0       |
|lua50 -e '                                     |function: 0x804dfc0       |
|  foo = function ()                            |table: 0x804d420          |
|    local storage                              |table: 0x804d420          |
|    return                                     |/home/edrx(edrx)#         |
|      (function () return storage end),        |__________________________|
|      (function (x) storage = x; return x end)              |
|  end                                                       |
|  get1, set1 = foo()                                        |
|  get2, set2 = foo()               -- Output:               |
|  print(set1(22), get1())          -- 22 22                 |
|  print(set2(33), get1(), get2())  -- 33 22 33              |
|'                                                           |
|#                                                          |
|                                                            |
|-:--  lua5.e   91% L325    (Fundamental)--------------------|
|____________________________________________________________|

Figure 2: sending a delimited block with F3 (find-fline "ss-lua.png") (find-eevex "screenshots.e" "fisl-screenshots")

Eev binds the key \QKF3 to the function \QLFeeb-default, which runs the current \DQdefault bounded function (which is set initially to \QLFeev, \ITnot \QLFeev-bounded) on the region between the current default delimiters, using the current default \DQhighlight-spec; so, instead of typing \QKM-x eev-bounded inside the region to save it, we can just type \QKF3.

All these defaults values come from a single list, which is stored in the variable \QLVeeb-defaults. The real definition of \QLVeev-bounded is something like:

\EX (setq eev-bounded '(eev ee-delimiter-hash nil t t))

(defun eev-bounded () (interactive) (setq eeb-defaults eev-bounded) (eeb-default))

Note that in Emacs Lisp (and in most other Lisps) each symbol has a value as a variable that is independent from its \DQvalue as a function: actually a symbol is a structure containg a name, a \DQvalue cell, a \DQfunction cell and a few other fields. Our definition of \QLFeev-bounded, above, includes both a definition of the function \QLFeev-bounded and a value for the variable \QLVeev-bounded.

Eev has an auxiliary function for defining these \DQbounded functions; running

\EX (eeb-define 'eev-bounded 'eev 'ee-delimiter-hash nil t t)

\NI has the same effect as doing the \QLFsetq and the \QLFdefun above.

As for the meaning of the entries of the list \QLVeeb-defaults, the first one (\QLFeev) says which function to run; the second one (\QLVee-delimiter-hash) says which initial delimiter to use --- in this case it is a symbol instead of a string, and so \QLFeeb-default takes the value of the variable \QLVee-delimiter-hash; the third one (nil) is like the second one, but for the final delimiter, and when it is nil \QLFeeb-default considers that the final delimiter is equal to the initial delimiter; the fourth entry (\QLCt) means to use the standard highlight-spec, and the fifth one (\QLCt, again) tells \QLFeeb-default to make an adjustment to the highlighted region for purely aestethical reasons: the saved region does not include the initial \QSTR\n in the final delimiter, \QSTR\n#\n, but the highlighting looks nicer if it is included; without it the last highlighted line in Figure 2 would have only its first character --- an apostrophe --- highlighted.

Eev also implements other of these \DQbounded functions. For example, running \QKM-x eelatex on a region saves it in a temporary LaTeX file, and also saves into the temporary script file the commands to process it with LaTeX; \QLFeelatex-bounded is defined by

\EX (eeb-define 'eelatex-bounded 'eelatex 'ee-delimiter-percent nil t t)

\NI where the variable \QLVee-delimiter-percent holds the string \QSTR\n%\n; comments in LaTeX start with percent signs, not hash signs, and it is convenient to use delimiters that are treated as comments.

((The block below ... tricky ... blah. How to typeset \QGL in LaTeX. Running \QLFeelatex-bounded changed the defaults stored in \QLVeeb-defaults, but \QLFee-once blah doesn't.))

\UEX % % (eelatex-bounded) % (ee-once (eelatex-bounded)) \def\myttbox#1% \setbox0=\hbox\texttta% \hbox to \wd0\hss#1\hss%

\catcode`=13 \def\myttbox$\bullet$ \beginverbatim abcdefg dfg \endverbatim %

...for example \QLFeelatex, that saves the region (plus certain standard header and footer lines) to a \DQtemporary LaTeX file and saves into the temporary script file the commands to make \QSHee run LaTeX on that and display the result. The block below is an example of (...)

...The block below shows a typical application of \QLFeev-bounded:

\EX # (find-es "lua5" "install-5.0.2") # (find-es "lua5" "install-5.0.2" "Edrx's changes") # (code-c-d "lua5" "/tmp/usrc/lua-5.0.2/") # (find-lua5file "INSTALL") # (find-lua5file "config" "support for dynamic loading") # (find-lua5file "config") # (find-lua5file "") # rm   -Rv ~/usrc/lua-5.0.2/ mkdir -p ~/usrc/lua-5.0.2/ tar   -C ~/usrc/ \ -xvzf $S/http/www.lua.org/ftp/lua-5.0.2.tar.gz cd       ~/usrc/lua-5.0.2/ cat >> config <<'---' LOADLIB= -DUSE_DLOPEN=1 DLLIB= -ldl MYLDFLAGS= -Wl,-E EXTRA_LIBS= -lm -ldl --- make test  2>&1 | tee omt ./bin/lua -e 'print(loadlib)' #

\NI it unpacks a program (the interpreter for Lua), changes its default configuration slightly, then compiles and tests it.

((Comment about the size: the above code is \DQtoo small for being a script, and the hyperlinks are important))

((gdb (here-documents, gcc, ee-once)))

((alternative: here-documents, gcc, gdb, screenshot(s) for gdb))

-- «channels»  (to ".channels") -- (find-TH "eev-article" "channels") \SECTION  communication channels   Communication channels

\SEE (find-eev "eev-steps.el") (find-eev "eev-mini-steps.el") (find-eev "eegchannel") (find-eev "anim/channels.anim")

\KIND  F9 \LFIND  eechannel \LFIND  eechannel-xterm \LFIND  eexterm

The way that we saw to send commands to a shell is in two steps: first we use \QKM-x eev in Emacs to \DQsend a block of commands, and then we run \QSHee at the shell to make it \DQreceive these commands. But there is also a way to create shells that \DQlisten not only to the keyboard for their input, but also to certain \DQcommunication channels; by making Emacs send commands through these communication channels we can skip the step of going to the shell and typing \QSHee --- the commands are received immediately.

\SCREENSHOT
_________emacs____________
|                                    |  ___________channel A______________
| (eechannel-xterm "A") ;; create   | |/tmp(edrx)# # Send things to port |
| (eechannel-xterm "B") ;; create   | | 1234                             |
|# Listen on port 1234               | |/tmp(edrx)#                      |
|netcat -l -p 1234                   | |>   echo hi                       |
|                                   | |>   sleep 1                       |
| (eechannel "A") ;; change target  | |>   echo bye                      |
|# Send things to port 1234          | |>   sleep 1                       |
|                                   | |>  | netcat -q 0 localhost 1234  |
|  echo hi                           | |/tmp(edrx)#                       |
|  sleep 1                           | |/tmp(edrx)#                       |
|  echo bye                          | |__________________________________|
|  sleep 1                           |  ___________channel B______________
| | netcat -q 0 localhost 1234      | |/tmp(edrx)# # Listen on port 1234 |
|                                    | |/tmp(edrx)# netcat -l -p 1234     |
|-:--  screenshots.e   95% L409   (Fu| |hi                                |
|_Wrote /home/edrx/.eev/eeg.A.str____| |bye                               |
|/tmp(edrx)#                       |
|                                  |
|__________________________________|
Figure 3: sending commands to two xterms using F9
(find-eevex "screenshots.e" "fisl-screenshots")
(find-eevfile "article/ss-f9.png")

The screenshot at [Figure 3] shows this at work. The user has started with the cursor at the second line from the top of the screen in the Emacs window and then has typed \QKF9 several times. Eev binds \QKF9 to a command that operates on the current line and then moves down to the next line; if the current line starts with \QGL then what comes after the \QGL is considered as Lisp code and executed immediately, and the current line doesn't start with \QGL then its contents are sent through the default communication channel, or though a dummy communication channel if no default was set.]

The first \QKF9 executed \QSEXP(eechannel-xterm "A"), which created an xterm with title \DQchannel A, running a shell listening on the communication channel \DQA, and set the default channel to A; the second \QKF9 created another xterm, now listening to channel B, and set the default channel to B.

The next two \QKF9s sent each one one line to channel B. The first line was a shell comment (\QLINE# Listen...); the second one started the program \QSHnetcat, with options to make \QSHnetcat \DQlisten to the internet port 1234 and dump to standard output what it receives.

The next line had just \QLINE; executing the rest of it as Lisp did nothing. The following line changed the default channel to A.]

In the following lines there is a small shell program that outputs \DQhi, then waits one second, then outputs \DQbye, then waits for another second, then finishes; due to the \QSH| netcat... its output is redirected to the internet port 1234, and so we see it appearing as the output of the netcat running on channel B, with all the expected delays: one second between \DQhi and \DQbye, and one second after \DQbye; after that last one-second delay the netcat at channel A finishes receiving input (because the program between "{" and "}" ends) and it finishes its execution, closing the port 1234; the netcat at B notices that the port was closed and finishes its execution too, and both shells return to the shell prompt.

There are also ways to send whole blocks of lines at once through communication channels; see [Section bigmodular].

-- «channels-implementation»  (to ".channels-implementation") -- (find-TH "eev-article" "channels-implementation") \SECTION  implementation of channels   The Implementation of Communication Channels

\SEE (find-eev "eev-mini-steps.el") (find-eev "eev-steps.el") (find-eev "eegchannel") (find-eev "anim/channels.anim")

Communication channels are implemented using an auxiliary script called \QSHeegchannel, which is written in Expect ([L90] and [L95]). If we start an xterm in the default way it starts a shell (say, \QFN/bin/bash) and interacts with it: the xterm sends to the shell as characters the keystrokes that it receives from the window manager and treats the characters that the shell sends back as being instructions to draw characters, numbers and symbols on the screen. But when we run \QSEXP(eechannel-xterm "A") Emacs creates an xterm that interacts with another program --- \QSHeegchannel --- instead of with a shell, and \QSHeegchannel in its turn runs a shell and interacts with it.

Eegchannel passes characters back and forth between the xterm and the shell without changing them in any way; it mostly tries to pretend that it is not there and that the xterm is communicating directly with the shell. However, when eegchannel receives a certain signal it sends to the shell a certain sequence of characters that were not sent by the xterm; it \DQfakes a sequence of keystrokes.

Let's see a concrete example. Suppose than Emacs was running with process id (\DQpid) 1000, and running \QSEXP(eechannel-xterm "A") in it made it create an xterm, which got pid 1001; that xterm ran \QSHeegchannel (pid 1002), which ran \QSH/bin/bash (pid 1003). Actually Emacs invoked xterm using this command line:

\EX xterm -n "channel A" -e eegchannel A /bin/bash

\NI and xterm invoked eegchannel with \QSHeegchannel A /bin/bash; eegchannel saw the \SQA, saved its pid (1002) to the file \QFN~/.eev/eeg.A.pid, and watched for \SQSIGUSR1 signals; every time that it (the eegchannel) receives a \SQSIGUSR1 it reads the contents of [QQ ~/.eev/eeg.A.str] and sends that as fake input to the shell that it is controlling. So, running

\EX echo 'echo $[1+2]' > ~/.eev/eeg.A.str kill -USR1 $(cat ~/.eev/eeg.A.pid)

\NI in a shell sends the string \QSTRecho $[1+2] (plus a newline) \DQthrough the channel A; what Emacs does when we type \QKF9 on a line that does not start with \QGL corresponds exactly to that.

-- «anchors»  (to ".anchors") -- (find-TH "eev-article" "anchors") -- (find-eevnode "anchors") \SECTION  anchors   Anchors

\SEE (find-eev "eev.el" "ee-goto-anchor") I need to set local vars to make the "to"s in the examples work. ;; (find-eevtexi "eev.texi.lua" "anchors") ;; (find-efunction      'ee-goto-anchor) ;; (find-efunctiondescr 'ee-goto-anchor)

\LFIND  to \LFIND  find-anchor \LFIND  find-status \LFIND  find-available \LVIND  ee-anchor-format

The function \QFNto can be used to create hyperlink to certain positions --- called \DQanchors --- in the current file. For example,

\EX
# Index:
# «.first_block»        (to "first_block")
# «.second_block»       (to "second_block")

# # «first_block»  (to ".first_block") echo blah # # «second_block»  (to ".second_block") echo blah blah #

What \QFNto does is simply to wrap its argument inside \QGL« and \QGL» characters and then jump to the first occurrence of the resulting string in the current file. In the (toy) example above, the line that starts with \QLINE# «.first_block» has a link that jumps to the line that starts with \QLINE# «first_block», which has a link that jumps back --- the anchors and \QSEXP(to ...)s act like an index for that file.

The function \QLFfind-anchor works like a \QLFto that first opens another file. For example,

\EX (find-anchor "~/.zshrc" "update-homepage")

\NI does roughly the same as:

\EX (find-fline "~/.zshrc" "«update-homepage»")

Actually \QLFfind-anchor consults a variable, \QLVee-anchor-format, to see in which strings to wrap the argument. Some functions modify \QLVee-anchor-format temporarily to obtain special effects; for example, a lot of information about the packages installed in a Debian GNU system is kept in a text file called \QFN/var/lib/dpkg/info/status; \QSEXP(find-status "emacs21") opens this file and searches for the string \QSTR\nPackage: emacs21\n there --- that string is the header for the block with information about the package \QSTRemacs21, and it tells the size of the package, description, version, whether it is installed or not, etc, in a format that is both machine-readable and human-readable.

-- «e-scripts»  (to ".e-scripts") -- (find-TH "eev-article" "e-scripts") \SECTION  e-scripts   E-scripts

The best short definition for eev that I've found involves some cheating, as it is a circular definition: \DQeev is a library that adds support for e-scripts to Emacs --- and e-scripts are files that contain chunks meant to be processed by eev's functions. Almost any file can contain parts \DQmeant for eev: for example, a HOWTO or README file about some program will usually contain some example shell commands, and we can mark these commands and execute them with \QKM-x eev; and if we have the habit of using eev and we are writing code in, say, C or Lua we will often put elisp hyperlinks inside comment blocks in our code. These two specific languages (and a few others) have a feature that is quite convenient for eev: they have syntactical constructs that allow comment blocks spanning several lines --- for example, in Lua, where these comment blocks are delimited by \QLINE--[[ and \QLINE--]]s, we can have a block like

\EX --[[ # # This file: (find-fline "~/LUA/lstoindexhtml.lua") # A test: cd /tmp/ ls -laF | col -x \ | lua50 ~/LUA/lstoindexhtml.lua tmp/ \ | lua50 -e 'writefile("index.html", io.read("*a"))' # --]]

\NI in a Lua script, and the script will be at the same time a Lua script and an e-script.

When I started using GNU and Emacs the notion of an e-script was something quite precise to me: I was keeping notes on what I was learning and on all that I was trying to do, and I was keeping those notes in a format that was partly English (or Portuguese), partly executable things --- not all of them finished, or working --- after all, it was much more practical to write

\EX rm -Rv ~/usrc/busybox-1.00/ tar -C ~/usrc/ -xvzf \ $S/http/www.busybox.net/downloads/busybox-1.00.tar.gz cd ~/usrc/busybox-1.00/ cp -iv ~/BUSYBOX/myconfig .config make menuconfig make       2>&1 | tee om

\NI than to write

\EX Unpack BusyBox's source, then run "make menuconfig" and "make" on its main directory

\NI because if I had the second form in my notes I would have to translate that from English into machine commands every time... So, those files where I was keeping my notes contained \DQexecutable notes, or were \DQscripts for Emacs, and I was quite sure that everyone else around were also keeping notes in executable formats, possibly using other editors and environments (vi, maybe?) and that if I showed these people my notes and they were about some task that they were also struggling with then they would also show me \ITtheir notes... I ended up making a system that uploaded regularly all my e-scripts (no matter how messy they were) to my home page, and writing a text --- \DQThe Eev Manifesto ([O99]) --- about sharing these executable notes.

Actually trying to define an e-script as being \DQa file containing executable parts, that are picked up and executed interactively makes the concept of an e-script \ITvery loose.

Note that we \ITcan execute the Lua parts in the code above by running the Lua interpreter on it, we \ITcan execute the elisp one-liner with \QKM-e in Emacs, and we \ITcan execute the shell commands using \QKF3 or \QKM-x eev; but the code will do nothing by itself --- it is passive.

A piece of code containing instructions in English on how to use it is also an e-script, in a sense; but to execute these instructions we need to invoke an external entity --- a human, usually ourselves --- to interpret them. This is much more flexible, but also much more error-prone and slow, than just pressing a simple sequence of keys like \QKM-e, or \QKF9, or \QKF3 alt-tab e e enter.

-- «splitting-eev.el»  (to ".splitting-eev.el") -- (find-TH "eev-article" "splitting-eev.el") \SECTION  splitting eev.el   Splitting eev.el

\SEE (find-eev "eev.el" "find-man") (find-eev "eev-mini.el" "find-man")

\LFIND  find-man \LFIND  eeman

When I first submittted eev for inclusion in GNU Emacs, in 1999, the people at the FSF requested some changes. One of them was to split eev.el --- the code at that point was all in a single Emacs Lisp file, called eev.el --- into several separate source files according to functionality; at least the code for saving temporary scripts and the code for hyperlinks should be kept separate.

It turned out that that was the wrong way of splitting eev. The frontier between what is a hyperlink and what is a block of commands is blurry:

\EX man foo man -P 'less +/bar' foo # (eev "man foo") # (eev "man -P 'less +/bar' foo") # (find-man "foo" "bar")

The two \QSHman commands above can be considered as hyperlinks to a manpage, but we need to send those commands to a shell to actually open the manpage; the option \QSH-P 'less +/bar' instructs \QSHman to use the program \QSHless to display the manpage, and it tells \QSHless to jump to the first occurrence of the string \QSTRbar in the text, and so it is a hyperlink to a specific position in a manpage. Each of the two \QSTReev lines, when executed, saves one of these \QSHman commands to the temporary script file; because they contain Lisp expressions they look much more like hyperlinks than the \QSHman lines. The last line, \QFNfind-man, behaves much more like a \DQreal hyperlink: it opens the manpage \ITinside Emacs and searches for the first occurrence of \QSTRbar there; but Emacs's code for displaying manpages was tricky, and it took me a few years to figure out how to add support for pos-spec-lists to it...

So, what happens is that often a new kind of hyperlink will begin its life as a series of shell commands (another example: using \QSHgv --page 14 file.ps to open a PostScript file and then jump to a certain page) and then it takes some time to make a nice hyperlink function that does the same thing; and often these functions are implemented by executing commands in external programs.

There's a much better way to split conceptually what eev does, though. Most functions in eev take a region of text (for example Emacs's own \DQselected region, or the extent of Lisp expression coming before the cursor) and \DQexecute that in some way; the kinds of regions are:

\EX
Emacs's (selected) region   | M-x eev, M-x eelatex (sec. 4)
----------------------------+------------------------------
last-sexp (Lisp expression  | C-x C-e, M-E         (sec. 5)
at the left of the cursor)  |
----------------------------+------------------------------
sexp-eol (go to end of      | C-e C-x C-e, M-e     (sec. 7)
line, then last-sexp)       |
----------------------------+------------------------------
bounded region              | F3, M-x eev-bounded,
| M-x eelatex-bounded (sec. 14)
----------------------------+------------------------------
bounded region around       | (ee-at [`` anchor] ...)
anchor                      |                     (sec. 20)
----------------------------+------------------------------
current line                | F9                  (sec. 15)
----------------------------+------------------------------
no text (instead use the    | F12                 (sec. 19)
next item in a list)        |

\EX Actions (can be composed): * Saving a region or a string into a file * Sending a signal to a process * Executing as Lisp * Executing immediately in a shell * Start a debugger

((Emacs terminology: commands))

-- «eesteps»  (to ".eesteps") -- (find-TH "eev-article" "eesteps") \SECTION  eesteps   eesteps

\SEE (find-efunctiondescr 'eesteps) (find-eev "eev-steps.el"      "eesteps") (find-eev "eev-mini-steps.el" "eesteps") http://angg.twu.net/flipbooks/eesteps.html

\LFIND  eesteps \LFIND  eek \KIND   F12

((Simple examples))

((writing demos))

((hyperlinks for which no short form is known))

((producing animations and screenshots))

-- «eepitch»  (to ".eepitch") -- (find-TH "eev-article" "eepitch") \SECTION  eepitch   Sending lines to processes running in Emacs buffers

\SEE (find-es "davinci" "eepitch-gdb")

\LFIND  eepitch \LFIND  find-comintprocess \KIND  F8 \CIND  tar without -C

(These sections - 20 to 24 - are very new (handwritten in 2007jul12, typed a few days later). They are early drafts, full of errors, describing some code that does not yet exist (ee-tbr), etc. Also, I don't know Rubikitch's real name, so I used a random Japanese name...)

Emacs can run external programs interactively inside buffers; in the screenshot in Figure 5 there's a shell running in the buffer "*shell*" in the lower window. Technically, what is going on is much more complex than what we described in the previous section. The shell runs in a pseudo-terminal (pty), but ptys are usually associated to rectangular grids of characters with a definite width and height, while in an Emacs buffer the width of each line, and the total number of lines,are only limited by memory constraints. Many interactive programs expect their input to come through their more-or-less minimalistic line editors, that may try to send to the terminal commands like "clear the screen" or "go to column x at line y"; how should these things be handled in a shell buffer? Also, the user can move freely in a shell buffer, and edit its contents as text, but the "Return" key becomes special: when it is hit in a shell buffer Emacs takes the current line - except maybe some initial characters that are seen as a prompt - and sends that to the shell process, as if the user had typed exactly that; so, Emacs takes over the line editor of the shell process completely. The translation between character sequences going through the pty and buffer-editing functions is very tricky, full of non-obvious design choices, and even though it has been around for more than 20 years it still has some (inevitable) quirks.

I almost never used shell buffers, so I found the following idea, by OGAMI Itto, very surprising when he sent it to the eev mailing list in 2005.

\EX (find-eevfile "doc/shot-f8.png") (find-anggfile "IMAGES/eepitch-gdb.png") (Figure 5 will be a screenshot that I haven't taken yet.) (It will be simpler than the screenshot from Fig. 6, that is this: http://angg.twu.net/IMAGES/eepitch-gdb.png )

The current window, above in Figure 5, is editing an e-script, and the other window shows a shell buffer - that we will refer to as the "target buffer". When the user types a certain key - by default F8 - the current line is sent to the target buffer, and the point is moved down to the next line; pressing F8 n times in sequence sendsn lines, one by one.

One detail: "sending a line" means inserting its contents - except the newline - at the current position in the target buffer, and then running there the action associated to the "Return" key. "Return" is almost always a special key, bound to different actions in different major modes, so just inserting a newline would not work - that would not simulate what happens when a user types "Return".

F8-is-simpler-than-F9
---------------------

Note that, in a sense, the action of F8 is much more complex than that of F9, described in the last section; but user might perceive F8 as being much simpler, as there are no external programs involved (Expect, eegchannel, xterm), and no setup hassles - all the machinery to make Emacs buffers invoke external processes in buffers pretending to be terminals ("comint mode") comes built-in with Emacs since the early 1980s.

Ogami's idea also included three "bonus features": window setup, reconstruction of the target buffer, and star-escapes. In the default Emacs setting some commands - M-x shell between them - might split the current Emacs frame in two windows; none of eev's hyperlink functions do that, and I have always felt that it is more natural to use eev with a setting (pop-up-windows set to nil) that disables window splittings except when explicitly requested by the user. Anyway: M-x shell ensures that a "*shell*" buffer is visible in a window, and that a shell process is running in it; this setup code for F8,

\EX (eepitch '(shell))

\NI splits the window (if the frame has just one window), and runs `(shell)' in the other window - with the right defaults - to force that window to display a shell buffer with a live shell process running in it; it also sets a variable, `eepitch-target-buffer', to that buffer, so that the next `F8's will have a definite buffer to send lines too - as target buffers need not necessarily be shell buffers.

As for the star-escapes, it's the same idea as with F9: when a line starts with a red star glyph, running F8 on it executes everything on it - after the red star - as Lisp, and if there are no errors the point is moved down. So lines starting with a red star can be used to set up an eepitch target, to switch to another target, or to do special actions - like killing a certain target so that it will be reconstructed anew by the next F8. Note that once that we recognize that a region of an e-script is to be used by eepitch there is only one key to be used to "run" each of its lines, both the ones with red stars and the ones without: F8. However, as with F9, the user must know what to expect after each step. A badly-written e-script for eepitch may try, for example, to "cd" into a directory that does not exist, and if the next line is, say, \QSHtar -xvzf $S/http/foo/bar.tgz then it will try to unpack a tarball into the wrong place, creating a big mess.

-- «eepitch-unprepared»  (to ".eepitch-unprepared") -- (find-TH "eev-article" "eepitch-unprepared") \SECTION  eepitch and rcfiles   Using eepitch to control unprepared shells

\SEE (find-eevfile "eev.el" "EEVDIR") (find-eevfile "eev.el")

As we have seen in section 4, M-x eev sends the region to a "prepared shell"; if the shell has the right settings for the environment variables $EEVTMPDIR and $EE, and if it has the shell function `ee', then running `ee' in the shell "sources" the temporary script - corresponding to the regin - in verbose mode. Well, if Emacs loads eev.el and the environment variables $EEVDIR, $EEVTMPDIR and $EE are not set, then they are set, respectively, to the directory where eev.el was read from, to the subdirectory of it given by $EEVDIR/tmp, and to the file $EEVTMPDIR/ee.sh. Processes started from Emacs inherit these environment variables, so a shell buffer created by running F8 on these two lines,

\UEX  (eepitch-shell) function ee ()  set -v; . $EE; set +v;

\NI will be running a prepared shell. Such buffers can be used to let users understand better how prepared shells work, and decide if they want to patch their initialization files for the shell (see eev-rctool) so that their shells will be "prepared" by default.

(Note: I haven't yet played much with this idea - discuss running eev-rctool on such shells (and a function that creates a buffer with an e-script for that), and loading psne.sh from an unprepared shell).

-- «eepitch-gud»  (to ".eepitch-gud") -- (find-TH "eev-article" "eepitch-gud") \SECTION  eepitch-gud   Controlling debuggers with eepitch

\SEE (find-angg ".emacs" "eepitch-gdb") http://angg.twu.net/.emacs.html#eepitch-gdb http://article.gmane.org/gmane.emacs.eev.devel/47 http://lists.gnu.org/archive/html/eev/2007-07/msg00000.html (find-node "(emacs)Debuggers") (find-node "(gdb)Top")

On *NIX it is common to keep debuggers separated into two parts: a back-end, with a simple textual interface, and a front-end, that controls the back-end via its textual interface but presents a better interface, showing source files and breakpoints in a nice way, etc. The GNU Debugger, GDB, is a back-end, and it can be used to debug and single-step several compiled languages; the "Grand Unified Debugger" mode of Emacs, a.k.a. GUD, is a front-end for GDB and other back-ends.

Usually, GUD splits an Emacs frame into two windows, one for interaction with GDB (or other back-end, but let's say just "GDB" for simplicity), and another one for displaying the source file where the execution is. Some of the output of GDB - lines meaning, e.g., "we're at the source file foo.c, at line 25" - are filtered by GUD and are not shown in the GUD buffer; and the user can press special key sequences on source files that generate commands to GDB - like, "set a breakpoint on this line".

In order to control GDB with eepitch we need a window setting with three windows, like in the screenshot in Figure 6.

\EX http://article.gmane.org/gmane.emacs.eev.devel/47 http://lists.gnu.org/archive/html/eev/2007-07/msg00000.html http://lists.gnu.org/archive/html/eev/2007-07/pngXBfRlWr29Z.png (find-anggfile "IMAGES/eepitch-gdb.png")

The way to set up that does not integrate very well with the "standard" eepitch at this moment, but that should come with time.

-- «eepitch-gdb»  (to ".eepitch-gdb") -- (find-TH "eev-article" "eepitch-gdb") \SECTION  eepitch-gdb   E-scripting GDB with eepitch

\SEE # (find-node "(gdb)Set Breaks" "`tbreak ARGS'") # (find-node "(elisp)The Buffer List") # (find-es "lua5" "lua-api-from-gdb") # (find-TH "luaforth" "lua-api-from-gdb")

We can use elisp hyperlinks to point to specific lines in source files - and we can combine these hyperlinks with the code to set up breakpoints, in two ways.

\EX ;(find-lua51file "src/lvm.c" "case OP_CLOSE:" 1)  (find-lua51file "src/lvm.c" "case OP_CLOSE:" 1 '(ee-tbr))

The first line above contains an elisp hyperlink to a line in the source of Lua. Actually, it points to the code for an opcode in Lua's virtual machine that most people find rather mysterious. As the line starts with `;', an F8 on it executes a Lisp comment - i.e., does nothing - and moves down; only a `M-e' (or a `C-e C-x C-e') on that line would follow the hyperlink.

The second line, when executed with F8, would go to that line in the source, then run `(ee-tbr)' there; ee-tbr invokes gud-tbr to set a temporary breakpoint on that source line (i.e., one that is disabled when the execution stops there for the first time), and then buries the buffer - the one with "lmv.c" - like a `M-K' would do; the effect is that the buffer in that window - the top-left window in a situation like in Figure 6 - does not change, it will still show the e-script.

A variation on this is to wrap the hyperlink in an ee-tbr:

\EX  ;        (find-lua51file "src/lvm.c" "case OP_CLOSE:" 1)  (ee-tbr '(find-lua51file "src/lvm.c" "case OP_CLOSE:" 1))

When ee-tbr is called with an argument it evaluated the argument inside a save-excursion, and sets a breakpoint there; the effect is almost the same as the previous case, but this does not change the order of the buffers in the buffer list.

-- «little-dbg-langs»  (to ".little-dbg-langs") -- (find-TH "eev-article" "little-dbg-langs") \SECTION  little debugging languages   Two little languages for debugging

E-scripts for eepitch and GDB can be used to bring programs to a certain point (and to inspect their data structures there; we will have more to say about this in the next section). In a sense, as in [Bentley], these e-scripts are written in a language that describes states of running programs - and they can be executed step by step.

These e-scripts, being executable, can be used in e-mails to communicate particular states of programs - say, where a certain bug occurs. Unfortunately, they are too fragile and may cease working after minimal changes in the program, and they are almost impossible to read...

However, the screenshot in Figure 5 suggests another language for communicating controlling programs with GDB: the contents of the "*gud*" buffer. After removing some excess verbosity by hand we get something that is readable enough if included in e-mails - and to extract the original commands from that we just have to discard the lines that don't start with "(gdb)", then remove the "(gdb)" prompts. As for the hyperlinks with `(ee-tbr)', they may need to be copied to the GUD buffer, and not filtered out; we still need to experiment with different ways to do that to be able to choose one.

-- «inspecting-data»  (to ".inspecting-data") -- (find-TH "eev-article" "inspecting-data") \SECTION  inspecting data   Inspecting data in running programs

Almost anyone who has learned a bit of Lisp should be familiar with this kind of box diagrams. After running

\EX (setq x '(5 "ab")) (setq y (list x x '(5 "ab")))

\NI the value of y can be represented by:

\EX
___ ___       ___ ___             ___ ___
|___|___| --> |___|___| --------> |___|___| --> nil
| ___________/                    |
|/                                |
_v_ ___       ___ ___             _v_ ___       ___ ___
|___|___| --> |___|___| --> nil   |___|___| --> |___|___| --> nil
|             |                   |             |
v             v                   v             v
5            "ab"                 5            "ab"

This representation is very nice - it omits lots of details that are usually irrelevant, like the address in the memory of each cons, and the exact names of each struct in C and their fields. But sometimes we need to understand the implementation in C, and a more complete diagram would be convenient. At least, we would like to know how to get, in the C source of Emacs, from the address of the leftmost cons in the top line to the rightmost "ab" in the bottom line - but how do we express following the "cdr" arrows, the "car" arrows, and extracting the contents of a string object in elisp, One solution is to use GDB, and e-scripts for it:

((...))

A "complete diagram" corresponding to the one above, whatever the format that we choose to draw it, should include some information explaining that "cdr" arrows correspond to "->cdr", "car" arrows correspond to ..., and each string object corresponds to another kind of box different from the cons boxes; to get to the C string stored in an elisp string object we should examine its "foo" field, i.e., do a "->foo".

Obviously, this same idea applies also to other programs with complex data structures - and for some programs we may even have fancier ways to explore their data structures; for example, in a graphic toolkit it might be possible to change the background of a button to orange from GDB.

-- «big-modular-e-scripts»  (to ".big-modular-e-scripts") -- (find-TH "eev-article" "big-modular-e-scripts") \SECTION  big modular e-scripts   Big Modular E-scripts

\SEE % (find-eevex "screenshots.e" "fisl-screenshots-modular") % (find-eimage0 "./ss-modular.png") % (find-fline     "ss-modular.png") % (find-es "tex" "png_screenshots") % (find-fline "README" "ss-modular")

A shell can be run in two modes: either interactively, by expecting lines from the user and executing them as soon as they are received [[footnote: except for multi-line commands]], or by scripts: in the later case the shell already has access to the commands, and executes them in sequence as fast as possible, with no pause between one command and the next.

When we are sending lines to a shell with F9 we are telling it not only \ITwhat to execute but also \ITwhen to execute it; this is somewhat similar to running a program step-by-step inside a debugger --- but note that most shells provide no single-stepping facilities.

We will start with a toy example --- actually the example from [Section anchors] with five new lines added at the end --- and then in the next section we will see a real-world example that uses these ideas.

\EX Figure 4: sending a block at once with eevnow-at (find-fline "ss-modular.png")

Figure 5: single-stepping through a C program (find-fline "ss-gdbwide.png")

((Somewhere between a script and direct user interaction))

((No loops, no conditionals))

((Several xterms))

-- «iskidip»  (to ".iskidip") -- (find-TH "eev-article" "iskidip") \SECTION  iskidip   Internet Skills for Disconnected People

Suppose that we have a person \ITP who has learned how to use a computer and now wants to learn how the internet works. That person \ITP knows a bit of programming and can use Emacs, and sure she can use e-mail clients and web browsers by clicking around with the mouse, but she has grown tired of just using those things as black boxes; now she wants to experiment with setting up HTTP and mail servers, to understand how data packets are driven around, how firewalls can block some connections, such things.

The problem is that [IT P] has never had access to any machine besides her own, which is connected to the internet only through a modem; and also, she doesn't have any friends who are computer technicians or sysadmins, because from the little contact that she's had with these people she's got the impression that they live lifes that are almost as grey as the ones of factory workers, and she's afraid of them. To add up to all that, [IT P] has some hippie job that makes her happy but poor, so she's not going to buy a second computer, and the books she can borrow, for example, Richard Stevens' series on TCP/IP programming, just don't cut.

One of eev's intents isto make life easier for autodidacts. Can it be used to rescue people in positions like [IT P]'s(4)? It was thinking on that that I created a side-project to eev called [`` Internet Skills for Disconnected People]: it consists of e-scripts about running a second machine, called the [`` guest], emulated inside the [`` host], and making the two talk to each other via standard internet protocols, via emulated ethernet cards. Those e-scripts make heavy use of the concepts in the last section ((...))

\EX Figure 6: a call map (find-fline "iskidip.png") (find-eimage0 "./iskidip.png")

% (find-eevex "busybox.e" "bb_chroot_main") % (find-eevex "busybox.e" "bbinitrd-qemu-main") % (find-eevex "busybox.e" "iso-qemu-main") % (find-eevex "busybox.e" "iso-qemu-main-2")

(4). by the way, I created [IT P] inspired on myself; my hippie job is being a mathematician.

-- «loose-ends»  (to ".loose-ends") \CHAPTER  loose ends   Loose ends

\SEE What is automating a task? A tree of states (find-eevfile "README-0.95.2") actors, colors, and tones of voice

manpages from remote machines: http://article.gmane.org/gmane.emacs.eev.devel/107 flipbooks (find-eev "eev-sshot.el") (find-TH "emacs" "flipbooks") templates (find-eev "eev-insert.el" "ee-template") brep (find-eev "eev-browse-url.el") math glyphs (and fonts) (find-eev "eev-math-glyphs.el") eepitch-wrap (find-eev "eev-insert.el" "ee-wrap-eepitch")

-- «this-document»  (to ".this-document") \SECTION  this document   This document

This document is a \ITvery preliminary conversion to TeXinfo of the \DQeev article, whose HTML and source are at:

\EX http://angg.twu.net/eev-article.html http://angg.twu.net/TH/eev-article.blogme

Not only there are many incomplete sections, but there many things in the conversion that should \DQwork, and that currently don't: the \DQSee: blocks, the embedded e-scripts (the ones with delimited regions and the ones with lines starting with red stars can't be indented), the anchors in the section about anchors (because \QLVee-anchor-format should be adjusted to non-unibyte encoding of the info buffer)...

Also, at present it is not possible to generate dvi/ps/pdf files and working HTML (with all the elisp hyperlinks htmlized, etc) from the .texi file. Well, whatever.

The .texi file is generated by running a .texi.lua file through the Lua interpreter. The .texi.lua contains some macro definitions for a simple - and undocumented - preprocessor, and the marked-up text that becomes the .texi file. The .texi.lua and the preprocessor are not included in the eev tarball, but they can be fetched from:

\EX http://angg.twu.net/TEXINFO/eev.texi.lua.html http://angg.twu.net/LUA/preproc.lua.html

-- «eev-manifesto»  (to ".eev-manifesto") \SECTION  eev manifesto   The eev manifesto \SEE (find-eev "doc/EEVMANIFESTO")

-- «dedication»  (to ".dedication") \SECTION  dedication   Dedication \SEE (find-eev "DEDICATION") (find-eev "DEDICATION.c-r")

-- «eev-mode-map»  (to ".eev-mode-map") \SECTION  eev-mode-map   eev-mode-map \SEE http://lists.gnu.org/archive/html/eev/2008-04/msg00014.html http://article.gmane.org/gmane.emacs.eev.devel/99 (find-evariable 'eev-mode-map)

\LVIND  eev-mode-map

-- «ee-hyperlink-prefix»  (to ".ee-hyperlink-prefix") \SECTION  alternative to customize   A Lisp-ish alternative to customize \SEE http://lists.gnu.org/archive/html/eev/2005-12/msg00008.html http://article.gmane.org/gmane.emacs.eev.devel/34 (find-evariable 'ee-hyperlink-prefix) (find-efunction 'ee-hyperlink-prefix) (find-eev "eev-insert.el" "ee-hyperlink-prefix") (find-eev "eev-mini.el" "ee-hyperlink-prefix")

\LVIND  ee-hyperlink-prefix \CIND  customize

-- «running-TeX»  (to ".running-TeX") \SECTION  running TeX   Running TeX \SEE (find-es "tex")

\CIND  TeX \CIND  LaTeX \UEX  (eepitch-tex)  (eepitch-kill)  (eepitch-tex) \tracingonline=1\scrollmode

-- «ee-wrap»  (to ".ee-wrap") \SECTION  ee-wrap   ee-wrap \SEE (find-efunction 'ee-wrap-file)

-- «htmlizing-escripts»  (to ".htmlizing-escripts") \SECTION  htmlizing   Htmlizing e-scripts \SEE (find-blogme3 "Makefile")

\CIND  blogme3

-- «index»  (to ".index") \INDEX    index   Index

]=])

-- (find-TH "eev-article") -- (find-TH "eev-article" "abstract")

-- \CHAPTER  c1   C1   Chapter one.
-- \CHAPTER  c2   C2   Chapter two.
-- \CHAPTER  c3   C3   Chapter three.
-- \SECTION  s21   s21   Section 2.1.

-- Local variables: -- coding: raw-text-unix -- mode:   fundamental -- modes: (lua-mode texinfo-mode fundamental-mode) -- end: