(Re)generate: (find-links-conv-intro)
Source code: (find-efunction 'find-links-conv-intro)
More intros: (find-eev-quick-intro)
(find-eval-intro)
(find-eepitch-intro)
This buffer is _temporary_ and _editable_.
It is meant as both a tutorial and a sandbox.
This intro explains some conventions on the names and behaviors
of the hyperlink functions of eev.
1. Security vs. transparency
In a previous tutorial - here:
(find-eev-quick-intro "3. Elisp hyperlinks")
we saw that several kinds of sexps can be used as hyperlinks. For
example, these ones:
(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 in 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.
2. Learning to read 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', as explained here:
(find-eev-quick-intro "9.1. `code-c-d'")
(find-eev-quick-intro "9.1. `code-c-d'" "find-code-c-d")
Check:
(find-code-c-d "e" ee-emacs-lisp-directory :info "emacs")
(find-code-c-d "el" ee-emacs-lisp-directory :info "elisp")
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-page "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-page', `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.
3. Classification
Here's one way to classify the hyperlink functions defined by
eev. It's far from perfect, but that's how they are divided in
the source files.
We start from some observations:
a) The functions `code-c-d', `code-pdf-page' and
`code-pdf-text' define new hyperlink functions; we called
these new hyperlink functions "short(er) hyperlinks".
b) Functions like `find-efunction-links' create temporary
buffers with hyperlinks using `find-elinks', that is
described here:
(find-eev "eev-elinks.el" "find-elinks")
c) Functions like `find-latex-links' create temporary buffers
with hyperlinks plus templated text; they use `find-elinks'
and `ee-template0', that is described here:
(find-eev "eev-wrap.el" "ee-template0")
d) Functions like `find-sh' and `find-pdf-page' call external
processes.
e) `code-c-d' has a debugging function associated to it:
`find-code-c-d', that shows the "templated code" that the
corresponding `code-c-d' would execute. `code-pdf-page' has
`find-code-pdf-page' as its associated debugging function,
and so on.
f) `find-here-links' and its variants create temporary buffers
that violate this convention:
(find-links-intro "5. The first line regenerates the buffer")
g) If we call the hyperlinks in the items above "non-basic"
then we get - by exclusion! - a notion of what are "basic
hyperlinks".
Here is the classification, with the class or idea at the left
and a hyperlink to the source file at the right:
Basic hyperlinks: (find-eev "eev-blinks.el")
External processes: (find-eev "eev-plinks.el")
`find-elinks': (find-eev "eev-elinks.el")
`find-elinks'+`ee-template0': (find-eev "eev-tlinks.el")
`find-here-links': (find-eev "eev-hlinks.el")
`code-c-d' and `find-code-c-d': (find-eev "eev-code.el")
`code-pdf*' and `find-code-pdf*': (find-eev "eev-pdflike.el")
4. Elisp hyperlinks: some conventions
One of the main ideas of eev is that elisp hyperlinks can be
"followed" with `M-e', and we can _usually_ "go back" with `M-k'.
We saw a few cases where `M-k' didn't work for going back:
(find-eev-quick-intro "3. Elisp hyperlinks" "eek")
(find-eev-quick-intro "3. Elisp hyperlinks" "find-sh0")
(find-eev-quick-intro "8.1. Introduction: `to'")
(find-eev-quick-intro "9.3. Hyperlinks to PDF files" "find-pdf-page")
Emacs has several functions that _sort_ of can be used as hyperlinks,
but that are kind of messy. For example, this one
(man "cat")
may split the current window or even create another frame, and this
one
(describe-function 'find-file)
displays a lot of output in the echo area. Compare them with their
eev-ish variants:
(find-man "cat")
(find-man "cat" "-n, --number")
(find-efunctiondescr 'find-file)
(find-efunctiondescr 'find-file "RET")
They:
1) Have names that start with "find-" to indicate that they are from
eev (practically all functions and variables defined in eev start
with the prefixes "find-" or "ee"),
2) they open the new buffer in the current window (to make it
easier to go back),
3) they don't display much output in the echo area,
4) calls to them can be "refined" with a pos-spec.
4.1. Conventions on 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 help buffers have hyperlinks, that can be
followed by typing <RET> on them. They are explained here:
(find-enode "Help")
An example:
(find-enode "Key Help")
(eek "C-h k <down>")
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'). Try:
"C-h f find-file" -> (describe-function 'find-file)
"C-h f find-file" -> (find-efunctiondescr 'find-file)
"M-h M-f find-file" -> (find-efunction-links 'find-file)
`describe-function' and `find-efunctiondescr' are similar, but
the second one is better for use with `M-e'; we saw the reasons
in the previous section. `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) ------|
|_____________________________________________________________|
that looks very cryptic at first. It has lots of elisp
hyperlinks, some of them starting with "find-" and following
the conventions explained in section 2, some others not; some of
the sexps in it are easy to understand - try all of them! -,
while others are very technical.
This is an example of an "elisp hyperlinks buffer". The
functions that generate elisp hyperlinks buffers, like
`find-efunction-links', follow the convention (1)-(4) from
section 2 plus:
5) The buffer name is "*Elisp hyperlinks*",
6) The first sexp(s) in the elisp hyperlinks buffer regenerates
the buffer,
7) all the sexps are prefixed with the string stored in the
variable `ee-hyperlink-prefix', to let these sexps be
pasted into e-scripts as comments.
To understand the role of the first sexp let's look at the next
level of complexity.
4.2. Conventions on templated text
Some functions, like `find-latex-links', generate buffers that
are composed of a series of elisp hyperlinks, as in the previous
section, followed by some "templated text". Try to execute the
two sexps below with `M-2 M-e':
(find-latex-links)
(find-latex-links "/tmp/latextest")
(find-latex-links "~/LATEX/foobar")
Remember that `M-2 M-e' splits the window like this,
__________ __________
| | |
| source | target |
| | |
|__________|__________|
where the "source buffer" is this one and the "target buffer" will be
this in the first case,
___________________________________________________________________
|# (find-latex-links "{stem}") |
|# (find-latex-links "/tmp/test") |
|# (find-eev-quick-intro "`find-latex-links'") |
|# (ee-copy-rest 1 '(find-fline "{stem}.tex")) |
| |
|% (defun c () (interactive) (find-sh "pdflatex {stem}.tex")) |
|% (defun d () (interactive) (find-pdf-page "{stem}.pdf")) |
|% (defun e () (interactive) (find-fline "{stem}.tex")) |
|% |
|\documentclass{article} |
|\begin{document} |
| |
|\end{document} |
| |
| |
| -:**- *Elisp hyperlinks* All L1 (Fundamental) ------------|
|___________________________________________________________________|
In the second case all the "{stem}"s are substituted by
"/tmp/latextest", and in the third case they are substituted by
"~/LATEX/foobar". If you execute the second sexp in that
buffer, that is,
# (find-latex-links "/tmp/test")
you get the buffer with the "{stem}"s substituted by "/tmp/test".
We can think that `find-latex-links' generates an "*Elisp
hyperlinks*" buffer from a template that depends on an argument
`stem', and:
1) when `stem' is nil it is set to "{stem}",
2) the first sexp corresponds to how `find-latex-links' was
called (after the substitution of nils above),
3) the second sexp shows a typical, useful, value for `stem',
4) we can edit by hand the `stem's in the `find-latex-links'
sexps in first two lines, and run them to regenerate the
buffer with the new, hand-edited values.
4.3. Elisp hyperlinks buffers vs. Help buffers
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'.