Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
(Re)generate: (find-eval-intro) Source code: (find-eev "eev-intro.el" "find-eval-intro") More intros: (find-eev-quick-intro) (find-eepitch-intro) This buffer is _temporary_ and _editable_. It is meant as both a tutorial and a sandbox. For an introduction to the ideas here, see: (find-eev-quick-intro "2. Evaluating Lisp") 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 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 insted 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 hightlight the subsexps `(* 2 3)', `(* 4 5)', and `4'. (+ (* 2 3) (* 4 5)) 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. 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. 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") 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 by <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") 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) 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 occurence 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. 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 exemple, 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") 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 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") 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]