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




Introduction
============
In many situations - for example, when we want to script a
debugger, or to test programs that have to talk to one another,
or to control several external machines simultaneously - the
default window setup for eepitch, which is this,

   ____________________
  |          |         |
  |          |         |
  |  script  |  shell  |
  |          |         |
  |          |         |
  |__________|_________|

is not enough; other setups, like these,

   ______________________
  |          |           |        _________________________ 
  |          |  shell A  |       |            |            |
  |          |___________|       |   script   |     GDB    |
  |  script  |           |       |            |            |
  |          |  shell B  |       |____________|____________|
  |          |___________|       |            |            |
  |          |           |       |   program  |   program  |
  |          |  shell C  |       |     I/O    |    source  |
  |__________|___________|       |____________|____________|

may be necessary. Eev comes with a few _low-level_ tools for
creating these setups; they are not very smart, but they should
be easy to understand and to tweak - and I have the impression
that ideas for good high-level tools will only come from
practical experimentation.



`find-wset'
===========
Suppose that we are in a buffer A, and we want to create a window
configuration with A at the left, and with the buffers B and C
stacked on one another at the right. That is:

   ___________           ___________ 
  |           |         |     |     |
  |           |         |     |  B  |
  |     A     |   -->   |  A  |_____|
  |           |         |     |     |
  |           |         |     |  C  |
  |___________|         |_____|_____|

To do that from the keyboard we could type this:

  C-x 3   C-x o   C-x b B RET   C-x 2   C-x o   C-x b C RET

You can try that here (the initial `C-x 1' is an extra, for
convenience):

  (eek "C-x 1         ;; delete-other-windows
        C-x 3         ;; split-window-horizontally (left/right)
        C-x o         ;; other-window              (-> right)
        C-x b B RET   ;; switch to the buffer `B'
        C-x 2         ;; split-window-vertically   (upper/lower)
        C-x o         ;; other-window              (-> lower right)
        C-x b C RET   ;; switch to the buffer `C'
        ")

We can write something equivalent to that as a `progn', in a way
that makes it easy to replace later the `C-x b B RET' and the
`C-x b C RET' by arbitrary sexp hyperlinks. We get:

  (progn (eek "C-x 1 C-x 3 C-x o")
         (find-ebuffer "B")
         (eek "C-x 2 C-x o")
         (find-ebuffer "C")
         (eek "C-x o")
         )

When I started to rewrite my window configurations into that form
I realized that the `eek's were being used in a very limited way
- they only invoked a very small repertoire of window commands,
all of them starting with `C-x'. So maybe I should have an
interpreter for a simple language of window commands and sexp
hyperlinks, in the which window setup above could be expressed
like this:

  `("13o"
    (find-ebuffer "B")
    "2o"
    (find-ebuffer "C")
    "o"
   )

`find-wset' supports something like that, but with all the window
command strings collapsed into a single one, with "_"s meaning
"execute the next sexp from the sexp list". The corresponding
call to `find-wset' is:

  (find-wset "13o_2o_o" '(find-ebuffer "B") '(find-ebuffer "C"))

For the full list of supported window command characters - and
how to extend it - see the source:

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




High-level words
================
Very often we want to create window setups like

   _______________            _______________ 
  |       |       |          |       |       |
  |       |       |          |       |   B   |
  |   A   |   B   |    or    |   A   |_______| ;
  |       |       |          |       |       |
  |       |       |          |       |   C   |
  |_______|_______|          |_______|_______|

there are shorthands for that. If you run

  (find-2a sexpA sexpB)

that will create a window setting like the one at the left above,
initially with two copies of the current buffer, then will run
sexpA at the window "A" and sexpB at the window "B", and
finally will select the window "A", i.e., leave the cursor at
the window at the left; this

  (find-2b sexpA sexpB)

will do exactly the same as the `(find-2a ...)' above, but will
select the window "B" - the one at the right - at the end of
the process. For three-window settings we have these:

  (find-3a sexpA sexpB sexpC)
  (find-3b sexpA sexpB sexpC)
  (find-3c sexpA sexpB sexpC)

all three create the three-window setting at the right above,
initially with all three windows displaying the current buffer,
then run sexpA at the window "A", sexpB at the window "B",
and sexpC at the window "C"; the difference is that find-3a
selects the window "A", find-3b the window "B", find-3c the
window "C".




Several eepitch targets
=======================
If we try to build a window setup like this one, with two eepitch
targets, with just `find-wset', we will run into problems -

   ________________________
  |          |             |
  |          |   *shell*   |
  |  script  |_____________|
  |          |             |
  |          |  *shell 2*  |
  |__________|_____________|

because `(eepitch-shell)' and `(eepitch-shell2)' try to create a
shell buffer and put it in an _another_ window, not the one we
are in... one solution is to call the `(eepitch-*)' sexps inside
an `ee-here', like this:

  (ee-here '(eepitch-shell))
  (ee-here '(eepitch-shell2))

where `ee-here' is a hack that runs a sexp in a way that
preserves the current window configuration, then switches the
buffer in the current selected window to the current eepitch
target. We can use this to create the window setting above,

  (find-wset "13o2_o_o"
             ' (ee-here '(eepitch-shell))
             ' (ee-here '(eepitch-shell2))
             )

This is too long - and would make a very bad one-liner - but
there are two shorthands. First, "e" is a variant of "_" that
runs its sexp inside an `(ee-here ...) - so this is equivalent
the thing above,

  (find-wset "13o2eoeo"
             '(eepitch-shell)
             '(eepitch-shell2)
             )

Second, these things are useful enough to deserve a high-level
word, so this is equivalent to:

  (find-3ee '(eepitch-shell) '(eepitch-shell2))




Restarting eepitch targets
==========================
Sometimes we want to do the same as above, but restarting both
eepitch targets, i.e., something like this:

  (find-3ee '(progn (eepitch-shell)  (eepitch-kill) (eepitch-shell))
            '(progn (eepitch-shell2) (eepitch-kill) (eepitch-shell2))
            )

There's a variant of `ee-here' that does that: `ee-here-reset'.
For example,

  (ee-here-reset '(eepitch-shell2))

is equivalent to:

  (ee-here '(progn (eepitch-shell2) (eepitch-kill) (eepitch-shell2)))

and the letter "E" is a variant of "e" that uses
`ee-here-reset' instead of `ee-here'; also, `find-3EE' is a
variant of `find-3ee' that restarts both targets. Let's adapt
this example,

  (find-eepitch-intro "Other targets")

to make it show the two eepitch targets at once in a three-window
settings. It becomes:

* (find-3EE '(eepitch-shell) '(eepitch-python))
* (eepitch-shell)
echo Hello... > /tmp/o
* (eepitch-python)
print(open("/tmp/o").read())
* (eepitch-shell)
echo ...and bye >> /tmp/o
* (eepitch-python)
print(open("/tmp/o").read())

** Now compare:
* (eek "C-x 1")
* (find-3ee '(eepitch-shell) '(eepitch-python))
* (find-3EE '(eepitch-shell) '(eepitch-python))



Non-trivial examples
====================
See:

  (find-prepared-intro "An `ee' for Python")
  (find-rcirc-intro "The server buffer and the channel buffers")



Eepitch blocks for two targets
==============================
An eepitch script with two targets uses several different kinds
of red star lines - `(eepitch-target1)', `(eepitch-target2)',
`(find-3EE ...)', `(find-3ee ...)', etc. We don't want to have to
type all those by hand, so there is a hack similar to `M-T' that
generates all those kinds from just "target1" and "target2"
to let us just copy around the sexps we need. It is bound to
`meta-shift-3', which Emacs sees as `M-#'. Compare the result of
typing `M-T' here,

python

with the result of typing `M-#' on this line,

shell python

which yield this:

* (find-3EE '(eepitch-shell) '(eepitch-python))
* (find-3ee '(eepitch-shell) '(eepitch-python))
* (eepitch-shell)
* (eepitch-python)

Note that we use to `find-3EE' to restart targets instead of
`eepitch-kill' (this is non-trivial - think about it =/)...



Adding support for new characters in `find-wset'
================================================
The standard characters supported by `find-wset' are these:

  char  action                       key
  ---- ---------------------------- ---------
  `1'  `delete-other-windows'       (C-x C-1)
  `2'  `split-window-vertically'    (C-x C-2)
  `3'  `split-window-horizontally'  (C-x C-3)
  `s'  `split-window-sensibly'
  `o'  `other-window'               (C-x o)
  `+'  `balance-windows'            (C-x +)
  `_'  execute the next sexp

but the action of each one is defined in a different function,
and to add support for a new character, say, `=', we just need to
define a function with the right name - in this case,
`find-wset-='.

The source code is simple enough, so take a look:

  (find-eev "eev-multiwindow.el" "find-wset-_")
  (find-eev "eev-multiwindow.el" "find-wset-=")
  (find-eev "eev-multiwindow.el" "find-wset-!")

Note that `find-wset-!' restarts an eepitch target, while
`find-wset-=' will reuse an eepitch target if its buffer already
exists. [Obs: "=" and "!" have been mostly superseded by
"e" and "E"... to do: explain this]


See: (find-prepared-intro)

  [Example at find-prepared-intro]




Executing key sequences at other windows
========================================
It is possible to use multi-window settings, together with the
trick that `<f8>' on a red star line executes it as Lisp and
moves down, to create tutorials for Emacs modes. An example:



A tutorial for Info mode
========================
Here's a mini-tutorial for Info mode, demonstrating how to
navigate in Info using the usual movement keys, plus TAB,
<backtab>, RET, l (last), u (up), n (next), p (prev), q (quit),
C-h i, and the digits 1-9. Note that the display in Info mode is
like this:

   ____________________________________________
  |Next: Nonincremental Search,  Up: Search    | <- next/prev/up
  | (emacs)Top > Search > Incremental Search   | <- breadcrumbs
  |                                            |
  | 19.1 Incremental Search                    | <- section number /
  |                                            |    node name (long)
  |  (...)                                     |
  |                                            |
  |--:%%-  *info* (emacs) Incremental Search   |
  |____________________________________________|

Here:

** Define some hacks
* (defun ow (n) (other-window n))
* (defun eeoe (code) (ow 1) (prog1 (eval code) (ow -1)))
* (defun eeok (keystr) (eeoe `(eek ,keystr)))
*
** Prepare the windows
* (ee-kill-buffer "*info*")
* (find-wset "1so_o" '(find-enode "Search"))
*
** The arrows (and other movent keys) work as expected.
** Watch the cursor in the Info window...
* (eeok "3*<down>")
* (eeok "10*<right>")
*
** TAB and <backtab> move to the next and to the previous link.
** Note that they consider all the links in a page, not only
** the ones in menus - including the breadcrumb links at the top.
* (eeok "TAB       ;; Info-next-reference")
* (eeok "TAB       ;; Info-next-reference")
* (eeok "TAB       ;; Info-next-reference")
* (eeok "TAB       ;; Info-next-reference")
* (eeok "TAB       ;; Info-next-reference")
* (eeok "<backtab> ;; Info-prev-reference")
* (eeok "<backtab> ;; Info-prev-reference")
* (eeok "<backtab> ;; Info-prev-reference")
* (eeok "<backtab> ;; Info-prev-reference")
*
** RET follows a link, l (last) goes back.
** Watch the section number: 19 -> 32.3.6 -> 19.
* (eeok "RET       ;; Info-follow-nearest-node")
* (eeok "l         ;; Info-history-back")
*
** The digits 1-9 can be used to go straight to subsections.
** For example, a `4' would follow the 4th _menu_ link -
** ignoring the non-menu links.
** Watch the section number: 19 -> 19.1 -> 19.1.1.
* (eeok "1         ;; Info-nth-menu-item")
* (eeok "1         ;; Info-nth-menu-item")
*
** The keys `u', `n', `p' (up, next, and prev) move through the
** tree structure. Watch the section number:
** 19.1.1 -u-> 19.1 -u-> 19 -n-> 20 -n-> 21 -p-> 20 -p-> 19
* (eeok "u         ;; Info-up")
* (eeok "u         ;; Info-up")
* (eeok "n         ;; Info-next")
* (eeok "n         ;; Info-next")
* (eeok "p         ;; Info-prev")
* (eeok "p         ;; Info-prev")
*
** `q' leaves Info mode - more precisely, it buries the info buffer.
** `C-h i' goes back to the Info buffer (or restarts info). 
* (eeok "q         ;; Info-exit")
* (eeok "C-h i     ;; info")