Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
This is the `README' file of GNU eev.
Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
Author and version: Eduardo Ochs, 2007jul20.
How to get in touch with me: IRC is the fastest way. I'm "edrx" at
irc.freenode.net, try to /query or /whois me if I'm not at #emacs or
at #eev. If you prefer e-mail, I'm <eduardoochs@gmail.com>, and for
other ways, see <http://angg.twu.net/contact.html>.

  |  Note: the body of this README hasn't been changed since          |
  |  2005jan06, and this is not a good introduction to eev anymore.   |
  |  Please start by reading the HTML version of the article instead  |
  |  (<http://angg.twu.net/eev-article.html>) - it has links to       |
  |  everything else.                                                 |


New things in this file: added links to the mailing list and to the
ChangeLog file, and removed the mentions to eev-0.95.0 - 0.95.0 is
quite old now, and -current is almost becoming 0.95.1.

Latest version: <http://angg.twu.net/eev-current/README>
      htmlized: <http://angg.twu.net/eev-current/README.html>
    See also:   <http://angg.twu.net/eev-article.html>
                                      (find-eev "INSTALL")
                                      (find-eev "EMACS")
                                      (find-eev "NEWS")
                                      (find-eev "")
  Mailing list: <http://lists.nongnu.org/mailman/listinfo/eev>
      archives: <http://lists.gnu.org/archive/html/eev/>

1. What Is Eev

Eev is a package that adds suport for e-scripts in Emacs.

But what are e-scripts?...

1.1. A Short Description of What E-scripts are (The Sales Talk)

E-scripts are files containing notes about how to do certain computer
tasks. Some parts of an e-script are written in English or in other
human languages, and are not intended to be interpreted by the
computer in any way; other parts contain logs of the interactions with
the programs that were involved in the task, in a form that allows not
only inspection and textual modification but also controlled
"re-execution" - that is, repeating that interaction in another
moment, with or without modification, from the steps registered in the
log, without the need to repeat each keystroke or mouse-click by hand.

So: e-scripts are a way of taking "executable notes" of what you
do. If you interact with the system using Emacs and Eev then notes in
e-script form will get produced more or less automatically, and
redoing things that you've already done before becomes trivial.

1.2. A More Honest Description, or: Between Code and Actions, E-scripts

A typical e-script is a plain text file containg bits of text and
chunks of code intended to be interpreted by several different
programs. There's no way to execute a whole e-script file at once;
instead, the user interactively selects parts of the e-script while he
or she is editing it in Emacs - these parts can be the current line,
or Emacs's "region", or everything before and after the cursor until
certain delimiters strings are found, etc -, and then asks Emacs to
either execute those parts as Lisp code, or to save them into a
temporary script file (to run those parts in a shell or a shell-like
program later), or to send them immediately as input to some external
program, or to process them in another way.

An "action" can be "recorded" as text by writing down code that
produces that action when executed - remember that code is text! The

                  "action": effect
      code   ->     of executing
                     the code

is natural for the computer; the opposite direction,

                    code that
     action   ->    produces
                   that action

is not. For many actions we may know how to do that by hand, and for
some kinds of actions there are tools to automatically generate the
corresponding code; we will discuss some of these tools later (section
"Following and Creating Elisp Hyperlinks", below).

1.3. Two Basic Examples: Shell Commands and Hyperlinks

If our "action" is to enter these commands in a shell,

  cd /home/backups/
  tar -tvzf persephone-2002jun10.tar.gz > ~/.files
  grep books.db ~/.files

then we can record that by just pasting the commands to Emacs (by the
way, in this case it is the way of playing back the commands that is
not obvious! See the screenshot below for the trick). But now suppose
that we have just found a piece of interesting information in the
documentation (in Info) for Zsh, in the node called "Process
Substitution", around the first occurrence of the string "=(...)" in
the text - how do we create a "hyperlink" to that, that is, one whose
action when "followed" will be to take us to that page and to put the
cursor at that point?  The elisp expression below does the job:

  (find-node "(zsh)Process Substitution" "=(...)")

We can execute it by placing the cursor after it and typing C-x C-e,
or by placing the cursor anywhere in the line and typing M-e. Note:
C-x C-e is standard in Emacs, while (this behaviour for) M-e is
defined in eev; `find-node' is from eev, but Emacs comes with several
functions that make sense as hyperlinks, for example:

  (find-file "/etc/fstab")
  (info "(zsh)Process Substitution")
  (info "(emacs)Lisp Eval")
  (man "ls")
  (describe-key "\C-x\C-e")
  (describe-function 'eval-last-sexp)
  (where-is 'eval-last-sexp)

These "hyperlink" functions that are native to Emacs do not accept the
extra arguments specifying where to move the cursor to, but all the
functions in eev do (these extra arguments are called "pos-spec-list"s
in eev, by the way).

Note that these "elisp hyperlinks" can appear inside comments in code
for other languages:

  # (find-node "(zsh)Process Substitution" "=(...)")
  function catcat () { echo "Temp file: $1"; cat $1; tac $1 }
  catcat =(echo foo; echo bar; echo plic)

This is a valid block of shell commands - code for one language can
appear inside code for another language.

It would be very hard to make a system supporting several languages
this if the limits of each block had to be found automatically, and
the language identified; but in eev the boundaries of the block and
the language are selected interactively, and thanks to that the
implementation is very simple - and that makes adding support for
additional languages in eev quite easy [include a list of currently
supported languages, and write a (big) section about Interacting with
Unsupported Things].

The commented screenshot below illustrates one way of sending commands
to a shell - by putting the cursor inside a "delimited region" and
typing <f3>, then going to shell and running `ee' there.

  (find-eimage0 "doc/shot-f3.png" 1 nil "40%")

It is also possible to do something similar with regions that are not
bounded by delimiters; just mark the region in the usual way in Emacs,
by setting the "mark" and moving the "point", then type M-x eev.

One variation: if you mark a region and issue M-x eelatex instead of
M-x eev then the region will be "sent to LaTeX" instead of to the
shell; the region will be written in a temporary .tex file, and the
temporary script will receive commands to run latex on the temporary
.tex file and display the resulting .dvi file; after M-x eelatex you
switch to a shell and run `ee' there.

  (find-enode "Mark")

By the way, the name `eev' stands for something like
"Emacs-execute-(in a shell)-verbosely". It was one of the first Emacs
Lisp functions that I wrote, and as I was executing it several
hundreds of times a day it had to have a very short name that would be
very easy to type.

2. Actions That Are Executed Step-by-Step

2.1. Single-Stepping Through Series of Emacs Actions: `eesteps'

Try this: execute:

  (eesteps '("C-x b * scratch * RET"
             (insert "!")))

then type <f12> four times, slowly.  Emacs will:

  1) switch to the buffer "*scratch*"
  2) insert "foobar"
  3) move the point left three characters
  4) insert "!".

