(Re)generate: (find-eval-intro)
Source code: (find-eev "eev-intro.el" "find-eval-intro")
More intros: (find-eev-quick-intro)
(find-eepitch-intro)
(find-eev-intro)
This buffer is _temporary_ and _editable_.
It is meant as both a tutorial and a sandbox.
Note: this intro is messy and VERY old!
TODO: integrate it with:
(find-eev-quick-intro "2. Evaluating Lisp")
(find-elisp-intro)
1. The standard way to evaluate Lisp: `C-x C-e'
The most important idea in Emacs is that Lisp code can appear
anywhere, and you can evaluate a Lisp expression (a "sexp") by
placing the cursor (the "point") just after it and typing `C-x
C-e'; the result is then displayed in the echo area. Try it in
the line below, with the point in the three different indicated
positions - you should get different results.
(+ (* 2 3) (* 4 5))
^ ^^
| | \
6 20 26
2. The end of line and `M-e'
A common operation is to move the point to the end of the current
line, then run `C-x C-e'. That can be done with `C-e C-x C-e',
but eev-mode implements a shorthand for it: `M-e'. Try it here:
(+ (* 2 3)
(* 4 5)
)
`M-e' accepts several different numeric prefixes that alter its
behavior. We are only interested in one of them now - `M-0 M-e'
highlights the sexp for a fraction of a second instead of
executing it. Try it above.
In some rare occasions we might want to run something like `M-e'
but without moving to the end of the line first. Eev-mode
implements a key binding for that: `M-E' (meta-shift-e). As an
exercise, try to use `M-0 M-E' at several positions below, to
highlight the subsexps `(* 2 3)', `(* 4 5)', and `4'.
(+ (* 2 3) (* 4 5))
3. What to execute, and in what order
Note that the order of evaluation may be important:
(setq a 5)
(setq a 6)
(* a a)
By executing `(setq a 5)' and then `(* a a)' above we get 25,
by executing `(setq a 6)' and then `(* a a)' we get 36 - the
current value of `a' is the one of the last `setq' executed.
An exercise: edit the three sexps above to introduce a
`(setq a 22)', then use that sexp and the `(* a a)' to calculate
the square of 22.
Another exercise: just as `setq' sets variables and can override
their previous values, `defun' defines, and redefines, functions.
Execute the sexps below in different orders to obtain the results
25, 36, 50, and 60.
(setq a 5)
(setq a 6)
(defun f (x) (* x x))
(defun f (x) (* x 10))
(f a)
MORAL: Elisp code can appear anywhere in any Emacs buffer, but it
is _passive by default_. It only gets executed if we move the
point to the right positions and type `C-x C-e', `M-e', or
similar keys. Sexps can be executed any number of times, in any
order, and can be edited and modified.
4. Elisp hyperlinks
Some Emacs functions can be used as hyperlinks. When sexps like
(find-file "/tmp/")
(info "(emacs)Lisp Eval")
(describe-function 'find-file)
(find-function 'find-file)
(man "cat")
are executed they "open a new page" - actually, they create a
new buffer, or reuse it if it already exists - and it is usually
possible to "go back" by killing the new buffer. However for
some functions, like `man', which by default open a manpage in
another window, "going back" would mean something different.
Eev defines several functions to let us use sexps as hyperlinks.
The main conventions on these functions are:
1) their names start with "find-",
2) calls to them can be "refined" with a pos-spec (this will
be discussed below),
3) they open the new buffer in the current window (to make it
easier to "go back" after following them - see the next
section),
4) they don't display much output in the echo area,
5) when they create temporary buffers with lots of sexps then:
a) the first sexp in that buffer is one that can regenerate
that buffer when executed,
b) all the sexps are prefixed with the string stored in the
variable `ee-hyperlink-prefix', to let these sexps be
pasted into scripts as comments (see below).
Note that sometimes the most obvious name for a hyperlink
function starting with `find-' is already taken by Emacs - for
example, `find-file' and `find-function'. In those cases eev use
other names: `find-fline', `find-efunction', etc. Here are the
eev versions of the links above:
(find-fline "/tmp/")
(find-node "(emacs)Lisp Eval")
(find-efunctiondescr 'find-file)
(find-efunction 'find-file)
(find-man "cat")
5. Going back
Web browsers let you follow a hyperlink and then "go back".
There are different ways of going back - if you opened the new
page on a new window or tab, then going back means deleting the
new window or tab (or just switching to the old window/tab); if
you opened the new page on the same window/tab, then you need to
use the "back" button.
Eev-mode defines two keys for "going back": `M-k', that kills
the current buffer, and `M-K', that just hides it ("buries" it
in the bottom of the list of all buffers). Try following the link
below with `M-e', then deleting its buffer with `M-k' to go back:
(find-node "(emacs)Shell")
In some cases we know that we may want to go "forward" again
after going back, and we may not want to delete the target buffer
- for example, because it would take a while to rebuild it again,
or because we would lose the position of the point there. Most
hyperlink functions in eev are able to reuse a buffer that
"looks like" the desired target buffer; the test for
lookalikeness is based on the name of the buffer only. Try to
follow the links below with `M-e', then come back to this buffer
with `M-k', then follow them again. Then try the same thing with
`M-K' instead of `M-k', to see the difference - in the `find-sh'
example below the "sleep" takes one second to run, so
revisiting the existing output buffer after a `M-K' is much
quicker than recreating it anew.
(find-man "1 bash")
(find-sh "sleep 1; echo 'This was run at:'; date")
6. Refining hyperlinks
Note: this, and some of the following sections, were rewritten
and moved to:
(find-refining-intro "1. Pos-spec-lists")
(find-refining-intro "2. Refining hyperlinks")
Most hyperlinks functions defined by eev can be "refined" by
the addition of extra arguments. These extra arguments are called
a "pos-spec" (or a "pos-spec-list") and they specify a
position in the target buffer. The first argument means a certain
line number, when it is a number, or the first occurrence of a
certain string, when it is a string. Try:
(find-node "(emacs)Command Index")
(find-node "(emacs)Command Index" "eval-last-sexp")
Further arguments mean either "move down n lines" or "search
for the next occurrence of a string", depending on whether they
are numbers or strings. Try:
(find-sh "seq 2095 2115")
(find-sh "seq 2095 2115" "2100")
(find-sh "seq 2095 2115" "2100" "9")
(find-sh "seq 2095 2115" "2100" 2)
7. Pos-spec-lists
[Moved to:] (find-refining-intro "1. Pos-spec-lists")
The optional arguments that refine a hyperlink form what we call
a "pos-spec-list". For example, the pos-spec-list here has two
elements,
(find-sh "seq 2095 2115" "2100" "9")
and in most cases an empty pos-spec-list, like this,
(find-sh "seq 2095 2115")
means: "if the target buffer already exists then just open it"
- so that following that hyperlink would jump to the current
position of the point in that buffer.
Pos-spec-lists are usually interpreted by the function
`ee-goto-position'. The first argument is interpreted in a
special way, according to its type:
string -> jump to the first occurrence of
that string in the buffer
number -> jump to the n-th line
and the other arguments are interpreted (recursively) by
`ee-goto-rest':
string -> jump to the next occurrence of that string
number -> move down n lines
list -> evaluate the list
If you want to add support for more complex pos-spec-lists, just
replace `ee-goto-rest' with your own extended version.
8. Anchors and pages
[See:] (find-anchors-intro)
Some hyperlink functions, like `find-efunction' and
`find-evariable', jump to specific positions in buffers - the
beginning of the definition of a function or a variable in the
source code - even when their pos-spec-lists are empty, so they
process all their extra arguments with just `ee-goto-rest'.
Other hyperlink functions transform the first argument of a
pos-spec-list in a special way it if is a string - for example,
in `find-available', which is based on `find-Package',
(find-available "bash")
(find-available "bash" "bash-doc")
the argument "bash" is converted to "\nPackage: bash\n",
and the two hyperlinks above jump to the description of the
package "bash" in the list of the available packages in a
Debian system.
The functions based on `find-anchor' transform an initial string
argument in the pos-spec-list by running `ee-format-as-anchor' on
it [TODO: document this], and the ones based on
`ee-goto-position-page' jump to the n-th "page" of a buffer if
the first argument of the pos-spec-list is a number, n; for
example, if n is 234 that will jump to the 233-th formfeed (233
and not 234 because the page 1 is before the first formfeed). For
more on "pages", see:
(find-pdf-like-intro "PDF-like documents as text")
9. Producing and refining hyperlinks
If you are on an Info page, typing `M-h M-i' will create a
temporary buffer containing a header - which we will discuss
later - and several (possibly equivalent) links to that info
page. Something like this:
________________________________________________________
|;; (find-einfo-links) |
| |
|;; (info "(emacs)Misc Buffer") |
|;; (find-node "(emacs)Misc Buffer") |
|;; (find-enode "Misc Buffer") |
| |
| |
|--:**- *Elisp hyperlinks* All L1 (Fundamental)---|
|________________________________________________________|
These links are meant to be cut & pasted - possibly after
refining them to make them more precise. Let's look first at the
two key sequences that make refining much easier. Remember that
`M-w' (`kill-ring-save') is roughly correspondent to what is
called "copy" is most modern interfaces, and `C-y' (`yank') is
roughly correspondent to "paste". Both `M-w' and `C-y' operate
on Emacs's "kill ring", and to make our examples trivial to
follow we will first put a string on the kill ring:
(kill-new "C-y")
(car kill-ring)
Now let's see how to refine hyperlinks quickly. `M-h M-2'
duplicates the current line; we will use that to refine a copy of
a working hyperlink, instead of working directly on the original,
and risking breaking it. And `M-h M-y' refines the hyperlink on
the current line by adding a string - the top element in the kill
ring - to its sexp. Try this below; you should be able to convert
(find-enode "Kill Ring")
(find-enode "Yanking")
into
(find-enode "Kill Ring")
(find-enode "Kill Ring" "C-y")
(find-enode "Yanking")
(find-enode "Yanking" "C-y")
with few keystrokes, as you can leave the Meta key pressed. The
full key sequence for duplicating and refining is `M-h M-2 M-h
M-y', but we can think of it as `M-h2hy'.
Now try a more serious exercise: follow the `(find-enode ...)'
hyperlink below, copy a word or two from its contents to the kill
ring with `M-w', then generate the temporary buffer with
hyperlinks to that Info page with `M-h M-i', then duplicate one
of its hyperlinks with `M-h M-2', refine it with `M-h M-y', and
copy the result to this sandbox with `M-w' (or `C-w') and `C-y'.
As this is a long sequence of instructions, it is better to run
`C-x 1 C-x 2' or `C-x 1 C-x 3' before following the hyperlink, to
keep the instructions visible.
(find-enode "Command Index")
10. More on functions
A symbol - for example `f' - can be both a variable and a
function; its "value as a variable" and its "value as a
function" are stored in different places. Try:
(setq f 2)
(setq f 5)
(defun f (x) (* x x))
(defun f (x) (* 10 x))
(symbol-value 'f)
(symbol-function 'f)
This is explained here:
(find-elnode "Symbol Components")
(find-elnode "Symbol Components" "value cell")
(find-elnode "Symbol Components" "function cell")
The content of a "function cell" is _usually_ a lambda
expression. See:
(find-elnode "Lambda Expressions")
(find-elnode "What Is a Function")
(find-elnode "What Is a Function" "lambda expression")
(find-elnode "What Is a Function" "byte-code function")
Try:
(setq f 2)
(setq f 5)
(set 'f 2)
(set 'f 5)
(fset 'f (lambda (x) (* x x)))
(fset 'f (lambda (x) (* 10 x)))
(defun f (x) (* 10 x))
(defun f (x) (* x x))
(symbol-value 'f)
(symbol-function 'f)
(f 4)
(f f)
((lambda (x) (* x x))
4)
((lambda (x) (* 10 x))
4)
10.4. Quote and backquote
Eev uses backquote a lot and avoids macros.
(find-elnode "Backquote")
(find-elnode "Macros")
11. What else?
Eev-mode defines several other key sequences similar to `M-h
M-i'. You can get the full list here:
(find-efunctiondescr 'eev-mode)
(find-efunctiondescr 'eev-mode "M-h f")
Try also this:
(find-efunction-links 'eev-mode)
and for other tutorials like this one, try:
(find-wrap-intro)
(find-eepitch-intro)
[To do: explain M-x ee-hyperlink prefix and how to embed
hyperlinks in scripts]