(Re)generate: (find-escripts-intro) Source code: (find-efunction 'find-escripts-intro) More intros: (find-eev-quick-intro) (find-eev-intro) This buffer is _temporary_ and _editable_. It is meant as both a tutorial and a sandbox. The quickest way to open or recreate this is with `M-6 M-j'. Eev's central idea is that you can keep "executable logs" of what you do, in a format that is reasonably readable and that is easy to "play back" later, step by step and in any order. We call these executable logs "e-scripts". We will start this intro by explaining how eev and e-scripts appeared. Then we will see how to read and play back a sample e-script, and understand its conventions; then we will see some tools to help writing e-scripts in several usual formats: 1) a file with hyperlinks and eepitch blocks, 2) a file with e-script blocks and an index, 3) several files with e-script blocks and indexes, 4) source files with eepitch blocks in multi-line comments, 5) temporary buffers, like the ones generated by `find-latex-links' and `find-lua-links'.
1. PrehistoryEev appeared by accident. I started using Emacs in 1994 or 1995. I knew a bit of Lisp from a course in the university, and after just a few hours using Emacs I started putting sexps like this in my notes, (find-file "/usr/share/emacs/19.24/lisp/") (find-file "/usr/share/emacs/19.24/lisp/files.el") to go quickly to files or directories that I found interesting. A few days after that I wrote a function - that I could invoke as `M-x eev' - that saved the text of the region in the file "~/ee.sh", and I had an alias `ee' in my shell that would execute the contents of that file in verbose mode, i.e., showing each line before executing it. "Eev" meant "Emacs-execute-verbosely", but `M-x eev' only saved a block of commands into "~/ee.sh"; to execute them I had to switch to a terminal and type "ee". If the function `eev' was called with a string argument instead of being called interactively it would write that string to "~/ee.sh"; a sexp like (eev "man tar") was a very primitive hyperlink to the manpage for "tar". I wrote extensions to these ideas gradually, and for YEARS I was absolutely sure that Emacs was meant to be used exactly in that way, and that EVERYBODY used elisp code as hyperlinks. At some point in 1999 I sent a message to a mailing list about Emacs, and I casually apologized for using my own functions - with weird names - for elisp hyperlinks and for saving code to be sent to a shell, and asked where in the elisp source files I could find the standard function that did that. RMS himself answered. He said that no one else was using Emacs in that way; that that was very interesting, and that someone should clean up and document my code so that it could be included in Emacs. Eev is not yet an official part of Emacs (long story!) and eepitch practically replaced `M-x eev' as a way to execute shell commands. For more on `M-x eev', see: (find-prepared-intro)
2. E-scriptsThe best short definition for eev that I've found involves some cheating, as it is a circular definition: "eev is a library that adds support for e-scripts to Emacs" - and e-scripts are files that contain chunks meant to be processed by eev's functions. Almost any file can contain parts "meant for eev": for example, a HOWTO or README file about some program will usually contain some shell commands, and we can use `M-x eev' or eepitch to send these commands to a shell; most of my own files contain lots of elisp hyperlinks, and some of them even contain eepitch blocks inside multi-line comments - for example, this Lua library: http://angg.twu.net/LATEX/dednat6/eoo.lua.html#Vector Some of my files are "pure e-scripts": they are mostly made of "e-script blocks" like the ones described here: (find-eev-quick-intro "8.4. Creating e-script blocks") Here are two examples structured like this: http://angg.twu.net/e/emacs.e.html http://angg.twu.net/e/lua5.e.html Each of these "e-script blocks" is an "executable log" of something that I was trying to understand, or trying to do.
3. SharingOne of my first public texts about eev was the "Eev Manifesto": http://angg.twu.net/eev-manifesto.html Here are its main parts. Everybody is fluent in only a small fraction of all Unix commands. If you could "listen" to how the Unix gurus "speak" to their machines you would learn which "words" are related to solving a particular task, and learn how they fit in "sentences". By checking the "dictionary entries" for them (i.e., manpages, info pages, READMEs, source code, etc) you could learn the real meaning of them. But then you'd be learning Unix by immersion, from real use, instead of having to rely only on "textbooks", "dictionaries" and sometimes "Rosetta stones", "graffitis on toilet walls" and "old newspapers". The fact is that you can make a record of how you "speak" Unix, and more, you can become a lot more productive if you do so. Many tasks consist on short fixed sequences of commands: connecting to your ISP via modem, unpacking a source package and recompiling it, printing a text file in two-column mode, and so on. The trick is that with some functions defined in eev.el you can write these sequences of commands in a plain text file, then mark a block of this file with your editor (which must be Emacs for this to work), then tell a shell to execute only the commands in that block; in this way you can easily execute only portions of what would otherwise have to be a monolythic script; this is great for when you're not sure if everything works, or if you just want to do some steps. Also, it would be easy to change bits of the "script" before execution, as you'll be doing things from inside an editor. (...) I have placed essentially all my "scripts" written in this way (I call them "e-scripts") in a public place. They contain almost everything I know about Unix. If you like this idea, please get in touch, send comments, ask questions -- about e-scripts or questions whose answer could become an e-script chunk -- or send me your e-scripts when you have some, or even ask for help on setting up your own e-script collection or e-script public site... anything! By asking good questions you can help me make the documentation get better. I really want to make this e-scripts idea spread. Learning Unix -- or simply more Unix -- could be made easier for everybody... please help! E-scripts are more fun to use, and easier to write, than texts that tell everything in terms of "press this, do that". A lot of effort and money are being invested now on these kinds of text, and they're often very depressing. Let's try to save the world from them, at least a bit, and maybe this money will be directed to better things. And teaching people Unix tricks will be both easier and more fun. The Manifesto said that 1) *NIX can be compared to an oral language, 2) we can "write" the commands that we "speak", 3) we learn mostly by "listening", or "reading", others, 4) we have good reasons to write: a) executable logs make us more productive, b) our notes/logs can, and should, be shared. What it *did not* say explicitly was: 5) that *not sharing* should be *immoral*, 6) one of my main objectives with eev was REVENGE. I spent (what felt like) hundreds of hours in the university trying to learn things with the *NIX users and gurus there - to practically no avail. They answered very few of my questions, they only very rarely showed me their code or notes, and I can remember only a handful of cases in which we sat side-by-side on a terminal. These people - who shared very little - were the most respected hackers of that place. They had to be stripped of their status.
4. How to read an e-scriptThe indented block below between the two "snip, snip" lines - we will call it "Example 1" - exemplifies most of the basic techniques available for e-scripts. These techniques will be reviewed in the subsections below. --snip, snip-- # Index: # «.lua5.1-debian» (to "lua5.1-debian") # «.lua-tutorial» (to "lua-tutorial") ##### # # The main Debian packages for Lua 5.1 # 2018jun02 # ##### # «lua5.1-debian» (to ".lua5.1-debian") # (find-status "lua5.1") # (find-vldifile "lua5.1.list") # (find-udfile "lua5.1/") # (find-status "lua5.1-doc") # (find-vldifile "lua5.1-doc.list") # (find-udfile "lua5.1-doc/") # (find-udfile "lua5.1-doc/doc/") # (find-udfile "lua5.1-doc/test/") # http://www.lua.org/docs.html # http://www.lua.org/manual/5.1/manual.html # file:///usr/share/doc/lua5.1-doc/doc/manual.html * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) sudo apt-get install lua5.1 lua5.1-doc ##### # # Downloading and opening an eev-based Lua tutorial # 2018jun02 # ##### # «lua-tutorial» (to ".lua-tutorial") # http://angg.twu.net/e/lua-intro.e.html # http://angg.twu.net/e/lua-intro.e * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) cd /tmp/ rm -v lua-intro.e wget http://angg.twu.net/e/lua-intro.e # (find-fline "/tmp/lua-intro.e") # (find-anchor "/tmp/lua-intro.e" "intro:types") # (defun eejump-71 () (find-fline "/tmp/lua-intro.e")) --snip, snip--
4.1. Anchors and `to'The two lines below # «.foo» (to "foo") # «foo» (to ".foo") "point to one another". This is explained here: (find-eev-quick-intro "8. Anchors") We used this in Example 1 to create an index. Compare with: # Index: # «.one» (to "one") # «.two» (to "two") ### ## Stuff in block "one" ### # «one» (to ".one") (...) ### ## Stuff in block "two" ### # «two» (to ".two")
4.2. Debian hyperlinksThe hyperlinks using `find-status', `find-vldifile', and `find-udfile' are hyperlinks to information about a Debian package. These hyperlinks (find-status "bash") (find-vldifile "bash.list") (find-udfile "bash/") are equivalent to: (find-fline "/var/lib/dpkg/status" "\nPackage: bash\n") (find-fline "/var/lib/dpkg/info/bash.list") (find-fline "/usr/share/doc/bash/") See: (find-eev "eev-blinks.el" "find-Package") (find-eev "eev-blinks.el" "find-Package" "find-status") (find-eev-quick-intro "9.1. `code-c-d'") (find-eev-quick-intro "9.1. `code-c-d'" "(code-c-d \"ud\"") (find-eev "eev-code.el" "code-c-d-s") (find-eev "eev-code.el" "code-c-d-s" "(code-c-d \"ud\"") (find-eev "eev-code.el" "code-c-d-s" "(code-c-d \"vldi\"")
4.3. URL hyperlinksThe lines # http://www.lua.org/docs.html # http://www.lua.org/manual/5.1/manual.html # file:///usr/share/doc/lua5.1-doc/doc/manual.html are URL hyperlinks. Here's how to follow them: (find-eev-quick-intro "3.1. Non-elisp hyperlinks") Note that the "file:///" URL above points to a local copy of the Lua manual at "http://www.lua.org/manual/5.1/manual.html" - but the local copy will only exist if the Debian package "lua5.1-doc" is installed.
4.4. Eepitch blocksThis * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) sudo apt-get install lua5.1 lua5.1-doc is an "eepitch block", as explained here: (find-eev-quick-intro "6. Controlling shell-like programs") (find-eev-quick-intro "6.1. The main key: <F8>") Note that it will only work if you delete the whitespace before the "*"s!
4.5. Htmlized e-scriptsThe "Eev Manifesto" in section 3 above has this: I have placed essentially all my "scripts" written in this way (I call them "e-scripts") in a public place. They contain almost everything I know about Unix. The "public place" is here: http://angg.twu.net/e/ The links # http://angg.twu.net/e/lua-intro.e.html # http://angg.twu.net/e/lua-intro.e point to one of these e-scripts - one that I use to teach (or introduce) Lua to people that already know other programming languages. The # http://angg.twu.net/e/lua-intro.e.html point to an "htmlized version" of it, in which many of the hyperlinks are converted to something that works in a browser. The header of the .html explains briefly how the htmlized version is produced.
4.6. The `rm' in the eepitch blockWhen we execute this eepitch block a first time, * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) cd /tmp/ rm -v lua-intro.e wget http://angg.twu.net/e/lua-intro.e the "rm" gives an error: rm: cannot remove 'lua-intro.e': No such file or directory When we execute it a second, third, fourth time, the "rm" deletes the file "/tmp/lua-intro.e" that the wget downloaded in the previous run. I usually write my eepitch blocks a few lines at a time, and I test the new lines by running the whole block again from the beginning. This means that for me most of the time a line like rm -v lua-intro.e does not give an error - and I got used to ignoring the error when it's run for the first time. Most e-scripts in http://angg.twu.net/e/ follow these conventions: 1) they can be re-run, 2) they start with clean-up code, 3) I prefer to write the clean-up code to be short, even when this means that I will have to ignore errors and warnings.
4.7. A convention about order(Explain why I feel natural to put the eepitch block that installs the lua5.1 packages at the end of the first e-script block, after the hyperlinks to files from that package)
5. Tools for writing e-scriptsOne of my favorite ways of describing eev is as a "tool to create executable logs", but this only make sense if we clarify some ideas and terms. The e-script in Example 1 has two _e-script blocks_ plus an _index_. The fist block has notes about installing the packages for Lua5.1 in Debian and inspecting them, and the second block is about downloading and using an eev-based Lua tutorial. Let's think of each of these blocks as a _task_. The task "install Lua5.1" is performed in one way if we're doing it for the first time, and in a different way if we're doing it for the n-th time with some memory of what we did in the previous times and of what we found important and what not. Performing a task like this consists of several steps, that can be roughly divided into "visiting" and "commands". I borrowed the term "visiting" from Emacs: (find-enode "Visiting" "Visiting Files") Look at the first block of Example 1 again. It has several elisp hyperlinks to information about the packages "lua5.1" and "lua5.1-doc". Following those hyperlinks let us "visit" the descriptions of the two packages, their lists of files, and some of their directories. Then the e-script block has three URL links to the Lua documentation in general and to its reference manual, and then an eepitch block that runs an "apt-get install". We saw how to follow links and how to execute eepitch blocks, so an e-script block is "executable". But in what sense it is a "log"? 1. In the old days log books were always made of paper, and there was nothing automatic in taking notes with them. We would have to decide what to write and how to write it, and we would have to alternate between the "task" and "taking notes". After many years of practice _some_ people would learn how to take notes without distracting themselves much from the task at hand, and they would learn how to make their notes at the same time concise and readable enough. 2. Nowadays, with computers, there are _some_ ways to write logs automatically - for example, most shells record the commands given to them - but the output is of low quality. 3. Eev takes an intermediate stance between "notes by hand" and "automatic notes". It is possible to do "task"+"notes" with just a few more keystrokes than for doing just "task", but that requires learning some tricks, and having some practice. The next sections discuss those tricks.
5.1. Anchors-to pairs and e-script blocksAnchor-to pairs can be generated easily using `M-A': (find-eev-quick-intro "8.3. Creating index/section anchor pairs") (find-eev-quick-intro "8.3. Creating index/section anchor pairs" "M-A") Typing `M-A' on this line: # <bletch> yields this pair of anchor-to lines: # «.bletch» (to "bletch") # «bletch» (to ".bletch") let's call the first one a "to-forward" and the second one a "to-back". In my e-scripts files I follow the convention that the to-forwards are all together at the beginning of the file, forming an index of sections of the file, and each to-back is at the beginning of a section. Most of the source files of eev follow this convention; see, for example: (find-eev "eev-blinks.el" ".eek") (find-eev "eev-blinks.el" "eek") Note that there, and in most source files of eev, above each to-back line there a title in big letters in ASCII art in Lisp comments. After creating a to-forward-to-back pair with `M-A' we have to move the to-forward line to the index by hand, using cut and paste. In the e-script files in http://angg.twu.net/e/ I follow another convention - "e-script blocks". The title above each to-backward line is written like this: ##### # # Long description for the section Bletch # 2016feb29 # ##### Note that you can generate a title in "#"s like that, followed by a to-forward-to-back pair, by typing `M-B' on a line like: bletch Long description for the section Bletch See: (find-eev-quick-intro "8.4. Creating e-script blocks") (find-eev-quick-intro "8.4. Creating e-script blocks" "`M-B'") The to-forward line still has to be moved to the index by cut and paste by hand.
5.2. Debian hyperlinksThe key `M-D' converts a line with the name of a Debian package, like this, lua5.1-doc to these three hyperlinks, # (find-status "lua5.1-doc") # (find-vldifile "lua5.1-doc.list") # (find-udfile "lua5.1-doc/") and moves the point to the next line. Try it! Put the point on the "bash" line below and type `M-D M-D M-D': bash lua5.1 lua5.1-doc
5.3. URL hyperlinksI usually "write" URLs in Emacs by copying them from a browser to Emacs.
5.4. Eepitch blocksWe saw in (find-eev-quick-intro "6.3. Creating eepitch blocks: `M-T'") how to create eepitch blocks with `M-T'. Try that on the line that says "lua51" below: lua51
5.5. `rm/mkdir/cd' triplesTry typing `M-R' on the line with the "/tmp/foo/" below: /tmp/foo/
5.6. Hyperlinks to files, directories, and info nodesOne practical way to create a `find-fline' hyperlink is with `M-F' (`eewrap-find-fline'). Try it here: /usr/share/doc/lua5.1-doc/test/ /usr/share/doc/lua5.1-doc/test/README /usr/share/doc/lua5.1-doc/test/fibfor.lua Note that the three lines above were copied from: (find-vldifile "lua5.1-doc.list") (find-vldifile "lua5.1-doc.list" "/usr/share/doc/lua5.1-doc/test") Another way is by visiting a file and typing `M-h M-h'. See: (find-eev-quick-intro "4.1. `find-here-links'") This can also be used to generate links to info nodes. (...)
5.7. Refining hyperlinks(...)
5.8. Pointing to anchors(...)
5.9. Using a TODO file(...)
5.10. Using several e-script files(...)
5.11. Eepitch blocks in multi-line comments(...)