Typing another <f12> will give an error ("No more steps").

Here's how this works, internally: the variable `eesteps-list' holds a
list of "steps" to execute, and the variable `eesteps-pos' holds a
pointer (a number) saying where we are in that list; the function
`eesteps' receives a list of steps, stores that in `eesteps-list' and
resets `eesteps-pos' to 0.

The steps in `eesteps-list' can be either lists -- and in this case
executing the step means evaluating the list -- or strings; strings
are interpreted as sequences of keys, written in the verbose format
used by `edmacro-mode'.

    (find-eev "eev-dev.el" "eesteps")
    (find-eev "eev-dev.el" "eek")
    (find-eev "eev-dev.el" "eek0")
    (find-efile "")
    (find-efile "edmacro.el")

The function `eek' is a kind of "hyperlink to executing a key
sequence"; it is used by `eesteps-do-step'. `eek0' is similar but
uses Emacs's native format for keyboard macros, which is usually
more compact and harder to read.

[Problem: eek and eek0 run their strings as macros, but macros runs
in a kind of non-verbose mode - M-w doesn't give visual feedback]

2.2. Sending one line at a time to an external program: `eechannel'

This is a new feature that is très chic: controlling several programs
at the same time. Click on the screenshot to enlarge.

  (find-eimage0 "doc/shot-f9.png" 1 nil "40%")

  (find-eev "eegchannel")

News: we can use the same trick - save the "line" in a file, then send
a SIGUSR1 to the process responsible for the channel - with strings
that are not necessarily lines and with controlling processes that are
no eegchannel; see:

  (find-eevex "python.e" "eechannel-python")
  (find-eevex "tcltk.e"  "eechannel-tcl")

3. Splitting Eev in Two Halves (and Their Frontier)

Eev is mainly composed of two parts: one that deals with creating and
following elisp hyperlinks, and another one that is concerned with
selecting a part of a text and sending it to an external program
(usually a shell).

In reality the frontier between the two parts is quite blurry - there
are too many hybrids, and there's no way to get rid of them. That will
be discussed in section 3.3.

[This section is much more technical than the others.  The idea is
that people who read this section would be able to understand modify
and extend the code...]

3.1. One half of eev: sending commands to a shell and other related things

    (find-eimage0 "doc/diag-save.jpg" 1 4 'inline)

  The diagram above shows what is involved in writing some lines of
  code for an external program (most typically a shell) in Emacs and
  then making the program execute those lines. I've made a commented
  screenshot about that:

    (find-eevfile "doc/shot-f3.png")

  The "technically simpler" way - that is, the one involving less
  functions - to send commands to a shell is to write the commands as
  text in a buffer, then mark the region containing these commands,
  then type `M-x eev'; that will save the region in a certain
  temporary file. The name of that file is given by a certain
  environment variable - $EE, usually set to ~/eev-current/tmp/ee.sh -
  and that value of variable is set in rcfiles - check your .bashrc,
  .zshrc and .emacs after installation. Then to execute these commands
  we go to a shell and type `ee'; `ee' is a shell function (also
  defined in .bashrc/.zshrc) that "sources" the contents of $EE.

  It is usually more practical to write the commands inside a "region"
  bounded by delimiters (see the "shot-f3.png" screenshot above), then
  just place the cursor inside that region and type <f3>. By default
  <f3> will execute `eev-bounded', that will run `eev' in that bounded
  region; but there are several ways to change this default. The
  variable `eeb-defaults' contains the "default bounded function", the
  delimiters to use, and other things; if you another "bounded
  function" explicitly, say, with `M-x eelatex-bounded', that will set
  the defaults - the next time you time <f3> it will run
  `eelatex-bounded' using block delimiters that make more sense for
  LaTeX - "\n%*\n" instead of "\n#*\n". So actually <f3> runs

  [Actually the diagram is a bit misleading... eev-bounded calls
  eeb-default[s], or something like that. Explain and show how the old
  implementation was]

    (find-eev "eev-dev.el")

3.2. Funny Characters

  To type the red stars in these delimiters, use C-q C-o. This inserts
  a "literal C-o" in the text, whose ascii code is 15; it would
  normally be displayed as "^O", but we change that to a red star
  using "glyphs" (see the file glyphs.el). glyphs.el defines several
  other non-standard glyphs, like "«" and "»". We can enter those
  typing M-, < < and M-, > >, respectively. The function associated to
  `M-,', `compose-two-keys', is defined in compose.el. Neither glyphs
  nor these "compose pairs" would be strictly needed for eev, but I
  find them convenient.

    (find-eev "glyphs.el")
    (find-eev "compose.el")

