(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'.