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




What is a hyperlink?
====================
In a previous tutorial - (find-eval-intro) - we saw that several
kinds of sexps can be used as hyperlinks. For example, these:

  (find-fline "/tmp/")
  (find-node "(emacs)Lisp Eval")
  (find-efunctiondescr 'find-file)
  (find-efunction      'find-file)
  (find-man "cat")

Hyperlinks in a web browser _usually_ take us to a different
page, or to a different position in the same page, and in those
cases it is possible to go back to previous position from there;
but sometimes hyperlinks - or webpage buttons - are associated to
Javascript code, and "following the link" then means executing
that code. Web browsers try to make it impossible to have
hyperlinks or webpages that will send out your private
information, or that will put your system in a unusable state.
Security is web browsers is achieved by restricting what the
scripts in a page can do.

Sexp hyperlinks, in contrast, can do essentially anything - and,
instead of _security_, they have _transparency_. The code that a
sexp hyperlink will execute is visible, and users are supposed to
know that sexp hyperlinks with `find-fline', `find-node',
`find-efunctiondescr', etc, are very safe - but the ones that
start with `find-sh' may not be. It is possible to write
something like:

  (find-sh "<code that deletes all your e-mails>")

but it is not possible to hide that action behind an
innocent-looking button that says "click for a larger image".

So, _any_ elisp sexp can be _used_ as a sexp hyperlink; but
people are only going to follow a sexp hyperlink if they can more
or less predict (quickly!) what that hyperlink is going to do...
Readability is important, so let's take a look at the most common
kinds of hyperlinks.




Elisp hyperlinks buffers
========================
Emacs has several help commands, whose bindings start with `C-h',
that display their information in (temporary) "help buffers" -
and in many cases these generated help buffers have hyperlinks,
that can be followed by typing <RET> on them.

Eev has something similar, but using the prefix `M-h' and
following very different design decisions. Let's start with a
comparison, between Emacs's `C-h f' (`describe-function') and
eev's `M-h M-f' (`find-efunction-links'). Remember that `M-e'
accepts prefix arguments, and that `M-2 M-e' displays the target
of a hyperlink at another window without switching to there; use
that on the two sexps below to see the results by yourself:

  "C-h f   find-file" -> (find-efunctiondescr  'find-file)
  "M-h M-f find-file" -> (find-efunction-links 'find-file)

Note that we used `find-efunctiondescr' instead of
`describe-function'; `find-efunctiondescr' is a variant of
`describe-function' that that follows eev's conventions, as
explained here:

  (find-eval-intro "main conventions")

`C-h f find-file' produces a buffer with readable text and
"usual" hyperlinks that can be followed by typing RET on them,
while `M-h M-f find-file' produces a buffer like this:

   ___________________________________________________________
  |# (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-estring (documentation 'find-file))                |
  |# (find-estring (documentation 'find-file t))              |
  |# (symbol-file 'find-file 'defun)                          |
  |# (find-fline (symbol-file 'find-file 'defun))             |
  |                                                           |
  |# (Info-goto-emacs-command-node 'find-file)                |
  |# (find-enode "Command Index" "* find-file:")              |
  |# (find-elnode "Index" "* find-file:")                     |
  |                                                           |
  |                                                           |
  |--:**-  *Elisp hyperlinks*   All L1     (Fundamental eev)--|
  |___________________________________________________________|

What is that?...




Elisp hyperlinks buffers conventions
====================================
Let's refer to Emacs's help buffers as "C-h buffers" and to
eev's elisp hyperlink buffers as "M-h buffers". Here is a quick
list of the main differences and conventions; some of them will
be expanded later:

  1) C-h buffers are usually named "*Help*", while
     M-h buffers are usually named "*Elisp Hyperlinks*";

  2) C-h buffers are generated by functions called "describe-*",
     M-h buffers are generated by functions called "find-*-links";

  3) C-h buffers may contain "usual-looking" links, that can be
     followed by typing RET on them, and this is implemented via
     "buttons"; C-h buffers are "ascii plus text properties",
     while M-h buffers are plain ascii;

  4) C-h buffers are read-only, while
     M-h buffers are read-and-write. The idea is that we can not
     only follow the hyperlinks in a M-h buffer but also modify
     them - usually by "refining" them, like this,

       (find-eval-intro "Refining hyperlinks")

     then test the modified versions, and copy-and-paste those
     hyperlinks to other, more permanent places. This is much
     easier to do when we are working in plain ascii; the buttons
     in C-h buffers are non-trivial to create, to edit and to
     save.

  5) C-h buffers are _readable_, while
     M-h buffers may look like (technical) gibberish.

     This is intentional - M-h buffers have a do-it-yourself,
     "I'm the result of a 5-minute hack" feeling because most
     of them started just like that, as 5-minute hacks that
     turned out to be useful enough, and only suffered very minor
     changes later on. Try this:

       (find-find-links-links)

     Most `find-*-links' were created from that template - and it
     should be easy to create other ones.

  5) Many `M-h' commands, like `M-h f' and `M-h M-i', generate
     sexp hyperlinks that "point to where we are now"; but once
     we are in an M-h buffer this idea - whose basis is:
     from (almost) anywhere in Emacs it should to be easy to
     create a hyperlink to where we are now - changes to:

  6) The first line (the "top sexp") of an M-h buffer
     regenerates the buffer. And, at last,

  7) The elisp hyperlinks in M-h buffers are prefixed by the
     string in `ee-hyperlink-prefix'.



`find-here-links'
=================
The most important of the commands that generates buffers with elisp
hyperlinks - "M-h commands", in the terminology explained above - is
`find-here-links', which integrates most of the functionalities of
several more basic M-h commands. We will explain first what it _does_,
then its _usage_.

`find-here-links' is bound to `M-h M-h' to make it very easy to
invoke. If you are reading this then "here" means the buffer
"*(find-links-intro)*", in a certain position. Try to type `M-h M-h';
you will get a buffer like this,

   ____________________________________________________________
  |# See:                                                      |
  |# (find-links-intro "`find-here-links'")                    |
  |# (find-efunctiondescr 'eev-mode "M-h M-h")                 |
  |                                                            |
  |# (find-links-intro)                                        |
  |                                                            |
  |                                                            |
  |--:**-  *Elisp hyperlinks*   All L1     (Fundamental eev)  -|
  |____________________________________________________________|

which contains a 3-line header with help links, that we will explain
soon, and then a link to "here", i.e., to the buffer
"*(find-links-intro)*". Note that the link

  (find-links-intro)

can be "refined" to, for example,

  (find-links-intro "which contains a 3-line header")

using the tricks described in these sections:

  (find-eval-intro "Refining hyperlinks")
  (find-eval-intro "Producing and refining hyperlinks")
  (find-eval-intro "Producing and refining hyperlinks" "`M-h M-2'")
  (find-eval-intro "Producing and refining hyperlinks" "`M-h2hy'")

but `find-here-links' by itself only produces "unrefined" links - so
when we say that `find-here-links' produces links to "here" we mean
just "to the current buffer", not "to the a certain position in the
current buffer".

`find-here-links' works for several kinds of "here"s - it works for
intros like this one, for Info pages, for manpages, for files and
directories, for descriptions of Emacs functions and variables, and
for a few other cases. Try the sexps below:

  (find-here-links-test '(find-eval-intro))
  (find-here-links-test '(find-node "(dir)Top"))
  (find-here-links-test '(find-enode "Lisp Eval"))
  (find-here-links-test '(find-fline "~/"))
  (find-here-links-test '(find-eevfile "eepitch.el"))
  (find-here-links-test '(find-efunction 'ee-eval-last-sexp))

  (find-here-links-test '(find-efunctiondescr 'ee-eval-last-sexp))
  (find-here-links-test '(find-evardescr      'ee-hyperlink-prefix))
  (find-here-links-test '(find-efacedescr     'eepitch-star-face))

  (find-here-links-test '(find-ecolors "\nred"))
  (find-here-links-test '(find-efaces  "eepitch-star-face"))
  (find-here-links-test '(find-customizegroup 'rcirc))

  (find-here-links-test '(find-man "1 cat"))
   [^ oops, this test doesn't work on multi-window settings...]

Each one of them tests a different case of `find-here-links',
creating a window setup like this:

   ______________________________________ 
  |               |                      |
  |               |      target of       |
  |               |        sexp          |
  |     this      |______________________|
  |     intro     |                      |
  |               |  result of running   |
  |               |  find-here-links on  |
  |               |   [target of sexp]   |
  |_______________|______________________|

The cursor is kept at the left window ("this intro"), so you
can compare the different cases using just <up>, <down>, and M-e.




`find-here-links': usage patterns
=================================
Typically what happens is this. We are putting our notes - eepitch
blocks, hyperlinks, etc - in a certain file; let's refer to it as the
"e-script". Then we start to navigate for information, and we find
something interesting. We want to add a link pointing to that
"something interesting" to our e-script notes - but for that we need
to produce that sexp hyperlink, and ideally we would like to do that
in a way that does not disturb much our attention. Consider this
diagram [note: it DOES NOT imply that the Emacs frame is split into three
windows - typically we will switch between buffers in a single window]:

   ______________________________________ 
  |               |                      |
  |               |      something       |
  |              ==>    interesting      |
  |   e-script    |_________||___________|
  |               |         \/           |
  |               |  result of running   |
  |              <== find-here-links on  |
  |               |   [sthing intrstng]  |
  |_______________|______________________|

and this series of steps:

  0. We start navigating from the e-script buffer, and when we
  1. find something interesting [in another buffer], we
  2. run `find-here-links' at the "something interesting" buffer,
  3. identify among the sexps in the find-here-links buffer one that
     points to that "something interesting",
  4. copy that sexp to the kill-ring,
  5. go back to the e-script buffer,
  6. insert that sexp into the e-script buffer,
  7. execute that sexp to go back to the "something interesting",
  8. continue navigating & doing stuff.

At (8) we are essentially back to (1), but we have added to our
e-script buffer a link to "something interesting". 

Note that to add refining we need to add a step before (2) and
another one after (3):

  1.9. select a string to search for and copy it to the kill-ring,
  3.1. refine that sexp using the "string to search for" (with M-h2hy)

[TO DO: explain the keys that I normally use to perform all
this; explain why I am not the right person to optimize these
steps - because I can type these key sequences without thinking,
and step (3) sometimes gives several sexps for us to choose from]




Basic and non-basic hyperlinks
==============================
How can we learn to recognize what each hyperlink sexp does? And
which ones are safe(r), and which ones are not? How do we
classify all hyperlink sexps?

We can start by dividing the hyperlink functions into a fixed set
of "basic" ones and an unbounded set of "non-basic" ones. In
the buffer generated by

  (find-efunction-links 'find-file)

these hyperlinks

  (find-efunctiondescr 'find-file)
  (find-efunction 'find-file)
  (find-efunctionpp 'find-file)
  (find-efunctiond 'find-file)
  (find-estring (documentation 'find-file))
  (find-estring (documentation 'find-file t))
  (find-fline (symbol-file 'find-file 'defun))

calls "basic" eev hyperlink functions, that are just interfaces
to Emacs function slightly tweaked into functions that follow
eev's conventions - they are refinable, use the current window,
etc. But these two,

  (find-enode "Command Index" "* find-file:")
  (find-elnode "Index" "* find-file:")

are generated by calls to `code-c-d' or similar functions, that
generate some elisp code as text, from templates, and evaluate
that code, as explained here:

  (find-code-c-d-intro)
  (find-pdf-like-intro)
  (find-audiovideo-intro)

The `code-*' functions define hyperlink functions whose names are
of the form `find-{stem}{suffix}', and each of these `code-*'
function has an associated `find-code-*' function that just
displays what the corresponding `code-*' would execute. So one
way to get acquainted to the most common of these suffixes is to
follow these hyperlinks:

  (find-code-c-d      "CODE" "/DIR/" :info "INFO")
  (find-code-pdf      "CODE" "FILE.pdf")
  (find-code-pdf-text "CODE" "FILE.pdf")
  (find-code-audio    "CODE" "FILE")
  (find-code-video    "CODE" "FILE")

From these only the functions whose suffixes end with "sh" or
"sh0" and inherently dangerous; the others are usually safe if
no hacks had been done.

Some hyperlinks functions - for example the ones created by
`code-pdf', `code-audio', etc - invoke external programs, and
_may_ behave in bad ways when given unsafe arguments; these
functions are implemented using the low-level functions
`find-bgprocess' and `find-callprocess', which of course are
unsafe too.

Also, the functions `find-*-links', `find-*-intro' and
`find-code-*' simply create temporary buffers, and are thus very
safe - but, as always, think carefully before executing any code
that they generate.




ee-hyperlink-prefix
===================
`ee-hyperlink-prefix' is both a variable and a function that
helps us set that variable; it started to an experiment on how to
create an alternative to `M-x customize' and ended up becoming
the inspiration for all the `find-*-links' functions.

If you run `M-x ee-hyperlink-prefix' you should get a buffer like
this:

   ___________________________________________________________
  |# (ee-hyperlink-prefix)                                    |
  |# (setq ee-hyperlink-prefix "# ")                          |
  |                                                           |
  |# (setq ee-hyperlink-prefix "# ")                          |
  |# (setq ee-hyperlink-prefix ";; ")                         |
  |# (setq ee-hyperlink-prefix "-- ")                         |
  |# (setq ee-hyperlink-prefix "// ")                         |
  |# (setq ee-hyperlink-prefix "% ")                          |
  |                                                           |
  |                                                           |
  |--:**-  *Elisp hyperlinks*   All L1     (Fundamental eev)--|
  |___________________________________________________________|

where the first line regenerates the buffer, the second line sets
the variable `ee-hyperlink-prefix' to its current value, and each
one of the lines after the first blank line sets
`ee-hyperlink-prefix' to one of several fixed common values. If
we change the value of `ee-hyperlink-prefix' with one of the
`setq's and execute the first line again we see that all the
prefixes, plus the argument "# " in the second line, change.
Try this, with `M-2 M-e' on each line:

  (progn (setq ee-hyperlink-prefix "# ") (ee-hyperlink-prefix))
  (progn (setq ee-hyperlink-prefix "% ") (ee-hyperlink-prefix))




The first line regenerates the buffer
=====================================
[To do: explain this convention with examples; explain the
conventions for the "variants of the first line"]

  (find-find-links-links)
  (find-find-links-links "\\M-u")
  (find-find-links-links "\\M-u" "USERTEST")
  (find-find-links-links "\\M-u" "USERTEST" "a")
  (find-find-links-links "\\M-u" "USERTEST" "a b")
  (find-find-links-links "\\M-u" "USERTEST" "a b c")



Pointing to where we are now
============================
Several of the `M-h' commands are mainly meant to help us
generate hyperlinks to "where we are now": to the current file,
to the current Info page, to the current `find-*-intro', to an
Emacs function or variable we are inspecting, to the current
buffer, and so on. They don't try to be very smart -

[To do: write this]

  (find-efunctiondescr 'eev-mode)
  (find-efunctiondescr 'eev-mode "M-h f")

                                  (eek "M-h M-i")

         (find-enode "Lisp Eval")
  (progn (find-enode "Lisp Eval") (eek "M-h M-i"))

  (eek "M-h f    ;; find-file-links")
  (eek "M-h M-b  ;; find-ebuffer-links")

  for example, `M-h M-i' generates links to
     the current "intro" buffer - like this one - _and_ to the
     current Info page (the "i" in `M-h M-i' has two meanings).
     Try:

       (eek "M-h M-i")

     you should get something like this:

      ___________________________________________________________
     |# (find-einfo-links "links")                               |
     |                                                           |
     |[No "*info*" buffer]                                       |
     |                                                           |
     |# (find-links-intro)                                       |
     |                                                           |
     |                                                           |
     |--:**-  *Elisp hyperlinks*   All L1     (Fundamental eev)--|
     |___________________________________________________________|



The rest of the buffer
======================

Several elisp hyperlinks buffers are composed of two parts: a
series of links at the top, and then a template-generated text
that is mean to be copied to somewhere else. The canonical
example is 

  (find-eev-update-links)

which ends with stuff that you can copy to your .emacs file to
make Emacs load eev by default. The end of the buffer generated
by `find-eev-update-links' looks more or less like this:

   ____________________________________________________________
  |# (ee-copy-rest 0 '(find-fline "~/.emacs"))                 |
  |                                                            |
  |;; Load eev2.                                               |
  |;; See:  (find-file "~/eev/")                               |
  |;;       (find-file "~/eev/eev-readme.el")                  |
  |;; Generated by: (find-eev-update-links "~/eev/")           |
  |;;                                                          |
  |(add-to-list 'load-path "~/eev/")                           |
  |(require 'eev2-all)      ; (find-eev "eev2-all.el")         |
  |(eev-mode 1)             ; (find-eev "eev-mode.el")         |
  |                                                            |
  |                                                            |
  |--:**-  *Elisp hyperlinks*   Bot L56    (Fundamental eev)---|
  |____________________________________________________________|

The line with `ee-copy-rest' is a hack. Its first argument is a
number, that we will call the "skip", and the second is
a (quoted) sexp hyperlink, that we will call the "code". The
rule that defines what is the "rest of the buffer" is this:

  Move to the beginning of the next line, then skip (i.e., move
  down) more SKIP lines. The rest of the buffer is everything
  from that point on.

A sexp like `(ee-copy-rest ...)' does several things:

  1) it highlights the rest of the buffer temporarily (like as
     with `M-0 M-e'),

  2) it copies the rest of the buffer to the kill ring (like as
     with `M-w'),

  3) it runs CODE to open its target in a window at the right
     side (like as with `M-3 M-e')

[To do: add examples - including examples that let us create Lua
scripts etc]