Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
(Re)generate: (find-prepared-intro)
Source code:  (find-eev "eev-intro.el" "find-prepared-intro")
More intros:  (find-eval-intro)
This buffer is _temporary_ and _editable_.
Is is meant as both a tutorial and a sandbox.

Prepared shells
Long before eepitch had been created, eev had another way -
technically much simpler, but clumsier from the user's point of
view - to send commands to external shells (and other shell-like
programs; but to simplify we will say just "shells"). Here is
an overview of how it worked: if the user marked the three lines

  rm -Rv /tmp/foo
  mkdir  /tmp/foo/
  cd     /tmp/foo/

and typed `M-x eev' (which stood for "Emacs-execute-verbosely")
then Emacs would save those three lines into a temporary script
file, usually "~/.eev/ee.sh"; that would be just half of
"sending commands to an external shell", and for the other half
the user would have to go to an external prepared shell - that
would usually be running in an xterm, and totally independent
from Emacs - and type "ee" there. The shell had to be
"prepared" in the sense that it would understand the "ee"
command correctly, as meaning: "execute the commands in the
temporary script as if the user were typing them at the prompt".
Technically, that would mean that instead of calling
"~/.eev/ee.sh" as a shell script its contents would be
"sourced" - i.e., executed in the current shell context - and
in verbose mode.

Usually we would prepare bash by patching the file ~/.bashrc and
putting the definition for "ee" there. We will discuss how to
do that later; now let's test a simple environment in which `M-x
eev' and "ee" work. First execute these two sexps:

  (make-directory "~/.eev/" 'force)
  (eev "rm -Rv /tmp/foo\nmkdir  /tmp/foo/\ncd     /tmp/foo/\n")

Now run this script

* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
export PS1='$PWD# '
function ee () { set -v; . ~/.eev/ee.sh; set +v; }

[Explain how several interpreters can be programmed to accept
an `ee' command to execute temporary scripts]


  (find-eev "eev-langs.el")
  (find-eev "eev-bounded.el")
  (find-eev "eev-rctool")

An `ee' for Python
Here is a simple way to make Python execute commands saved in a
temporary script when the user types `ee()' (note that it is not
just `ee' - the `()' is needed). We will show first an example in
which the temporary script is prepared by running "cat" from a
shell - then we will explain a more user-friendly way to save a
region from the current buffer as the temporary script.

Note that the demo below uses `find-wset', which is an
advanced (i.e., hackish) feature explained here:

  (find-multiwindow-intro "Several eepitch targets")

* (find-3EE '(eepitch-shell) '(eepitch-python))
* (find-3ee '(eepitch-shell) '(eepitch-python))
* (eepitch-python)
import os
def ee():
  execfile(os.getenv("HOME")+"/.eev/ee.py", globals())

* (eepitch-shell)
cat > ~/.eev/ee.py <<'%%%'

* (eepitch-python)

* (eepitch-shell)
cat > ~/.eev/ee.py <<'%%%'
def foo (x):
    return x*x

print foo(5)

* (eepitch-python)

The function `eev' receives three parameters, called `s', `e', and
`altfile'; `e' and `altfile' are optional, and `s' should be either a
string or a number. When `s' is a string, then the commands to be
saved into the temporary script are taken from `s'; the numeric case
will be discussed later.

A call to

  (eev "print(1+2)" nil "~/.eev/ee.py")

writes "print(1+2)" (with an added trailing newline, but that's
a technical detail) into the "alternative file"
"~/.eev/ee.py" - the default would be "~/.eev/ee.sh". We can
that to simplify our demo a bit:

* (eek "C-x 1")
* (eepitch-python)
* (eepitch-kill)
* (eepitch-python)
import os
def ee():
  execfile(os.getenv("HOME")+"/.eev/ee.py", globals())

* (eev "print(1+2)" nil "~/.eev/ee.py")
* (eev "def foo (x):\n    return x*x\n\nprint foo(5)" nil "~/.eev/ee.py")

  In the example below the first line defines a `eepy' in a
  simplistic way:

* (defun eepy (s &optional e) (eev s e "~/.eev/ee.py"))
* (eek "C-x 1")
* (eepitch-python)
* (eepitch-kill)
* (eepitch-python)
import os
def ee():
  execfile(os.getenv("HOME")+"/.eev/ee.py", globals())

* (eepy "print(1+2)")
* (eepy "def foo (x):\n    return x*x\n\nprint foo(5)")

`M-x eepy' and `M-x eev'
Now let's define a more realistic `eepy' - one that can also be
called interactively. We want `M-x eepy' to save the current
_region_ into the temporary script; `eepy' has to be a _command_,
and we will use the argument "r" to its `interactive' clause,
to make the function `eepy' receive two numbers - the start and
the end of the region - and it will pass these two numbers to

  (defun eepy (s &optional e)
  "Save the region between S and E (or the string S) into ~/.eev/ee.py ."
    (interactive "r")
    (eev s e "~/.eev/ee.py"))

When the first argument, `s', to `eev', is a number, not a
string, then `eev' expects the second argument, `e', to also be a
number - and then `s' and `e' are considered as the extremities
of a region of text in the current buffer. This idea - that the
first argument can be either a string or a number - comes from:

  (find-efunctiondescr 'write-region "If START is a string")

But try these:

  (ee-se-to-string         "foo" nil)
  (ee-se-to-string-with-nl "foo" nil)
  (ee-se-to-string         "foo\n" nil)
  (ee-se-to-string-with-nl "foo\n" nil)
  (ee-se-to-string         (- (point) 5) (point))
  (ee-se-to-string-with-nl (- (point) 5) (point))
  (ee-se-to-string         (point) (- (point) 5))
  (ee-se-to-string-with-nl (point) (- (point) 5))


  (find-elnode "Defining Commands")
  (find-defun-intro "\ninteractive\n")
  (find-efunction 'eev)