3.3. The other half: following and creating Elisp hyperlinks

  (find-eimage0 "doc/diag-links.jpg" 1 2 'inline)

  Emacs's support for executing Lisp expressions
  (a.k.a. "S-expressions", or "sexps") embedded in any kind of text
  lets us put some simple types of hyperlinks anywhere; for example,
  typing `C-x C-f /usr/share/doc/bash' or `M-x find-file
  /usr/share/doc/bash' has the same effect as placing the cursor after
  the text (find-file "/usr/share/doc/bash") and executing that with
  C-x C-e or with M-e; the effect is to create a buffer visiting
  /usr/share/doc/bash/ - that, incidentally, is a directory, so the
  buffer will be in "dired mode".

  Eev defines the function `find-fline', that is a bit more adequate
  than `find-file' for hyperlinks. For example,

    (find-fline "/usr/share/doc/bash/" "FAQ")

  will do the same but will also place the cursor after the first
  occurence of the string "FAQ" in the buffer. Most hyperlinks
  functions in eev support this kind of finer control; the optional
  arguments after the file name are called the "pos-spec-list".

  If we need to create links to several files inside a certain
  directory we can use `code-c-d': for example, (code-c-d "ud"
  "/usr/share/doc/") will define a function `find-udfile' and several
  others with names like `find-ud___' `ee-ud___'.

  Until some time ago we had to write almost all these hyperlinks by
  hand - there were a function called `inn', that would insert a
  hyperlink to the last Info node visited, and `dff' and `dfa', that
  would convert lines containing names of Debian packages into
  hyperlinks to their descriptions, to their lists of files and to
  their documentation directory, but just that.  Then in November of
  2004 I got an idea for a group of functions that would take either a
  file being visited, or a name of an Emacs Lisp function, or a key
  sequence, or several other things, and would create a temporary
  buffer containing several interesting hyperlinks about that thing.
  For example: typing `M-h f' on a buffer visiting
  /usr/share/doc/bash/examples/ gives us a buffer like this:

     |(find-file-links "/usr/share/doc/bash/examples/")          |
     |                                                           |
     |(find-fline "/usr/share/doc/bash/examples/")               |
     |                                                           |
     |(find-bashfile "examples/")                                |
     |(find-udfile "bash/examples/")                             |
     |                                                           |
     |                                                           |
     |                                                           |
     |--:**  *Elisp hyperlinks*   All L9      (Fundamental)------|

  In this case there aren't any surprising hyperlinks (but try `M-h
  M-k <del>', `M-h M-v ctl-x-map' or `M-h M-d bash'!) but it is clear
  that we can not only follow each of these hyperlinks but also edit
  them and copy them to more permanent places.

  There are a few special keys for working on these hyperlinks. `M-h
  M-2' or `M-h 2' will duplicate the current line, `M-h M-y' - the
  name is to remind us of `C-y' - will paste the last element of the
  kill ring as a pos-spec; for example, if the last string we killed
  (say, with `C-w') was "scripts" then `M-h M-2 M-h M-y' will

    (find-udfile "bash/examples/")


    (find-udfile "bash/examples/")
    (find-udfile "bash/examples/" "scripts")

  There are currently no special keys to help us build `code-c-d'
  expressions - but check this:

    (find-efile "hippie-exp.el")
    (global-set-key [f11] 'hippie-expand)

  then try to type part of a file name and use <f11> to complete it.

  See (find-eev "eev-insert.el")

3.4. Emacs's tools for transforming actions into code

[To be written. Mention debugging, C-h k, interactive calls, keymaps,

3.5. The frontier: hybrid functions

[To be written.]

# (eev-bounded)
wget --help

# (eev "wget --help")
# (find-sh "wget --help")

inkscape $EEVDIR/doc/diag-save.svg
# (eev "inkscape $EEVDIR/doc/diag-save.svg &")

eev or find-sh0 links inside lisp comments
eev or find-sh  links inside shell comments

hybrid links will exist every time that we are learning a new program
and still don't know how to make links to it using more common-looking

3.4. More on hyperlinks (plus garbage)

[Fix this, give examples]

[and so we don't need to quote portions of external texts inside an
e-script; instead, we can point directly to the original sources. Eev
defines many kinds of "hyperlinks" like these: for text files, for
info manuals, for manpages, for ps/pdf/dvi/html files, for the output
of shell commands, for Emacs's own source code in Lisp or in C, for
Debian packages, for images, and a few others.]

The two hyperlinks below are equivalent:

  (find-man "1 expect" "\nCOMMANDS" "\n       interact [string1 body1] ...")
  (find-expcommand "interact [string1 body1] ...")

The first one opens the manpage for the program Expect (like "man 1
expect"), then searches for the first ocurrence of a newline followed
by the string "COMMANDS" -- that's the beginning of the section of the
manpage that describes expect's commands --, then searches for the
first place after that where the string "interact [string1 body1] ..."
(preceded by a newline and exactly 8 spaces) occurs; that's the point
of the manpage where is the description of the command "interact".

the underlying idea (or "belief"?) is that we should be able to
"record" all kinds of textual interactions with the machine in
e-scripts, in a way that will let us "play back" these interactions
later - maybe with modifications - and maybe even share them with
other people.

Also: readability. Recording the way to open up an info page as a
series of keys is not very useful... (give an example). Idem for
mouseclicks. Show how commands in Gimp have textual names:

# (find-sh "cd ~/.gimp-2.0/; sort menurc")

E-scripts may be a more powerful way to communicate
actions and procedures than either finished programs or texts and
how-tos, which usually describe most of the steps using human

[For a detailed introduction to Emacs, Lisp expresions and evaluation

  (find-eev "EMACS")

The main stuff:              (find-eev "eev-dev.el")
eev-mode keys:               (find-eev "eev-dev.el" "eev-mode-map")
Support for other programs:  (find-eev "eev-langs.el")
Glyphs ("*", "«", "»", etc):
  Typing them:               (find-eev "compose.el")
  Displaying them:           (find-eev "glyphs.el")

Trying it

See <http://angg.twu.net/eev-current/INSTALL.html> for installation

Sorry, I haven't yet organized the examples in a logical way that can
be used as a tutorial...

The file "eev-tests.e" used to contain tests for almost all the
functions of eev-del.el, but it is outdated, sorry.

  emacs ~/eev-current/examples/eev-tests.e

More later, as always.  Some interesting links:


  (find-elinode "List Processing")

;; (find-angg ".emacs" "emacs-ascii-screenshots")
;; (setq my-screenshot-prefix "     ")

;; Local Variables:
;; mode:                      text
;; coding:                    raw-text-unix
;; ee-anchor-format:          "«%s»"
;; ee-comment-prefix:         ";;"
;; sentence-end-double-space: t
;; End: