[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eev cdbbd6d: Added (find-saving-links-intro).
From: |
ELPA Syncer |
Subject: |
[elpa] externals/eev cdbbd6d: Added (find-saving-links-intro). |
Date: |
Sun, 5 Dec 2021 09:57:16 -0500 (EST) |
branch: externals/eev
commit cdbbd6d3afc00cd788644a415da1db4fba70216c
Author: Eduardo Ochs <eduardoochs@gmail.com>
Commit: Eduardo Ochs <eduardoochs@gmail.com>
Added (find-saving-links-intro).
---
ChangeLog | 7 +
README | 43 +-
VERSION | 4 +-
eev-intro.el | 14541 +++++++++++++++++++++++++++++----------------------------
eev.el | 2 +-
5 files changed, 7372 insertions(+), 7225 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5ca2804..b120d6f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2021-12-05 Eduardo Ochs <eduardoochs@gmail.com>
+
+ * README: rewritten to explain an issue with autoloads.
+
+ * eev-intro.el (find-saving-links-intro): new function.
+ (find-eev-intro): mention `(find-saving-links-intro)'.
+
2021-12-04 Eduardo Ochs <eduardoochs@gmail.com>
* eev-videolinks.el (find-2021workshop4video)
diff --git a/README b/README
index 6703a17..188d8d4 100644
--- a/README
+++ b/README
@@ -13,35 +13,44 @@ eev-mode keybindings, and open this tutorial,
http://angg.twu.net/eev-intros/find-eev-quick-intro.html
(find-eev-quick-intro)
-in a sandboxed buffer. For a list of the other sandboxed tutorials,
-see:
+in a sandboxed buffer. The URL aboves points to an HTMLized version of
+the sandboxed tutorial, and the `(find-*-intro)' sexp opens it in
+Emacs. You can find an index of the other sandboxed tutorials here:
http://angg.twu.net/eev-intros/find-eev-intro.html
(find-eev-intro)
-Note that the URLs point to the HTMLized versions of the sandboxed
-tutorials, and the `(find-*-intro)' sexps open them in Emacs.
+The home page of eev is:
-For a _non-technical_ description of what e-scripts are, see:
+ http://angg.twu.net/#eev
- http://angg.twu.net/escripts.html
-For an analysis of an e-script that uses most of the main features of
-eev, see:
- http://angg.twu.net/eev-intros/find-escripts-intro.html#4
- (find-escripts-intro "4. How to read an e-script")
+Autoloads
+=========
+Eev handles autoloads in a very atypical way, explained in these two
+places:
-The home page of eev is:
+ http://angg.twu.net/eev-current/eev-load.el.html#autoloads
+ http://angg.twu.net/eev-intros/find-eev-intro.html#4
+ (find-eev "eev-load.el" "autoloads")
+ (find-eev-intro "4. The prefix `find-'")
- http://angg.twu.net/#eev
+If you load eev in one of these three ways
+ 1. `M-x eev-beginner'
+ 2. (require 'eev-beginner)
+ 3. (require 'eev-load)
+then everything will work. If you try to use a package that tries to
+bypass autoloads - say, by loading the file that seems to contain the
+definition of `eev-foo' when you try to run `M-x eev-foo' - then lots
+of things will break. =(
-EEV WITHOUT EEV-MODE
-====================
+Eev mode
+========
Eev mode only activates some keybindings and adds a reminder saying
"eev" to the mode line, as explained here:
@@ -50,10 +59,8 @@ Eev mode only activates some keybindings and adds a reminder
saying
It is possible to use eev's elisp hyperlink functions with eev-mode
turned off: just put the point on a line with an elisp hyperlink and
-type `C-e C-x C-e'.
-
-If you want to load all the main modules of eev to make its functions
-available in this way, do:
+type `C-e C-x C-e' to execute it. To load all the main modules of eev
+to make its functions available to be used in this way, do this:
(require 'eev-load)
diff --git a/VERSION b/VERSION
index b48b623..ada586c 100644
--- a/VERSION
+++ b/VERSION
@@ -1,2 +1,2 @@
-Sat Dec 4 09:29:29 GMT 2021
-Sat Dec 4 06:29:29 -03 2021
+Sun Dec 5 14:24:12 GMT 2021
+Sun Dec 5 11:24:12 -03 2021
diff --git a/eev-intro.el b/eev-intro.el
index d7d3e54..15b4817 100644
--- a/eev-intro.el
+++ b/eev-intro.el
@@ -19,7 +19,7 @@
;;
;; Author: Eduardo Ochs <eduardoochs@gmail.com>
;; Maintainer: Eduardo Ochs <eduardoochs@gmail.com>
-;; Version: 20211204
+;; Version: 20211205
;; Keywords: e-scripts
;;
;; Latest version: <http://angg.twu.net/eev-current/eev-intro.el>
@@ -65,6 +65,7 @@
;; «.find-eev-intro» (to "find-eev-intro")
;; «.find-here-links-intro» (to "find-here-links-intro")
;; «.find-refining-intro» (to "find-refining-intro")
+;; «.find-saving-links-intro» (to "find-saving-links-intro")
;;
;; «.find-eval-intro» (to "find-eval-intro")
;; «.find-links-conv-intro» (to "find-links-conv-intro")
@@ -1912,21 +1913,24 @@ The beginner's way of creating \"hyperlinks to here\"
is with:
M-h M-1 - (find-here-links-intro \"5. `find-here-links-1'\")
M-h M-w - (find-here-links-intro \"6. Copying the hyperlink\" \"M-h M-w\")
-The other keys for creating hyperlinks to here and refining them are:
+The main keys for creating buffers with elisp hyperlinks are:
M-h M-h - `find-here-links': (find-eev-quick-intro \"4.1.
`find-here-links'\")
- M-h M-2 - `ee-duplicate-this-line'. See: (find-eval-intro \"M-h M-2\")
- M-h M-y - `ee-yank-pos-spec'. See: (find-eval-intro \"M-h M-y\")
- See also: (find-refining-intro \"2. Refining hyperlinks\")
- (find-refining-intro \"4. A tip for beginners\")
-
-Some other keys that create buffers with elisp hyperlinks:
M-h M-k - (find-eev-quick-intro \"4.2. `find-ekey-links' and friends\")
M-h M-f - (find-eev-quick-intro \"4.2. `find-ekey-links' and friends\")
+ M-h M-e - (find-audiovideo-intro \"4.1. `find-extra-file-links'\")
M-h M-p - (find-pdf-like-intro \"9. Generating three pairs\")
(find-pdf-like-intro \"9. Generating three pairs\" \"M-h M-p\")
- M-h M-e - (find-audiovideo-intro \"4.1. `find-extra-file-links'\")
See also: (find-links-intro \"5. The first line regenerates the buffer\")
+The main keys for refining hyperlinks are:
+ M-h M-2 - `ee-duplicate-this-line'. See: (find-eval-intro \"M-h M-2\")
+ M-h M-y - `ee-yank-pos-spec'. See: (find-eval-intro \"M-h M-y\")
+ M-1 M-h M-w - copy the preceding tag to the kill ring
+ M-h M-- - shrink hyperlink to make it point to an anchor
+ See also: (find-refining-intro \"2. Refining hyperlinks\")
+ (find-anchors-intro \"2. Shrinking\")
+ (find-anchors-intro \"3. The preceding tag\")
+
2. Key sequences and how to abort them
@@ -2660,59 +2664,60 @@ recommended reading order. These are the basic ones:
2. (find-eev-intro)
3. (find-here-links-intro)
4. (find-refining-intro)
- 5. (find-pdf-like-intro)
- 6. (find-eepitch-intro)
- 7. (find-audiovideo-intro)
- 8. (find-video-links-intro)
- 9. (find-videos-intro)
- 10. (find-psne-intro)
- 11. (find-rcirc-intro)
- 12. (find-elisp-intro)
- 13. (find-lexical-intro)
- 14. (find-multiwindow-intro)
- 15. (find-eev-install-intro)
+ 5. (find-saving-links-intro)
+ 6. (find-pdf-like-intro)
+ 7. (find-eepitch-intro)
+ 8. (find-audiovideo-intro)
+ 9. (find-video-links-intro)
+ 10. (find-videos-intro)
+ 11. (find-psne-intro)
+ 12. (find-rcirc-intro)
+ 13. (find-elisp-intro)
+ 14. (find-lexical-intro)
+ 15. (find-multiwindow-intro)
+ 16. (find-eev-install-intro)
These are things that I am using in workshops:
- 16. (find-windows-beginner-intro)
- 17. (find-eev-exercises-intro)
+ 17. (find-windows-beginner-intro)
+ 18. (find-eev-exercises-intro)
These ones explain ideas, conventions, and usage patterns:
- 18. (find-escripts-intro)
- 19. (find-links-conv-intro)
+ 19. (find-escripts-intro)
+ 20. (find-links-conv-intro)
These are older and more technical versions of sections of the
eev-quick-intro:
- 20. (find-eval-intro)
- 21. (find-links-intro)
- 22. (find-brxxx-intro)
- 23. (find-wrap-intro)
- 24. (find-eejump-intro)
- 25. (find-anchors-intro)
- 26. (find-code-c-d-intro)
+ 21. (find-eval-intro)
+ 22. (find-links-intro)
+ 23. (find-brxxx-intro)
+ 24. (find-wrap-intro)
+ 25. (find-eejump-intro)
+ 26. (find-anchors-intro)
+ 27. (find-code-c-d-intro)
These are etcs:
- 27. (find-templates-intro)
- 28. (find-org-intro)
- 29. (find-git-intro)
+ 28. (find-templates-intro)
+ 29. (find-org-intro)
+ 30. (find-git-intro)
These ones explain advanced features that require extra setup:
- 30. (find-prepared-intro)
- 31. (find-bounded-intro)
- 32. (find-channels-intro)
+ 31. (find-prepared-intro)
+ 32. (find-bounded-intro)
+ 33. (find-channels-intro)
-This one is used in a video:
+This one was used in a video:
- 33. (find-three-main-keys-intro)
+ 34. (find-three-main-keys-intro)
These ones are obsolete:
- 34. (find-emacs-intro)
- 35. (find-defun-intro)
+ 35. (find-emacs-intro)
+ 36. (find-defun-intro)
Item 25 is an index of old video tutorials, with scripts for
downloading local copies of them and links to important positions
@@ -3618,1973 +3623,2083 @@ please get in touch!
-;;; _
-;;; _____ ____ _| |
-;;; / _ \ \ / / _` | |
-;;; | __/\ V / (_| | |
-;;; \___| \_/ \__,_|_|
-;;;
-;; «find-eval-intro» (to ".find-eval-intro")
-;; Skel: (find-intro-links "eval")
-;; (find-TH "eev-article" "hyperlinks")
-;; (find-TH "eev-article" "forward-and-back")
-;; http://angg.twu.net/eev-article.html#hyperlinks
-;; file:///home/edrx/TH/L/eev-article.html#hyperlinks
-;; (find-efunction 'ee-eval-last-sexp)
-(defun find-eval-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-eval-intro)*"))
+;;; _ _ _ _
+;;; ___ __ ___ _(_)_ __ __ _ | (_)_ __ | | _____
+;;; / __|/ _` \ \ / / | '_ \ / _` | | | | '_ \| |/ / __|
+;;; \__ \ (_| |\ V /| | | | | (_| | | | | | | | <\__ \
+;;; |___/\__,_| \_/ |_|_| |_|\__, | |_|_|_| |_|_|\_\___/
+;;; |___/
+;;
+;; «find-saving-links-intro» (to ".find-saving-links-intro")
+;; Skel: (find-intro-links "saving-links")
+;; Test: (find-saving-links-intro)
+
+(defun find-saving-links-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-saving-links-intro)*"))
(apply 'find-eintro "\
-\(Re)generate: (find-eval-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-eval-intro\")
+\(Re)generate: (find-saving-links-intro)
+Source code: (find-efunction 'find-saving-links-intro)
More intros: (find-eev-quick-intro)
- (find-eepitch-intro)
+ (find-here-links-intro)
+ (find-refining-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)
+THIS IS A WORK IN PROGRESS AND IS CURRENTLY A MESS.
+This was split from:
+ (find-eev-exercises-intro)
+Pre-requisites:
+ (find-here-links-intro)
+ (find-refining-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.
+1. Reading diagrams aloud
+=========================
+I will use 2D diagrams to represent sequences of actions. In
+beginning of this tutorial these diagrams will have lots of
+details, but they will become progressively more and more
+streamlined; in the last exercises of this intro we will work
+with diagrams in which only the details that are very hard to
+infer are written down explicitly.
+
+1.1. Key sequences
+------------------
+I will suppose that you are familiar with the first few sequences
+of keys below, and that you are trying to become familiar with
+the other ones. The pronounciations at the right are the ones
+that we will use in the text of this intro and in its videos.
- (+ (* 2 3) (* 4 5))
- ^ ^^
- | | \\
- 6 20 26
+ Pronounciations
+ C-w cut
+ M-w copy, or copy into the kill ring
+ C-y paste, or copy from the kill ring
+ C-x 0 delete window
+ C-x 1 one window
+ M-k kill buffer
+ M-K bury buffer
-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:
+ M-j meta-jay, or list of jumps
+ M-1j jump to notes
+ M-2j jump to emacs keys
+ M-5j jump to main tutorial
+ M-21j show notes at the right
+ M-31j jump to notes at the right
- (+ (* 2 3)
- (* 4 5)
- )
+ M-h3 find here links beginner
+ M-h1 go back (to the previous window configuration)
-`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.
+ M-hh find here links
+ M-hk find key links
+ M-hf find function links
+ M-he find extra links
-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'.
+ M-h2 duplicate
+ M-hy refine, or yank into pos-spec
+ M-h- shrink
- (+ (* 2 3) (* 4 5))
+ M-hw copy line
+ M-1hw copy last tag
+Exercise: all the key sequences above are mentioned here:
+ (find-emacs-keys-intro)
+check that their pronounciations above make sense. Find the link
+to the documentation of each key sequence, follow it, and read
+the explanation. A few of the explanations have exercises that
+show in practice how those key sequences work - do these exercises.
-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)
+1.2. Windows and buffer names
+-----------------------------
+We will use two ways to explain what our abbreviations for buffer
+names, like [EX], [EH], and [N], mean: pronounciations and sexps.
+For example:
-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.
+ [EX] exercises (find-eev-exercises-intro)
+ [HL] here-links (find-here-links)
+ [N] notes (find-fline \"~/TODO\")
-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.
+A diagram like this
-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.
+ _________________ ____________
+ | | | | |
+ | | [HL] | | |
+ | [EX] | | | [EX] |
+ | |________| ---> | |
+ | | | | |
+ | | [N] | | |
+ | | | | |
+ |________|________| |____________|
- (setq a 5)
- (setq a 6)
- (defun f (x) (* x x))
- (defun f (x) (* x 10))
- (f a)
+We mean that we started in a window configuration with three
+windows, with [EX] at the left half, [HR] at the upper right, and
+[N] at the lower right, and then we switched to a window
+configuration with a single window displaying [EX].
-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.
+1.3. Adding keys
+----------------
+Look at this diagram:
+
+ _________________ ____________
+ | | | | |
+ | [EX] | [HL] | | [EX] |
+ | M-w | M-h2 | | |
+ | | M-hy | | |
+ | | M-w | M-h1 | |
+ | |___::___| ---> | |
+ | | \\/ | | |
+ | | | | |
+ | | [N] | | |
+ | | C-y | | |
+ |________|________| |____________|
+
+We added key sequences to the diagram of the previous section,
+and we did that in a way that lets us deduce from the diagram in
+which buffer each key sequence was typed, and in which order.
+
+For me these diagrams become easy to understand and to remember
+if I translate mentally each key sequence to its pronounciation -
+like this:
-4. Elisp hyperlinks
-===================
-Some Emacs functions can be used as hyperlinks. When sexps like
+ In the buffer with exercises,
+ copy a string to the kill ring; (1)
+ In the buffer with here-links,
+ duplicate,
+ refine,
+ copy; (2)
+ go to the buffer with notes, and
+ paste; (3)
+ go back to the previous
+ window configuration.
- (find-file \"/tmp/\")
- (info \"(emacs)Lisp Eval\")
- (describe-function 'find-file)
- (find-function 'find-file)
- (man \"cat\")
+This is somewhat similar to reading a score sheet.
-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.
+In the steps (1), (2), and (3) some information hard to put in
+words was omitted from the pronounciation. In (1) we copy to the
+kill ring exactly the string that will be used in the refining
+step; in (2) we copy to the kill ring two links, one \"original\"
+and one that it is refined version; in the step (3) we copy these
+two links to the right place in our notes, but the pronounciation
+doesn't say where.
-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:
+2. The base cases
+=================
+Watch this video first:
- a) the first sexp in that buffer is one that can regenerate
- that buffer when executed,
+ [Video links:]
+ (find-2021workshop1video \"0:22\" \"The base case 1 is described here\")
+ (find-2021workshop1video \"0:52\" \"The instructions are here\")
+ (find-2021workshop1video \"1:24\" \"The base case 2\")
+ (find-2021workshop1video \"1:39\" \"What I need to do is slightly\")
+ (find-2021workshop1video \"1:55\" \"This is not yet the link that I
want\")
- 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:
+2.1. The base case 1
+--------------------
+We are going to start by something that we will refer to as the
+\"base case 1\", and we will treat the other cases as variations
+of the base case 1. Here it is:
- (find-fline \"/tmp/\")
- (find-node \"(emacs)Lisp Eval\")
- (find-efunctiondescr 'find-file)
- (find-efunction 'find-file)
- (find-man \"cat\")
+ You realize that this buffer is interesting and you want to
+ save a link to it to your notes. Let's refer to this buffer as
+ the \"target buffer\", as the link will point to it. You run
+ this,
+ (eek \"M-h M-3 ;; find-here-links-3\")
+ and you get a 3-window configuration like this one:
+ _______________ _____________________ ________________
+ | | | | | | |
+ | | | | elinks | | |
+ | | | | buffer | | |
+ | target | M-h M-3 | target |__________| M-h M-1 | target |
+ | buffer | ------> | buffer | | ------> | buffer |
+ | | | | notes | | |
+ | | | | buffer | | |
+ |_______________| |__________|__________| |________________|
-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.
+ you select the line of the \"elinks buffer\" that contains an
+ elisp hyperlink that points to the \"target buffer\", you copy
+ that line your \"notes buffer\" - that contains the file ~/TODO
+ - and you run this
-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:
+ (eek \"M-h M-1 ;; find-here-links-1\")
- (find-node \"(emacs)Shell\")
+ to go back to the original window configuration in which only
+ the target buffer was being shown.
-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.
+What you did can be summarized as:
- (find-man \"1 bash\")
- (find-sh \"sleep 1; echo 'This was run at:'; date\")
+ create (the elisp hyperlinks buffer)
+ select (the correct elisp hyperlink)
+ copy (it to the notes buffer)
+ go back (to the previous window configuration)
+or:
+ create / select / copy / go back
+[Video links:]
+ (find-2021workshop1video \"0:22\" \"The base case 1 is described here\")
+ (find-2021workshop1video \"0:52\" \"The instructions are here\")
-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:
+2.2. The base case 2
+--------------------
+The \"base case 2\" is similar to the base case 1, but in the
+base case 2 we will create a link with a pos-spec-list containing
+the name of this section. Pos-spec-lists are explained here:
- (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)
+ (find-eev2020video \"2:53\" \"pos-spec-lists\")
+The sequence of steps in the base case 2 will include two new
+steps:
+ save (the name of this section to the kill ring) <- new!
+ create (the elisp hyperlinks buffer)
+ select (the correct elisp hyperlink)
+ refine (add the name of the section to the pos-spec-list) <- new!
+ copy (it to the notes buffer)
+ go back (to the previous window configuration)
-7. Pos-spec-lists
-=================
-[Moved to:] (find-refining-intro \"1. Pos-spec-lists\")
+so:
-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,
+ save / create / select / refine / copy / go back
- (find-sh \"seq 2095 2115\" \"2100\" \"9\")
+instead of:
-and in most cases an empty pos-spec-list, like this,
+ create / select / copy / go back
- (find-sh \"seq 2095 2115\")
+The diagram will be this one,
-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.
+ _______________ _____________________ ________________
+ | | | | | | |
+ | | | target | elinks | | |
+ | | | buffer | buffer | | |
+ | | | M-w | M-hy :: | | |
+ | target | M-h M-3 | |______::__| M-h M-1 | target |
+ | buffer | ------> | | \\/ | ------> | buffer |
+ | | | | | | buffer |
+ | | | | notes | | |
+ | | | | 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:
+The dotted arrow indicates a copy and paste from the elinks
+buffer to the notes buffer, and the `M-hy' at the left of the
+dotted arrow indicated the we will have to type `M-hy' - that is
+an abbreviation for `M-h M-y' at some point; the placement of the
+`M-hy' suggests that it is typed before the cut and paste.
- string -> jump to the first occurrence of
- that string in the buffer
- number -> jump to the n-th line
+ (find-refining-intro \"2. Refining hyperlinks\")
+ (find-refining-intro \"2. Refining hyperlinks\" \"M-h M-y\")
-and the other arguments are interpreted (recursively) by
-`ee-goto-rest':
+[Video links:]
+ (find-2021workshop1video \"1:24\" \"The base case 2\")
+ (find-2021workshop1video \"1:39\" \"What I need to do is slightly\")
+ (find-2021workshop1video \"1:55\" \"This is not yet the link that I want\")
- 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.
+2.3. The base case 3
+--------------------
+The base case 3 will only make sense to people who understand
+anchors, short hyperlinks and anchors, using `M-1 M-h M-w' to
+copy the preceding tag to the kill ring, and using `M-h M--' to
+shrink a hyperlink to make it point to an anchor. You can learn
+these extra prerequisites here:
-8. Anchors and pages
-====================
-\[See:\] (find-anchors-intro)
+ (find-eev-quick-intro \"8. Anchors\")
+ (find-eev-quick-intro \"8.1. Introduction: `to'\")
+ (find-eev-quick-intro \"8.5. Hyperlinks to anchors in other files\")
+ (find-eev-quick-intro \"9. Shorter hyperlinks\")
+ (find-eev-quick-intro \"9.1. `code-c-d'\")
+ (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\")
+ (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\" \":anchor\")
+ (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\" \":anchor\"
\"3)\")
+ (find-anchors-intro \"2. Shrinking\")
+ (find-anchors-intro \"3. The preceding tag\")
-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'.
+ _______________ _____________________ ________________
+ | | | | | | |
+ | | | target | elinks | | |
+ | | | buffer | buffer | | |
+ | target | | M-1hw | M-h2 :: | | target |
+ | buffer | | | M-hy :: | | buffer |
+ | | | | M-h- :: | | |
+ | | M-h M-3 | |______::__| M-h M-1 | |
+ | | ------> | | \\/ | ------> | |
+ | | | | | | |
+ | | | | notes | | |
+ | | | | buffer | | |
+ |_______________| |__________|__________| |________________|
-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',
+Exercise: watch this video and try to reproduce what happens in it:
- (find-available \"bash\")
- (find-available \"bash\" \"bash-doc\")
+ (find-2021workshop7video \"0:00\")
-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.
+Use this to go to the target that appears in the video:
-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-eev \"eev-videolinks.el\" \"ee-1stclassvideos-field\")
- (find-pdf-like-intro \"PDF-like documents as text\")
+3. Copy from left to right
+==========================
-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)---|
- |________________________________________________________|
+3.1. Two basic exercises
+------------------------
+In the diagrams below the names of the buffers are abbreviated:
-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:
+ [EX] - (find-eev-exercises-intro)
+ [J] - (find-eejumps)
+ [N] - notes, i.e., (find-fline \"~/TODO\")
+ [EK] - (find-emacs-keys-intro)
- (kill-new \"C-y\")
- (car kill-ring)
+ ________ _______ ______________ ________
+ | | | | | | | | |
+ | [EX] | M-j | [J] | M-21j | [J] | [N] | C-x 1 M-K* | [EX] |
+ | | ----> | | -----> | M-w ::> C-y | ----------> | |
+ |________| |_______| |_______|______| |________|
-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
+ ________ _______ ______________ ________
+ | | | | | | | | |
+ | [EX] | M-2j | [EK] | M-21j | [EK] | [N] | C-x 1 M-K* | [EX] |
+ | | ----> | | -----> | M-w ::> C-y | ----------> | |
+ |________| |_______| |_______|______| |________|
- (find-enode \"Kill Ring\")
- (find-enode \"Yanking\")
+`M-21j' is `M-2 M-1 M-j' written in an abbreviated form -
+ mnemonic: \"hold the meta key, type 21j, lift meta\" - and
+ `M-K*' means \"type M-K as many times as needed\".
-into
+Watch this video and try to reproduce what happens in it:
- (find-enode \"Kill Ring\")
- (find-enode \"Kill Ring\" \"C-y\")
- (find-enode \"Yanking\")
- (find-enode \"Yanking\" \"C-y\")
+ (find-2021workshop5video \"0:00\")
-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\")
+3.2. `find-extra-file-links'
+----------------------------
+Here you will need to understand `code-c-d' and
+`find-extra-file-links'. See:
+ (find-eev-quick-intro \"9. Shorter hyperlinks\")
+ (find-eev-quick-intro \"9.1. `code-c-d'\")
+ (find-audiovideo-intro \"4.1. `find-extra-file-links'\")
+The diagram will be this one:
-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:
+ ________ _______ _______ ______________
________
+ | | | | | | | | |
| |
+ | [EX] | | [D] | M-he | [EH] | M-21j | [EH] | [N] | C-x 1 M-K*
| [EX] |
+ | | --> | | ----> | | -----> | M-w ::> C-y | ---------->
| |
+ |________| |_______| |_______| |_______|______|
|________|
- (setq f 2)
- (setq f 5)
- (defun f (x) (* x x))
- (defun f (x) (* 10 x))
- (symbol-value 'f)
- (symbol-function 'f)
+Where [D] is a dired buffer. Watch this video and try to
+reproduce what happens in it:
-This is explained here:
+ (find-2021workshop6video \"0:00\")
- (find-elnode \"Symbol Components\")
- (find-elnode \"Symbol Components\" \"value cell\")
- (find-elnode \"Symbol Components\" \"function cell\")
+Do this twice. In the first time you should create elisp
+hyperlinks pointing to this directory and this file,
-The content of a \"function cell\" is _usually_ a lambda
-expression. See:
+ (find-efile \"play/\")
+ (find-efile \"play/\" \"life.el\")
- (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\")
+and in the second time you should create elisp hyperlinks to a
+directory and a file that you find interesting.
-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)
+3.3. Invisible text
+-------------------
+Run this sexp:
-10.4. Quote and backquote
--------------------------
-Eev uses backquote a lot and avoids macros.
+ (eek \"3*<up> C-a C-SPC C-e\")
- (find-elnode \"Backquote\")
- (find-elnode \"Macros\")
+and then use `M-w' to copy the region to the kill ring and `M-hy'
+to yank it into this sexp:
+ (insert \"\\n\")
+Instead of getting the first sexp below you will get the second
+one:
+ (insert \"\\n\" \"2.3. Invisible text\")
+ (insert \"\\n\" \"2.3. Invisible text\\n-------------------\")
+That's becase when you type `C-e' on the title of a section of an
+\"intro\" the `C-e' takes you to the right of the line _after_
+the invisible text. If you type `<left> <right>' there this moves
+the point to a position before the invisible text.
+Exercise: create a pair of elisp hyperlinks, the first one
+pointing to this intro and the second pointing to this section,
+and copy the pair to your notes. You'll have to watch the video
+to understand some tricky points and you will have to follow the
+diagram below.
-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\")
+ ________ _______ _______________ ________
+ | | | | | | | | |
+ | [EX] | M-hh | [EH] | M-21j | [EH] | [N] | C-x 1 M-K* | [EX] |
+ | M-w | ----> | | -----> | M-h2 ::> C-y | ----------> | |
+ | | | | | M-hy | | | |
+ |________| |_______| |________|______| |________|
-Try also this:
+[Video links:]
+ (find-2021workshop4video \"0:00\")
- (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]
-" rest)))
-;; (find-eval-intro)
+[The rest is old]
-;;; _ _ _ _ _
-;;; | (_)_ __ | | _____ ___ ___ _ ____ _____ _ __ | |_(_) ___ _ __
___
-;;; | | | '_ \| |/ / __|_____ / __/ _ \| '_ \ \ / / _ \ '_ \| __| |/ _ \| '_
\/ __|
-;;; | | | | | | <\__ \_____| (_| (_) | | | \ V / __/ | | | |_| | (_) | | |
\__ \
-;;; |_|_|_| |_|_|\_\___/ \___\___/|_| |_|\_/ \___|_| |_|\__|_|\___/|_|
|_|___/
-;;;
-;; «find-links-conv-intro» (to ".find-links-conv-intro")
-;; Skel: (find-intro-links "links-conv")
-(defun find-links-conv-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-links-conv-intro)*"))
- (apply 'find-eintro "\
-\(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.
+3.3. Copy from `find-ekey-links'
+--------------------------------
+ 1. use M-5j to go to (find-eev-quick-intro) - a.k.a. \"the main
+ tutorial\",
+ 2. go to the section 4.2 in that main tutorial, and find where it
+ says \"Try the eek links below\",
+ 3. run the eek link that says:
+ (eek \"M-h M-k C-s ;; isearch-forward\")
-This intro explains some conventions on the names and behaviors
-of the hyperlink functions of eev.
+ 4. it should open a temporary buffer whose buffer name is \"*Elisp
+ hyperlinks*\". Find the two lines in that buffer that say:
+ # (Info-goto-emacs-command-node 'isearch-forward)
+ # (find-enode \"Command Index\" \"* isearch-forward:\")
+ 5. mark and copy those lines,
+ 6. use `M-21j' or `M-31j' to open your notes buffer in the right
+ window,
+ 7. paste those lines to your notes buffer.
+In a diagram:
+ __________ __________ ________________
+ | | | | | | |
+ M-5j | [MT] | M-e | [EH] | M-21j | [EH] | [N] |
+ -----> | sec. 4.2 | ----> | | ---------> | ::> |
+ | | | | or M-31j | | |
+ |__________| |__________| |________|_______|
-1. Security vs. transparency
-============================
-In a previous tutorial - here:
- (find-eev-quick-intro \"3. Elisp hyperlinks\")
+3.4. A variant
+--------------
+Someone who knows how to use `M-h M-k' (`find-ekey-links') and
+who doesn't need to split windows can do essentially the same as
+we did in the previous section with fewer keystrokes. Let's see
+how.
-we saw that several kinds of sexps can be used as hyperlinks. For
-example, these ones:
+Exercise:
- (find-fline \"/tmp/\")
- (find-node \"(emacs)Lisp Eval\")
- (find-efunctiondescr 'find-file)
- (find-efunction 'find-file)
- (find-man \"cat\")
+ 1. Type `M-hk C-s' to open a temporary buffer with elisp
+ hyperlinks on the key `C-s',
+ 2. mark, and copy with `M-w', the lines that say:
-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.
+ # (Info-goto-emacs-command-node 'isearch-forward)
+ # (find-enode \"Command Index\" \"* isearch-forward:\")
-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:
+ 3. use `M-1j' to go to your notes buffer,
+ 4. paste those lines to your notes buffer with `C-y'.
- (find-sh \"<code that deletes all your e-mails>\")
+In a diagram:
-but it is not possible to hide that action behind an
-innocent-looking button that says \"click for a larger image\".
+ ___________ ___________
+ | | | |
+ M-hk C-s | [EH] | M-1j | [N] |
+ ---------> | mark, M-w | -----> | C-y |
+ | | | |
+ |___________| |___________|
-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
+4. A two-window setting (hard)
==============================
-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?
+Exercise: copy the diagram below to your notes,
-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
+ ____________ _____________ ____________
_____________
+ | | | | | | | | | | |
|
+ | [EX] | [T] | M-hh | [EX] | [EH] | M-21j | [EH] | [N] | M-K* | [EH] |
[EX] |
+ | | M-w | ----> | | M-h2 | -----> | | C-y | ---> | |
|
+ | | | | | M-hy | | | | | |
|
+ | | | | | M-w | | | | | |
|
+ |______|_____| |______|______| |______|_____|
|______|______|
- (find-efunction-links 'find-file)
+then come back here and type `C-x 1 C-x 3' to split the window.
+In the window at the right, go this directory,
-these hyperlinks
+ (find-efile \"\")
- (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))
+find the subdirectory \"play\", enter it, find the file
+\"life.el\", and inside the file \"life.el\" find the line that
+starts with this string, with a space at its end:
-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,
+ \"(defun life \"
- (find-enode \"Command Index\" \"* find-file:\")
- (find-elnode \"Index\" \"* find-file:\")
+Then follow the instructions in the diagram above to create a
+link to the file \"life.el\". Refine that link to make it point
+to the first occurrence of the string \"(defun life \" inside the
+file \"life.el\", and copy the original link and the refined one
+to your notes.
-are generated by calls to `code-c-d', as explained here:
+[Video links:]
+ (find-2021workshop2video \"0:00\")
- (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\")
+1. Saving interesting links
+===========================
+The documentation of eev says at several places that people
+should \"save all interesting links to their notes\". It is
+easier to learn that if we split it into these tasks:
-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.
+ a. save links to your notes
+ b. test these links
+ c. mark the links that you don't understand
+ d. undestand what each link does (with M-h M-f)
+ e. recognize which links are interesting
-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.
+" pos-spec-list)))
+;; (find-saving-links-intro)
-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.
+;;; _
+;;; _____ ____ _| |
+;;; / _ \ \ / / _` | |
+;;; | __/\ V / (_| | |
+;;; \___| \_/ \__,_|_|
+;;;
+;; «find-eval-intro» (to ".find-eval-intro")
+;; Skel: (find-intro-links "eval")
+;; (find-TH "eev-article" "hyperlinks")
+;; (find-TH "eev-article" "forward-and-back")
+;; http://angg.twu.net/eev-article.html#hyperlinks
+;; file:///home/edrx/TH/L/eev-article.html#hyperlinks
+;; (find-efunction 'ee-eval-last-sexp)
- 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.
+(defun find-eval-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-eval-intro)*"))
+ (apply 'find-eintro "\
+\(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.
- 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:
+Note: this intro is messy and VERY old!
+TODO: integrate it with:
+ (find-eev-quick-intro \"2. Evaluating Lisp\")
+ (find-elisp-intro)
- 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\")
+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
-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
+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:
- (man \"cat\")
+ (+ (* 2 3)
+ (* 4 5)
+ )
-may split the current window or even create another frame, and this
-one
+`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.
- (describe-function 'find-file)
+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'.
-displays a lot of output in the echo area. Compare them with their
-eev-ish variants:
+ (+ (* 2 3) (* 4 5))
- (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,
+3. What to execute, and in what order
+=====================================
+Note that the order of evaluation may be important:
- 4) calls to them can be \"refined\" with a pos-spec.
+ (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.
-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:
+ (setq a 5)
+ (setq a 6)
+ (defun f (x) (* x x))
+ (defun f (x) (* x 10))
+ (f a)
- (find-enode \"Help\")
+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.
-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)
+4. Elisp hyperlinks
+===================
+Some Emacs functions can be used as hyperlinks. When sexps like
-`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-file \"/tmp/\")
+ (info \"(emacs)Lisp Eval\")
+ (describe-function 'find-file)
+ (find-function 'find-file)
+ (man \"cat\")
- _____________________________________________________________
- |# (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) ------|
- |_____________________________________________________________|
+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.
-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.
+Eev defines several functions to let us use sexps as hyperlinks.
+The main conventions on these functions are:
-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:
+ 1) their names start with \"find-\",
- 5) The buffer name is \"*Elisp hyperlinks*\",
+ 2) calls to them can be \"refined\" with a pos-spec (this will
+ be discussed below),
- 6) The first sexp(s) in the elisp hyperlinks buffer regenerates
- the buffer,
+ 3) they open the new buffer in the current window (to make it
+ easier to \"go back\" after following them - see the next
+ section),
- 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.
+ 4) they don't display much output in the echo area,
-To understand the role of the first sexp let's look at the next
-level of complexity.
+ 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:
-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-fline \"/tmp/\")
+ (find-node \"(emacs)Lisp Eval\")
+ (find-efunctiondescr 'find-file)
+ (find-efunction 'find-file)
+ (find-man \"cat\")
- (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\")) |
- |% (defun w () (interactive) (find-texworks \"{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,
+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.
- # (find-latex-links \"/tmp/test\")
+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:
-you get the buffer with the \"{stem}\"s substituted by \"/tmp/test\".
+ (find-node \"(emacs)Shell\")
-We can think that `find-latex-links' generates an \"*Elisp
-hyperlinks*\" buffer from a template that depends on an argument
-`stem', and:
+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.
- 1) when `stem' is nil it is set to \"{stem}\",
+ (find-man \"1 bash\")
+ (find-sh \"sleep 1; echo 'This was run at:'; date\")
- 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.
+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\")
-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:
+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:
- 1) C-h buffers are usually named \"*Help*\", while
- M-h buffers are usually named \"*Elisp Hyperlinks*\";
+ (find-node \"(emacs)Command Index\")
+ (find-node \"(emacs)Command Index\" \"eval-last-sexp\")
- 2) C-h buffers are generated by functions called \"describe-*\",
- M-h buffers are generated by functions called \"find-*-links\";
+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:
- 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;
+ (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)
- 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.
+7. Pos-spec-lists
+=================
+[Moved to:] (find-refining-intro \"1. Pos-spec-lists\")
- 5) C-h buffers are _readable_, while
- M-h buffers may look like (technical) gibberish.
+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,
- 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-sh \"seq 2095 2115\" \"2100\" \"9\")
- (find-find-links-links)
+and in most cases an empty pos-spec-list, like this,
- Most `find-*-links' were created from that template - and it
- should be easy to create other ones.
+ (find-sh \"seq 2095 2115\")
- 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:
+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.
- 6) The first line (the \"top sexp\") of an M-h buffer
- regenerates the buffer. And, at last,
+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:
- 7) The elisp hyperlinks in M-h buffers are prefixed by the
- string in `ee-hyperlink-prefix'.
+ 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':
-" pos-spec-list)))
+ string -> jump to the next occurrence of that string
+ number -> move down n lines
+ list -> evaluate the list
-;; (find-links-conv-intro)
+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',
-;;; _ _ _
-;;; | (_)_ __ | | _____
-;;; | | | '_ \| |/ / __|
-;;; | | | | | | <\__ \
-;;; |_|_|_| |_|_|\_\___/
-;;;
-;; Skel: (find-intro-links "links")
-;; «find-links-intro» (to ".find-links-intro")
+ (find-available \"bash\")
+ (find-available \"bash\" \"bash-doc\")
-(defun find-links-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-links-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-links-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-links-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.
+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\")
-Note: this intro is obsolete!
-I need to move some parts of it to other intros and then delete it.
- See: (find-here-links-intro)
- (find-refining-intro)
- (find-templates-intro)
- (find-links-conv-intro \"3. Classification\")
- (find-links-conv-intro \"3. Classification\" \"regenerate\")
+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)---|
+ |________________________________________________________|
-1. Functions for templated text
-===============================
-The function that is used to generate templated text from a
-string is called `ee-template0'. The function that generates a
-templated text from a list of sexps and strings is called
-`ee-links-to-string'. The function that generates an \"*Elisp
-hyperlinks*\" buffer from a list of sexps and strings is called
-`find-elinks'. They are explained, with examples, in the source
-code, at:
+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:
- (find-eev \"eev-wrap.el\" \"ee-template0\")
- (find-eev \"eev-elinks.el\" \"find-elinks\")
- (find-eev \"eev-elinks.el\" \"find-elinks\" \"ee-links-to-string\")
+ (kill-new \"C-y\")
+ (car kill-ring)
-Some functions like `find-latex-links' generate buffers with
-elisp hyperlinks at the top, some templated text meant to be
-saved to a file at the bottom, and with a call to `ee-copy-rest'
-separating the top part from the bottom part. The `ee-copy-rest'
-is explained in detail here:
+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-eev \"eev-tlinks.el\" \"ee-copy-rest\")
+ (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'.
-2. `find-here-links'
-====================
-The most important of the commands that generates buffers with elisp
-hyperlinks - \"M-h commands\", in the terminology explained above - is
-`find-here-links', which integrates most of the functionalities of
-several more basic M-h commands. We will explain first what it _does_,
-then its _usage_.
+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-here-links' is bound to `M-h M-h' to make it very easy to
-invoke. If you are reading this then \"here\" means the buffer
-\"*(find-links-intro)*\", in a certain position. Try to type `M-h M-h';
-you will get a buffer like this,
+ (find-enode \"Command Index\")
- ____________________________________________________________
- |# See: |
- |# (find-links-intro \"`find-here-links'\") |
- |# (find-efunctiondescr 'eev-mode \"M-h M-h\") |
- | |
- |# (find-links-intro) |
- | |
- | |
- |--:**- *Elisp hyperlinks* All L1 (Fundamental eev) -|
- |____________________________________________________________|
-
-which contains a 3-line header with help links, that we will explain
-soon, and then a link to \"here\", i.e., to the buffer
-\"*(find-links-intro)*\". Note that the link
-
- (find-links-intro)
-can be \"refined\" to, for example,
-
- (find-links-intro \"which contains a 3-line header\")
-using the tricks described in these sections:
- (find-eval-intro \"Refining hyperlinks\")
- (find-eval-intro \"Producing and refining hyperlinks\")
- (find-eval-intro \"Producing and refining hyperlinks\" \"`M-h M-2'\")
- (find-eval-intro \"Producing and refining hyperlinks\" \"`M-h2hy'\")
+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:
-but `find-here-links' by itself only produces \"unrefined\" links - so
-when we say that `find-here-links' produces links to \"here\" we mean
-just \"to the current buffer\", not \"to the a certain position in the
-current buffer\".
+ (setq f 2)
+ (setq f 5)
+ (defun f (x) (* x x))
+ (defun f (x) (* 10 x))
+ (symbol-value 'f)
+ (symbol-function 'f)
-`find-here-links' works for several kinds of \"here\"s - it works for
-intros like this one, for Info pages, for manpages, for files and
-directories, for descriptions of Emacs functions and variables, and
-for a few other cases. Try the sexps below:
+This is explained here:
- (find-here-links-test '(find-eval-intro))
- (find-here-links-test '(find-node \"(dir)Top\"))
- (find-here-links-test '(find-enode \"Lisp Eval\"))
- (find-here-links-test '(find-fline \"~/\"))
- (find-here-links-test '(find-eevfile \"eepitch.el\"))
- (find-here-links-test '(find-efunction 'ee-eval-last-sexp))
+ (find-elnode \"Symbol Components\")
+ (find-elnode \"Symbol Components\" \"value cell\")
+ (find-elnode \"Symbol Components\" \"function cell\")
- (find-here-links-test '(find-efunctiondescr 'ee-eval-last-sexp))
- (find-here-links-test '(find-evardescr 'ee-hyperlink-prefix))
- (find-here-links-test '(find-efacedescr 'eepitch-star-face))
+The content of a \"function cell\" is _usually_ a lambda
+expression. See:
- (find-here-links-test '(find-ecolors \"\\nred\"))
- (find-here-links-test '(find-efaces \"eepitch-star-face\"))
- (find-here-links-test '(find-customizegroup 'rcirc))
+ (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\")
- (find-here-links-test '(find-man \"1 cat\"))
- [^ oops, this test doesn't work on multi-window settings...]
+Try:
-Each one of them tests a different case of `find-here-links',
-creating a window setup like this:
+ (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)
- ______________________________________
- | | |
- | | target of |
- | | sexp |
- | this |______________________|
- | intro | |
- | | result of running |
- | | find-here-links on |
- | | [target of sexp] |
- |_______________|______________________|
+ ((lambda (x) (* x x))
+ 4)
+ ((lambda (x) (* 10 x))
+ 4)
-The cursor is kept at the left window (\"this intro\"), so you
-can compare the different cases using just <up>, <down>, and M-e.
+10.4. Quote and backquote
+-------------------------
+Eev uses backquote a lot and avoids macros.
+ (find-elnode \"Backquote\")
+ (find-elnode \"Macros\")
-3. `find-here-links': usage patterns
-====================================
-Typically what happens is this. We are putting our notes - eepitch
-blocks, hyperlinks, etc - in a certain file; let's refer to it as the
-\"e-script\". Then we start to navigate for information, and we find
-something interesting. We want to add a link pointing to that
-\"something interesting\" to our e-script notes - but for that we need
-to produce that sexp hyperlink, and ideally we would like to do that
-in a way that does not disturb much our attention. Consider this
-diagram [note: it DOES NOT imply that the Emacs frame is split into three
-windows - typically we will switch between buffers in a single window]:
- ______________________________________
- | | |
- | | something |
- | ==> interesting |
- | e-script |_________||___________|
- | | \\/ |
- | | result of running |
- | <== find-here-links on |
- | | [sthing intrstng] |
- |_______________|______________________|
-and this series of steps:
- 0. We start navigating from the e-script buffer, and when we
- 1. find something interesting [in another buffer], we
- 2. run `find-here-links' at the \"something interesting\" buffer,
- 3. identify among the sexps in the find-here-links buffer one that
- points to that \"something interesting\",
- 4. copy that sexp to the kill-ring,
- 5. go back to the e-script buffer,
- 6. insert that sexp into the e-script buffer,
- 7. execute that sexp to go back to the \"something interesting\",
- 8. continue navigating & doing stuff.
-At (8) we are essentially back to (1), but we have added to our
-e-script buffer a link to \"something interesting\".
-Note that to add refining we need to add a step before (2) and
-another one after (3):
+11. What else?
+==============
+Eev-mode defines several other key sequences similar to `M-h
+M-i'. You can get the full list here:
- 1.9. select a string to search for and copy it to the kill-ring,
- 3.1. refine that sexp using the \"string to search for\" (with M-h2hy)
+ (find-efunctiondescr 'eev-mode)
+ (find-efunctiondescr 'eev-mode \"M-h f\")
-\[TO DO: explain the keys that I normally use to perform all
-this; explain why I am not the right person to optimize these
-steps - because I can type these key sequences without thinking,
-and step (3) sometimes gives several sexps for us to choose from]
+Try also this:
+ (find-efunction-links 'eev-mode)
+and for other tutorials like this one, try:
+ (find-wrap-intro)
+ (find-eepitch-intro)
-4. ee-hyperlink-prefix
-======================
-`ee-hyperlink-prefix' is both a variable and a function that
-helps us set that variable; it started to an experiment on how to
-create an alternative to `M-x customize' and ended up becoming
-the inspiration for all the `find-*-links' functions.
+\[To do: explain M-x ee-hyperlink prefix and how to embed
+hyperlinks in scripts]
+" rest)))
-If you run `M-x ee-hyperlink-prefix' you should get a buffer like
-this:
+;; (find-eval-intro)
- ___________________________________________________________
- |# (ee-hyperlink-prefix) |
- |# (setq ee-hyperlink-prefix \"# \") |
- | |
- |# (setq ee-hyperlink-prefix \"# \") |
- |# (setq ee-hyperlink-prefix \";; \") |
- |# (setq ee-hyperlink-prefix \"-- \") |
- |# (setq ee-hyperlink-prefix \"// \") |
- |# (setq ee-hyperlink-prefix \"% \") |
- | |
- | |
- |--:**- *Elisp hyperlinks* All L1 (Fundamental eev)--|
- |___________________________________________________________|
-where the first line regenerates the buffer, the second line sets
-the variable `ee-hyperlink-prefix' to its current value, and each
-one of the lines after the first blank line sets
-`ee-hyperlink-prefix' to one of several fixed common values. If
-we change the value of `ee-hyperlink-prefix' with one of the
-`setq's and execute the first line again we see that all the
-prefixes, plus the argument \"# \" in the second line, change.
-Try this, with `M-2 M-e' on each line:
- (progn (setq ee-hyperlink-prefix \"# \") (ee-hyperlink-prefix))
- (progn (setq ee-hyperlink-prefix \"% \") (ee-hyperlink-prefix))
+;;; _ _ _ _ _
+;;; | (_)_ __ | | _____ ___ ___ _ ____ _____ _ __ | |_(_) ___ _ __
___
+;;; | | | '_ \| |/ / __|_____ / __/ _ \| '_ \ \ / / _ \ '_ \| __| |/ _ \| '_
\/ __|
+;;; | | | | | | <\__ \_____| (_| (_) | | | \ V / __/ | | | |_| | (_) | | |
\__ \
+;;; |_|_|_| |_|_|\_\___/ \___\___/|_| |_|\_/ \___|_| |_|\__|_|\___/|_|
|_|___/
+;;;
+;; «find-links-conv-intro» (to ".find-links-conv-intro")
+;; Skel: (find-intro-links "links-conv")
+(defun find-links-conv-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-links-conv-intro)*"))
+ (apply 'find-eintro "\
+\(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.
-5. The first line regenerates the buffer
-========================================
-Most of the \"M-h commands\" generate buffers with elisp
-hyperlinks in which the the first line \"regenerates the
-buffers\". This means two things:
- 1. You can copy the first line to your notes, and it will work
- as a link to that buffer. Here are some examples of these
- first lines:
- (find-latex-links \"/tmp/mytest\")
- (find-latex-links \"~/latextest\")
- (find-code-pdf-links
\"/usr/local/texlive/2019/texmf-dist/doc/asymptote/\" \"{c}\")
- (find-code-pdf-links
\"/usr/local/texlive/2019/texmf-dist/doc/asymptote/\" \"asy\")
+This intro explains some conventions on the names and behaviors
+of the hyperlink functions of eev.
- A good way to compare the results of the two
- `find-latex-links' and the two `find-code-pdf-links' sexps
- above is to run them with `M-2 M-e'. The prefix `M-2' to
- `M-e' makes the \"target\" of a sexp be displayed in a
- second window without switching to it. See:
- (find-efunctiondescr 'ee-eval-sexp-eol)
- (find-multiwindow-intro \"find-2a\")
- 2. You can change the arguments of the sexp in the first line
- and run it again, and this will regenerate the buffer with
- some modifications. This was explained here:
- (find-eev-quick-intro \"7.5. `find-latex-links'\" \"change the
\\\"{stem}\\\"\")
- (find-eev-quick-intro \"11.1. `find-pdf-links'\" \"adjust by hand\")
-\[To do: explain how this works in more complex templates.
-Example:\]
+1. Security vs. transparency
+============================
+In a previous tutorial - here:
- (find-find-links-links)
- (find-find-links-links \"\\\\M-u\")
- (find-find-links-links \"\\\\M-u\" \"USERTEST\")
- (find-find-links-links \"\\\\M-u\" \"USERTEST\" \"a\")
- (find-find-links-links \"\\\\M-u\" \"USERTEST\" \"a b\")
- (find-find-links-links \"\\\\M-u\" \"USERTEST\" \"a b c\")
+ (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.
-6. Pointing to where we are now
-===============================
-Several of the `M-h' commands are mainly meant to help us
-generate hyperlinks to \"where we are now\": to the current file,
-to the current Info page, to the current `find-*-intro', to an
-Emacs function or variable we are inspecting, to the current
-buffer, and so on. They don't try to be very smart -
-
-\[To do: write this\]
+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-efunctiondescr 'eev-mode)
- (find-efunctiondescr 'eev-mode \"M-h f\")
+ (find-sh \"<code that deletes all your e-mails>\")
- (eek \"M-h M-i\")
+but it is not possible to hide that action behind an
+innocent-looking button that says \"click for a larger image\".
- (find-enode \"Lisp Eval\")
- (progn (find-enode \"Lisp Eval\") (eek \"M-h M-i\"))
+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.
- (eek \"M-h f ;; find-file-links\")
- (eek \"M-h M-b ;; find-ebuffer-links\")
- for example, `M-h M-i' generates links to
- the current \"intro\" buffer - like this one - _and_ to the
- current Info page (the \"i\" in `M-h M-i' has two meanings).
- Try:
- (eek \"M-h M-i\")
- you should get something like this:
+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?
- ___________________________________________________________
- |# (find-einfo-links \"links\") |
- | |
- |[No \"*info*\" buffer] |
- | |
- |# (find-links-intro) |
- | |
- | |
- |--:**- *Elisp hyperlinks* All L1 (Fundamental eev)--|
- |___________________________________________________________|
+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
-7. The rest of the buffer
-=========================
-Several elisp hyperlinks buffers are composed of two parts: a
-series of links at the top, and then a template-generated text
-that is mean to be copied to somewhere else. The canonical
-example is
+ (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))
- (find-eev-update-links)
+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,
-which ends with stuff that you can copy to your .emacs file to
-make Emacs load eev by default. The end of the buffer generated
-by `find-eev-update-links' looks more or less like this:
+ (find-enode \"Command Index\" \"* find-file:\")
+ (find-elnode \"Index\" \"* find-file:\")
- ____________________________________________________________
- |# (ee-copy-rest 0 '(find-fline \"~/.emacs\")) |
- | |
- |;; Load eev2. |
- |;; See: (find-file \"~/eev/\") |
- |;; (find-file \"~/eev/eev-readme.el\") |
- |;; Generated by: (find-eev-update-links \"~/eev/\") |
- |;; |
- |(add-to-list 'load-path \"~/eev/\") |
- |(require 'eev2-all) ; (find-eev \"eev2-all.el\") |
- |(eev-mode 1) ; (find-eev \"eev-mode.el\") |
- | |
- | |
- |--:**- *Elisp hyperlinks* Bot L56 (Fundamental eev)---|
- |____________________________________________________________|
+are generated by calls to `code-c-d', as explained here:
-The line with `ee-copy-rest' is a hack. Its first argument is a
-number, that we will call the \"skip\", and the second is
-a (quoted) sexp hyperlink, that we will call the \"code\". The
-rule that defines what is the \"rest of the buffer\" is this:
+ (find-eev-quick-intro \"9.1. `code-c-d'\")
+ (find-eev-quick-intro \"9.1. `code-c-d'\" \"find-code-c-d\")
- Move to the beginning of the next line, then skip (i.e., move
- down) more SKIP lines. The rest of the buffer is everything
- from that point on.
+Check:
-A sexp like `(ee-copy-rest ...)' does several things:
+ (find-code-c-d \"e\" ee-emacs-lisp-directory :info \"emacs\")
+ (find-code-c-d \"el\" ee-emacs-lisp-directory :info \"elisp\")
- 1) it highlights the rest of the buffer temporarily (like as
- with `M-0 M-e'),
+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:
- 2) it copies the rest of the buffer to the kill ring (like as
- with `M-w'),
+ (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\")
- 3) it runs CODE to open its target in a window at the right
- side (like as with `M-3 M-e')
+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.
-\[To do: add examples - including examples that let us create Lua
-scripts etc\]
+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.
-" rest)))
-;; (find-links-intro)
-;; (find-eevfile "eev-template.el" "defun find-efunction-links")
+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-eepitch-intro» (to ".find-eepitch-intro")
-;; Skel: (find-intro-links "eepitch")
-;; (find-eev "eepitch.readme")
+ (find-eev \"eev-elinks.el\" \"find-elinks\")
-(defun find-eepitch-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-eepitch-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-eepitch-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-eepitch-intro\")
-More intros: (find-eev-quick-intro)
- (find-eval-intro)
- (find-wrap-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial (for eepitch) and a sandbox.
+ 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.
-This intro _complements_ the material in:
- (find-eev-quick-intro \"6. Controlling shell-like programs\")
+ f) `find-here-links' and its variants create temporary buffers
+ that violate this convention:
-My video for the EmacsConf2019 has a simple demo of eepitch:
- https://www.youtube.com/watch?v=86yiRG8YJD0&t=956
- http://angg.twu.net/emacsconf2019.html
+ (find-links-intro \"5. The first line regenerates the buffer\")
-This (old) video shows a demo like the one in section 1.3:
- https://www.youtube.com/watch?v=Lj_zKC5BR64&t=16s
-The relevant part is from t=16s to t=25s.
+ g) If we call the hyperlinks in the items above \"non-basic\"
+ then we get - by exclusion! - a notion of what are \"basic
+ hyperlinks\".
-In this intro we suppose that the reader knows what is a terminal
-and what is a shell. In Unix-like systems the terminal and the
-shell are clearly different programs, and it's easy to understand
-how a terminal can be used to run other programs that are not
-shells (e.g., a Python interpreter; see \"REPL\" below); in
-Windows most people don't know that the \"DOS window\" is in fact
-a Windows console running cmd.exe. Some links:
- https://en.wikipedia.org/wiki/Pipeline_(Unix)
- https://en.wikipedia.org/wiki/Unix_philosophy
- https://en.wikipedia.org/wiki/Unix-like
- https://en.wikipedia.org/wiki/Shell_(computing)
- https://en.wikipedia.org/wiki/Shell_(computing)#Text_(CLI)_shells
- https://en.wikipedia.org/wiki/Shell_script
- https://en.wikipedia.org/wiki/Command-line_interface
- https://en.wikipedia.org/wiki/Command-line_interface#Command-line_interpreter
- https://en.wikipedia.org/wiki/Read-eval-print_loop (\"REPL\")
- https://en.wikipedia.org/wiki/Terminal_emulator
- https://en.wikipedia.org/wiki/Text_terminal
- https://en.wikipedia.org/wiki/MS-DOS#Windows_command-line_interface
- https://en.wikipedia.org/wiki/Windows_Console
- https://en.wikipedia.org/wiki/Cmd.exe
+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\")
-1. Some demos
-=============
-Let's start with the simplest case. If you put the cursor on the
-first line that starts with a red star below and type the key
-<f8> six times,
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
-echo \"We are at: $PWD\"
-cd /tmp/
-echo \"We changed to: $(pwd)\"
+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:
-you will notice that each <f8> does something with the current
-line and move the cursor to the next line; first three <f8>s - on
-the lines that start with red stars - create a window setting
-like this,
+ (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\")
- ________________________________
- | | |
- | notes | target |
- | buffer | buffer |
- | (this intro) | (\"*shell*\") |
- | | |
- |________________|_______________|
+Emacs has several functions that _sort_ of can be used as hyperlinks,
+but that are kind of messy. For example, this one
-and the last three <f8>s - on \"non-red star lines\" - send the
-lines
+ (man \"cat\")
- echo \"We are at: $PWD\"
- cd /tmp/
- echo \"We changed to: $(pwd)\"
+may split the current window or even create another frame, and this
+one
-to the \"target buffer\", that in this case is the buffer with a
-terminal running a shell; the shell behaves exactly is if the the
-user had typed those three lines at its prompt.
+ (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.1. Another target
--------------------
-If you put the cursor at the first red star line below and type
-<f8> six times you will get something very similar to the example
-above,
+ 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\"),
- (eepitch-python)
- (eepitch-kill)
- (eepitch-python)
-1 + 2
-print(\"Hello \" +
- \"world\")
+ 2) they open the new buffer in the current window (to make it
+ easier to go back),
-but now the window setting will be like this:
+ 3) they don't display much output in the echo area,
- ________________________________
- | | |
- | notes | target |
- | buffer | buffer |
- | (this intro) | (\"*python*\") |
- | | |
- |________________|_______________|
+ 4) calls to them can be \"refined\" with a pos-spec.
-and the target buffer will be called \"*python*\", and it
-contains a terminal running a Python interpreter.
+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:
-1.2. Two targets
-----------------
-The demo below uses an advanced feature - the function
-`find-3EE', explained at:
+ (find-enode \"Help\")
- (find-multiwindow-intro \"find-3EE\")
+An example:
-to create a 3-window setup like this:
+ (find-enode \"Key Help\")
+ (eek \"C-h k <down>\")
- _______________________
- | | |
- | | *shell* |
- | notes |____________|
- | buffer | |
- | | *python* |
- |__________|____________|
+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:
-Some non-red star lines in it send the current line to the
-\"*shell*\" buffer, and some send the current line to the
-\"*python*\" buffer. The red star lines with \"(eepitch-shell)\"
-set the target to \"*shell*\", and the red star lines with with
-\"(eepitch-python)\" set the target to \"*python*\". Try it! Put
-the cursor on the first red star line below, then type <f8>
-twelve times:
+ \"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)
- (find-3EE '(eepitch-shell) '(eepitch-python))
- (eepitch-shell)
-echo Hello... > /tmp/o
+`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:
- (eepitch-python)
-print(open(\"/tmp/o\").read())
+ _____________________________________________________________
+ |# (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) ------|
+ |_____________________________________________________________|
- (eepitch-shell)
-echo ...and bye >> /tmp/o
+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.
- (eepitch-python)
-print(open(\"/tmp/o\").read())
+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.
-1.3. Two targets, two windows
------------------------------
-The demo below is similar to the one with three windows in the
-previous section, but it uses just two windows - and the window
-at the right alternates between \"*shell*\" and \"*python*\":
+To understand the role of the first sexp let's look at the next
+level of complexity.
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
-echo Hello... > /tmp/o
- (eepitch-python)
- (eepitch-kill)
- (eepitch-python)
-print(open(\"/tmp/o\").read())
- (eepitch-shell)
-echo ...and bye >> /tmp/o
- (eepitch-python)
-print(open(\"/tmp/o\").read())
+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\")) |
+ |% (defun w () (interactive) (find-texworks \"{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\")
-2. How <f8> works
-=================
-The key <f8> works in one way when the cursor is on a line that
-starts with a red star - it executes everything at the right of
-the \"\" as Lisp code, and then moves down - and in a totally
-different way on non-red star lines: on non-red star lines it
-makes sure that the target buffer is being displayed, then sends
-the current line to the target buffer \"as if the user had typed
-it\", then moves down.
+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),
-2.1. Eepitch blocks
--------------------
-A block of three red star lines like
+ 3) the second sexp shows a typical, useful, value for `stem',
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
+ 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.
-or
- (eepitch-python)
- (eepitch-kill)
- (eepitch-python)
-is called an \"eepitch block\". The _final effect_ of typing <f8>
-thrice on an eepitch block like this
+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:
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
+ 1) C-h buffers are usually named \"*Help*\", while
+ M-h buffers are usually named \"*Elisp Hyperlinks*\";
-is easy to describe: after the third <f8> we get a window setting
-like this,
-
- ________________________
- | | |
- | notes | target |
- | buffer | buffer |
- | | (\"*shell*\") |
- | | |
- |__________|_____________|
-
-where the target buffer is running a _new_ shell...
+ 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,
-2.2. `(eepitch-kill)'
----------------------
-The effect of running <f8> on a line like
+ (find-eval-intro \"Refining hyperlinks\")
- (eepitch-kill)
+ 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.
-is to kill the current target. More precisely, `(eepitch-kill)'
-kills a buffer with the name stored in the variable
-`eepitch-buffer-name', if a buffer with that name exists; in the
-examples above the target buffer names are always either
-\"*shell*\" or \"*python*\". If we are in a window setting like
-this and the target is \"*shell*\"
+ 5) C-h buffers are _readable_, while
+ M-h buffers may look like (technical) gibberish.
- ________________________
- | | |
- | notes | target |
- | buffer | buffer |
- | | (\"*shell*\") |
- | | |
- |__________|_____________|
+ 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:
-and we run `(eepitch-kill)' the window setting becomes this:
+ (find-find-links-links)
- _____________________
- | | |
- | notes | some |
- | buffer | other |
- | | buffer |
- | | |
- |__________|__________|
+ Most `find-*-links' were created from that template - and it
+ should be easy to create other ones.
-which may be confusing...
+ 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'.
-2.2. `(eepitch-shell)'
-----------------------
-The effect of running <f8> on a line like
+" pos-spec-list)))
- (eepitch-shell)
+;; (find-links-conv-intro)
-can be *roughly* described as:
- a) Set the name of the target buffer to \"*shell*\".
- b) If the target buffer does not exist, create it - by
- running `(shell)'.
- c) If the target buffer is not being displayed then display it
- - by creating a two-window setting with the target buffer at
- the right.
-This is a simplification, though... the sexp
- (eepitch-shell)
+;;; _ _ _
+;;; | (_)_ __ | | _____
+;;; | | | '_ \| |/ / __|
+;;; | | | | | | <\__ \
+;;; |_|_|_| |_|_|\_\___/
+;;;
+;; Skel: (find-intro-links "links")
+;; «find-links-intro» (to ".find-links-intro")
-runs this,
+(defun find-links-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-links-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-links-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-links-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.
- (eepitch '(shell))
-and the name of the target buffer is obtained from the
-sexp `(shell)' by running it in a certain way.
+Note: this intro is obsolete!
+I need to move some parts of it to other intros and then delete it.
+ See: (find-here-links-intro)
+ (find-refining-intro)
+ (find-templates-intro)
+ (find-links-conv-intro \"3. Classification\")
+ (find-links-conv-intro \"3. Classification\" \"regenerate\")
-2.3. `eepitch'
---------------
-The documentation for `eepitch' says:
- (eepitch CODE)
+1. Functions for templated text
+===============================
+The function that is used to generate templated text from a
+string is called `ee-template0'. The function that generates a
+templated text from a list of sexps and strings is called
+`ee-links-to-string'. The function that generates an \"*Elisp
+hyperlinks*\" buffer from a list of sexps and strings is called
+`find-elinks'. They are explained, with examples, in the source
+code, at:
- Set up a target for eepitch and make sure it is displayed in
- another window.
- The argument CODE must be a \"shell-like sexp\", i.e., one that
- when evaluated always switches to a buffer with a fixed name,
- and when that buffer does not exists it creates it.
+ (find-eev \"eev-wrap.el\" \"ee-template0\")
+ (find-eev \"eev-elinks.el\" \"find-elinks\")
+ (find-eev \"eev-elinks.el\" \"find-elinks\" \"ee-links-to-string\")
-For example, running `(shell)' switches to a buffer whose name is
-\"*shell*\"; the name of the target buffer can obtained
-from the sexp `(shell)' by running this:
+Some functions like `find-latex-links' generate buffers with
+elisp hyperlinks at the top, some templated text meant to be
+saved to a file at the bottom, and with a call to `ee-copy-rest'
+separating the top part from the bottom part. The `ee-copy-rest'
+is explained in detail here:
- (save-window-excursion
- (shell)
- (setq eepitch-buffer-name
- (buffer-name (current-buffer))))
+ (find-eev \"eev-tlinks.el\" \"ee-copy-rest\")
-2.4. `(eepitch-python)'
------------------------
-The effect of running <f8> on a line like
+2. `find-here-links'
+====================
+The most important of the commands that generates buffers with elisp
+hyperlinks - \"M-h commands\", in the terminology explained above - is
+`find-here-links', which integrates most of the functionalities of
+several more basic M-h commands. We will explain first what it _does_,
+then its _usage_.
- (eepitch-python)
+`find-here-links' is bound to `M-h M-h' to make it very easy to
+invoke. If you are reading this then \"here\" means the buffer
+\"*(find-links-intro)*\", in a certain position. Try to type `M-h M-h';
+you will get a buffer like this,
-is very similar to `(eepitch-shell)', but it uses \"*python*\" as
-the name of the target buffer. `(eepitch-python)' is defined as:
+ ____________________________________________________________
+ |# See: |
+ |# (find-links-intro \"`find-here-links'\") |
+ |# (find-efunctiondescr 'eev-mode \"M-h M-h\") |
+ | |
+ |# (find-links-intro) |
+ | |
+ | |
+ |--:**- *Elisp hyperlinks* All L1 (Fundamental eev) -|
+ |____________________________________________________________|
- (eepitch '(find-comintprocess \"python\" \"python\"))
+which contains a 3-line header with help links, that we will explain
+soon, and then a link to \"here\", i.e., to the buffer
+\"*(find-links-intro)*\". Note that the link
+ (find-links-intro)
+can be \"refined\" to, for example,
+ (find-links-intro \"which contains a 3-line header\")
-2.5. `find-comintprocess'
--------------------------
-The sexp
+using the tricks described in these sections:
- (find-comintprocess \"buffer name\" \"program and args\")
+ (find-eval-intro \"Refining hyperlinks\")
+ (find-eval-intro \"Producing and refining hyperlinks\")
+ (find-eval-intro \"Producing and refining hyperlinks\" \"`M-h M-2'\")
+ (find-eval-intro \"Producing and refining hyperlinks\" \"`M-h2hy'\")
-switches to a buffer called \"*buffer name*\" and if that buffer
-does not have an associated process then it runs \"program and
-args\" there in comint mode.
+but `find-here-links' by itself only produces \"unrefined\" links - so
+when we say that `find-here-links' produces links to \"here\" we mean
+just \"to the current buffer\", not \"to the a certain position in the
+current buffer\".
-The sexp
+`find-here-links' works for several kinds of \"here\"s - it works for
+intros like this one, for Info pages, for manpages, for files and
+directories, for descriptions of Emacs functions and variables, and
+for a few other cases. Try the sexps below:
- (eepitch-comint \"buffer name\" \"program and args\")
+ (find-here-links-test '(find-eval-intro))
+ (find-here-links-test '(find-node \"(dir)Top\"))
+ (find-here-links-test '(find-enode \"Lisp Eval\"))
+ (find-here-links-test '(find-fline \"~/\"))
+ (find-here-links-test '(find-eevfile \"eepitch.el\"))
+ (find-here-links-test '(find-efunction 'ee-eval-last-sexp))
-works as an abbreviation for:
+ (find-here-links-test '(find-efunctiondescr 'ee-eval-last-sexp))
+ (find-here-links-test '(find-evardescr 'ee-hyperlink-prefix))
+ (find-here-links-test '(find-efacedescr 'eepitch-star-face))
- (eepitch '(find-comintprocess \"buffer name\" \"program and args\"))
+ (find-here-links-test '(find-ecolors \"\\nred\"))
+ (find-here-links-test '(find-efaces \"eepitch-star-face\"))
+ (find-here-links-test '(find-customizegroup 'rcirc))
-Most `eepitch-<lang>' functions are defined using
-`eepitch-comint'. See:
+ (find-here-links-test '(find-man \"1 cat\"))
+ [^ oops, this test doesn't work on multi-window settings...]
- (find-eev \"eepitch.el\" \"eepitch-langs\")
- (find-eev \"eepitch.el\" \"find-comintprocess\")
- (find-eev \"eepitch.el\" \"find-comintprocess\" \"defun eepitch-comint \")
+Each one of them tests a different case of `find-here-links',
+creating a window setup like this:
+ ______________________________________
+ | | |
+ | | target of |
+ | | sexp |
+ | this |______________________|
+ | intro | |
+ | | result of running |
+ | | find-here-links on |
+ | | [target of sexp] |
+ |_______________|______________________|
+The cursor is kept at the left window (\"this intro\"), so you
+can compare the different cases using just <up>, <down>, and M-e.
-3. Test blocks
-==============
-Suppose that we have a file \"foo.py\" containing this (without
-the indentation):
- def square (x):
- return x*x
- \"\"\"
- (eepitch-python)
- (eepitch-kill)
- (eepitch-python)
- execfile(\"foo.py\", globals())
- print(square(5))
+3. `find-here-links': usage patterns
+====================================
+Typically what happens is this. We are putting our notes - eepitch
+blocks, hyperlinks, etc - in a certain file; let's refer to it as the
+\"e-script\". Then we start to navigate for information, and we find
+something interesting. We want to add a link pointing to that
+\"something interesting\" to our e-script notes - but for that we need
+to produce that sexp hyperlink, and ideally we would like to do that
+in a way that does not disturb much our attention. Consider this
+diagram [note: it DOES NOT imply that the Emacs frame is split into three
+windows - typically we will switch between buffers in a single window]:
- \"\"\"
-
-Python treats everything between the first and the second
-`\"\"\"'s as a multiline comment, and ignores it - but for us
-this multiline comment contains an eepitch block that starts a
-Python interpreter, then a line that loads \"foo.py\" in it, then
-a line that tests the function \"square\" defined in foo.py. We
-call the block between the `\"\"\"'s a \"test block\".
-
-A \"test block\" is a multiline comment in a Python script, a Lua
-script, or in a script in one of the other supported languages -
-we call them the \"ambient script\" and the \"ambient language\"
-- that contains at least:
-
- 1) an eepitch block that runs an interpreter for the ambient
- language,
-
- 2) a line that loads the ambient script in that interpreter,
-
- 3) code that tests functions defined in the ambient script.
+ ______________________________________
+ | | |
+ | | something |
+ | ==> interesting |
+ | e-script |_________||___________|
+ | | \\/ |
+ | | result of running |
+ | <== find-here-links on |
+ | | [sthing intrstng] |
+ |_______________|______________________|
-We can insert a test block in the current buffer by running `M-x
-ee-insert-test', or `M-x eeit'. The current implementation of M-x
-ee-insert-test' uses the name of the major mode to decide which
-other function to call. If you are in a buffer in which the value
-of the variable
+and this series of steps:
- major-mode
+ 0. We start navigating from the e-script buffer, and when we
+ 1. find something interesting [in another buffer], we
+ 2. run `find-here-links' at the \"something interesting\" buffer,
+ 3. identify among the sexps in the find-here-links buffer one that
+ points to that \"something interesting\",
+ 4. copy that sexp to the kill-ring,
+ 5. go back to the e-script buffer,
+ 6. insert that sexp into the e-script buffer,
+ 7. execute that sexp to go back to the \"something interesting\",
+ 8. continue navigating & doing stuff.
-is `FooBar-mode' then `M-x eeit' tries to run the function
-`ee-insert-test-FooBar-mode', and yields an error if that
-function does not exist. To add support for `FooBar-mode' to `M-x
-eeit', just define a function with the right name. See the source
-for examples:
+At (8) we are essentially back to (1), but we have added to our
+e-script buffer a link to \"something interesting\".
- (find-eev \"eev-testblocks.el\" \"examples\")
+Note that to add refining we need to add a step before (2) and
+another one after (3):
+ 1.9. select a string to search for and copy it to the kill-ring,
+ 3.1. refine that sexp using the \"string to search for\" (with M-h2hy)
+\[TO DO: explain the keys that I normally use to perform all
+this; explain why I am not the right person to optimize these
+steps - because I can type these key sequences without thinking,
+and step (3) sometimes gives several sexps for us to choose from]
-3.1. `find-eeit-links'
-----------------------
-If you run this,
- (find-eeit-links 'lua-mode)
-you will get a buffer with:
+4. ee-hyperlink-prefix
+======================
+`ee-hyperlink-prefix' is both a variable and a function that
+helps us set that variable; it started to an experiment on how to
+create an alternative to `M-x customize' and ended up becoming
+the inspiration for all the `find-*-links' functions.
- a) links to inspect the current definition of
- `ee-insert-test-lua-mode',
+If you run `M-x ee-hyperlink-prefix' you should get a buffer like
+this:
- b) links that let you compare that with the `ee-insert-test-'s
- for other major modes,
+ ___________________________________________________________
+ |# (ee-hyperlink-prefix) |
+ |# (setq ee-hyperlink-prefix \"# \") |
+ | |
+ |# (setq ee-hyperlink-prefix \"# \") |
+ |# (setq ee-hyperlink-prefix \";; \") |
+ |# (setq ee-hyperlink-prefix \"-- \") |
+ |# (setq ee-hyperlink-prefix \"// \") |
+ |# (setq ee-hyperlink-prefix \"% \") |
+ | |
+ | |
+ |--:**- *Elisp hyperlinks* All L1 (Fundamental eev)--|
+ |___________________________________________________________|
- c) a barebones `(defun ...)' that lets you redefine
- `ee-insert-test-lua-mode'.
+where the first line regenerates the buffer, the second line sets
+the variable `ee-hyperlink-prefix' to its current value, and each
+one of the lines after the first blank line sets
+`ee-hyperlink-prefix' to one of several fixed common values. If
+we change the value of `ee-hyperlink-prefix' with one of the
+`setq's and execute the first line again we see that all the
+prefixes, plus the argument \"# \" in the second line, change.
+Try this, with `M-2 M-e' on each line:
-If you run `find-eeit-links' interactively with `M-x' then it
-will run as:
+ (progn (setq ee-hyperlink-prefix \"# \") (ee-hyperlink-prefix))
+ (progn (setq ee-hyperlink-prefix \"% \") (ee-hyperlink-prefix))
- (find-eeit-links <current-major-mode>)
-and you can use that to inspect the `ee-insert-test-' support for
-the current major mode, or to implement it yourself.
+5. The first line regenerates the buffer
+========================================
+Most of the \"M-h commands\" generate buffers with elisp
+hyperlinks in which the the first line \"regenerates the
+buffers\". This means two things:
+ 1. You can copy the first line to your notes, and it will work
+ as a link to that buffer. Here are some examples of these
+ first lines:
-3.2. Test blocks as documentation
----------------------------------
-I found that test blocks are a really good way to document my
-programs. Most people think that they look very alien at first,
-but they understand them immediately when they see a demo - so
-here are some demos. You need to have lua5.1 in your path to run
-them; they use eepitch-lua51, that calls lua5.1. So try this
-first:
+ (find-latex-links \"/tmp/mytest\")
+ (find-latex-links \"~/latextest\")
+ (find-code-pdf-links
\"/usr/local/texlive/2019/texmf-dist/doc/asymptote/\" \"{c}\")
+ (find-code-pdf-links
\"/usr/local/texlive/2019/texmf-dist/doc/asymptote/\" \"asy\")
- (eepitch-lua51)
- (eepitch-kill)
- (eepitch-lua51)
- print(\"Hello!\")
- for k,v in pairs(os) do print(k, v) end
- os.exit()
+ A good way to compare the results of the two
+ `find-latex-links' and the two `find-code-pdf-links' sexps
+ above is to run them with `M-2 M-e'. The prefix `M-2' to
+ `M-e' makes the \"target\" of a sexp be displayed in a
+ second window without switching to it. See:
-If it works then try the demo below. Note that eepitch treats the
-lines with two red stars as comments; the sexps in \"\"-lines
-are hyperlinks, and the ones in \"\"-lines are not.
-
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- rm -Rv /tmp/dednat6/
- mkdir /tmp/dednat6/
- cd /tmp/dednat6/
- wget http://angg.twu.net/dednat6-minimal.zip
- unzip dednat6-minimal.zip
-
- (code-c-d \"dn6lua\" \"/tmp/dednat6/dednat6/\" :anchor)
- (setenv \"LUA_INIT\" \"@/tmp/dednat6/dednat6/edrxlib.lua\")
- (find-dn6lua \"edrxlib.lua\")
- (find-dn6lua \"treetex.lua\" \"TreeNode-tests\" 3)
- (find-dn6lua \"rect.lua\" \"dedtorect-tests\" 3)
+ (find-efunctiondescr 'ee-eval-sexp-eol)
+ (find-multiwindow-intro \"find-2a\")
+ 2. You can change the arguments of the sexp in the first line
+ and run it again, and this will regenerate the buffer with
+ some modifications. This was explained here:
+ (find-eev-quick-intro \"7.5. `find-latex-links'\" \"change the
\\\"{stem}\\\"\")
+ (find-eev-quick-intro \"11.1. `find-pdf-links'\" \"adjust by hand\")
+\[To do: explain how this works in more complex templates.
+Example:\]
+ (find-find-links-links)
+ (find-find-links-links \"\\\\M-u\")
+ (find-find-links-links \"\\\\M-u\" \"USERTEST\")
+ (find-find-links-links \"\\\\M-u\" \"USERTEST\" \"a\")
+ (find-find-links-links \"\\\\M-u\" \"USERTEST\" \"a b\")
+ (find-find-links-links \"\\\\M-u\" \"USERTEST\" \"a b c\")
+6. Pointing to where we are now
+===============================
+Several of the `M-h' commands are mainly meant to help us
+generate hyperlinks to \"where we are now\": to the current file,
+to the current Info page, to the current `find-*-intro', to an
+Emacs function or variable we are inspecting, to the current
+buffer, and so on. They don't try to be very smart -
+\[To do: write this\]
+ (find-efunctiondescr 'eev-mode)
+ (find-efunctiondescr 'eev-mode \"M-h f\")
+ (eek \"M-h M-i\")
+ (find-enode \"Lisp Eval\")
+ (progn (find-enode \"Lisp Eval\") (eek \"M-h M-i\"))
+ (eek \"M-h f ;; find-file-links\")
+ (eek \"M-h M-b ;; find-ebuffer-links\")
+ for example, `M-h M-i' generates links to
+ the current \"intro\" buffer - like this one - _and_ to the
+ current Info page (the \"i\" in `M-h M-i' has two meanings).
+ Try:
+ (eek \"M-h M-i\")
+ you should get something like this:
+ ___________________________________________________________
+ |# (find-einfo-links \"links\") |
+ | |
+ |[No \"*info*\" buffer] |
+ | |
+ |# (find-links-intro) |
+ | |
+ | |
+ |--:**- *Elisp hyperlinks* All L1 (Fundamental eev)--|
+ |___________________________________________________________|
+7. The rest of the buffer
+=========================
+Several elisp hyperlinks buffers are composed of two parts: a
+series of links at the top, and then a template-generated text
+that is mean to be copied to somewhere else. The canonical
+example is
+ (find-eev-update-links)
+which ends with stuff that you can copy to your .emacs file to
+make Emacs load eev by default. The end of the buffer generated
+by `find-eev-update-links' looks more or less like this:
+ ____________________________________________________________
+ |# (ee-copy-rest 0 '(find-fline \"~/.emacs\")) |
+ | |
+ |;; Load eev2. |
+ |;; See: (find-file \"~/eev/\") |
+ |;; (find-file \"~/eev/eev-readme.el\") |
+ |;; Generated by: (find-eev-update-links \"~/eev/\") |
+ |;; |
+ |(add-to-list 'load-path \"~/eev/\") |
+ |(require 'eev2-all) ; (find-eev \"eev2-all.el\") |
+ |(eev-mode 1) ; (find-eev \"eev-mode.el\") |
+ | |
+ | |
+ |--:**- *Elisp hyperlinks* Bot L56 (Fundamental eev)---|
+ |____________________________________________________________|
+The line with `ee-copy-rest' is a hack. Its first argument is a
+number, that we will call the \"skip\", and the second is
+a (quoted) sexp hyperlink, that we will call the \"code\". The
+rule that defines what is the \"rest of the buffer\" is this:
+ Move to the beginning of the next line, then skip (i.e., move
+ down) more SKIP lines. The rest of the buffer is everything
+ from that point on.
+A sexp like `(ee-copy-rest ...)' does several things:
+ 1) it highlights the rest of the buffer temporarily (like as
+ with `M-0 M-e'),
+ 2) it copies the rest of the buffer to the kill ring (like as
+ with `M-w'),
+ 3) it runs CODE to open its target in a window at the right
+ side (like as with `M-3 M-e')
+\[To do: add examples - including examples that let us create Lua
+scripts etc\]
+" rest)))
+;; (find-links-intro)
+;; (find-eevfile "eev-template.el" "defun find-efunction-links")
+;;; _ _ _
+;;; ___ ___ _ __ (_) |_ ___| |__
+;;; / _ \/ _ \ '_ \| | __/ __| '_ \
+;;; | __/ __/ |_) | | || (__| | | |
+;;; \___|\___| .__/|_|\__\___|_| |_|
+;;; |_|
+;;
+;; «find-eepitch-intro» (to ".find-eepitch-intro")
+;; Skel: (find-intro-links "eepitch")
+;; (find-eev "eepitch.readme")
+(defun find-eepitch-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-eepitch-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-eepitch-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-eepitch-intro\")
+More intros: (find-eev-quick-intro)
+ (find-eval-intro)
+ (find-wrap-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial (for eepitch) and a sandbox.
+This intro _complements_ the material in:
+ (find-eev-quick-intro \"6. Controlling shell-like programs\")
+My video for the EmacsConf2019 has a simple demo of eepitch:
+ https://www.youtube.com/watch?v=86yiRG8YJD0&t=956
+ http://angg.twu.net/emacsconf2019.html
+This (old) video shows a demo like the one in section 1.3:
+ https://www.youtube.com/watch?v=Lj_zKC5BR64&t=16s
+The relevant part is from t=16s to t=25s.
+In this intro we suppose that the reader knows what is a terminal
+and what is a shell. In Unix-like systems the terminal and the
+shell are clearly different programs, and it's easy to understand
+how a terminal can be used to run other programs that are not
+shells (e.g., a Python interpreter; see \"REPL\" below); in
+Windows most people don't know that the \"DOS window\" is in fact
+a Windows console running cmd.exe. Some links:
+ https://en.wikipedia.org/wiki/Pipeline_(Unix)
+ https://en.wikipedia.org/wiki/Unix_philosophy
+ https://en.wikipedia.org/wiki/Unix-like
+ https://en.wikipedia.org/wiki/Shell_(computing)
+ https://en.wikipedia.org/wiki/Shell_(computing)#Text_(CLI)_shells
+ https://en.wikipedia.org/wiki/Shell_script
+ https://en.wikipedia.org/wiki/Command-line_interface
+ https://en.wikipedia.org/wiki/Command-line_interface#Command-line_interpreter
+ https://en.wikipedia.org/wiki/Read-eval-print_loop (\"REPL\")
+ https://en.wikipedia.org/wiki/Terminal_emulator
+ https://en.wikipedia.org/wiki/Text_terminal
+ https://en.wikipedia.org/wiki/MS-DOS#Windows_command-line_interface
+ https://en.wikipedia.org/wiki/Windows_Console
+ https://en.wikipedia.org/wiki/Cmd.exe
--=-=-=-=-
-Old stuff:
-1. Motivation
+1. Some demos
=============
-Suppose that we have to do some reasonably complex task using a
-shell, and that we want to take notes of what we do because we
-might have to do something similar later.
+Let's start with the simplest case. If you put the cursor on the
+first line that starts with a red star below and type the key
+<f8> six times,
-The two usual ways to interact with a shell are:
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+echo \"We are at: $PWD\"
+cd /tmp/
+echo \"We changed to: $(pwd)\"
- 1) through a _script_, that is, by preparing in advance all
- commands to be executed, putting them in a script file, and
- then running that file,
+you will notice that each <f8> does something with the current
+line and move the cursor to the next line; first three <f8>s - on
+the lines that start with red stars - create a window setting
+like this,
- 2) _interactively_, by typing the commands one by one on a
- shell prompt.
+ ________________________________
+ | | |
+ | notes | target |
+ | buffer | buffer |
+ | (this intro) | (\"*shell*\") |
+ | | |
+ |________________|_______________|
-Suppose that we have to discover which commands to run as we go;
-that rules out preparing a script beforehand, so we need to use
-the shell interactively. After issuing the right commands, the
-two usual ways to retrieve what we did are:
+and the last three <f8>s - on \"non-red star lines\" - send the
+lines
- a) through the _shell history_, which records the last commands
- that the shell received,
+ echo \"We are at: $PWD\"
+ cd /tmp/
+ echo \"We changed to: $(pwd)\"
- b) by looking at the full _transcript_ of our interaction with
- the shell.
+to the \"target buffer\", that in this case is the buffer with a
+terminal running a shell; the shell behaves exactly is if the the
+user had typed those three lines at its prompt.
-The way (a) gets a list of commands, without comments, that can
-be then saved into a text editor; the way (b) may require some
-tricky editing to isolate the commands from their outputs.
-Eepitch.el implements a simple alternative way of interacting
-with shells (and other shell-like programs) while keeping notes.
-It has only one essential key binding, <F8>, which is better
-explained through the executable example in the next section, and
-two unessential features, `M-T' and \"\", which will be
-explained later.
+1.1. Another target
+-------------------
+If you put the cursor at the first red star line below and type
+<f8> six times you will get something very similar to the example
+above,
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+1 + 2
+print(\"Hello \" +
+ \"world\")
+but now the window setting will be like this:
-2. The main key: <F8>
-=====================
-Emacs can run a shell in a buffer, and it can split its frame
-into windows, like this:
- ___________________
- | | |
- | our | a |
- | notes | shell |
- | | buffer |
- |_________|_________|
+ ________________________________
+ | | |
+ | notes | target |
+ | buffer | buffer |
+ | (this intro) | (\"*python*\") |
+ | | |
+ |________________|_______________|
-The usual way to use a shell buffer is to move the cursor there
-and type commands into its prompt; the eepitch-y way is to leave
-the cursor at the \"notes\" buffer, write the commands for the
-shell there, and send these commands to the shell with <F8>.
+and the target buffer will be called \"*python*\", and it
+contains a terminal running a Python interpreter.
-Here's what <F8> does:
- When we type <F8> on a line that starts with a red
- star (\"\"), it executes the rest of the line as Lisp, and
- moves down; when we type <F8> on a line that does not start
- with a \"\", it makes sure that the \"target buffer\" is being
- displayed (the \"target\" is usually the buffer called
- \"*shell*\"), it \"send\"s the current line to the target
- buffer, and moves down.
- \"Sending the current line to the target buffer\" means copying
- the contents of the current line to the target - as if the user
- had typed that line there by hand -, then \"typing\" a <RET> at
- the target buffet.
-Please try that in the example after this paragraph, by typing
-<F8> six times starting at the first line that says
-\" (eepitch-shell)\". The three red star lines at the top will
-create a target buffer, destroy it, and create it again; the
-other three lines will send commands to the target shell.
+1.2. Two targets
+----------------
+The demo below uses an advanced feature - the function
+`find-3EE', explained at:
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
-echo \"We are at: $PWD\"
-cd /tmp/
-echo \"We changed to: $(pwd)\"
+ (find-multiwindow-intro \"find-3EE\")
+to create a 3-window setup like this:
+ _______________________
+ | | |
+ | | *shell* |
+ | notes |____________|
+ | buffer | |
+ | | *python* |
+ |__________|____________|
+Some non-red star lines in it send the current line to the
+\"*shell*\" buffer, and some send the current line to the
+\"*python*\" buffer. The red star lines with \"(eepitch-shell)\"
+set the target to \"*shell*\", and the red star lines with with
+\"(eepitch-python)\" set the target to \"*python*\". Try it! Put
+the cursor on the first red star line below, then type <f8>
+twelve times:
-3. Other targets
-================
-Just like `(eepitch-shell)' creates a shell buffer and sets the
-eepitch target to it, `(eepitch-python)' creates a buffer with a
-Python interpreter and uses it as the eepitch target. Try:
+ (find-3EE '(eepitch-shell) '(eepitch-python))
+ (eepitch-shell)
+echo Hello... > /tmp/o
(eepitch-python)
- (eepitch-kill)
+print(open(\"/tmp/o\").read())
+
+ (eepitch-shell)
+echo ...and bye >> /tmp/o
+
(eepitch-python)
-def square (x):
- return x*x
+print(open(\"/tmp/o\").read())
-print(square(5))
- We can use several targets at the time, alternating between them.
- For example:
+
+
+1.3. Two targets, two windows
+-----------------------------
+The demo below is similar to the one with three windows in the
+previous section, but it uses just two windows - and the window
+at the right alternates between \"*shell*\" and \"*python*\":
(eepitch-shell)
(eepitch-kill)
@@ -5603,770 +5718,586 @@ echo ...and bye >> /tmp/o
print(open(\"/tmp/o\").read())
- There is a (much) more advanced example of working with several
- targets here:
- (find-prepared-intro \"An `ee' for Python\")
+2. How <f8> works
+=================
+The key <f8> works in one way when the cursor is on a line that
+starts with a red star - it executes everything at the right of
+the \"\" as Lisp code, and then moves down - and in a totally
+different way on non-red star lines: on non-red star lines it
+makes sure that the target buffer is being displayed, then sends
+the current line to the target buffer \"as if the user had typed
+it\", then moves down.
+
-4. More on eepitch-kill
-=======================
-Note that `(eepitch-kill)' kills the _current_ target, that may
-or may not be a shell buffer, a Python interaction buffer, etc...
-That explains the first line in blocks like:
+
+2.1. Eepitch blocks
+-------------------
+A block of three red star lines like
+
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+
+or
(eepitch-python)
(eepitch-kill)
(eepitch-python)
-and:
+is called an \"eepitch block\". The _final effect_ of typing <f8>
+thrice on an eepitch block like this
(eepitch-shell)
(eepitch-kill)
(eepitch-shell)
-by running the first `(eepitch-python)' we can be sure that the
-following `(eepitch-kill)' will kill the Python buffer, not the
-shell buffer! And the last `(eepitch-python)' in the block of
-three lines will then create a new Python interaction buffer,
-erasing all definitions done in previous sessions.
+is easy to describe: after the third <f8> we get a window setting
+like this,
+ ________________________
+ | | |
+ | notes | target |
+ | buffer | buffer |
+ | | (\"*shell*\") |
+ | | |
+ |__________|_____________|
+where the target buffer is running a _new_ shell...
-5. Creating eepitch blocks: `M-T'
-=================================
-Write just \"shell\" or \"python\" in a line, then type
-`M-T' (i.e., meta-shift-t) there. The line will be turned into
-three - an \" (eepitch-xxx)\", an \" (eepitch-kill)\", and an
-\" (eepitch-xxx)\". We call these blocks of three lines
-\"eepitch blocks\". Try this below, converting the \"shell\" into
-an eepitch block for starting a shell.
-shell
-pwd
-cd /tmp/
-pwd
+2.2. `(eepitch-kill)'
+---------------------
+The effect of running <f8> on a line like
+ (eepitch-kill)
+is to kill the current target. More precisely, `(eepitch-kill)'
+kills a buffer with the name stored in the variable
+`eepitch-buffer-name', if a buffer with that name exists; in the
+examples above the target buffer names are always either
+\"*shell*\" or \"*python*\". If we are in a window setting like
+this and the target is \"*shell*\"
+ ________________________
+ | | |
+ | notes | target |
+ | buffer | buffer |
+ | | (\"*shell*\") |
+ | | |
+ |__________|_____________|
-6. Red stars
-============
-Eepitch.el sets the glyph for the char 15 to a red star in the
-standard display table. In layman's terms: eepitch.el tells Emacs
-that the character 15 should be displayed as a red star. The
-character 15 corresponds to control-O, whose default
-representation on screen would be \"^O\". You can enter a
-literal ^O in a buffer by typing `C-q C-o'.
+and we run `(eepitch-kill)' the window setting becomes this:
+ _____________________
+ | | |
+ | notes | some |
+ | buffer | other |
+ | | buffer |
+ | | |
+ |__________|__________|
+which may be confusing...
-7. For more information
-=======================
-On hyperlinks: (find-eval-intro)
-On keys similar to `M-T': (find-wrap-intro)
-An older text about eepitch:
- (find-eev \"eepitch.readme\")
- (find-eev \"eepitch.readme\" \"the-trivial-case\")
- (find-eev \"eepitch.readme\" \"red-stars\")
- (find-eev \"eepitch.readme\" \"eepitch-blocks\")
- (find-eev \"eepitch.readme\" \"eepitch-blocks\")
-Many functions like `eepitch-shell':
- (find-efunction 'eepitch-bash)
-What functions can generate target buffers:
- (find-eevfile \"eepitch.el\" \"shell-like sexp\")
- (find-efunction 'eepitch)
-" rest)))
-;; (find-eepitch-intro)
-;; (find-pytutnode "Methods of File Objects")
+2.2. `(eepitch-shell)'
+----------------------
+The effect of running <f8> on a line like
+ (eepitch-shell)
+can be *roughly* described as:
-;;;
-;;; __ ___ __ __ _ _ __
-;;; \ \ /\ / / '__/ _` | '_ \
-;;; \ V V /| | | (_| | |_) |
-;;; \_/\_/ |_| \__,_| .__/
-;;; |_|
-;;
-;; Skel: (find-intro-links "wrap")
-;; «find-wrap-intro» (to ".find-wrap-intro")
+ a) Set the name of the target buffer to \"*shell*\".
-(defun find-wrap-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-wrap-intro)*"))
- (apply 'find-eintro-latin1 "\
-\(Re)generate: (find-wrap-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-wrap-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.
+ b) If the target buffer does not exist, create it - by
+ running `(shell)'.
+ c) If the target buffer is not being displayed then display it
+ - by creating a two-window setting with the target buffer at
+ the right.
+This is a simplification, though... the sexp
-Note: this intro needs to be rewritten!
-Ideally it should _complement_ the material in:
- (find-eev-quick-intro \"6.3. Creating eepitch blocks: `M-T'\")
- (find-eev-quick-intro \"8.3. Creating index/section anchor pairs\")
- (find-eev-quick-intro \"8.4. Creating e-script blocks\")
+ (eepitch-shell)
+runs this,
+ (eepitch '(shell))
+and the name of the target buffer is obtained from the
+sexp `(shell)' by running it in a certain way.
-1. Eepitch and eev
-==================
-Eepitch defines only two keys - <F8> and <M-T> - and <M-T> is a
-particular case of something more general: \"wrapping commands\", that
-follow these conventions:
- 1) they are bound to meta-shift-letter keys (M-T, M-F, M-M, ...),
- 2) they transform the current line and then move down,
- 3) they produce Lisp code meant to be executed with `M-e' or `F8',
- 4) they are listed at:
- (find-efunctiondescr 'eev-mode \"M-F\")
- 5) their keybindings are only available when eev-mode is turned on.
-To understand how they work, please follow the instructions below and
-try them here. Note that this buffer is a sandbox, and it can be
-recreated by executing the sexp \"(find-wrap-intro)\" at the top.
+2.3. `eepitch'
+--------------
+The documentation for `eepitch' says:
-Note that the wrapping commands are all bound to key sequences of
-the form meta-SHIFT-letter - don't forget the shift!!!
+ (eepitch CODE)
+ Set up a target for eepitch and make sure it is displayed in
+ another window.
+ The argument CODE must be a \"shell-like sexp\", i.e., one that
+ when evaluated always switches to a buffer with a fixed name,
+ and when that buffer does not exists it creates it.
+For example, running `(shell)' switches to a buffer whose name is
+\"*shell*\"; the name of the target buffer can obtained
+from the sexp `(shell)' by running this:
-2. <M-T>: produce an eepitch block
-==================================
-If you type <M-T> on a line containing just the word \"shell\" you get
-three lines, like this:
+ (save-window-excursion
+ (shell)
+ (setq eepitch-buffer-name
+ (buffer-name (current-buffer))))
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
-We call a block of three lines like this an \"eepitch block\", and
-eepitch blocks can be used to set up interactions with external
-programs. Try typing <M-T> on the lines that say \"shell\" and \"python\"
-below, and use them to send some lines to bash and to a python
-interpreter (with <F8>):
-bash
-export PS1='$PWD% '
-cd /tmp/
-function ee () { set -v; . /tmp/ee.sh; set +v; }
-rm -v /tmp/ee.sh
-cat > /tmp/ee.sh <<'%%%'
- echo Hello
- cd /etc/
-%%%
-cat /tmp/ee.sh
-bash /tmp/ee.sh
-ee
-python
-square = lambda x: x*x
-square(5)
+2.4. `(eepitch-python)'
+-----------------------
+The effect of running <f8> on a line like
+ (eepitch-python)
+is very similar to `(eepitch-shell)', but it uses \"*python*\" as
+the name of the target buffer. `(eepitch-python)' is defined as:
-3. <M-F>: hyperlink to a file or a directory
-============================================
-If you type <M-F> on the lines below,
+ (eepitch '(find-comintprocess \"python\" \"python\"))
-/etc/
-/tmp/
-~/
-~/.emacs
-you get hyperlinks like these:
-# (find-fline \"/etc/\")
-# (find-fline \"/tmp/\")
-# (find-fline \"~/\")
-# (find-fline \"~/.emacs\")
+2.5. `find-comintprocess'
+-------------------------
+The sexp
+ (find-comintprocess \"buffer name\" \"program and args\")
-4. <M-S>: hyperlink to the output of a shell command
-====================================================
-If you type <M-S> on a line containing a shell command you get a
-hyperlink that starts with `find-sh', and that when followed opens a
-temporary buffer with the output of that shell command, like these:
+switches to a buffer called \"*buffer name*\" and if that buffer
+does not have an associated process then it runs \"program and
+args\" there in comint mode.
- # (find-sh \"find --help\")
- # (find-sh \"find /etc | sort\")
- # (find-sh \"find /etc -type d | sort\")
- # (find-sh \"find /etc -type d -maxdepth 1 | sort\")
- # (find-sh \"find /etc -type d -maxdepth 2 | sort\")
+The sexp
-Try it here:
+ (eepitch-comint \"buffer name\" \"program and args\")
-dict smop
-dict 'minor detail'
+works as an abbreviation for:
-If you have the packages dict, dictd and dict-jargon installed
-these hyperlinks will show you the meaning of the expressions
-\"smop\" and \"minor detail\".
+ (eepitch '(find-comintprocess \"buffer name\" \"program and args\"))
- # (find-sh \"dict smop\")
- # (find-sh \"dict 'minor detail'\")
+Most `eepitch-<lang>' functions are defined using
+`eepitch-comint'. See:
+ (find-eev \"eepitch.el\" \"eepitch-langs\")
+ (find-eev \"eepitch.el\" \"find-comintprocess\")
+ (find-eev \"eepitch.el\" \"find-comintprocess\" \"defun eepitch-comint \")
-5. <M-M>: hyperlink to a manpage
-================================
-Try <M-M> here:
-1 tac
+3. Test blocks
+==============
+Suppose that we have a file \"foo.py\" containing this (without
+the indentation):
+ def square (x):
+ return x*x
-6. All wrapping functions
-=========================
-Below is a list of all wrapping functions, with tests and
-hyperlinks:
+ \"\"\"
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+ execfile(\"foo.py\", globals())
+ print(square(5))
- (eek \"2*<down> M-A <down> ;;; Test eewrap-anchor\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-anchor\")
-;; <anchor>
+ \"\"\"
- (eek \"2*<down> M-C <down> ;;; Test eewrap-code-c-d\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-code-c-d\")
-foo /tmp/foobar/
+Python treats everything between the first and the second
+`\"\"\"'s as a multiline comment, and ignores it - but for us
+this multiline comment contains an eepitch block that starts a
+Python interpreter, then a line that loads \"foo.py\" in it, then
+a line that tests the function \"square\" defined in foo.py. We
+call the block between the `\"\"\"'s a \"test block\".
- (eek \"2*<down> M-D <down> ;;; Test eewrap-debian\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-debian\")
-bash
+A \"test block\" is a multiline comment in a Python script, a Lua
+script, or in a script in one of the other supported languages -
+we call them the \"ambient script\" and the \"ambient language\"
+- that contains at least:
- (eek \"2*<down> M-F <down> ;;; Test eewrap-find-fline\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-find-fline\")
-/tmp/foobar/
+ 1) an eepitch block that runs an interpreter for the ambient
+ language,
- (eek \"2*<down> M-J <down> ;;; Test eewrap-eejump\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-eejump\")
-422 (find-eev-intro \"find-wrap-intro\")
+ 2) a line that loads the ambient script in that interpreter,
- (eek \"2*<down> M-J <down> ;;; Test eewrap-eejump\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-eejump\")
-42
+ 3) code that tests functions defined in the ambient script.
- (eek \"2*<down> M-M <down> ;;; Test eewrap-man\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-man\")
-1 tac
+We can insert a test block in the current buffer by running `M-x
+ee-insert-test', or `M-x eeit'. The current implementation of M-x
+ee-insert-test' uses the name of the major mode to decide which
+other function to call. If you are in a buffer in which the value
+of the variable
- (eek \"2*<down> M-P <down> ;;; Test eewrap-pdflike\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-pdflike\")
-foopdf $S/http/foo.org/bar.pdf
+ major-mode
- (eek \"2*<down> M-R <down> ;;; Test eewrap-rm/mkdir/cd\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-rm/mkdir/cd\")
-/tmp/foo/
+is `FooBar-mode' then `M-x eeit' tries to run the function
+`ee-insert-test-FooBar-mode', and yields an error if that
+function does not exist. To add support for `FooBar-mode' to `M-x
+eeit', just define a function with the right name. See the source
+for examples:
- (eek \"2*<down> M-S <down> ;;; Test eewrap-sh\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-sh\")
-seq 1 20
+ (find-eev \"eev-testblocks.el\" \"examples\")
- (eek \"2*<down> M-T <down> ;;; Test eewrap-eepitch\")
- Source: (find-eev \"eepitch.el\" \"eewrap-eepitch\")
-python
- (eek \"2*<down> M-V <down> ;;; Test eewrap-audiovideo\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-audiovideo\")
-slimetutorial /tmp/slime-tutorial.mp4
- (eek \"2*<down> M-Z <down> ;;; Test eewrap-zsh\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-zsh\")
-echo $SHELL
- (eek \"2*<down> <<eewrap-eewrap>> <down> ;;; Test eewrap-eewrap\")
- Source: (find-eev \"eev-wrap.el\" \"eewrap-eewrap\")
-U user-defined a b c
+3.1. `find-eeit-links'
+----------------------
+If you run this,
+ (find-eeit-links 'lua-mode)
+you will get a buffer with:
+ a) links to inspect the current definition of
+ `ee-insert-test-lua-mode',
-7. Wrapping functions generate hyperlinks
-=========================================
-...this is a slogan - a huge idea, in a very shortened form. In its
-full form, that would be:
+ b) links that let you compare that with the `ee-insert-test-'s
+ for other major modes,
- (Some) wrapping function provide one of the basic ways to produce
- elisp hyperlinks quickly; the second basic way, which is a bit more
- complex conceptually, is via Elisp hyperlinks buffers. This, and the
- whole rationale behind generating and using elisp hyperlinks, is
- explained here:
+ c) a barebones `(defun ...)' that lets you redefine
+ `ee-insert-test-lua-mode'.
- (find-links-intro \"Elisp hyperlinks buffers\")
+If you run `find-eeit-links' interactively with `M-x' then it
+will run as:
-The \"some\" in beginning of the long version of the slogan, above, is
-because a few of the wrapping commands, for example, <M-T> and <M-R>,
-are used to produce things that are not hyperlinks - usually other
-kinds of scripts.
-" rest)))
+ (find-eeit-links <current-major-mode>)
-;; (find-wrap-intro)
+and you can use that to inspect the `ee-insert-test-' support for
+the current major mode, or to implement it yourself.
-;;; _
-;;; ___ ___ (_)_ _ _ __ ___ _ __
-;;; / _ \/ _ \| | | | | '_ ` _ \| '_ \
-;;; | __/ __/| | |_| | | | | | | |_) |
-;;; \___|\___|/ |\__,_|_| |_| |_| .__/
-;;; |__/ |_|
-;;
-;; (find-elnode "Defining Commands")
-;; (find-enode "Arguments")
-;; (find-TH "emacs" "eejump")
-;; http://angg.twu.net/emacs.html#eejump
-;; file:///home/edrx/TH/L/emacs.html#eejump
-;; «find-eejump-intro» (to ".find-eejump-intro")
+3.2. Test blocks as documentation
+---------------------------------
+I found that test blocks are a really good way to document my
+programs. Most people think that they look very alien at first,
+but they understand them immediately when they see a demo - so
+here are some demos. You need to have lua5.1 in your path to run
+them; they use eepitch-lua51, that calls lua5.1. So try this
+first:
-(defun find-eejump-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-eejump-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-eejump-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-eejump-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.
+ (eepitch-lua51)
+ (eepitch-kill)
+ (eepitch-lua51)
+ print(\"Hello!\")
+ for k,v in pairs(os) do print(k, v) end
+ os.exit()
+If it works then try the demo below. Note that eepitch treats the
+lines with two red stars as comments; the sexps in \"\"-lines
+are hyperlinks, and the ones in \"\"-lines are not.
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ rm -Rv /tmp/dednat6/
+ mkdir /tmp/dednat6/
+ cd /tmp/dednat6/
+ wget http://angg.twu.net/dednat6-minimal.zip
+ unzip dednat6-minimal.zip
-Note: this intro needs to be rewritten!
-Ideally it should _complement_ the material in:
- (find-eev-quick-intro \"7.1. `eejump'\")
-See the comments in:
- (find-eev \"eejump.el\")
+ (code-c-d \"dn6lua\" \"/tmp/dednat6/dednat6/\" :anchor)
+ (setenv \"LUA_INIT\" \"@/tmp/dednat6/dednat6/edrxlib.lua\")
+ (find-dn6lua \"edrxlib.lua\")
+ (find-dn6lua \"treetex.lua\" \"TreeNode-tests\" 3)
+ (find-dn6lua \"rect.lua\" \"dedtorect-tests\" 3)
-1. The problem
-==============
-Suppose that we have several files that we are working on, and we
-want a quick way to jump to (i.e., to visit) any of them with
-very few keystrokes; moreover,
- 1) we want our list of files to be preserved between one Emacs
- session and another,
- 2) we know that each \"visit a file\" command will correspond
- to an elisp hyperlink.
-One quick solution would be to put the list of elisp hyperlinks
-in a file, and make the key `M-j' open that file. But then
-jumping to a file in that list becomes a two-step process: type
-`M-j', move the point to the right line, type `M-e'. This would
-be similar to what happens when we use one of the `find-e*'
-commands, for example `find-efunction':
- (find-efunction 'find-efunction)
- (eek \"M-h M-f find-efunction\")
-Those intermediate steps - seeing the list, locating visually the
-right line, moving to it - are distracting, so we want to add new
-items to our wishlist:
- 3) it should be possible to jump straight to any of the files
- in the list, and with very few keystrokes,
- 4) the list should be stored in a format that lets us see
- quickly which are the keystrokes for accessing each item - so
- that we won't need to memorize anything,
- 5) the list should be easy to modify,
- 6) it should be possible to assign shorter key sequences to
- files we visit more often,
- 7) the source code must be very simple.
-2. A miniature
-==============
-My original solution was this: I used only one keybinding, `M-j',
-that acted differently when invoked with different numeric
-prefixes; when invoked as `M-1 M-j' it opened a certain file,
-when invoked with `M-2 M-j' it opened another, and so on, and
-when it was invoked with an unrecognized prefix or with no prefix
-it jumped to its definition in my ~/.emacs. Its code was like
-this (NOTE: do not execute these defuns):
- ;; eejump-simplified (`M-j'):
- ;; M-1 M-j opens a certain file,
- ;; M-2 M-j opens another file,
- ;; when the argument is 11, 22, 33 or 44 do something special,
- ;; like changing the font;
- ;; with no argument or with an unrecognized argument jump to the
- ;; definition of eejump in ~/.emacs; then we can see which numbers
- ;; correspond to which actions (the source is the documentation!), and
- ;; we can change the definition if needed - just run `M-e' at the
- ;; right place to make the changes apply.
- ;;
- \(global-set-key (kbd \"M-j\") 'eejump-simplified)
- \(defun eejump-simplified (arg) (interactive \"P\")
- (cond ((eq arg 1) (find-file \"~/NOTES\"))
- ((eq arg 2) (find-file \"~/otherfile.txt\"))
- ;;
- ((eq arg 11) (set-frame-font \"fixed\"))
- ((eq arg 22) (set-frame-font \"terminus-16\"))
- ((eq arg 33) (set-frame-font \"terminus-bold-16\"))
- ((eq arg 44) (set-frame-font \"10x20\"))
- (t (find-function 'eejump-simplified))))
-except that my definition became huge with time as I added to it
-more entries for files (and other actions!) that I used often,
-and also entries that were used not so often...
-All the \"options\" - i.e., all the `(eq arg nnn)' lines - had to
-be together in a single very big defun, and there was no way to
-add new options temporarily...
-3. Families
-===========
-Let's use a shorthand for key sequences: for example, `M-123j'
-instead of `M-1 M-2 M-3 M-j'.
-I tend to assign related numbers to related files. For example, I
-use the prefix \"5\" for things that are Emacs-related: `M-5j'
-visits my .emacs, `M-555j' visits the directory with all of eev's
-elisp files, and `M-51j', `M-52j', etc, visit specific eev source
-files that I happen to be working on. Also, I use the prefix
-\"7\" for things related to LaTeX. So, the \"5*\" family is
-composed of Emacs-related files, and the \"7*\" family of
-LaTex-related files.
-The definition of `eejump-simplified' given above does not
-satisfy these two (new!) wishlist items:
- 8) it should be possible to jump to the definition of the
- \"5*\" family by typing something like `M-5678j', where
- \"5678\" is a non-assigned number that starts with the \"5*\"
- prefix,
- 9) it should be possible to convert a number/hyperlink pair
- very easily into to the code that assigns that elisp hyperlink
- as the desired behavior for that number - and it should be
- possible to do that both permanently (think in changing the
- definition of `eejump-simplified' in your .emacs) and
- temporarily (i.e., for the current Emacs session only).
-4. `eejump'
-===========
-The definition of `eejump' that comes with eev is a bit more
-complex than the one given above, and it will not be shown
-here (it involves a tricky recursive function) but it satisfies
-the 9 wishlist items above. It works in this way: if you type,
-say, `M-123j', then:
- a) if `eejump-123' is defined, then execute it;
- b) otherwise, if `eejump-12*' is defined, execute it;
- c) otherwise, if `eejump-1*' is defined, execute it;
- d) otherwise, if `eejump-*' is defined, execute it,
-and if `eejump-*' also is not defined, you get an error.
-Here is a block of \"defun\"s that defines (trivial) meanings for
-\"91\", \"92\", \"991\", and \"992\", plus targets for the \"9*\"
-family and for the \"99*\" family; it also has two tests in
-comments that will be very important for an explanation below.
-Let's refer as that, in this section and the next ones, as \"the
-block of six defuns (plus four tests)\".
- (defun eejump-9* () (find-efunction 'eejump-9*))
- (defun eejump-91 () (message \"M-91j\"))
- (defun eejump-92 () (message \"M-92j\"))
- (defun eejump-99* () (find-efunction 'eejump-99*))
- (defun eejump-991 () (message \"M-991j\"))
- (defun eejump-992 () (message \"M-992j\"))
- ;; (find-function-noselect 'eejump-9*)
- ;; (find-function-noselect 'eejump-99*)
- ;; (find-efunction 'eejump-9*)
- ;; (find-efunction 'eejump-99*)
-Try to evaluate each of the sexps above with `M-e', then try to
-run things like `M-92j' and `M-992j' - they should work - and
-then something like `M-99876j'; that will not work, you'll get an
-error like \"Don't know where `eejump-99*' is defined\"...
-5. eejump blocks
-================
-Let's a call a sequence of defuns for eejumps with the same
-prefix, like this, starting with a `(defun eejump-<prefix>* ...)',
-
- (defun eejump-99* () (find-efunction 'eejump-99*))
- (defun eejump-991 () (message \"M-991j\"))
- (defun eejump-992 () (message \"M-992j\"))
-
-an \"eejump block\".
-There are two sample eejump blocks in eejump.el, for the prefixes
-\"\" and \"5\", starting at:
- (find-eev \"eejump.el\" \"eejump-*\")
- (find-eev \"eejump.el\" \"eejump-5*\")
-You should probably copy them to your .emacs, and then start
-modifying them.
-6. Making an `eejump-nn*' work
-==============================
-If you execute a line like
- (defun eejump-9* () (find-efunction 'eejump-9*))
-then Emacs will only record that `eejump-9*' has been defined in
-this buffer - and thus will be able to jump to its definition
-when you type something like `M-987j' - if two conditions are
-met:
- a) the defun is executed with `M-x eval-region', `M-x
- eval-buffer', or some variant of `load' or `require' (`M-e'
- will not do!),
+-=-=-=-=-
+Old stuff:
- b) the buffer with the definition is associated to a file; see
- these two pages of the Emacs manuals
- (find-enode \"Buffers\" \"visiting\")
- (find-elnode \"Buffer File Name\")
- if that concept is not totally familiar to you.
+1. Motivation
+=============
+Suppose that we have to do some reasonably complex task using a
+shell, and that we want to take notes of what we do because we
+might have to do something similar later.
-So, as an experiment, copy the block with six defuns and four
-tests above to some buffer associated to a file, mark it, and
-execute it with `M-x eval-region'. Now the tests should work -
-and key sequences like `M-987j' should also work, and should jump
-to the right places. See also:
+The two usual ways to interact with a shell are:
- (find-elnode \"Where Defined\")
+ 1) through a _script_, that is, by preparing in advance all
+ commands to be executed, putting them in a script file, and
+ then running that file,
+ 2) _interactively_, by typing the commands one by one on a
+ shell prompt.
+Suppose that we have to discover which commands to run as we go;
+that rules out preparing a script beforehand, so we need to use
+the shell interactively. After issuing the right commands, the
+two usual ways to retrieve what we did are:
-7. Producing `eejump-nnn's and `eejump-nnn*'s
-=============================================
-Look again to the block of six \"defun\"s above. Now type `M-J'
-on each of the six lines below:
+ a) through the _shell history_, which records the last commands
+ that the shell received,
- 9
- 91 (message \"M-91j\")
- 92 (message \"M-92j\")
- 99
- 991 (message \"M-991j\")
- 992 (message \"M-992j\")
+ b) by looking at the full _transcript_ of our interaction with
+ the shell.
-you will notice that you've just generated a block of defuns like
-the one in the previous section! `M-J' works like this: it tries
-to split the current line into \"words\" separated by whitespace,
-but producing a maximum of two \"words\" (the 2nd, 3rd, etc
-\"words\" as treated as a single \"word\"); if the second word is
-empty, then `M-J' produces a definition for an `eejump-nnn*'; if
-it is not empty, then `M-J' produces a definition for an
-`eejump-nnn', treating the second \"word\" as a sexp.
+The way (a) gets a list of commands, without comments, that can
+be then saved into a text editor; the way (b) may require some
+tricky editing to isolate the commands from their outputs.
-Note that `M-J' is quite dumb - it doesn't check if the first
-\"word\" is a number, nor if the second is a sexp. Use it with
-care! Try using `M-J' on the \"a b ...\" lines below - you will
-get useless definitions.
+Eepitch.el implements a simple alternative way of interacting
+with shells (and other shell-like programs) while keeping notes.
+It has only one essential key binding, <F8>, which is better
+explained through the executable example in the next section, and
+two unessential features, `M-T' and \"\", which will be
+explained later.
- a b c d
- a b c
- a b
- a
-8. Permanent and temporary
-==========================
-If you create a block like the block of six defuns above in your
-.emacs file then you'll be attributing a \"permanent\" meaning to
-`M-91j', ..., `M-992j', and if you create it in a file that is
-not evaluated in every Emacs session (and execute it, of course),
-then you'll be attributing just a \"temporary\" meaning to
-`M-91j', ..., `M-992j'.
-" rest)))
+2. The main key: <F8>
+=====================
+Emacs can run a shell in a buffer, and it can split its frame
+into windows, like this:
+ ___________________
+ | | |
+ | our | a |
+ | notes | shell |
+ | | buffer |
+ |_________|_________|
-;; (find-eejump-intro)
+The usual way to use a shell buffer is to move the cursor there
+and type commands into its prompt; the eepitch-y way is to leave
+the cursor at the \"notes\" buffer, write the commands for the
+shell there, and send these commands to the shell with <F8>.
+Here's what <F8> does:
+ When we type <F8> on a line that starts with a red
+ star (\"\"), it executes the rest of the line as Lisp, and
+ moves down; when we type <F8> on a line that does not start
+ with a \"\", it makes sure that the \"target buffer\" is being
+ displayed (the \"target\" is usually the buffer called
+ \"*shell*\"), it \"send\"s the current line to the target
+ buffer, and moves down.
+ \"Sending the current line to the target buffer\" means copying
+ the contents of the current line to the target - as if the user
+ had typed that line there by hand -, then \"typing\" a <RET> at
+ the target buffet.
-;;; _
-;;; __ _ _ __ ___| |__ ___ _ __ ___
-;;; / _` | '_ \ / __| '_ \ / _ \| '__/ __|
-;;; | (_| | | | | (__| | | | (_) | | \__ \
-;;; \__,_|_| |_|\___|_| |_|\___/|_| |___/
-;;;
-;; «find-anchors-intro» (to ".find-anchors-intro")
-;; Skel: (find-intro-links "anchors")
+Please try that in the example after this paragraph, by typing
+<F8> six times starting at the first line that says
+\" (eepitch-shell)\". The three red star lines at the top will
+create a target buffer, destroy it, and create it again; the
+other three lines will send commands to the target shell.
-(defun find-anchors-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-anchors-intro)*"))
- (apply 'find-eintro-latin1 "\
-\(Re)generate: (find-anchors-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-anchors-intro\")
-More intros: (find-eev-quick-intro)
- (find-here-links-intro)
- (find-refining-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+echo \"We are at: $PWD\"
+cd /tmp/
+echo \"We changed to: $(pwd)\"
-Notes: this is an advanced tutorial!
-And it is very incomplete at the moment!
+3. Other targets
+================
+Just like `(eepitch-shell)' creates a shell buffer and sets the
+eepitch target to it, `(eepitch-python)' creates a buffer with a
+Python interpreter and uses it as the eepitch target. Try:
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+def square (x):
+ return x*x
+print(square(5))
-1. Introduction
-===============
-These sections of the main tutorial explain what anchors are, and
-explain two simple ways of creating index/section anchor pairs:
+ We can use several targets at the time, alternating between them.
+ For example:
- (find-eev-quick-intro \"8. Anchors\")
- (find-eev-quick-intro \"8.1. Introduction: `to'\")
- (find-eev-quick-intro \"8.3. Creating index/section anchor pairs\")
- (find-eev-quick-intro \"8.3. Creating index/section anchor pairs\" \"`M-A'\")
- (find-eev-quick-intro \"8.4. Creating e-script blocks\")
- (find-eev-quick-intro \"8.4. Creating e-script blocks\" \"`M-B'\")
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+echo Hello... > /tmp/o
-and these other sections explain briefly how hyperlinks to
-anchors in other files work,
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+print(open(\"/tmp/o\").read())
- (find-eev-quick-intro \"8.5. Hyperlinks to anchors in other files\")
- (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\")
- (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\" \":anchor)\")
- (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\" \"makes
(find-eev\")
+ (eepitch-shell)
+echo ...and bye >> /tmp/o
-but they stop right before explaining how to use them in a
-practical way, i.e., with few keystrokes. This intro is about
-this.
+ (eepitch-python)
+print(open(\"/tmp/o\").read())
+ There is a (much) more advanced example of working with several
+ targets here:
+ (find-prepared-intro \"An `ee' for Python\")
-2. Shrinking
-============
-We saw in
- (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\" \"makes
(find-eev\")
-that these two hyperlinks are equivalent:
- (find-eevfile \"eev-blinks.el\" \"«find-wottb»\")
- (find-eev \"eev-blinks.el\" \"find-wottb\")
+4. More on eepitch-kill
+=======================
+Note that `(eepitch-kill)' kills the _current_ target, that may
+or may not be a shell buffer, a Python interaction buffer, etc...
+That explains the first line in blocks like:
-The first one searches for a string in \"eev-blinks.el\" in the
-normal way; the second one treats the \"find-wottb\" as a tag,
-wraps it in `«»'s, and then searches for the anchor
-\"«find-wottb»\" in the file \"eev-blinks.el\".
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
-We will refer to the operation that converts the hyperlink
+and:
- (find-eevfile \"eev-blinks.el\")
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
-to
+by running the first `(eepitch-python)' we can be sure that the
+following `(eepitch-kill)' will kill the Python buffer, not the
+shell buffer! And the last `(eepitch-python)' in the block of
+three lines will then create a new Python interaction buffer,
+erasing all definitions done in previous sessions.
- (find-eev \"eev-blinks.el\")
-as _shrinking_ the hyperlink. Eev has a key sequence that does
-that, and for simplicity its behavor is just this: it looks at
-first element of the sexp at eol (the \"head\" of the sexp), and
-if it is a symbol that ends with \"file\" then rewrite the sexp
-replacing the head symbol by it minus its suffix \"file\". That
-key sequence is `M-h M--' (`ee-shrink-hyperlink-at-eol'), and its
-source code is here:
- (find-eev \"eev-edit.el\" \"ee-shrink-hyperlink-at-eol\")
-Try it on the two lines below:
+5. Creating eepitch blocks: `M-T'
+=================================
+Write just \"shell\" or \"python\" in a line, then type
+`M-T' (i.e., meta-shift-t) there. The line will be turned into
+three - an \" (eepitch-xxx)\", an \" (eepitch-kill)\", and an
+\" (eepitch-xxx)\". We call these blocks of three lines
+\"eepitch blocks\". Try this below, converting the \"shell\" into
+an eepitch block for starting a shell.
- (find-eevfile \"eev-edit.el\" \"ee-shrink-hyperlink-at-eol\")
- (find-eev \"eev-edit.el\" \"ee-shrink-hyperlink-at-eol\")
-
-
-
-
-3. The preceding tag
-====================
-The key sequence `M-h M-w' copies the current line to the kill
-ring, highlights it for a fraction of a second, and shows the
-message
-
- \"Copied the current line to the kill ring - use C-y to paste\"
-
-in the echo area. Here are links to its source code and to a
-section of a tutorial that mentions it:
-
- (find-eev \"eev-edit.el\" \"ee-copy-this-line-to-kill-ring\")
- (find-refining-intro \"3. Three buffers\" \"M-h M-w\")
-
-When we run `M-h M-w' with a numeric argument - for example, as
-`M-1 M-h M-w' - it highlights and copies to the kill ring the
-\"preceding tag\" instead of the current line; the \"preceding
-tag\" is the string between `«»'s in the anchor closest to the
-point if we search backwards. As an exercise, type `M-1 M-h M-w'
-at some point below, and then use `M-h M-y' (`ee-yank-pos-spec')
-to add it to the hyperlink with `find-anchors-intro' below the
-anchors.
+shell
+pwd
+cd /tmp/
+pwd
- «first-anchor»
- «second-anchor»
- «third-anchor»
- (find-anchors-intro)
+6. Red stars
+============
+Eepitch.el sets the glyph for the char 15 to a red star in the
+standard display table. In layman's terms: eepitch.el tells Emacs
+that the character 15 should be displayed as a red star. The
+character 15 corresponds to control-O, whose default
+representation on screen would be \"^O\". You can enter a
+literal ^O in a buffer by typing `C-q C-o'.
-[TO DO: write the other sections!]
+7. For more information
+=======================
+On hyperlinks: (find-eval-intro)
+On keys similar to `M-T': (find-wrap-intro)
+An older text about eepitch:
+ (find-eev \"eepitch.readme\")
+ (find-eev \"eepitch.readme\" \"the-trivial-case\")
+ (find-eev \"eepitch.readme\" \"red-stars\")
+ (find-eev \"eepitch.readme\" \"eepitch-blocks\")
+ (find-eev \"eepitch.readme\" \"eepitch-blocks\")
+Many functions like `eepitch-shell':
+ (find-efunction 'eepitch-bash)
+What functions can generate target buffers:
+ (find-eevfile \"eepitch.el\" \"shell-like sexp\")
+ (find-efunction 'eepitch)
" rest)))
-;; (find-anchors-intro)
+;; (find-eepitch-intro)
+
+;; (find-pytutnode "Methods of File Objects")
-;;; _ _
-;;; ___ ___ __| | ___ ___ __| |
-;;; / __/ _ \ / _` |/ _ \_____ / __|____ / _` |
-;;; | (_| (_) | (_| | __/_____| (_|_____| (_| |
-;;; \___\___/ \__,_|\___| \___| \__,_|
;;;
-;; «find-code-c-d-intro» (to ".find-code-c-d-intro")
+;;; __ ___ __ __ _ _ __
+;;; \ \ /\ / / '__/ _` | '_ \
+;;; \ V V /| | | (_| | |_) |
+;;; \_/\_/ |_| \__,_| .__/
+;;; |_|
+;;
+;; Skel: (find-intro-links "wrap")
+;; «find-wrap-intro» (to ".find-wrap-intro")
-(defun find-code-c-d-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-code-c-d-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-code-c-d-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-code-c-d-intro\")
+(defun find-wrap-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-wrap-intro)*"))
+ (apply 'find-eintro-latin1 "\
+\(Re)generate: (find-wrap-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-wrap-intro\")
More intros: (find-eev-quick-intro)
(find-eval-intro)
(find-eepitch-intro)
@@ -6377,3227 +6308,3177 @@ It is meant as both a tutorial and a sandbox.
Note: this intro needs to be rewritten!
Ideally it should _complement_ the material in:
- (find-eev-quick-intro \"9. Shorter hyperlinks\")
- (find-eev-quick-intro \"9.1. `code-c-d'\")
+ (find-eev-quick-intro \"6.3. Creating eepitch blocks: `M-T'\")
+ (find-eev-quick-intro \"8.3. Creating index/section anchor pairs\")
+ (find-eev-quick-intro \"8.4. Creating e-script blocks\")
-1. Avoiding full path names
-===========================
-Suppose that you have downloaded (\"psne\"-ed) this URL,
- http://www.lua.org/ftp/lua-5.1.4.tar.gz
-with `M-x brep' - see:
+1. Eepitch and eev
+==================
+Eepitch defines only two keys - <F8> and <M-T> - and <M-T> is a
+particular case of something more general: \"wrapping commands\", that
+follow these conventions:
- (find-psne-intro)
+ 1) they are bound to meta-shift-letter keys (M-T, M-F, M-M, ...),
+ 2) they transform the current line and then move down,
+ 3) they produce Lisp code meant to be executed with `M-e' or `F8',
+ 4) they are listed at:
+ (find-efunctiondescr 'eev-mode \"M-F\")
+ 5) their keybindings are only available when eev-mode is turned on.
-and you unpacked that tarball into the directory ~/usrc/ (I
-prefer to use that instead of /usr/src/) with:
+To understand how they work, please follow the instructions below and
+try them here. Note that this buffer is a sandbox, and it can be
+recreated by executing the sexp \"(find-wrap-intro)\" at the top.
- tar -C ~/usrc/ -xvzf $S/http/www.lua.org/ftp/lua-5.1.4.tar.gz
+Note that the wrapping commands are all bound to key sequences of
+the form meta-SHIFT-letter - don't forget the shift!!!
-Now you can access some directories and files of the unpacked
-tarball with:
- (find-fline \"~/usrc/lua-5.1.4/\")
- (find-fline \"~/usrc/lua-5.1.4/src/\")
- (find-fline \"~/usrc/lua-5.1.4/src/lstrlib.c\")
- (find-fline \"~/usrc/lua-5.1.4/test/\")
- (find-fline \"~/usrc/lua-5.1.4/test/README\")
- (find-fline \"~/usrc/lua-5.1.4/doc/\")
- (find-w3m \"~/usrc/lua-5.1.4/doc/contents.html\")
-but it's a bit clumsy to have to use the \"~/usrc/lua-5.1.4/\"
-every time, so eev provides a nice way to define shorthands. We
-want to be able to write just this instead of the sexps above,
+2. <M-T>: produce an eepitch block
+==================================
+If you type <M-T> on a line containing just the word \"shell\" you get
+three lines, like this:
- (find-lua51file \"\")
- (find-lua51file \"src/\")
- (find-lua51file \"src/lstrlib.c\")
- (find-lua51file \"test/\")
- (find-lua51file \"test/README\")
- (find-lua51file \"doc/\")
- (find-lua51w3m \"doc/contents.html\")
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
-and here the directory \"~/usrc/lua-5.1.4/\" became a mnemonic
-\"lua51\" in the middle of the names of some functions.
+We call a block of three lines like this an \"eepitch block\", and
+eepitch blocks can be used to set up interactions with external
+programs. Try typing <M-T> on the lines that say \"shell\" and \"python\"
+below, and use them to send some lines to bash and to a python
+interpreter (with <F8>):
-We will call these sexps with \"lua51\" \"shorter hyperlinks\".
+bash
+export PS1='$PWD% '
+cd /tmp/
+function ee () { set -v; . /tmp/ee.sh; set +v; }
+rm -v /tmp/ee.sh
+cat > /tmp/ee.sh <<'%%%'
+ echo Hello
+ cd /etc/
+%%%
+cat /tmp/ee.sh
+bash /tmp/ee.sh
+ee
+python
+square = lambda x: x*x
+square(5)
-2. Shorter hyperlinks
-=====================
-How can we generate the definitions for `find-lua51file' and
-`find-lua51w3m' from just the strings \"lua51\" and
-\"~/usrc/lua-5.1.4/\"? Try this:
- (find-code-c-d \"lua51\" \"~/usrc/lua-5.1.4/\")
+3. <M-F>: hyperlink to a file or a directory
+============================================
+If you type <M-F> on the lines below,
-you will get a temporary buffer with a lot of Lisp code -
-including a definition for `find-lua51file' and another one for
-`find-lua51w3m'. That Lisp code has not been executed yet; the
-function `find-code-c-d' is just for debugging, and we can regard
-it as a hyperlink to the code that this sexp would execute:
+/etc/
+/tmp/
+~/
+~/.emacs
- (code-c-d \"lua51\" \"~/usrc/lua-5.1.4/\")
+you get hyperlinks like these:
-So, to define a family of functions including `find-lua51file'
-and `find-lua51w3m', for a given \"mnemonic\" - \"lua51\" in this
-case - and a given \"directory\" - \"~/usrc/lua-5.1.4/\" - we run
-this:
+# (find-fline \"/etc/\")
+# (find-fline \"/tmp/\")
+# (find-fline \"~/\")
+# (find-fline \"~/.emacs\")
- (code-c-d \"lua51\" \"~/usrc/lua-5.1.4/\")
-which generates a block of Lisp code, as a string, and evaluates
-it. Note: the original (and rather confusing) terminology for the
-\"mnemonic\" was \"code\"; that's why the \"c\" in `code-c-d'.
+4. <M-S>: hyperlink to the output of a shell command
+====================================================
+If you type <M-S> on a line containing a shell command you get a
+hyperlink that starts with `find-sh', and that when followed opens a
+temporary buffer with the output of that shell command, like these:
+ # (find-sh \"find --help\")
+ # (find-sh \"find /etc | sort\")
+ # (find-sh \"find /etc -type d | sort\")
+ # (find-sh \"find /etc -type d -maxdepth 1 | sort\")
+ # (find-sh \"find /etc -type d -maxdepth 2 | sort\")
-3. Extra arguments to `code-c-d'
-================================
-`code-c-d' supports extra arguments - for example, this works:
+Try it here:
- (find-code-c-d \"el\" \"~/usrc/emacs/lisp/\" :info \"elisp\")
+dict smop
+dict 'minor detail'
-Look at the end of the generated code and you will see that it
-has a definition for `find-elnode' - such that
+If you have the packages dict, dictd and dict-jargon installed
+these hyperlinks will show you the meaning of the expressions
+\"smop\" and \"minor detail\".
- (find-elnode \"Constant Variables\")
+ # (find-sh \"dict smop\")
+ # (find-sh \"dict 'minor detail'\")
-is a shorthand (a \"shorter hyperlink\") for:
- (find-node \"(elisp)Constant Variables\")
-What is important to understand here is how these definitions
-with extra arguments are structured - so that you will be able to
-understand the source code when you need to. Both `code-c-d' and
-`find-code-c-d' are defined with a `&rest' in their argument
-lists, like this (NOTE: do not execute these defuns!):
+5. <M-M>: hyperlink to a manpage
+================================
+Try <M-M> here:
- (defun code-c-d (c d &rest rest) ...)
- (defun find-code-c-d (c d &rest rest) ...)
+1 tac
-and they both invoke `ee-code-c-d', which does all the template
-work and returns a big string; `ee-code-c-d' passes its `rest'
-argument to a recursive function called `ee-code-c-d-rest', and
-for each one of the supported keywords there is a corresponding
-function, also recursive; for `:info' it is called
-`ee-code-c-d-:info'. Their specifications are like this:
- (defun ee-code-c-d (c d &rest rest) ...)
- (defun ee-code-c-d-rest (rest) ...)
- (defun ee-code-c-d-:info (manual &rest rest) ...)
-
-and one very non-obvious trick is used to make the code short.
-When `ee-code-c-d-rest' and `ee-code-c-d-:info' are run they can
-access the values the `c' and the `d' that were passed to
-`ee-code-c-d' (due to dynamic scoping), so `c' and `d' do not
-need to be passed down explicitly as arguments.
-
-Try:
-
- (find-code-c-d \"CODE\" \"/DIR/\" :info \"INFO\")
+6. All wrapping functions
+=========================
+Below is a list of all wrapping functions, with tests and
+hyperlinks:
+ (eek \"2*<down> M-A <down> ;;; Test eewrap-anchor\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-anchor\")
+;; <anchor>
+ (eek \"2*<down> M-C <down> ;;; Test eewrap-code-c-d\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-code-c-d\")
+foo /tmp/foobar/
-4. Other similar functions
-==========================
-See: (find-brxxx-intro)
- (find-pdf-like-intro)
- (find-audiovideo-intro)
+ (eek \"2*<down> M-D <down> ;;; Test eewrap-debian\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-debian\")
+bash
-Try: (find-code-pdf \"CODE\" \"FILE.pdf\")
- (find-code-pdf-text \"CODE\" \"FILE.pdf\")
- (find-code-audio \"CODE\" \"FILE.mp3\")
- (find-code-video \"CODE\" \"FILE.mp4\")
-" rest)))
+ (eek \"2*<down> M-F <down> ;;; Test eewrap-find-fline\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-find-fline\")
+/tmp/foobar/
-;; (find-TH "eev-article")
-;; (find-TH "eev-article" "shorter-hyperlinks")
-;; (find-code-c-d-intro)
+ (eek \"2*<down> M-J <down> ;;; Test eewrap-eejump\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-eejump\")
+422 (find-eev-intro \"find-wrap-intro\")
+ (eek \"2*<down> M-J <down> ;;; Test eewrap-eejump\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-eejump\")
+42
+ (eek \"2*<down> M-M <down> ;;; Test eewrap-man\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-man\")
+1 tac
+ (eek \"2*<down> M-P <down> ;;; Test eewrap-pdflike\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-pdflike\")
+foopdf $S/http/foo.org/bar.pdf
+ (eek \"2*<down> M-R <down> ;;; Test eewrap-rm/mkdir/cd\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-rm/mkdir/cd\")
+/tmp/foo/
-;;; _ __ _ _ _
-;;; _ __ __| |/ _| | (_) | _____
-;;; | '_ \ / _` | |_ _____| | | |/ / _ \
-;;; | |_) | (_| | _|_____| | | < __/
-;;; | .__/ \__,_|_| |_|_|_|\_\___|
-;;; |_|
-;;
-;; «find-pdf-like-intro» (to ".find-pdf-like-intro")
+ (eek \"2*<down> M-S <down> ;;; Test eewrap-sh\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-sh\")
+seq 1 20
-(defun find-pdf-like-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-pdf-like-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-pdf-like-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-pdf-like-intro\")
-More intros: (find-eev-quick-intro)
- (find-eev-intro)
- (find-here-links-intro)
- (find-refining-intro)
- (find-eepitch-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
+ (eek \"2*<down> M-T <down> ;;; Test eewrap-eepitch\")
+ Source: (find-eev \"eepitch.el\" \"eewrap-eepitch\")
+python
+ (eek \"2*<down> M-V <down> ;;; Test eewrap-audiovideo\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-audiovideo\")
+slimetutorial /tmp/slime-tutorial.mp4
+ (eek \"2*<down> M-Z <down> ;;; Test eewrap-zsh\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-zsh\")
+echo $SHELL
-Note: you will need a basic understanding of eepitch and
-code-c-d to understand parts of this intro. See:
+ (eek \"2*<down> <<eewrap-eewrap>> <down> ;;; Test eewrap-eewrap\")
+ Source: (find-eev \"eev-wrap.el\" \"eewrap-eewrap\")
+U user-defined a b c
- (find-eev-quick-intro \"6.1. The main key: <F8>\")
- (find-eev-quick-intro \"9. Shorter hyperlinks\")
- (find-eev-quick-intro \"9.1. `code-c-d'\")
+7. Wrapping functions generate hyperlinks
+=========================================
+...this is a slogan - a huge idea, in a very shortened form. In its
+full form, that would be:
+ (Some) wrapping function provide one of the basic ways to produce
+ elisp hyperlinks quickly; the second basic way, which is a bit more
+ complex conceptually, is via Elisp hyperlinks buffers. This, and the
+ whole rationale behind generating and using elisp hyperlinks, is
+ explained here:
-1. PDF-like documents
-=====================
-Let's introduce a bit of (improvised!) terminology: we will say
-that a document is \"PDF-like\" when it is in a format like PDF,
-PostScript, DVI or DJVU - i.e., divided into pages. Emacs has a
-standard mode for viewing PDF-like documents,
+ (find-links-intro \"Elisp hyperlinks buffers\")
- (find-enode \"Document View\")
+The \"some\" in beginning of the long version of the slogan, above, is
+because a few of the wrapping commands, for example, <M-T> and <M-R>,
+are used to produce things that are not hyperlinks - usually other
+kinds of scripts.
+" rest)))
-but we will see a more eev-like way of pointing to pages of
-PDF-like documents.
+;; (find-wrap-intro)
-2. Preparation
-==============
-We need to start by downloading a PDF file to use in our
-examples. If you run this e-script
+;;; _
+;;; ___ ___ (_)_ _ _ __ ___ _ __
+;;; / _ \/ _ \| | | | | '_ ` _ \| '_ \
+;;; | __/ __/| | |_| | | | | | | |_) |
+;;; \___|\___|/ |\__,_|_| |_| |_| .__/
+;;; |__/ |_|
+;;
+;; (find-elnode "Defining Commands")
+;; (find-enode "Arguments")
+;; (find-TH "emacs" "eejump")
+;; http://angg.twu.net/emacs.html#eejump
+;; file:///home/edrx/TH/L/emacs.html#eejump
+;; «find-eejump-intro» (to ".find-eejump-intro")
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- cd
- wget -nc
https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
+(defun find-eejump-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-eejump-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-eejump-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-eejump-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.
-you will download a local copy of J.M. Coetzee's \"The Lives of
-Animals\" into your home directory. To check that the PDF has been
-downloaded, use:
- (find-fline \"~/\")
- (find-fline \"~/\" \"Coetzee99.pdf\")
- (find-sh0 \"ls -l ~/Coetzee99.pdf\")
-Eev also implements another way, called \"psne\", to download
-local copies of files from the internet.\"Psne-ing\" a URL like
+Note: this intro needs to be rewritten!
+Ideally it should _complement_ the material in:
+ (find-eev-quick-intro \"7.1. `eejump'\")
+See the comments in:
+ (find-eev \"eejump.el\")
- https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
-downloads it to a local file with a name like:
-
$S/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
-
~/snarf/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
-that is _much_ longer that just \"~/Coetzee99.pdf\"; this has the
-advantage of preserving more information about the URL from which
-the file came, but sometimes these longer names feels clumsy.
-Psne-ing is discussed a more advanced tutorial:
+1. The problem
+==============
+Suppose that we have several files that we are working on, and we
+want a quick way to jump to (i.e., to visit) any of them with
+very few keystrokes; moreover,
- (find-psne-intro)
+ 1) we want our list of files to be preserved between one Emacs
+ session and another,
-In this tutorial we will use the home directory and the shorter
-file name.
+ 2) we know that each \"visit a file\" command will correspond
+ to an elisp hyperlink.
+One quick solution would be to put the list of elisp hyperlinks
+in a file, and make the key `M-j' open that file. But then
+jumping to a file in that list becomes a two-step process: type
+`M-j', move the point to the right line, type `M-e'. This would
+be similar to what happens when we use one of the `find-e*'
+commands, for example `find-efunction':
+ (find-efunction 'find-efunction)
+ (eek \"M-h M-f find-efunction\")
+Those intermediate steps - seeing the list, locating visually the
+right line, moving to it - are distracting, so we want to add new
+items to our wishlist:
-3. Hyperlinks to PDF files
-==========================
-If you have xpdf installed then this sexp
+ 3) it should be possible to jump straight to any of the files
+ in the list, and with very few keystrokes,
- (find-pdf-page \"~/Coetzee99.pdf\")
+ 4) the list should be stored in a format that lets us see
+ quickly which are the keystrokes for accessing each item - so
+ that we won't need to memorize anything,
-should work as a \"hyperlink to the PDF\": it calls xpdf as an
-external program - like we did with browsers in the main tutorial -
+ 5) the list should be easy to modify,
- (find-eev-quick-intro \"3.1. Non-elisp hyperlinks\")
- (find-eev-quick-intro \"3.1. Non-elisp hyperlinks\" \"find-firefox\")
+ 6) it should be possible to assign shorter key sequences to
+ files we visit more often,
-to display the PDF file that we downloaded.
+ 7) the source code must be very simple.
-The main keys of xpdf are:
- q quit xpdf
- PageDown scroll down/go to next page
- PageUp scroll up/go to previous page
- arrows scroll within the current page
- + zoom in one step
- - zoom out out step
- 0 set zoom to 125%
- alt-f toggle full-screen; use twice to fit document to page
-Note that `q' \"goes back to Emacs\".
+2. A miniature
+==============
+My original solution was this: I used only one keybinding, `M-j',
+that acted differently when invoked with different numeric
+prefixes; when invoked as `M-1 M-j' it opened a certain file,
+when invoked with `M-2 M-j' it opened another, and so on, and
+when it was invoked with an unrecognized prefix or with no prefix
+it jumped to its definition in my ~/.emacs. Its code was like
+this (NOTE: do not execute these defuns):
-If you have the program pdftotext installed - hint: \"apt-get install
-poppler-utils\"! - then you can also display PDFs in another way. This
-sexp
+ ;; eejump-simplified (`M-j'):
+ ;; M-1 M-j opens a certain file,
+ ;; M-2 M-j opens another file,
+ ;; when the argument is 11, 22, 33 or 44 do something special,
+ ;; like changing the font;
+ ;; with no argument or with an unrecognized argument jump to the
+ ;; definition of eejump in ~/.emacs; then we can see which numbers
+ ;; correspond to which actions (the source is the documentation!), and
+ ;; we can change the definition if needed - just run `M-e' at the
+ ;; right place to make the changes apply.
+ ;;
+ \(global-set-key (kbd \"M-j\") 'eejump-simplified)
+ \(defun eejump-simplified (arg) (interactive \"P\")
+ (cond ((eq arg 1) (find-file \"~/NOTES\"))
+ ((eq arg 2) (find-file \"~/otherfile.txt\"))
+ ;;
+ ((eq arg 11) (set-frame-font \"fixed\"))
+ ((eq arg 22) (set-frame-font \"terminus-16\"))
+ ((eq arg 33) (set-frame-font \"terminus-bold-16\"))
+ ((eq arg 44) (set-frame-font \"10x20\"))
+ (t (find-function 'eejump-simplified))))
- (find-pdf-text \"~/Coetzee99.pdf\")
+except that my definition became huge with time as I added to it
+more entries for files (and other actions!) that I used often,
+and also entries that were used not so often...
-work as a \"hyperlink to the _text_ of the PDF\": it extracts the text
-from the PDF using the program \"pdftotext\" and displays that in an
-Emacs buffer.
+All the \"options\" - i.e., all the `(eq arg nnn)' lines - had to
+be together in a single very big defun, and there was no way to
+add new options temporarily...
-4. Hyperlinks to pages of PDF files
-===================================
-It is possible to create hyperlinks that point to a specific page in a
-PDF file. Compare what happens when you run these sexps:
-
- (find-pdf-page \"~/Coetzee99.pdf\")
- (find-pdf-page \"~/Coetzee99.pdf\" 1)
- (find-pdf-page \"~/Coetzee99.pdf\" 1 \"The Lives of Animals\")
- (find-pdf-page \"~/Coetzee99.pdf\" 3)
- (find-pdf-page \"~/Coetzee99.pdf\" 3 \"LECTURE I\")
- (find-pdf-page \"~/Coetzee99.pdf\" 3 \"LECTURE I\" \"[113]\")
+3. Families
+===========
+Let's use a shorthand for key sequences: for example, `M-123j'
+instead of `M-1 M-2 M-3 M-j'.
-The top three sexps open the PDF at page 1 - the default. The bottom
-three sexps open it at page 3. The arguments after the number are
-ignored by Emacs - they are there to make these links more expressive
-for humans.
+I tend to assign related numbers to related files. For example, I
+use the prefix \"5\" for things that are Emacs-related: `M-5j'
+visits my .emacs, `M-555j' visits the directory with all of eev's
+elisp files, and `M-51j', `M-52j', etc, visit specific eev source
+files that I happen to be working on. Also, I use the prefix
+\"7\" for things related to LaTeX. So, the \"5*\" family is
+composed of Emacs-related files, and the \"7*\" family of
+LaTex-related files.
-The hyperlinks to the text of a PDF interpret the numeric number as a
-page number and the following arguments as strings to search for. Try:
+The definition of `eejump-simplified' given above does not
+satisfy these two (new!) wishlist items:
- (find-pdf-text \"~/Coetzee99.pdf\" 1)
- (find-pdf-text \"~/Coetzee99.pdf\" 1 \"The Lives of Animals\")
- (find-pdf-text \"~/Coetzee99.pdf\" 3)
- (find-pdf-text \"~/Coetzee99.pdf\" 3 \"LECTURE I\")
- (find-pdf-text \"~/Coetzee99.pdf\" 3 \"LECTURE I\" \"[113]\")
+ 8) it should be possible to jump to the definition of the
+ \"5*\" family by typing something like `M-5678j', where
+ \"5678\" is a non-assigned number that starts with the \"5*\"
+ prefix,
-For more information about these string arguments, see:
+ 9) it should be possible to convert a number/hyperlink pair
+ very easily into to the code that assigns that elisp hyperlink
+ as the desired behavior for that number - and it should be
+ possible to do that both permanently (think in changing the
+ definition of `eejump-simplified' in your .emacs) and
+ temporarily (i.e., for the current Emacs session only).
- (find-refining-intro \"1. Pos-spec-lists\")
-A pair of sexps like this, in which both point to the same
-position of a PDF,
- (find-pdf-page \"~/Coetzee99.pdf\" 3 \"LECTURE I\" \"[113]\")
- (find-pdf-text \"~/Coetzee99.pdf\" 3 \"LECTURE I\" \"[113]\")
+4. `eejump'
+===========
+The definition of `eejump' that comes with eev is a bit more
+complex than the one given above, and it will not be shown
+here (it involves a tricky recursive function) but it satisfies
+the 9 wishlist items above. It works in this way: if you type,
+say, `M-123j', then:
-will be called a `find-pdf'-pair.
+ a) if `eejump-123' is defined, then execute it;
+ b) otherwise, if `eejump-12*' is defined, execute it;
+ c) otherwise, if `eejump-1*' is defined, execute it;
+ d) otherwise, if `eejump-*' is defined, execute it,
-[Video links:]
- (find-eev2020video \"4:52\" \"`find-pdf-page' calls an external program\")
- (find-eev2020video \"5:26\" \"`find-pdf-text' converts the PDF to text and\")
+and if `eejump-*' also is not defined, you get an error.
+Here is a block of \"defun\"s that defines (trivial) meanings for
+\"91\", \"92\", \"991\", and \"992\", plus targets for the \"9*\"
+family and for the \"99*\" family; it also has two tests in
+comments that will be very important for an explanation below.
+Let's refer as that, in this section and the next ones, as \"the
+block of six defuns (plus four tests)\".
+ (defun eejump-9* () (find-efunction 'eejump-9*))
+ (defun eejump-91 () (message \"M-91j\"))
+ (defun eejump-92 () (message \"M-92j\"))
+ (defun eejump-99* () (find-efunction 'eejump-99*))
+ (defun eejump-991 () (message \"M-991j\"))
+ (defun eejump-992 () (message \"M-992j\"))
+ ;; (find-function-noselect 'eejump-9*)
+ ;; (find-function-noselect 'eejump-99*)
+ ;; (find-efunction 'eejump-9*)
+ ;; (find-efunction 'eejump-99*)
+Try to evaluate each of the sexps above with `M-e', then try to
+run things like `M-92j' and `M-992j' - they should work - and
+then something like `M-99876j'; that will not work, you'll get an
+error like \"Don't know where `eejump-99*' is defined\"...
-5. A convention on page numbers
-===============================
-The `(+ -110 113)'s in
- (find-livesofanimalspage (+ -110 113) \"LECTURE I.\")
- (find-livesofanimalstext (+ -110 113) \"LECTURE I.\")
+5. eejump blocks
+================
+Let's a call a sequence of defuns for eejumps with the same
+prefix, like this, starting with a `(defun eejump-<prefix>* ...)',
-are a bit mysterious at first sight.
+ (defun eejump-99* () (find-efunction 'eejump-99*))
+ (defun eejump-991 () (message \"M-991j\"))
+ (defun eejump-992 () (message \"M-992j\"))
-We are accessing a PDF that is an excerpt of a book. The third
-page of the PDF has a \"[113]\" at its footer to indicate that it
-is the page 113 of the book. Let's use the terms _page number_
-and _page label_ to distinguish the two numberings: in this case,
-the page whose page number is 3 is the page whose page label is
-113. These two sexps
+an \"eejump block\".
- (find-livesofanimalspage (+ -110 113))
- (find-livesofanimalspage 3)
+There are two sample eejump blocks in eejump.el, for the prefixes
+\"\" and \"5\", starting at:
-are equivalent, but the first one is more human-friendly: the 113
-is a page label, and the -110 is an adjustment (we call it the
-\"offset\") to convert the 113 that humans prefer to see into
-the 3 that xpdf needs to receive.
+ (find-eev \"eejump.el\" \"eejump-*\")
+ (find-eev \"eejump.el\" \"eejump-5*\")
+You should probably copy them to your .emacs, and then start
+modifying them.
-6. How the external programs are called
-=======================================
-Both `find-pdf-page' and `find-pdf-text' invoke external programs -
-but how, exactly? Let's take a look at a hack that shows this. If
-you prepend an \"ee-\" to `find-pdf-page' and `find-pdf-text' sexps,
-like in:
+6. Making an `eejump-nn*' work
+==============================
+If you execute a line like
- (ee-find-pdf-page \"~/Coetzee99.pdf\")
- (ee-find-pdf-page \"~/Coetzee99.pdf\" 3)
- (ee-find-pdf-text \"~/Coetzee99.pdf\")
- (ee-find-pdf-text \"~/Coetzee99.pdf\" 3)
+ (defun eejump-9* () (find-efunction 'eejump-9*))
-you will get sexps that stop just before invoking the external
-programs - they just show how these externals programs _would be_
-invoked, i.e., they show the options that would be passed to them. The
-results of the sexps above will be lists like these:
+then Emacs will only record that `eejump-9*' has been defined in
+this buffer - and thus will be able to jump to its definition
+when you type something like `M-987j' - if two conditions are
+met:
- (\"xpdf\" \"-fullscreen\" \"~/Coetzee99.pdf\")
- (\"xpdf\" \"-fullscreen\" \"~/Coetzee99.pdf\" \"3\")
- (\"pdftotext\" \"-layout\" \"-enc\" \"Latin1\" \"~/Coetzee99.pdf\" \"-\")
- (\"pdftotext\" \"-layout\" \"-enc\" \"Latin1\" \"~/Coetzee99.pdf\" \"-\")
+ a) the defun is executed with `M-x eval-region', `M-x
+ eval-buffer', or some variant of `load' or `require' (`M-e'
+ will not do!),
-Note that `ee-find-pdf-text' does not pass the argument \"3\" to
-\"pdftotext\". A sexp like
+ b) the buffer with the definition is associated to a file; see
+ these two pages of the Emacs manuals
- (find-pdf-text \"~/Coetzee99.pdf\" 3)
+ (find-enode \"Buffers\" \"visiting\")
+ (find-elnode \"Buffer File Name\")
-first produces the conversion to text of the full PDF, and then
-finds the page 3 in it by counting formfeeds, as described here:
+ if that concept is not totally familiar to you.
- (find-enode \"Pages\" \"formfeed\")
+So, as an experiment, copy the block with six defuns and four
+tests above to some buffer associated to a file, mark it, and
+execute it with `M-x eval-region'. Now the tests should work -
+and key sequences like `M-987j' should also work, and should jump
+to the right places. See also:
+ (find-elnode \"Where Defined\")
+7. Producing `eejump-nnn's and `eejump-nnn*'s
+=============================================
+Look again to the block of six \"defun\"s above. Now type `M-J'
+on each of the six lines below:
-7. Shorter hyperlinks to PDF files
-==================================
-If you run these sexps
+ 9
+ 91 (message \"M-91j\")
+ 92 (message \"M-92j\")
+ 99
+ 991 (message \"M-991j\")
+ 992 (message \"M-992j\")
- (code-pdf-page \"livesofanimals\" \"~/Coetzee99.pdf\")
- (code-pdf-text \"livesofanimals\" \"~/Coetzee99.pdf\" -110)
+you will notice that you've just generated a block of defuns like
+the one in the previous section! `M-J' works like this: it tries
+to split the current line into \"words\" separated by whitespace,
+but producing a maximum of two \"words\" (the 2nd, 3rd, etc
+\"words\" as treated as a single \"word\"); if the second word is
+empty, then `M-J' produces a definition for an `eejump-nnn*'; if
+it is not empty, then `M-J' produces a definition for an
+`eejump-nnn', treating the second \"word\" as a sexp.
-they will define the functions `find-livesofanimalspage' and
-`find-livesofanimalstext', and then these hyperlinks should work:
+Note that `M-J' is quite dumb - it doesn't check if the first
+\"word\" is a number, nor if the second is a sexp. Use it with
+care! Try using `M-J' on the \"a b ...\" lines below - you will
+get useless definitions.
- (find-livesofanimalspage)
- (find-livesofanimalstext)
- (find-livesofanimalspage (+ -110 113))
- (find-livesofanimalstext (+ -110 113))
- (find-livesofanimalspage (+ -110 113) \"LECTURE I.\")
- (find-livesofanimalstext (+ -110 113) \"LECTURE I.\")
- (find-livesofanimalspage (+ -110 127) \"wrong thoughts\")
- (find-livesofanimalstext (+ -110 127) \"wrong thoughts\")
- (find-livesofanimalspage (+ -110 132) \"into the place of their victims\")
- (find-livesofanimalstext (+ -110 132) \"into the place of their victims\")
- (find-livesofanimalspage (+ -110 133) \"To write that book I had to think\")
- (find-livesofanimalstext (+ -110 133) \"To write that book I had to think\")
- (find-livesofanimalspage (+ -110 134) \"woke up haggard in the mornings\")
- (find-livesofanimalstext (+ -110 134) \"woke up haggard in the mornings\")
- (find-livesofanimalspage (+ -110 143) \"Babies have no self-consciousness\")
- (find-livesofanimalstext (+ -110 143) \"Babies have no self-consciousness\")
- (find-livesofanimalspage (+ -110 145) \"squirrel doing its thinking\")
- (find-livesofanimalstext (+ -110 145) \"squirrel doing its thinking\")
- (find-livesofanimalspage (+ -110 147) \"Rilke's panther\")
- (find-livesofanimalstext (+ -110 147) \"Rilke's panther\")
- (find-livesofanimalspage (+ -110 162) \"a grasp of the meaning\")
- (find-livesofanimalstext (+ -110 162) \"a grasp of the meaning\")
- (find-livesofanimalspage (+ -110 164) \"last common ground\")
- (find-livesofanimalstext (+ -110 164) \"last common ground\")
+ a b c d
+ a b c
+ a b
+ a
-Hyperlinks like
- (find-livesofanimalspage (+ -110 113) \"LECTURE I.\")
- (find-livesofanimalstext (+ -110 113) \"LECTURE I.\")
-behave roughly as abbreviations for:
- (find-pdf-page \"~/Coetzee99.pdf\" (+ -110 113) \"LECTURE I.\")
- (find-pdf-text \"~/Coetzee99.pdf\" (+ -110 113) \"LECTURE I.\")
+8. Permanent and temporary
+==========================
+If you create a block like the block of six defuns above in your
+.emacs file then you'll be attributing a \"permanent\" meaning to
+`M-91j', ..., `M-992j', and if you create it in a file that is
+not evaluated in every Emacs session (and execute it, of course),
+then you'll be attributing just a \"temporary\" meaning to
+`M-91j', ..., `M-992j'.
+" rest)))
-[Video links:]
- (find-eev2020video \"10:22\" \"1.3. Shorter hyperlinks to PDFs and videos\")
- (find-eev2020video \"10:45\" \"`code-pdf-page' creates short hyperlink
functions\")
- (find-eev2020video \"11:38\" \"let's try...\")
- (find-eev2020video \"11:55\" \"`find-fongspivatext'\")
+;; (find-eejump-intro)
+;;; _
+;;; __ _ _ __ ___| |__ ___ _ __ ___
+;;; / _` | '_ \ / __| '_ \ / _ \| '__/ __|
+;;; | (_| | | | | (__| | | | (_) | | \__ \
+;;; \__,_|_| |_|\___|_| |_|\___/|_| |___/
+;;;
+;; «find-anchors-intro» (to ".find-anchors-intro")
+;; Skel: (find-intro-links "anchors")
-8. `find-pdf'-pairs
-===================
-Let's introduce some terminology. Remember that we call a pair of
-sexps like
-
- (find-pdf-page \"~/Coetzee99.pdf\" (+ -110 113) \"LECTURE I.\")
- (find-pdf-text \"~/Coetzee99.pdf\" (+ -110 113) \"LECTURE I.\")
+(defun find-anchors-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-anchors-intro)*"))
+ (apply 'find-eintro-latin1 "\
+\(Re)generate: (find-anchors-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-anchors-intro\")
+More intros: (find-eev-quick-intro)
+ (find-here-links-intro)
+ (find-refining-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
-a \"`find-pdf'-pair\"; a pair like
- (find-livesofanimalspage (+ -110 113) \"LECTURE I.\")
- (find-livesofanimalstext (+ -110 113) \"LECTURE I.\")
-will be called a \"short `find-pdf'-pair\", as in:
+Notes: this is an advanced tutorial!
+And it is very incomplete at the moment!
- (find-eev-quick-intro \"9. Shorter hyperlinks\")
-and a pair like
- (code-pdf-page \"livesofanimals\" \"~/Coetzee99.pdf\")
- (code-pdf-text \"livesofanimals\" \"~/Coetzee99.pdf\" -110)
-will be called a `code-pdf'-pair.
+1. Introduction
+===============
+These sections of the main tutorial explain what anchors are, and
+explain two simple ways of creating index/section anchor pairs:
-The \"livesofanimals\" will the called the _stem_. The \"-110\"
-will be called the _offset_.
+ (find-eev-quick-intro \"8. Anchors\")
+ (find-eev-quick-intro \"8.1. Introduction: `to'\")
+ (find-eev-quick-intro \"8.3. Creating index/section anchor pairs\")
+ (find-eev-quick-intro \"8.3. Creating index/section anchor pairs\" \"`M-A'\")
+ (find-eev-quick-intro \"8.4. Creating e-script blocks\")
+ (find-eev-quick-intro \"8.4. Creating e-script blocks\" \"`M-B'\")
+and these other sections explain briefly how hyperlinks to
+anchors in other files work,
+ (find-eev-quick-intro \"8.5. Hyperlinks to anchors in other files\")
+ (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\")
+ (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\" \":anchor)\")
+ (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\" \"makes
(find-eev\")
+but they stop right before explaining how to use them in a
+practical way, i.e., with few keystrokes. This intro is about
+this.
-9. Generating three pairs
-=========================
-Eev has a high-level function that generates at once, for a
-single PDF file, a `find-pdf'-pair, a `code-pdf'-pair, and a
-short `find-pdf'-pair. To see what it produces, try:
- (find-code-pdf-links \"~/Coetzee99.pdf\")
- (find-code-pdf-links \"~/Coetzee99.pdf\" \"livesofanimals\")
-The second link above produces a temporary buffer containing this:
- ;; (find-pdf-page \"~/Coetzee99.pdf\")
- ;; (find-pdf-text \"~/Coetzee99.pdf\")
- (code-pdf-page \"livesofanimals\" \"~/Coetzee99.pdf\")
- (code-pdf-text \"livesofanimals\" \"~/Coetzee99.pdf\")
- ;; (find-livesofanimalspage)
- ;; (find-livesofanimalstext)
-`find-code-pdf-links' is somewhat similar to `find-latex-links',
-in this aspect:
+2. Shrinking
+============
+We saw in
- (find-eev-quick-intro \"7.5. `find-latex-links'\" \"change the
\\\"{stem}\\\"\")
+ (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\" \"makes
(find-eev\")
-If you run just
+that these two hyperlinks are equivalent:
- (find-code-pdf-links \"~/Coetzee99.pdf\")
+ (find-eevfile \"eev-blinks.el\" \"«find-wottb»\")
+ (find-eev \"eev-blinks.el\" \"find-wottb\")
-it will generate a buffer that has \"{c}\"s in several places and
-that follows the convention that \"the first line regenerates the
-buffer\". If you substitute the \"{c}\" in the top sexp by
-\"livesofanimals\" and type `M-e' the buffer will be recreated
-with each \"{c}\" replaced by \"livesofanimals\".
+The first one searches for a string in \"eev-blinks.el\" in the
+normal way; the second one treats the \"find-wottb\" as a tag,
+wraps it in `«»'s, and then searches for the anchor
+\"«find-wottb»\" in the file \"eev-blinks.el\".
-The user-friendly way to run `find-code-pdf-links' is by typing
-`M-h M-p' in Dired mode. If you want to generate the three pairs
-for a file \"~/foo/bar/story.pdf\" then visit the directory
-\"~/foo/bar/\", put the cursor on the line that lists the file
-\"story.pdf\", and type `M-h M-p'. Try it with our test file:
+We will refer to the operation that converts the hyperlink
- (find-fline \"~/\" \"Coetzee99.pdf\")
+ (find-eevfile \"eev-blinks.el\")
+to
+ (find-eev \"eev-blinks.el\")
-10. Generating a pair with the page number
-==========================================
-If you type `M-h M-p' and you're not in Dired mode then `M-h M-p'
-will try to generate a short `find-pdf'-pair pointing to the
-current position in the current page of the current PDF
-file (converted to text). The function bound to `M-h M-p' tries
-to guess four things: the stem, the offset, the page number, and
-the string to the be used as a pos-spec. Let's see first a
-situation where everything works. Run the four sexps below and
-type `M-h M-p':
+as _shrinking_ the hyperlink. Eev has a key sequence that does
+that, and for simplicity its behavor is just this: it looks at
+first element of the sexp at eol (the \"head\" of the sexp), and
+if it is a symbol that ends with \"file\" then rewrite the sexp
+replacing the head symbol by it minus its suffix \"file\". That
+key sequence is `M-h M--' (`ee-shrink-hyperlink-at-eol'), and its
+source code is here:
- (code-pdf-page \"livesofanimals\" \"~/Coetzee99.pdf\")
- (code-pdf-text \"livesofanimals\" \"~/Coetzee99.pdf\" -110)
- (kill-new \"wrong thoughts\")
- (find-livesofanimalstext (+ -110 127) \"wrong thoughts\")
+ (find-eev \"eev-edit.el\" \"ee-shrink-hyperlink-at-eol\")
-You will get an elisp hyperlinks buffer whose middle links are
-four short `find-pdf'-pairs, all pointing to the current page:
+Try it on the two lines below:
- # (find-livesofanimalspage 17)
- # (find-livesofanimalstext 17)
- # (find-livesofanimalspage (+ -110 127))
- # (find-livesofanimalstext (+ -110 127))
+ (find-eevfile \"eev-edit.el\" \"ee-shrink-hyperlink-at-eol\")
+ (find-eev \"eev-edit.el\" \"ee-shrink-hyperlink-at-eol\")
- # (find-livesofanimalspage 17 \"wrong thoughts\")
- # (find-livesofanimalstext 17 \"wrong thoughts\")
- # (find-livesofanimalspage (+ -110 127) \"wrong thoughts\")
- # (find-livesofanimalstext (+ -110 127) \"wrong thoughts\")
-The second and the fourth pairs use \"(+ -110 127)\" instead of
-\"17\" as the page number; the third and the fourth pairs point
-to the string \"wrong thoughts\" in the page.
+3. The preceding tag
+====================
+The key sequence `M-h M-w' copies the current line to the kill
+ring, highlights it for a fraction of a second, and shows the
+message
+ \"Copied the current line to the kill ring - use C-y to paste\"
-11. How `M-h M-p' guesses everything
-====================================
-The method that `M-h M-p' uses to guess the stem, the offset, the
-page and the pos-spec is so error-prone and gives unexpected
-results so often that it's worth to describe it in detail.
+in the echo area. Here are links to its source code and to a
+section of a tutorial that mentions it:
- 1. The stem is taken from the global variable `ee-page-c'.
+ (find-eev \"eev-edit.el\" \"ee-copy-this-line-to-kill-ring\")
+ (find-refining-intro \"3. Three buffers\" \"M-h M-w\")
- 2. Every call to a function like `find-xxxtext' sets
- `ee-page-c' to \"xxx\" - for example, a call to
- `find-livesofanimalstext' sets `ee-page-c' to
- \"find-livesofanimalstext\". So `ee-page-c' usually holds
- the stem of the last function of the form `find-xxxtext'
- that was run.
+When we run `M-h M-w' with a numeric argument - for example, as
+`M-1 M-h M-w' - it highlights and copies to the kill ring the
+\"preceding tag\" instead of the current line; the \"preceding
+tag\" is the string between `«»'s in the anchor closest to the
+point if we search backwards. As an exercise, type `M-1 M-h M-w'
+at some point below, and then use `M-h M-y' (`ee-yank-pos-spec')
+to add it to the hyperlink with `find-anchors-intro' below the
+anchors.
- 3. The offset is taken from the global variable
- `ee-page-offset'.
+ «first-anchor»
+ «second-anchor»
+ «third-anchor»
- 4. A call to, say, `find-livesofanimalstext', sets
- `ee-page-offset' to the offset that was declared here:
+ (find-anchors-intro)
- (code-pdf-text \"livesofanimals\" \"~/Coetzee99.pdf\" -110)
- So `ee-page-offset' usually holds the offset of the last
- function of the form `find-xxxtext' that was run.
- 5. The page number is obtained by counting the number of
- formfeeds between the beginning of the buffer and the
- current position. If there are 16 formfeeds then the current
- page is 17.
+[TO DO: write the other sections!]
- 6. The pos-spec - \"wrong thoughts\" in the example - is the
- string in the top of the kill ring. See:
- (find-refining-intro \"2. Refining hyperlinks\" \"kill-new\")
+" rest)))
-If you want to see an example where `M-h M-p' guesses everything
-wrong you can type `M-h M-p' here... as we're not in Dired mode
-`M-h M-p' will think that we're in the conversion to text of
-\"livesofanimals\", in page 1, and it will generate hyperlinks to
-that page of the book!
+;; (find-anchors-intro)
-12. Other ways to generate `code-pdf'-pairs
-===========================================
-The easiest way is with `M-h M-e'. See:
+;;; _ _
+;;; ___ ___ __| | ___ ___ __| |
+;;; / __/ _ \ / _` |/ _ \_____ / __|____ / _` |
+;;; | (_| (_) | (_| | __/_____| (_|_____| (_| |
+;;; \___\___/ \__,_|\___| \___| \__,_|
+;;;
+;; «find-code-c-d-intro» (to ".find-code-c-d-intro")
- (find-audiovideo-intro \"4.1. `find-extra-file-links'\" \"M-h M-e\")
+(defun find-code-c-d-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-code-c-d-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-code-c-d-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-code-c-d-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.
-There is also `M-P', that is a \"wrapping function\" that
-transforms the current line, like `M-B' - see:
- (find-eev-quick-intro \"8.4. Creating e-script blocks\" \"M-B\")
-`M-P' parses the current line as a short string and a file name,
-and then deletes the current line and inserts in its place a
-block of five lines containing a `code-pdf'-pair and some
-comments. Try:
+Note: this intro needs to be rewritten!
+Ideally it should _complement_ the material in:
+ (find-eev-quick-intro \"9. Shorter hyperlinks\")
+ (find-eev-quick-intro \"9.1. `code-c-d'\")
- (eek \"<down> M-P ;; eewrap-pdflike\")
- livesofanimals ~/Coetzee99.pdf
-" rest)))
-;; (find-pdf-like-intro)
+1. Avoiding full path names
+===========================
+Suppose that you have downloaded (\"psne\"-ed) this URL,
+ http://www.lua.org/ftp/lua-5.1.4.tar.gz
+with `M-x brep' - see:
+ (find-psne-intro)
-;;; _
-;;; | |__ _ ____ ____ ____ __
-;;; | '_ \| '__\ \/ /\ \/ /\ \/ /
-;;; | |_) | | > < > < > <
-;;; |_.__/|_| /_/\_\/_/\_\/_/\_\
-;;;
-;; «find-brxxx-intro» (to ".find-brxxx-intro")
+and you unpacked that tarball into the directory ~/usrc/ (I
+prefer to use that instead of /usr/src/) with:
-(defun find-brxxx-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-brxxx-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-brxxx-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-brxxx-intro\")
-More intros: (find-eev-quick-intro)
- (find-eev-intro)
- (find-psne-intro)
- (find-pdf-like-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
+ tar -C ~/usrc/ -xvzf $S/http/www.lua.org/ftp/lua-5.1.4.tar.gz
+Now you can access some directories and files of the unpacked
+tarball with:
+ (find-fline \"~/usrc/lua-5.1.4/\")
+ (find-fline \"~/usrc/lua-5.1.4/src/\")
+ (find-fline \"~/usrc/lua-5.1.4/src/lstrlib.c\")
+ (find-fline \"~/usrc/lua-5.1.4/test/\")
+ (find-fline \"~/usrc/lua-5.1.4/test/README\")
+ (find-fline \"~/usrc/lua-5.1.4/doc/\")
+ (find-w3m \"~/usrc/lua-5.1.4/doc/contents.html\")
-This intro expands an idea that was mentioned briefly at:
- (find-eev-quick-intro \"3.1. Non-elisp hyperlinks\")
-and combines it with the idea of \"local copies\" from:
- (find-psne-intro \"the second way\")
- (find-psne-intro \"1. Local copies of files from the internet\")
- (find-psne-intro \"5. `browse-url' and friends\")
+but it's a bit clumsy to have to use the \"~/usrc/lua-5.1.4/\"
+every time, so eev provides a nice way to define shorthands. We
+want to be able to write just this instead of the sexps above,
-At this moment the best explanation of these ideas in here:
- (find-eev \"eev-brxxx.el\" \";;; Commentary:\")
-in the source code. I need to rewrite this intro!
+ (find-lua51file \"\")
+ (find-lua51file \"src/\")
+ (find-lua51file \"src/lstrlib.c\")
+ (find-lua51file \"test/\")
+ (find-lua51file \"test/README\")
+ (find-lua51file \"doc/\")
+ (find-lua51w3m \"doc/contents.html\")
-[Video links:]
- (find-eevtemplvideo \"9:17\" \"3. The function that defines brep\")
- (find-eevtemplvideo \"9:38\" \"`code-brurl' is a variant of `code-c-d'\")
- (find-eevtemplvideo \"10:07\" \"find-code-url shows the code instead of
executing it\")
- (find-eevtemplvideo \"11:26\" \"this is explained in the main tutorial\")
- (find-eevtemplvideo \"12:12\" \"accept extra arguments\")
- (find-eevtemplvideo \"12:34\" \"if we run just this\")
- (find-eevtemplvideo \"12:40\" \"one of the reasons for using text:
comments\")
- (find-eevtemplvideo \"13:03\" \"if we run just this with extra arguments\")
- (find-eevtemplvideo \"14:10\" \"code-brurl executes this code here\")
+and here the directory \"~/usrc/lua-5.1.4/\" became a mnemonic
+\"lua51\" in the middle of the names of some functions.
+We will call these sexps with \"lua51\" \"shorter hyperlinks\".
+2. Shorter hyperlinks
+=====================
+How can we generate the definitions for `find-lua51file' and
+`find-lua51w3m' from just the strings \"lua51\" and
+\"~/usrc/lua-5.1.4/\"? Try this:
-1. Introduction
-===============
-We saw in
+ (find-code-c-d \"lua51\" \"~/usrc/lua-5.1.4/\")
- (find-eev-quick-intro \"3.1. Non-elisp hyperlinks\")
+you will get a temporary buffer with a lot of Lisp code -
+including a definition for `find-lua51file' and another one for
+`find-lua51w3m'. That Lisp code has not been executed yet; the
+function `find-code-c-d' is just for debugging, and we can regard
+it as a hyperlink to the code that this sexp would execute:
-that eev defines some functions with names starting with `br'
-that are similar to `browse-url', and we saw in
+ (code-c-d \"lua51\" \"~/usrc/lua-5.1.4/\")
- (find-psne-intro \"the second way\")
- (find-psne-intro \"1. Local copies of files from the internet\")
- (find-psne-intro \"3. The new way: M-x brep\")
+So, to define a family of functions including `find-lua51file'
+and `find-lua51w3m', for a given \"mnemonic\" - \"lua51\" in this
+case - and a given \"directory\" - \"~/usrc/lua-5.1.4/\" - we run
+this:
-how to create local copies of files; after downloading a local
-copy of, say,
+ (code-c-d \"lua51\" \"~/usrc/lua-5.1.4/\")
- http://www.gnu.org/software/emacs/emacs-paper.html
+which generates a block of Lisp code, as a string, and evaluates
+it. Note: the original (and rather confusing) terminology for the
+\"mnemonic\" was \"code\"; that's why the \"c\" in `code-c-d'.
-into
- $S/http/www.gnu.org/software/emacs/emacs-paper.html
-you can open the local copy by running `M-x browse-url', `M-x brg'
-or `M-x brff' on the \"file:///\" URL below,
+3. Extra arguments to `code-c-d'
+================================
+`code-c-d' supports extra arguments - for example, this works:
- file:///home/edrx/snarf/http/www.gnu.org/software/emacs/emacs-paper.html
+ (find-code-c-d \"el\" \"~/usrc/emacs/lisp/\" :info \"elisp\")
-but note that the \"file:///\" URL has an \"edrx\" - my username
-- in the middle of the file name, so this only works without
-changes if you use \"edrx\" as your username...
+Look at the end of the generated code and you will see that it
+has a definition for `find-elnode' - such that
+ (find-elnode \"Constant Variables\")
+is a shorthand (a \"shorter hyperlink\") for:
+ (find-node \"(elisp)Constant Variables\")
-2. The `l' variants
-===================
-After creating `brg' and `brff' I created variants of them that
-would open the local copy of the URL at point instead of the
-original URL - or, more precisely, that would open the result of
-applying `ee-url-to-local-url' to the original URL. Try:
+What is important to understand here is how these definitions
+with extra arguments are structured - so that you will be able to
+understand the source code when you need to. Both `code-c-d' and
+`find-code-c-d' are defined with a `&rest' in their argument
+lists, like this (NOTE: do not execute these defuns!):
- (ee-url-to-local-url
- \"http://www.gnu.org/software/emacs/emacs-paper.html\")
+ (defun code-c-d (c d &rest rest) ...)
+ (defun find-code-c-d (c d &rest rest) ...)
-These variants were called `brgl' and `brffl' - I used the
-convention that the suffix `l' meant \"use the local copy\".
+and they both invoke `ee-code-c-d', which does all the template
+work and returns a big string; `ee-code-c-d' passes its `rest'
+argument to a recursive function called `ee-code-c-d-rest', and
+for each one of the supported keywords there is a corresponding
+function, also recursive; for `:info' it is called
+`ee-code-c-d-:info'. Their specifications are like this:
+ (defun ee-code-c-d (c d &rest rest) ...)
+ (defun ee-code-c-d-rest (rest) ...)
+ (defun ee-code-c-d-:info (manual &rest rest) ...)
+and one very non-obvious trick is used to make the code short.
+When `ee-code-c-d-rest' and `ee-code-c-d-:info' are run they can
+access the values the `c' and the `d' that were passed to
+`ee-code-c-d' (due to dynamic scoping), so `c' and `d' do not
+need to be passed down explicitly as arguments.
-3. The `d' variants
-===================
-After creating `brgl' and `brffl' I realized that it would be
-easy to create variants of them that would work in dired mode.
-If we visit a directory - for example, this one,
+Try:
- (find-fline \"$S/http/www.gnu.org/software/emacs/\")
+ (find-code-c-d \"CODE\" \"/DIR/\" :info \"INFO\")
-and we put the point in a line with an HTML on it - for example,
-on the line with the \"emacs-paper.html\" - then typing `M-x
-brgd' there converts the full pathname of the file at point to a
-\"file:///\" URL, like this,
- $S/http/www.gnu.org/software/emacs/emacs-paper.html
- -> file:///home/edrx/snarf/http/www.gnu.org/software/emacs/emacs-paper.html
-and opens the resulting \"file:///\" url with `brg'.
-The suffix `d' means \"use the file in this line in dired\".
+4. Other similar functions
+==========================
+See: (find-brxxx-intro)
+ (find-pdf-like-intro)
+ (find-audiovideo-intro)
+Try: (find-code-pdf \"CODE\" \"FILE.pdf\")
+ (find-code-pdf-text \"CODE\" \"FILE.pdf\")
+ (find-code-audio \"CODE\" \"FILE.mp3\")
+ (find-code-video \"CODE\" \"FILE.mp4\")
+" rest)))
+;; (find-TH "eev-article")
+;; (find-TH "eev-article" "shorter-hyperlinks")
+;; (find-code-c-d-intro)
-4. `brxxx'-functions
-====================
-`browse-url' has several variants, with names like
-`browse-url-firefox' and `browse-url-chromium', that open the URL
-at point using specific programs. See:
- (find-epackage 'browse-url)
- (find-enode \"Browse-URL\")
-We say that `brg', `brgl' and `brgd' are \"`brxxx'-functions\"
-with \"base function\" `find-googlechrome'; `brgl' is the `l' (or
-\"local\") variant, and `brgd' is the `d' (or \"dired\") variant;
-`brg' is sometimes called the \"remote\" variant.
+;;; _ __ _ _ _
+;;; _ __ __| |/ _| | (_) | _____
+;;; | '_ \ / _` | |_ _____| | | |/ / _ \
+;;; | |_) | (_| | _|_____| | | < __/
+;;; | .__/ \__,_|_| |_|_|_|\_\___|
+;;; |_|
+;;
+;; «find-pdf-like-intro» (to ".find-pdf-like-intro")
+
+(defun find-pdf-like-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-pdf-like-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-pdf-like-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-pdf-like-intro\")
+More intros: (find-eev-quick-intro)
+ (find-eev-intro)
+ (find-here-links-intro)
+ (find-refining-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
-5. `code-brurl'
-===============
-Remember that `code-c-d' generates lisp code and executes it, and
-that `find-code-c-d' generates the same lisp code as `code-c-d'
-but displays it instead of executing it; this was explained, with
-examples, here:
+Note: you will need a basic understanding of eepitch and
+code-c-d to understand parts of this intro. See:
+ (find-eev-quick-intro \"6.1. The main key: <F8>\")
+ (find-eev-quick-intro \"9. Shorter hyperlinks\")
(find-eev-quick-intro \"9.1. `code-c-d'\")
- (find-eev-quick-intro \"9.1. `code-c-d'\" \"find-code-c-d\")
-Eev has a function called `code-brurl' that works like `code-c-d'
-and that creates several `brxxx'-functions with the same base
-function. To understand what the `code-brurl' sexp below does,
- ;; From:
- ;; (find-eev \"eev-brxxx.el\" \"code-brxxxs\")
- ;; (find-eev \"eev-brxxx.el\" \"code-brxxxs\" \"brg\")
- (code-brurl 'find-googlechrome :remote 'brg :local 'brgl :dired 'brgd)
-We run:
- (find-code-brurl 'find-googlechrome :remote 'brg :local 'brgl :dired
'brgd)
+1. PDF-like documents
+=====================
+Let's introduce a bit of (improvised!) terminology: we will say
+that a document is \"PDF-like\" when it is in a format like PDF,
+PostScript, DVI or DJVU - i.e., divided into pages. Emacs has a
+standard mode for viewing PDF-like documents,
-Note that the base function in this example is
-`find-googlechrome', that is a function that expects a URL.
+ (find-enode \"Document View\")
+but we will see a more eev-like way of pointing to pages of
+PDF-like documents.
-6. `code-brfile'
-================
-We saw how to create `brxxx'-functions using `find-googlechrome'
-as the base function; remember that `find-googlechrome' is a
-function that expects a URL.
-If we download a local copy of a PDF, like we did here,
+2. Preparation
+==============
+We need to start by downloading a PDF file to use in our
+examples. If you run this e-script
- (find-pdf-like-intro \"2. Preparation\")
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ cd
+ wget -nc
https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
-
https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
- ->
$S/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
+you will download a local copy of J.M. Coetzee's \"The Lives of
+Animals\" into your home directory. To check that the PDF has been
+downloaded, use:
-then it makes sense to have a `brxxx'-function, called `brpdfl',
-that we can run on the \"https://\" URL above, and that will open
-the \"$S/https/\" file corresponding to the URL using
-`find-pdf-page'... but `find-pdf-page' is a function that expects
-a filename, not a URL, so `code-brurl' wouldn't work...
+ (find-fline \"~/\")
+ (find-fline \"~/\" \"Coetzee99.pdf\")
+ (find-sh0 \"ls -l ~/Coetzee99.pdf\")
-What we want can be done by the sexp below:
+Eev also implements another way, called \"psne\", to download
+local copies of files from the internet.\"Psne-ing\" a URL like
- ;; From:
- ;; (find-eev \"eev-pdflike.el\" \"code-brxxxs\")
- ;; (find-eev \"eev-pdflike.el\" \"code-brxxxs\" \"brpdfl\")
- (code-brfile 'find-pdf-page :local 'brpdfl :dired 'brpdfd)
+ https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
-To understand what it does, run:
+downloads it to a local file with a name like:
- (find-code-brfile 'find-pdf-page :local 'brpdfl :dired 'brpdfd)
+
$S/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
+
~/snarf/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
-and read the docstrings.
+that is _much_ longer that just \"~/Coetzee99.pdf\"; this has the
+advantage of preserving more information about the URL from which
+the file came, but sometimes these longer names feels clumsy.
+Psne-ing is discussed a more advanced tutorial:
-Note that in the previous section we had a \":remote 'brg\", that
-defined a remote variant. It doesn't make sense to apply
-`find-pdf-page' to a remote URL, so we don't have a \":remote\"
-here.
+ (find-psne-intro)
-
-
-
-Old stuff:
-(TODO: revise it!)
-
-
-
-
-7. Old introduction
-===================
-We saw in
-
- (find-psne-intro)
- (find-psne-intro \"M-x brep\")
- (find-psne-intro \"M-x brfl\")
- (find-psne-intro \"5. `browse-url' and friends\")
-
-that we can use `M-x brep' to download local copies of files from
-the internet, and that `M-x brfl' on a URL runs `find-fline' on
-the local copy of that URL. `brep' and `brfl' are
-\"`browse-url'-like functions\" defined by eev; we will refer to
-them, and to other such functions, as \"brxxx-functions\". Every
-brxxx-function is an interactive interface to some \"base
-function\"; for `brep' and `brfl' we have:
-
- brxxx-function base function
- -------------- -------------
- brep find-psne-links
- brfl find-fline
-
-What we will see here is how `code-brfile' and `code-brurl' -
-which are somewhat similar to `code-c-d' - can be used to define
-brxxx-functions from base functions.
+In this tutorial we will use the home directory and the shorter
+file name.
-8. A first example
-==================
-Let's define two trivial base functions, one that expects a URL,
-and another one that expects a file name:
+3. Hyperlinks to PDF files
+==========================
+If you have xpdf installed then this sexp
- (defun foo-url (url) (format \"Got URL: %s\" url))
- (defun foo-file (filename) (format \"Got filename: %s\" filename))
+ (find-pdf-page \"~/Coetzee99.pdf\")
-Note that they don't do much - they just return explanatory
-strings.
+should work as a \"hyperlink to the PDF\": it calls xpdf as an
+external program - like we did with browsers in the main tutorial -
-These two calls,
+ (find-eev-quick-intro \"3.1. Non-elisp hyperlinks\")
+ (find-eev-quick-intro \"3.1. Non-elisp hyperlinks\" \"find-firefox\")
- (code-brurl 'foo-url :remote 'brshowu :local 'brshowul)
- (code-brfile 'foo-file :local 'brshowfl)
+to display the PDF file that we downloaded.
-define three brxxx-functions: `brshowu' and `brshowul' for the
-base function `foo-url', and `brshowfl' for the base function
-`foo-file'. You can inspect the definitions by running these
-sexps,
+The main keys of xpdf are:
- (find-code-brurl 'foo-url :remote 'brshowu :local 'brshowul)
- (find-code-brfile 'foo-file :local 'brshowfl)
+ q quit xpdf
+ PageDown scroll down/go to next page
+ PageUp scroll up/go to previous page
+ arrows scroll within the current page
+ + zoom in one step
+ - zoom out out step
+ 0 set zoom to 125%
+ alt-f toggle full-screen; use twice to fit document to page
-and you can test what `foo-url', `foo-file', `brshowu',
-`brshowul', and `brshowfl' do by running the sexps below.
+Note that `q' \"goes back to Emacs\".
- (foo-url \"http://a/b\")
- => \"Got URL: http://a/b\"
+If you have the program pdftotext installed - hint: \"apt-get install
+poppler-utils\"! - then you can also display PDFs in another way. This
+sexp
- (foo-file \"/c/d/e/f\")
- => \"Got filename: /c/d/e/f\"
+ (find-pdf-text \"~/Coetzee99.pdf\")
- (brshowu \"http://a/b\")
- => `(foo-url \"http://a/b\") -> \"Got URL: http://a/b\"'
+work as a \"hyperlink to the _text_ of the PDF\": it extracts the text
+from the PDF using the program \"pdftotext\" and displays that in an
+Emacs buffer.
- (brshowul \"http://a/b\")
- => `(foo-url \"file:///home/edrx/snarf/http/a/b\") ->
- \"Got URL: file:///home/edrx/snarf/http/a/b\"'
- (brshowfl \"http://a/b\")
- => `(foo-file \"/home/edrx/snarf/http/a/b\") ->
- \"Got filename: /home/edrx/snarf/http/a/b\"'
-Now let's go to what matters. Put the point on the URL below, and
-run `M-x brshowu', `M-x brshowul' and `M-x brshowfl':
- http://a/b
+4. Hyperlinks to pages of PDF files
+===================================
+It is possible to create hyperlinks that point to a specific page in a
+PDF file. Compare what happens when you run these sexps:
-you will see that `brshowu', `brshowul', and `brshowfl' can be
-called interactively, and when they are called interactively they
-use as their argument either the URL around point, or something
-obtained from it - the local file name or a local URL associated
-to that URL.
+ (find-pdf-page \"~/Coetzee99.pdf\")
+ (find-pdf-page \"~/Coetzee99.pdf\" 1)
+ (find-pdf-page \"~/Coetzee99.pdf\" 1 \"The Lives of Animals\")
+ (find-pdf-page \"~/Coetzee99.pdf\" 3)
+ (find-pdf-page \"~/Coetzee99.pdf\" 3 \"LECTURE I\")
+ (find-pdf-page \"~/Coetzee99.pdf\" 3 \"LECTURE I\" \"[113]\")
+The top three sexps open the PDF at page 1 - the default. The bottom
+three sexps open it at page 3. The arguments after the number are
+ignored by Emacs - they are there to make these links more expressive
+for humans.
+The hyperlinks to the text of a PDF interpret the numeric number as a
+page number and the following arguments as strings to search for. Try:
+ (find-pdf-text \"~/Coetzee99.pdf\" 1)
+ (find-pdf-text \"~/Coetzee99.pdf\" 1 \"The Lives of Animals\")
+ (find-pdf-text \"~/Coetzee99.pdf\" 3)
+ (find-pdf-text \"~/Coetzee99.pdf\" 3 \"LECTURE I\")
+ (find-pdf-text \"~/Coetzee99.pdf\" 3 \"LECTURE I\" \"[113]\")
-9. The conversions
-==================
-One underlying idea behind all this is that we have two
-conversion functions, one from URLs to file names, and another
-from (absolute) file names to URLs starting with \"file:///\".
-They work like this:
+For more information about these string arguments, see:
- http://a/b -> $S/http/a/b -> file:///home/edrx/snarf/http/a/b
- /tmp/c -> file:///tmp/c
+ (find-refining-intro \"1. Pos-spec-lists\")
-try:
+A pair of sexps like this, in which both point to the same
+position of a PDF,
- (ee-url-to-fname \"http://a/b\")
- (ee-fname-to-url \"/tmp/c\")
- (ee-url-to-local-url \"http://a/b\")
+ (find-pdf-page \"~/Coetzee99.pdf\" 3 \"LECTURE I\" \"[113]\")
+ (find-pdf-text \"~/Coetzee99.pdf\" 3 \"LECTURE I\" \"[113]\")
-Now execute the sexps below (with `M-2 M-e') to examine the code
-that calls to `code-brurl' and `code-brfile' generate and
-execute:
+will be called a `find-pdf'-pair.
- (find-code-brurl 'foo-url :remote 'brshowu :local 'brshowul)
- (find-code-brfile 'foo-file :local 'brshowfl)
+[Video links:]
+ (find-eev2020video \"4:52\" \"`find-pdf-page' calls an external program\")
+ (find-eev2020video \"5:26\" \"`find-pdf-text' converts the PDF to text and\")
+5. A convention on page numbers
+===============================
+The `(+ -110 113)'s in
-10. Naming conventions for brxxx-functions
-==========================================
-By convention, each name for a brxxx-function is composed of a
-prefix, a stem, and a suffix. The prefix is always \"br\", the
-stem is a mnemonic for the base function, and the suffix is
-either \"\", \"l\", or \"d\", meaning:
+ (find-livesofanimalspage (+ -110 113) \"LECTURE I.\")
+ (find-livesofanimalstext (+ -110 113) \"LECTURE I.\")
- \"\" - use the URL without changes
- \"l\" - use the local copy
- \"d\" - dired variation (see below)
+are a bit mysterious at first sight.
-Here are the stems for some of the brxxx-functions defined by
-eev:
+We are accessing a PDF that is an excerpt of a book. The third
+page of the PDF has a \"[113]\" at its footer to indicate that it
+is the page 113 of the book. Let's use the terms _page number_
+and _page label_ to distinguish the two numberings: in this case,
+the page whose page number is 3 is the page whose page label is
+113. These two sexps
- Base function receives stem
- ------------- -------- ----
- find-psne-links URL \"ep\"
- browse-url-firefox URL \"m\"
- find-googlechrome URL \"g\"
- find-w3m URL \"w\"
- find-fline file name \"f\"
- find-audio file name \"audio\"
- find-video file name \"video\"
- find-xpdf-page file name \"xpdf\"
- find-evince-page file name \"evince\"
- find-xdvi-page file name \"xdvi\"
- find-djvu-page file name \"djvu\"
- find-pdf-text file name \"pdftext\"
- find-djvu-text file name \"djvutext\"
+ (find-livesofanimalspage (+ -110 113))
+ (find-livesofanimalspage 3)
-In our example with `foo-url' and `foo-file' we had:
+are equivalent, but the first one is more human-friendly: the 113
+is a page label, and the -110 is an adjustment (we call it the
+\"offset\") to convert the 113 that humans prefer to see into
+the 3 that xpdf needs to receive.
- Base function receives stem
- ------------- -------- ----
- foo-url URL showu
- foo-file file name showf
-11. Calling `code-brurl' and `code-brfile'
-==========================================
+6. How the external programs are called
+=======================================
+Both `find-pdf-page' and `find-pdf-text' invoke external programs -
+but how, exactly? Let's take a look at a hack that shows this. If
+you prepend an \"ee-\" to `find-pdf-page' and `find-pdf-text' sexps,
+like in:
- (code-brurl '<U-function>
- :remote 'br<stem> :local 'br<stem>l :dired 'br<stem>d)
- \\---------------/ \\---------------/
\\----------------/
- optional optional optional
+ (ee-find-pdf-page \"~/Coetzee99.pdf\")
+ (ee-find-pdf-page \"~/Coetzee99.pdf\" 3)
+ (ee-find-pdf-text \"~/Coetzee99.pdf\")
+ (ee-find-pdf-text \"~/Coetzee99.pdf\" 3)
- (code-brfile '<F-function> :local 'br<stem>l :dired 'br<stem>d)
- \\---------------/ \\----------------/
- optional optional
+you will get sexps that stop just before invoking the external
+programs - they just show how these externals programs _would be_
+invoked, i.e., they show the options that would be passed to them. The
+results of the sexps above will be lists like these:
-This, like many other parts of eev, is a hack with a very concise
-calling syntax - so we will see an example first, and then
-dissect it to understand precisely how it works. If you are
-curious about the inspirations behind it, here they are:
+ (\"xpdf\" \"-fullscreen\" \"~/Coetzee99.pdf\")
+ (\"xpdf\" \"-fullscreen\" \"~/Coetzee99.pdf\" \"3\")
+ (\"pdftotext\" \"-layout\" \"-enc\" \"Latin1\" \"~/Coetzee99.pdf\" \"-\")
+ (\"pdftotext\" \"-layout\" \"-enc\" \"Latin1\" \"~/Coetzee99.pdf\" \"-\")
- (find-code-c-d-intro)
- (find-code-c-d-intro \"find-code-c-d\")
- (find-code-c-d-intro \"Extra arguments\")
- (find-enode \"Browse-URL\")
+Note that `ee-find-pdf-text' does not pass the argument \"3\" to
+\"pdftotext\". A sexp like
+ (find-pdf-text \"~/Coetzee99.pdf\" 3)
+first produces the conversion to text of the full PDF, and then
+finds the page 3 in it by counting formfeeds, as described here:
-12. The dired variation
-=======================
+ (find-enode \"Pages\" \"formfeed\")
-In dired mode each line corresponds to a file
-" rest)))
-;; (find-brxxx-intro)
+7. Shorter hyperlinks to PDF files
+==================================
+If you run these sexps
+ (code-pdf-page \"livesofanimals\" \"~/Coetzee99.pdf\")
+ (code-pdf-text \"livesofanimals\" \"~/Coetzee99.pdf\" -110)
+they will define the functions `find-livesofanimalspage' and
+`find-livesofanimalstext', and then these hyperlinks should work:
-;;;
-;;; _ __ ___ _ __ ___
-;;; | '_ \/ __| '_ \ / _ \
-;;; | |_) \__ \ | | | __/
-;;; | .__/|___/_| |_|\___|
-;;; |_|
-;;
-;; «find-psne-intro» (to ".find-psne-intro")
-;; (find-TH "eev-article" "local-copies")
-;; (find-angg ".emacs" "brep")
-;; (find-eev "eev-browse-url.el" "find-psne-links")
-;; (find-eev "eev-browse-url.el" "brep")
+ (find-livesofanimalspage)
+ (find-livesofanimalstext)
+ (find-livesofanimalspage (+ -110 113))
+ (find-livesofanimalstext (+ -110 113))
+ (find-livesofanimalspage (+ -110 113) \"LECTURE I.\")
+ (find-livesofanimalstext (+ -110 113) \"LECTURE I.\")
+ (find-livesofanimalspage (+ -110 127) \"wrong thoughts\")
+ (find-livesofanimalstext (+ -110 127) \"wrong thoughts\")
+ (find-livesofanimalspage (+ -110 132) \"into the place of their victims\")
+ (find-livesofanimalstext (+ -110 132) \"into the place of their victims\")
+ (find-livesofanimalspage (+ -110 133) \"To write that book I had to think\")
+ (find-livesofanimalstext (+ -110 133) \"To write that book I had to think\")
+ (find-livesofanimalspage (+ -110 134) \"woke up haggard in the mornings\")
+ (find-livesofanimalstext (+ -110 134) \"woke up haggard in the mornings\")
+ (find-livesofanimalspage (+ -110 143) \"Babies have no self-consciousness\")
+ (find-livesofanimalstext (+ -110 143) \"Babies have no self-consciousness\")
+ (find-livesofanimalspage (+ -110 145) \"squirrel doing its thinking\")
+ (find-livesofanimalstext (+ -110 145) \"squirrel doing its thinking\")
+ (find-livesofanimalspage (+ -110 147) \"Rilke's panther\")
+ (find-livesofanimalstext (+ -110 147) \"Rilke's panther\")
+ (find-livesofanimalspage (+ -110 162) \"a grasp of the meaning\")
+ (find-livesofanimalstext (+ -110 162) \"a grasp of the meaning\")
+ (find-livesofanimalspage (+ -110 164) \"last common ground\")
+ (find-livesofanimalstext (+ -110 164) \"last common ground\")
-(defun find-psne-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-psne-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-psne-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-psne-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.
+Hyperlinks like
+ (find-livesofanimalspage (+ -110 113) \"LECTURE I.\")
+ (find-livesofanimalstext (+ -110 113) \"LECTURE I.\")
+behave roughly as abbreviations for:
+ (find-pdf-page \"~/Coetzee99.pdf\" (+ -110 113) \"LECTURE I.\")
+ (find-pdf-text \"~/Coetzee99.pdf\" (+ -110 113) \"LECTURE I.\")
-We mentioned briefly in
+[Video links:]
+ (find-eev2020video \"10:22\" \"1.3. Shorter hyperlinks to PDFs and videos\")
+ (find-eev2020video \"10:45\" \"`code-pdf-page' creates short hyperlink
functions\")
+ (find-eev2020video \"11:38\" \"let's try...\")
+ (find-eev2020video \"11:55\" \"`find-fongspivatext'\")
- (find-pdf-like-intro \"2. Preparation\")
-that there are two \"natural\" ways to store a local copy of a
-file from the internet... here we will discuss the second way, in
-which the conversion from URL to a local file name works like
-this:
-
https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
- ->
$S/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
+8. `find-pdf'-pairs
+===================
+Let's introduce some terminology. Remember that we call a pair of
+sexps like
+ (find-pdf-page \"~/Coetzee99.pdf\" (+ -110 113) \"LECTURE I.\")
+ (find-pdf-text \"~/Coetzee99.pdf\" (+ -110 113) \"LECTURE I.\")
+a \"`find-pdf'-pair\"; a pair like
-1. Local copies of files from the internet
-==========================================
-Emacs knows how to fetch files from the internet, but for most
-purposes it is better to use local copies. Suppose that the
-environment variable $S is set to ~/snarf/; then running this
+ (find-livesofanimalspage (+ -110 113) \"LECTURE I.\")
+ (find-livesofanimalstext (+ -110 113) \"LECTURE I.\")
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- mkdir -p $S/http/www.gnu.org/software/emacs/
- cd $S/http/www.gnu.org/software/emacs/
- wget http://www.gnu.org/software/emacs/emacs-paper.html
- echo 'http://www.gnu.org/software/emacs/emacs-paper.html' >> ~/.psne.log
+will be called a \"short `find-pdf'-pair\", as in:
- # (find-fline \"$S/http/www.gnu.org/software/emacs/emacs-paper.html\")
- # (find-w3m \"$S/http/www.gnu.org/software/emacs/emacs-paper.html\")
+ (find-eev-quick-intro \"9. Shorter hyperlinks\")
-creates a local copy of `emacs-paper.html' inside ~/snarf/http/
-and appends the URL to the file ~/.psne.log. The two lines in
-comments are hyperlinks to the local copy; The `find-fline' opens
-it as a file in the obvious way, and `find-w3m' opens it \"as
-HTML\", using a text-mode web browser called w3m that can be run
-either in standalone mode or inside Emacs; `find-w3m' uses w3m's
-Emacs interface, and it accepts extra arguments, which are
-treated as a pos-spec-list.
+and a pair like
+ (code-pdf-page \"livesofanimals\" \"~/Coetzee99.pdf\")
+ (code-pdf-text \"livesofanimals\" \"~/Coetzee99.pdf\" -110)
+will be called a `code-pdf'-pair.
-2. The old way: psne
-====================
-A long time ago eev used to include a shell function called
-`psne' that ran all that with a single command. This:
+The \"livesofanimals\" will the called the _stem_. The \"-110\"
+will be called the _offset_.
- psne http://www.gnu.org/software/emacs/emacs-paper.html
-would run the `mkdir', the `cd', the `wget' and the `echo' above.
-If psne were just a shell script then it wouldn't be able to
-change the current directory for the calling shell, so it had to
-be defined as shell function instead of a script, and the user
-had to patch his ~/.bashrc (or ~/.zshrc, or whatever) to install
-the definition for psne and make it available. That was VERY
-clumsy.
-From now on we will use \"psne\" as a verb: to psne a URL means
-to download a local copy of it into the right place, change to
-its directory and save its name into the file \"~/.psne.log\".
+9. Generating three pairs
+=========================
+Eev has a high-level function that generates at once, for a
+single PDF file, a `find-pdf'-pair, a `code-pdf'-pair, and a
+short `find-pdf'-pair. To see what it produces, try:
+ (find-code-pdf-links \"~/Coetzee99.pdf\")
+ (find-code-pdf-links \"~/Coetzee99.pdf\" \"livesofanimals\")
+The second link above produces a temporary buffer containing this:
+ ;; (find-pdf-page \"~/Coetzee99.pdf\")
+ ;; (find-pdf-text \"~/Coetzee99.pdf\")
+ (code-pdf-page \"livesofanimals\" \"~/Coetzee99.pdf\")
+ (code-pdf-text \"livesofanimals\" \"~/Coetzee99.pdf\")
+ ;; (find-livesofanimalspage)
+ ;; (find-livesofanimalstext)
-3. The new way: `M-x brep'
-==========================
-Try to run this:
+`find-code-pdf-links' is somewhat similar to `find-latex-links',
+in this aspect:
- (find-psne-links \"http://www.gnu.org/software/emacs/emacs-paper.html\")
+ (find-eev-quick-intro \"7.5. `find-latex-links'\" \"change the
\\\"{stem}\\\"\")
-or, equivalently, put the point on the URL below and then run
-`M-x brep':
+If you run just
- http://www.gnu.org/software/emacs/emacs-paper.html
+ (find-code-pdf-links \"~/Coetzee99.pdf\")
-You will get a temporary buffer for psne-ing the URL above. It
-will contain a `mkdir', a `cd', a `wget' and an `echo', plus an
-eepitch block and some elisp hyperlinks, and it can be executed
-with `F8's. Moral of the story: the \"new\" way to download a
-local copy of a url is to put the point on it, then run `M-x
-brep', then execute the resulting e-script. This does not require
-any patching of rcfiles, as the shell-function version of `psne'
-used to do.
+it will generate a buffer that has \"{c}\"s in several places and
+that follows the convention that \"the first line regenerates the
+buffer\". If you substitute the \"{c}\" in the top sexp by
+\"livesofanimals\" and type `M-e' the buffer will be recreated
+with each \"{c}\" replaced by \"livesofanimals\".
+The user-friendly way to run `find-code-pdf-links' is by typing
+`M-h M-p' in Dired mode. If you want to generate the three pairs
+for a file \"~/foo/bar/story.pdf\" then visit the directory
+\"~/foo/bar/\", put the cursor on the line that lists the file
+\"story.pdf\", and type `M-h M-p'. Try it with our test file:
+ (find-fline \"~/\" \"Coetzee99.pdf\")
-4. The environment variable $S
-==============================
-If when eev is loaded by Emacs the environment variable $S is
-unset, it will be set to a default value - namely, to the
-expansion of \"$HOME/snarf\". Processes started from Emacs, such
-as shells created with `eepitch-shell' or `find-sh', or external
-terminals created by sexps like
- (find-bgprocess \"xterm\")
- (find-bgprocess \"gnome-terminal\")
- (find-bgprocess \"eterm\")
+10. Generating a pair with the page number
+==========================================
+If you type `M-h M-p' and you're not in Dired mode then `M-h M-p'
+will try to generate a short `find-pdf'-pair pointing to the
+current position in the current page of the current PDF
+file (converted to text). The function bound to `M-h M-p' tries
+to guess four things: the stem, the offset, the page number, and
+the string to the be used as a pos-spec. Let's see first a
+situation where everything works. Run the four sexps below and
+type `M-h M-p':
-will then inherit that value. Try it:
+ (code-pdf-page \"livesofanimals\" \"~/Coetzee99.pdf\")
+ (code-pdf-text \"livesofanimals\" \"~/Coetzee99.pdf\" -110)
+ (kill-new \"wrong thoughts\")
+ (find-livesofanimalstext (+ -110 127) \"wrong thoughts\")
- (getenv \"S\")
- (find-sh0 \"echo $S\")
+You will get an elisp hyperlinks buffer whose middle links are
+four short `find-pdf'-pairs, all pointing to the current page:
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
-echo $S
+ # (find-livesofanimalspage 17)
+ # (find-livesofanimalstext 17)
+ # (find-livesofanimalspage (+ -110 127))
+ # (find-livesofanimalstext (+ -110 127))
-Try also to create an external shell not from Emacs - for
-example, from your window manager's list of available
-applications, or from a text-mode login - and run \"echo $S\"
-there: you will notice that $S is unset.
+ # (find-livesofanimalspage 17 \"wrong thoughts\")
+ # (find-livesofanimalstext 17 \"wrong thoughts\")
+ # (find-livesofanimalspage (+ -110 127) \"wrong thoughts\")
+ # (find-livesofanimalstext (+ -110 127) \"wrong thoughts\")
-Old versions of eev used to require the user to run a script that
-would patch his rcfiles (i.e., ~/.bashrc, ~/.zshrc, etc) to set
-$S on startup. That turned out to be unreliable - it was better
-to teach people how to distinguish those processes that inherit
-$S from Emacs from those that don't, and let the experts patch
-their rcfiles by hand.
+The second and the fourth pairs use \"(+ -110 127)\" instead of
+\"17\" as the page number; the third and the fourth pairs point
+to the string \"wrong thoughts\" in the page.
-5. `browse-url' and friends
-===========================
-If you place the point on the URL below
- http://www.gnu.org/software/emacs/emacs-paper.html
+11. How `M-h M-p' guesses everything
+====================================
+The method that `M-h M-p' uses to guess the stem, the offset, the
+page and the pos-spec is so error-prone and gives unexpected
+results so often that it's worth to describe it in detail.
-and run `M-x browse-url', Emacs will make an external browser
-visit the remote version of that URL. One (bad) way to visit the
-local copy of that URL is to modify the URL above by hand to
-adjust it to your value of $S, until you obtain something like
-this:
+ 1. The stem is taken from the global variable `ee-page-c'.
- file:///home/edrx/snarf/http/www.gnu.org/software/emacs/emacs-paper.html
+ 2. Every call to a function like `find-xxxtext' sets
+ `ee-page-c' to \"xxx\" - for example, a call to
+ `find-livesofanimalstext' sets `ee-page-c' to
+ \"find-livesofanimalstext\". So `ee-page-c' usually holds
+ the stem of the last function of the form `find-xxxtext'
+ that was run.
-and then run `M-x browse-url' on it.
+ 3. The offset is taken from the global variable
+ `ee-page-offset'.
-One - rather primitive - way of visiting the local copy of that
-URL with find-file is to modify the URL by hand, replacing its
-\"http://\" with n \"$S/http/\", and then visit that file. For
-example:
+ 4. A call to, say, `find-livesofanimalstext', sets
+ `ee-page-offset' to the offset that was declared here:
- http://www.gnu.org/software/emacs/emacs-paper.html
- (find-fline \"$S/http/www.gnu.org/software/emacs/emacs-paper.html\")
+ (code-pdf-text \"livesofanimals\" \"~/Coetzee99.pdf\" -110)
-If you put the point on the URL and run `M-x brfl' on it you will
-visit the local copy \"as a file\", with `find-file' /
-`find-fline'. Visiting URLs - or their local copies - is
-something that we do so frequently that we need ways to do that
-with few keystrokes, which is why `brfl' has a short - and
-cryptic - name. The conventions are:
+ So `ee-page-offset' usually holds the offset of the last
+ function of the form `find-xxxtext' that was run.
- \"br\" is the common prefix for all the browse-url-like
- functions in eev,
- \"f\" means to use `find-fline' (or, equivalently, `find-file'),
- \"l\" is an optional suffix meaning to use the local copy.
-
-The details on how to create these \"brxxx functions\" are here:
+ 5. The page number is obtained by counting the number of
+ formfeeds between the beginning of the buffer and the
+ current position. If there are 16 formfeeds then the current
+ page is 17.
- (find-brxxx-intro)
+ 6. The pos-spec - \"wrong thoughts\" in the example - is the
+ string in the top of the kill ring. See:
+ (find-refining-intro \"2. Refining hyperlinks\" \"kill-new\")
+If you want to see an example where `M-h M-p' guesses everything
+wrong you can type `M-h M-p' here... as we're not in Dired mode
+`M-h M-p' will think that we're in the conversion to text of
+\"livesofanimals\", in page 1, and it will generate hyperlinks to
+that page of the book!
-6. `ee-flip-psne-ness'
-======================
-Converting a \"non-psne URL\" to a \"psne URL\" by hand, like this,
-
https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
- ->
$S/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
+12. Other ways to generate `code-pdf'-pairs
+===========================================
+The easiest way is with `M-h M-e'. See:
-is error-prone and boring.
+ (find-audiovideo-intro \"4.1. `find-extra-file-links'\" \"M-h M-e\")
-Eev implements a command to do that, that works in both directions -
-it is called `ee-flip-psne-ness', and it searches for the next
-non-psne-or-psne URL and it \"flips its psne-ness\": it converts
-non-psne URLs to psne URLs and psne URLs to non-psne URLs.
+There is also `M-P', that is a \"wrapping function\" that
+transforms the current line, like `M-B' - see:
-To try it you will have to run this:
+ (find-eev-quick-intro \"8.4. Creating e-script blocks\" \"M-B\")
- (define-key eev-mode-map \"\\M-s\" 'ee-flip-psne-ness)
+`M-P' parses the current line as a short string and a file name,
+and then deletes the current line and inserts in its place a
+block of five lines containing a `code-pdf'-pair and some
+comments. Try:
-because most people prefer to use the key `M-s' for their other
-things. Then try it by putting the cursor here and typing `M-s' four
-times. Watch the four psne-nesses below flip.
+ (eek \"<down> M-P ;; eewrap-pdflike\")
+ livesofanimals ~/Coetzee99.pdf
- https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
- $S/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
- http://www.gnu.org/software/emacs/emacs-paper.html
- $S/http/www.gnu.org/software/emacs/emacs-paper.html
+" rest)))
+;; (find-pdf-like-intro)
-7. A historical note
-====================
-I wrote the first versions of \"psne\" in the late 1990s. At that point
-I was using a program called \"snarf\" to fetch files from the internet
-using FTP and HTTP, and I thought that it was natural to store the
-files downloaded with snarf into the directory \"~/snarf/\". Later I
-changed from snarf to wget, but I kept the directory as \"~/snarf/\".
+;;; _
+;;; | |__ _ ____ ____ ____ __
+;;; | '_ \| '__\ \/ /\ \/ /\ \/ /
+;;; | |_) | | > < > < > <
+;;; |_.__/|_| /_/\_\/_/\_\/_/\_\
+;;;
+;; «find-brxxx-intro» (to ".find-brxxx-intro")
-I tried using several languages for the part that converted a url into
-a directory. I still have the notes from my attempts to use Tcl and
-Awk to do that - but at one point I managed to write a script in Perl
-that was good enough and I stuck to that.
+(defun find-brxxx-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-brxxx-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-brxxx-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-brxxx-intro\")
+More intros: (find-eev-quick-intro)
+ (find-eev-intro)
+ (find-psne-intro)
+ (find-pdf-like-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
-The shell function that I could call as
- psne $S/http/www.gnu.org/software/emacs/emacs-paper.html
-and it would run the four steps in
+This intro expands an idea that was mentioned briefly at:
+ (find-eev-quick-intro \"3.1. Non-elisp hyperlinks\")
+and combines it with the idea of \"local copies\" from:
+ (find-psne-intro \"the second way\")
+ (find-psne-intro \"1. Local copies of files from the internet\")
+ (find-psne-intro \"5. `browse-url' and friends\")
- mkdir -p http://www.gnu.org/software/emacs/
- cd http://www.gnu.org/software/emacs/
- wget $S/http/www.gnu.org/software/emacs/emacs-paper.html
- echo 'http://www.gnu.org/software/emacs/emacs-paper.html' >> ~/.psne.log
+At this moment the best explanation of these ideas in here:
+ (find-eev \"eev-brxxx.el\" \";;; Commentary:\")
+in the source code. I need to rewrite this intro!
-was called \"psne\" because it used a Perl script to obtain the
-directory name, then it ran \"snarf\" (later \"wget\"), and it \"echo\"ed
-the URL to the end of a log file. So \"p-sn-e\".
+[Video links:]
+ (find-eevtemplvideo \"9:17\" \"3. The function that defines brep\")
+ (find-eevtemplvideo \"9:38\" \"`code-brurl' is a variant of `code-c-d'\")
+ (find-eevtemplvideo \"10:07\" \"find-code-url shows the code instead of
executing it\")
+ (find-eevtemplvideo \"11:26\" \"this is explained in the main tutorial\")
+ (find-eevtemplvideo \"12:12\" \"accept extra arguments\")
+ (find-eevtemplvideo \"12:34\" \"if we run just this\")
+ (find-eevtemplvideo \"12:40\" \"one of the reasons for using text:
comments\")
+ (find-eevtemplvideo \"13:03\" \"if we run just this with extra arguments\")
+ (find-eevtemplvideo \"14:10\" \"code-brurl executes this code here\")
-" rest)))
+1. Introduction
+===============
+We saw in
-;; (find-enode "Command Index" "browse-url")
-;; (find-efunction 'browse-url)
-;; (find-elnode "System Environment")
-;; (find-enode "Environment")
-;; (find-eevfile \"eev.el\" \"$HOME/snarf\")
+ (find-eev-quick-intro \"3.1. Non-elisp hyperlinks\")
-;; (find-psne-intro)
+that eev defines some functions with names starting with `br'
+that are similar to `browse-url', and we saw in
+ (find-psne-intro \"the second way\")
+ (find-psne-intro \"1. Local copies of files from the internet\")
+ (find-psne-intro \"3. The new way: M-x brep\")
+how to create local copies of files; after downloading a local
+copy of, say,
+ http://www.gnu.org/software/emacs/emacs-paper.html
+into
+ $S/http/www.gnu.org/software/emacs/emacs-paper.html
+you can open the local copy by running `M-x browse-url', `M-x brg'
+or `M-x brff' on the \"file:///\" URL below,
+ file:///home/edrx/snarf/http/www.gnu.org/software/emacs/emacs-paper.html
-;;; _ _ __ _ _
-;;; __ _ _ _ __| (_) ___ / /_ _(_) __| | ___ ___
-;;; / _` | | | |/ _` | |/ _ \ / /\ \ / / |/ _` |/ _ \/ _ \
-;;; | (_| | |_| | (_| | | (_) / / \ V /| | (_| | __/ (_) |
-;;; \__,_|\__,_|\__,_|_|\___/_/ \_/ |_|\__,_|\___|\___/
-;;;
-;; «find-audiovideo-intro» (to ".find-audiovideo-intro")
-;; Skel: (find-intro-links "audiovideo")
+but note that the \"file:///\" URL has an \"edrx\" - my username
+- in the middle of the file name, so this only works without
+changes if you use \"edrx\" as your username...
-(defun find-audiovideo-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-audiovideo-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-audiovideo-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-audiovideo-intro\")
-More intros: (find-eev-quick-intro)
- (find-eev-intro)
- (find-videos-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
-Prerequisite:
- (find-pdf-like-intro)
-This intro is being rewritten.
+2. The `l' variants
+===================
+After creating `brg' and `brff' I created variants of them that
+would open the local copy of the URL at point instead of the
+original URL - or, more precisely, that would open the result of
+applying `ee-url-to-local-url' to the original URL. Try:
+ (ee-url-to-local-url
+ \"http://www.gnu.org/software/emacs/emacs-paper.html\")
+These variants were called `brgl' and `brffl' - I used the
+convention that the suffix `l' meant \"use the local copy\".
-1. Time offsets
-===============
-Links to audio and video files are similar to links to pdf-like
-documents, but instead of page numbers we use \"time offsets\" to
-refer to positions. Time offsets are strings like 1:23, 12:34, or
-1:23:45. The sexp hyperlinks below should all work if you have the
-files that they refer to, and if you have mpv and xterm installed:
- (find-audio \"/tmp/mysong.mp3\")
- (find-audio \"/tmp/mysong.mp3\" \"1:23\")
- (find-audio \"/tmp/mysong.mp3\" \"1:23\" \"comments are ignored\")
- (find-video \"/tmp/myvideo.mp4\")
- (find-video \"/tmp/myvideo.mp4\" \"1:23\")
- (find-video \"/tmp/myvideo.mp4\" \"1:23\" \"comments are ignored\")
+3. The `d' variants
+===================
+After creating `brgl' and `brffl' I realized that it would be
+easy to create variants of them that would work in dired mode.
+If we visit a directory - for example, this one,
-Note that they work by invoking an external player - mpv, by
-default - and its error messages appear here:
+ (find-fline \"$S/http/www.gnu.org/software/emacs/\")
- (find-ebuffer \"*Messages*\")
+and we put the point in a line with an HTML on it - for example,
+on the line with the \"emacs-paper.html\" - then typing `M-x
+brgd' there converts the full pathname of the file at point to a
+\"file:///\" URL, like this,
-[Video links:]
- (find-eev2020video \"6:25\" \"`find-video'\")
+ $S/http/www.gnu.org/software/emacs/emacs-paper.html
+ -> file:///home/edrx/snarf/http/www.gnu.org/software/emacs/emacs-paper.html
+and opens the resulting \"file:///\" url with `brg'.
+The suffix `d' means \"use the file in this line in dired\".
-2. `eev-avadj-mode'
-===================
-\"avadj-mode\" is a shorthand for \"audio/video adjust mode\".
-When `eev-avadj-mode' is active we get keys for adjusting time
-offsets quickly and for playing again the default audio or video
-file at a given time offset, all of this without moving the
-point. The keys are:
- M-- decrease the time offset by one second
- M-+ increase the time offset by one second
- M-= same as M-+, for convenience
- M-p play the default audio/video file at a time offset
-You can toggle eev-avadj-mode on and off with `M-x
-eev-avadj-mode', or with these sexps:
+4. `brxxx'-functions
+====================
+`browse-url' has several variants, with names like
+`browse-url-firefox' and `browse-url-chromium', that open the URL
+at point using specific programs. See:
- (eev-avadj-mode 0)
- (eev-avadj-mode)
+ (find-epackage 'browse-url)
+ (find-enode \"Browse-URL\")
-When it is on you will see an \"avadj\" at the mode line. Let's
-examine `M--' and `M-+' first. With eev-avadj-mode on, try typing
-several `M--'s and `M-+'s (or `M-='s) on the line below:
+We say that `brg', `brgl' and `brgd' are \"`brxxx'-functions\"
+with \"base function\" `find-googlechrome'; `brgl' is the `l' (or
+\"local\") variant, and `brgd' is the `d' (or \"dired\") variant;
+`brg' is sometimes called the \"remote\" variant.
- This time offset - 9:59 - will change
-Now, as an exercise, try to use `M--'s and `M-+'s/`M-='s, plus
-`M-h M-2' (`ee-duplicate-this-line') and other more standard
-editing commands, to convert this line
- (find-exampleaudio \"0:00\")
-into:
+5. `code-brurl'
+===============
+Remember that `code-c-d' generates lisp code and executes it, and
+that `find-code-c-d' generates the same lisp code as `code-c-d'
+but displays it instead of executing it; this was explained, with
+examples, here:
- (find-exampleaudio \"0:00\")
- (find-exampleaudio \"0:12\" \"blah\")
- (find-exampleaudio \"0:30\" \"bleh\")
+ (find-eev-quick-intro \"9.1. `code-c-d'\")
+ (find-eev-quick-intro \"9.1. `code-c-d'\" \"find-code-c-d\")
-That should give you an idea of how to index audio or video files
-- by creating elisp hyperlinks, with comments, to specific
-positions in them. Of course in a real-world situation we would
-execute these sexps occasionally to check if they are really
-pointing to the right places, and then make further adjustments;
-we are not doing that yet.
-
-The idea of a \"default audio/video file\" will be explained in
-section 4.4.
+Eev has a function called `code-brurl' that works like `code-c-d'
+and that creates several `brxxx'-functions with the same base
+function. To understand what the `code-brurl' sexp below does,
+ ;; From:
+ ;; (find-eev \"eev-brxxx.el\" \"code-brxxxs\")
+ ;; (find-eev \"eev-brxxx.el\" \"code-brxxxs\" \"brg\")
+ (code-brurl 'find-googlechrome :remote 'brg :local 'brgl :dired 'brgd)
+We run:
-3. The time-from-bol
-====================
-All the keys in eev-avadj-mode operate on the \"time-from-bol\"
-of the current line: the first occurrence, in the current line,
-of a string that looks like a time offset. Note that the search
-starts from the beginning of the line (\"-from-bol\"), and if
-there are several possibilities, the first one is chosen.
+ (find-code-brurl 'find-googlechrome :remote 'brg :local 'brgl :dired
'brgd)
-Remember that `M-e' has a variant that just highlights what would
-be executed, instead of evaluating a sexp:
+Note that the base function in this example is
+`find-googlechrome', that is a function that expects a URL.
- (find-eval-intro \"`M-0 M-e'\")
-`M-p' also has something like this: `M-0 M-p' highlights the
-time-from-bol and displays in the echo area the sexp that it
-would execute to invoke a player - instead of running that sexp.
-Try to evaluate these sexps:
- (code-audio \"sunwillset\" \"~/Zoe_Keating/Sun_Will_Set.ogg\")
- (find-sunwillset)
- ;; ^ don't worry if this fails - we are only calling it
- ;; to set `ee-audiovideo-last'
-and now try `M-0 M-p' on these lines:
+6. `code-brfile'
+================
+We saw how to create `brxxx'-functions using `find-googlechrome'
+as the base function; remember that `find-googlechrome' is a
+function that expects a URL.
- ;; 4:19 blah
- ;; 2:19
+If we download a local copy of a PDF, like we did here,
-For more realistic examples, see:
+ (find-pdf-like-intro \"2. Preparation\")
- (find-videos-intro)
+
https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
+ ->
$S/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
+then it makes sense to have a `brxxx'-function, called `brpdfl',
+that we can run on the \"https://\" URL above, and that will open
+the \"$S/https/\" file corresponding to the URL using
+`find-pdf-page'... but `find-pdf-page' is a function that expects
+a filename, not a URL, so `code-brurl' wouldn't work...
+What we want can be done by the sexp below:
+ ;; From:
+ ;; (find-eev \"eev-pdflike.el\" \"code-brxxxs\")
+ ;; (find-eev \"eev-pdflike.el\" \"code-brxxxs\" \"brpdfl\")
+ (code-brfile 'find-pdf-page :local 'brpdfl :dired 'brpdfd)
+To understand what it does, run:
-4. Short hyperlinks to audio and video files
-============================================
-This sexp
+ (find-code-brfile 'find-pdf-page :local 'brpdfl :dired 'brpdfd)
- (code-video \"ec2020video\" \"~/eev-videos/emacsconf2020.mp4\")
+and read the docstrings.
-defines a function `find-ec2020video'. The function `code-video'
-is similar to the functions `code-c-d' and `code-pdf-page', that
-we saw in:
+Note that in the previous section we had a \":remote 'brg\", that
+defined a remote variant. It doesn't make sense to apply
+`find-pdf-page' to a remote URL, so we don't have a \":remote\"
+here.
- (find-eev-quick-intro \"9. Shorter hyperlinks\")
- (find-pdf-like-intro \"7. Shorter hyperlinks to PDF files\")
-After running the `(code-video ...)' above, this sexp
- (find-ec2020video \"8:20\" \"defines several functions\")
-becomes a shorthand for:
+Old stuff:
+(TODO: revise it!)
- (find-video \"~/eev-videos/emacsconf2020.mp4\" \"8:20\")
-Note that the string \"defines several functions\" is treated as a
-comment, and is ignored - as in `find-pdf-page'.
-If we run the second sexp below instead of the first one,
- (code-video \"ec2020video\" \"~/eev-videos/emacsconf2020.mp4\")
- (find-code-video \"ec2020video\" \"~/eev-videos/emacsconf2020.mp4\")
+7. Old introduction
+===================
+We saw in
-we get a temporary buffer with the code that the
-sexp `(code-video ...)' would execute. Try it - and note that the
-definition of `find-ec2020video' in the temporary buffer
-contains a line like this:
+ (find-psne-intro)
+ (find-psne-intro \"M-x brep\")
+ (find-psne-intro \"M-x brfl\")
+ (find-psne-intro \"5. `browse-url' and friends\")
- (setq ee-audiovideo-last 'find-ec2020video)
+that we can use `M-x brep' to download local copies of files from
+the internet, and that `M-x brfl' on a URL runs `find-fline' on
+the local copy of that URL. `brep' and `brfl' are
+\"`browse-url'-like functions\" defined by eev; we will refer to
+them, and to other such functions, as \"brxxx-functions\". Every
+brxxx-function is an interactive interface to some \"base
+function\"; for `brep' and `brfl' we have:
-This line will be explained in the section 4.4.
+ brxxx-function base function
+ -------------- -------------
+ brep find-psne-links
+ brfl find-fline
-[Video links:]
- (find-eev2020video \"12:54\" \"This block is a kind of an index for that
video\")
- (find-eev2020video \"13:30\" \"we can index video tutorials\")
+What we will see here is how `code-brfile' and `code-brurl' -
+which are somewhat similar to `code-c-d' - can be used to define
+brxxx-functions from base functions.
-4.1. `find-extra-file-links'
-----------------------------
-The easiest way to produce `code-audio' and `code-video'
-hyperlinks is with `M-h M-e', that runs `find-extra-file-links'.
-This an experimental feature whose behavior may change soon, but
-here is how it works now.
+8. A first example
+==================
+Let's define two trivial base functions, one that expects a URL,
+and another one that expects a file name:
-If you run
+ (defun foo-url (url) (format \"Got URL: %s\" url))
+ (defun foo-file (filename) (format \"Got filename: %s\" filename))
- (find-extra-file-links \"/tmp/foo.mp4\")
+Note that they don't do much - they just return explanatory
+strings.
-you will get a temporary buffer whose first line is
+These two calls,
- ;; (find-extra-file-links \"/tmp/foo.mp4\" \"{c}\")
+ (code-brurl 'foo-url :remote 'brshowu :local 'brshowul)
+ (code-brfile 'foo-file :local 'brshowfl)
-and that contains several blocks like this one:
+define three brxxx-functions: `brshowu' and `brshowul' for the
+base function `foo-url', and `brshowfl' for the base function
+`foo-file'. You can inspect the definitions by running these
+sexps,
- ;; Links to a video file:
- ;; (find-video \"/tmp/foo.mp4\")
- (code-video \"{c}video\" \"/tmp/foo.mp4\")
- ;; (find-{c}video)
- ;; (find-{c}video \"0:00\")
+ (find-code-brurl 'foo-url :remote 'brshowu :local 'brshowul)
+ (find-code-brfile 'foo-file :local 'brshowfl)
-If you change the \"{c}\" in the first line to \"FOO\" and
-execute it you will get a buffer generated from the same
-template, but with all the \"{c}\"s replaced by \"FOO\"s. In that
-buffer the block above will become this:
+and you can test what `foo-url', `foo-file', `brshowu',
+`brshowul', and `brshowfl' do by running the sexps below.
- ;; Links to a video file:
- ;; (find-video \"/tmp/foo.mp4\")
- (code-video \"FOOvideo\" \"/tmp/foo.mp4\")
- ;; (find-FOOvideo)
- ;; (find-FOOvideo \"0:00\")
+ (foo-url \"http://a/b\")
+ => \"Got URL: http://a/b\"
-The typical way of using `find-extra-file-links' is from dired,
-by placing the cursor on the line of a file that you want to
-create links to, and then typing `M-h M-e'. `M-h M-e' is similar
-to the \"dired half\" of `M-h M-p' - see:
+ (foo-file \"/c/d/e/f\")
+ => \"Got filename: /c/d/e/f\"
- (find-pdf-like-intro \"9. Generating three pairs\")
- (find-pdf-like-intro \"9. Generating three pairs\" \"M-h M-p\")
+ (brshowu \"http://a/b\")
+ => `(foo-url \"http://a/b\") -> \"Got URL: http://a/b\"'
-but `M-h M-e' produces many more links.
+ (brshowul \"http://a/b\")
+ => `(foo-url \"file:///home/edrx/snarf/http/a/b\") ->
+ \"Got URL: file:///home/edrx/snarf/http/a/b\"'
-[Video links:]
- (find-eevtemplvideo \"28:12\" \"6. `find-here-links' and
`find-extra-file-links'\")
- (find-eevtemplvideo \"30:18\" \"`M-h M-e' runs `find-extra-file-links'\")
- (find-eevtemplvideo \"30:42\" \"here is an example in Lisp\")
- (find-eevtemplvideo \"31:06\" \"and I can change this {c}\")
- (find-eevtemplvideo \"31:22\" \"Let me show a more realistic example\")
- (find-eevtemplvideo \"31:28\" \"let's go to the directory with the video
file\")
- (find-eevtemplvideo \"31:45\" \"this file is a video file\")
+ (brshowfl \"http://a/b\")
+ => `(foo-file \"/home/edrx/snarf/http/a/b\") ->
+ \"Got filename: /home/edrx/snarf/http/a/b\"'
+Now let's go to what matters. Put the point on the URL below, and
+run `M-x brshowu', `M-x brshowul' and `M-x brshowfl':
+ http://a/b
+you will see that `brshowu', `brshowul', and `brshowfl' can be
+called interactively, and when they are called interactively they
+use as their argument either the URL around point, or something
+obtained from it - the local file name or a local URL associated
+to that URL.
-4.2. `eewrap-audiovideo'
-------------------------
-And older, and clumsier, way of creating
-If you type `M-V' (`eewrap-audiovideo') on a line containing a
-shorthand word and a file name of an audio or video file, for
-example, here,
- sunwillset ~/Zoe_Keating/Sun_Will_Set.ogg
+9. The conversions
+==================
+One underlying idea behind all this is that we have two
+conversion functions, one from URLs to file names, and another
+from (absolute) file names to URLs starting with \"file:///\".
+They work like this:
-you will get something like this:
+ http://a/b -> $S/http/a/b -> file:///home/edrx/snarf/http/a/b
+ /tmp/c -> file:///tmp/c
- ;; (find-fline \"~/Zoe_Keating/\")
- (code-audio \"sunwillset\" \"~/Zoe_Keating/Sun_Will_Set.ogg\")
- (code-video \"sunwillset\" \"~/Zoe_Keating/Sun_Will_Set.ogg\")
- ;; (find-sunwillset)
- ;; (find-sunwillset \"0:00\")
+try:
-you should delete the line with the wrong sexp by hand - in this
-case the wrong one is the one with `code-video', as we are
-working with a sound file - and execute the other one; this will
-define a function called `find-sunwillset', that plays the audio
-file with `find-audio'. Run this this sexp to inspect its code:
+ (ee-url-to-fname \"http://a/b\")
+ (ee-fname-to-url \"/tmp/c\")
+ (ee-url-to-local-url \"http://a/b\")
- (find-code-audio \"sunwillset\" \"/tmp/Zoe_Keating__Sun_Will_Set.ogg\")
+Now execute the sexps below (with `M-2 M-e') to examine the code
+that calls to `code-brurl' and `code-brfile' generate and
+execute:
-you will notice that running `find-sunwillset' sets a variable,
-with:
+ (find-code-brurl 'foo-url :remote 'brshowu :local 'brshowul)
+ (find-code-brfile 'foo-file :local 'brshowfl)
- (setq ee-audiovideo-last 'find-sunwillset)
-As we shall see soon, some operations play again the default
-audio or video file, starting from some given time offset. The
-default is always what is stored in `ee-audiovideo-last', and
-each call to a short hyperlink of the form `find-xxxaudio' or
-`find-xxxvideo' sets that variable.
-4.3. A demo
------------
-Here's some code to test `find-video' and `code-video'. Make sure
-that you have mpv installed, and run this escript block:
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- # http://www.youtube.com/watch?v=K6LmZ0A1s9U
- # http://angg.twu.net/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4
- mkdir ~/eev-videos/
- cd ~/eev-videos/
- wget -nc
http://angg.twu.net/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4
+10. Naming conventions for brxxx-functions
+==========================================
+By convention, each name for a brxxx-function is composed of a
+prefix, a stem, and a suffix. The prefix is always \"br\", the
+stem is a mnemonic for the base function, and the suffix is
+either \"\", \"l\", or \"d\", meaning:
-It will download a copy of a video from youtube; I prepared the
-.mp4 by running \"youtube-dl -f 18\" on the youtube URL and
-renaming the result.
+ \"\" - use the URL without changes
+ \"l\" - use the local copy
+ \"d\" - dired variation (see below)
-Then try:
+Here are the stems for some of the brxxx-functions defined by
+eev:
- (find-video \"~/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\")
- (code-video \"punchandjudyvideo\"
\"~/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\")
- (find-punchandjudyvideo)
- (find-punchandjudyvideo \"0:00\")
- (find-punchandjudyvideo \"0:10\" \"calls the baby\")
- (find-punchandjudyvideo \"0:40\" \"where's the baby\")
- (find-punchandjudyvideo \"1:04\" \"right position\")
- (find-punchandjudyvideo \"1:17\" \"he will sing the baby to sleep\")
- (find-punchandjudyvideo \"1:33\" \"1-2-3\")
- (find-punchandjudyvideo \"1:48\" \"baby downstairs\")
- (find-punchandjudyvideo \"3:12\" \"slaps\")
- (find-punchandjudyvideo \"3:50\" \"1-2-3\")
- (find-punchandjudyvideo \"4:34\" \"you keep an eye on mr Punch\")
- (find-punchandjudyvideo \"4:46\" \"hat\")
- (find-punchandjudyvideo \"5:03\" \"hat\")
- (find-punchandjudyvideo \"5:25\" \"did you see him?\")
- (find-punchandjudyvideo \"5:55\" \"clown\")
- (find-punchandjudyvideo \"6:14\" \"slaps\")
- (find-punchandjudyvideo \"6:52\" \"sausages\")
- (find-punchandjudyvideo \"7:24\" \"crocodile\")
- (find-punchandjudyvideo \"8:07\" \"crocodile + sausages\")
- (find-punchandjudyvideo \"8:32\" \"another scene\")
- (find-punchandjudyvideo \"8:39\" \"fight\")
- (find-punchandjudyvideo \"9:03\" \"clown\")
- (find-punchandjudyvideo \"9:45\" \"mr punch\")
+ Base function receives stem
+ ------------- -------- ----
+ find-psne-links URL \"ep\"
+ browse-url-firefox URL \"m\"
+ find-googlechrome URL \"g\"
+ find-w3m URL \"w\"
+ find-fline file name \"f\"
+ find-audio file name \"audio\"
+ find-video file name \"video\"
+ find-xpdf-page file name \"xpdf\"
+ find-evince-page file name \"evince\"
+ find-xdvi-page file name \"xdvi\"
+ find-djvu-page file name \"djvu\"
+ find-pdf-text file name \"pdftext\"
+ find-djvu-text file name \"djvutext\"
+In our example with `foo-url' and `foo-file' we had:
+ Base function receives stem
+ ------------- -------- ----
+ foo-url URL showu
+ foo-file file name showf
-4.4. The default audio/video file
----------------------------------
-One of the things that the function `find-punchandjudyvideo' does
-when executed is this:
- (setq ee-audiovideo-last 'find-punchandjudyvideo)
-It sets the \"default audio/video file\" - more precisely, it
-sets the global variable `ee-audiovideo-last' that indicate that
-the way to play again the \"default audio/video file\" is by
-running the function `find-punchandjudyvideo'.
-This is similar to what the `find-xxxtext' functions do - they
-store some information about the last PDF opened with a
-`find-xxxtext' function into global variables. See:
+11. Calling `code-brurl' and `code-brfile'
+==========================================
- (find-pdf-like-intro \"11. How `M-h M-p' guesses everything\")
- (find-pdf-like-intro \"11. How `M-h M-p' guesses everything\"
\"find-xxxtext\")
+ (code-brurl '<U-function>
+ :remote 'br<stem> :local 'br<stem>l :dired 'br<stem>d)
+ \\---------------/ \\---------------/
\\----------------/
+ optional optional optional
-and, for more technical details:
+ (code-brfile '<F-function> :local 'br<stem>l :dired 'br<stem>d)
+ \\---------------/ \\----------------/
+ optional optional
- (find-eev-quick-intro \"9.1. `code-c-d'\")
- (find-eev-quick-intro \"9.1. `code-c-d'\" \"find-code-c-d\")
- (find-code-video \"punchandjudyvideo\"
-
\"~/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\")
+This, like many other parts of eev, is a hack with a very concise
+calling syntax - so we will see an example first, and then
+dissect it to understand precisely how it works. If you are
+curious about the inspirations behind it, here they are:
-In section 2 we mentioned that the key `M-p' in `eev-avadj-mode'
-does this:
+ (find-code-c-d-intro)
+ (find-code-c-d-intro \"find-code-c-d\")
+ (find-code-c-d-intro \"Extra arguments\")
+ (find-enode \"Browse-URL\")
- M-p play the default audio/video file at a time offset
-Let's see in practice what this means. If we run these three
-sexps here,
- (code-video \"punchandjudyvideo\"
\"~/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\")
- (find-punchandjudyvideo \"1:17\" \"he will sing the baby to sleep\")
- (eev-avadj-mode 1)
+12. The dired variation
+=======================
-we will a) define `find-punchandjudyvideo', b) set the global
-variable `ee-audiovideo-last' to `find-punchandjudyvideo', c)
-turn `eev-avadj-mode' on. Now `M-p' should work! If you type
-`M-p' on any of the lines with timestamps below it will open the
-default audio/video file at that timestamp.
+In dired mode each line corresponds to a file
- 0:00
- 0:10 calls the baby
- 0:40 where's the baby
- 1:04 right position
- 1:17 he will sing the baby to sleep
- 1:33 1-2-3
- 1:48 baby downstairs
- 3:12 slaps
- 3:50 1-2-3
- 4:34 you keep an eye on mr Punch
- 4:46 hat
- 5:03 hat
- 5:25 did you see him?
- 5:55 clown
- 6:14 slaps
- 6:52 sausages
- 7:24 crocodile
- 8:07 crocodile + sausages
- 8:32 another scene
- 8:39 fight
- 9:03 clown
- 9:45 mr punch
+" rest)))
+;; (find-brxxx-intro)
-5. Passing options to mpv
-=========================
-By default mpv is called with just a few command-line options,
-besides the ones that tell it at what position to start playing -
-typically just these for videos,
+;;;
+;;; _ __ ___ _ __ ___
+;;; | '_ \/ __| '_ \ / _ \
+;;; | |_) \__ \ | | | __/
+;;; | .__/|___/_| |_|\___|
+;;; |_|
+;;
+;; «find-psne-intro» (to ".find-psne-intro")
+;; (find-TH "eev-article" "local-copies")
+;; (find-angg ".emacs" "brep")
+;; (find-eev "eev-browse-url.el" "find-psne-links")
+;; (find-eev "eev-browse-url.el" "brep")
- -fs -osdlevel 2
+(defun find-psne-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-psne-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-psne-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-psne-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.
-to make it run in full-screen mode with an on-screen display
-showing the current position, and no options for audio.
-If you want to change this you should set the variable
-`ee-mpv-video-options'. See:
- (find-efunction 'find-mpv-video)
- (find-evariable 'ee-mpv-video-options)
-Here is an example of changing `'ee-mpv-video-options' temporarily:
+We mentioned briefly in
- (defun find-mpv-rot90-video (fname &optional pos &rest rest)
- \"Like `find-mpv-video', but with the extra option '--video-rotate=90'.\"
- (interactive \"sFile name: \")
- (let ((ee-mpv-video-options
- (cons \"--video-rotate=90\" ee-mpv-video-options)))
- (find-mpv-video fname pos)))
+ (find-pdf-like-intro \"2. Preparation\")
+that there are two \"natural\" ways to store a local copy of a
+file from the internet... here we will discuss the second way, in
+which the conversion from URL to a local file name works like
+this:
+
https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
+ ->
$S/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
-6. Youtube-dl
-=============
-Videos at Youtube are identified by unique 11-char codes that are
-assigned to them when they are uploaded. We will call those 11-char
-codes \"hashes\", even though the term is not totally adequade in this
-case, and we will explain the main ideas considering the case of an
-imaginary video whose title is just TITLE, and whose hash is
-\"abcdefghijk\". The URL to access that video at Youtube would be this:
- http://www.youtube.com/watch?v=abcdefghijk
- \\---------/
- its hash
-If we execute this on a shell,
+1. Local copies of files from the internet
+==========================================
+Emacs knows how to fetch files from the internet, but for most
+purposes it is better to use local copies. Suppose that the
+environment variable $S is set to ~/snarf/; then running this
- cd /tmp/
- youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk'
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ mkdir -p $S/http/www.gnu.org/software/emacs/
+ cd $S/http/www.gnu.org/software/emacs/
+ wget http://www.gnu.org/software/emacs/emacs-paper.html
+ echo 'http://www.gnu.org/software/emacs/emacs-paper.html' >> ~/.psne.log
-then youtube-dl would download a local copy of the video; due to the
-option \"-t\" (\"--title\"), the name of the local copy would have both
-the title of the video and its hash, and, if the video is in MP4
-format, that would be
+ # (find-fline \"$S/http/www.gnu.org/software/emacs/emacs-paper.html\")
+ # (find-w3m \"$S/http/www.gnu.org/software/emacs/emacs-paper.html\")
- /tmp/TITLE-abcdefghijk.mp4.part
+creates a local copy of `emacs-paper.html' inside ~/snarf/http/
+and appends the URL to the file ~/.psne.log. The two lines in
+comments are hyperlinks to the local copy; The `find-fline' opens
+it as a file in the obvious way, and `find-w3m' opens it \"as
+HTML\", using a text-mode web browser called w3m that can be run
+either in standalone mode or inside Emacs; `find-w3m' uses w3m's
+Emacs interface, and it accepts extra arguments, which are
+treated as a pos-spec-list.
-during the download, and would be renamed to
- /tmp/TITLE-abcdefghijk.mp4
-as soon as the download is finished.
+2. The old way: psne
+====================
+A long time ago eev used to include a shell function called
+`psne' that ran all that with a single command. This:
+ psne http://www.gnu.org/software/emacs/emacs-paper.html
+would run the `mkdir', the `cd', the `wget' and the `echo' above.
+If psne were just a shell script then it wouldn't be able to
+change the current directory for the calling shell, so it had to
+be defined as shell function instead of a script, and the user
+had to patch his ~/.bashrc (or ~/.zshrc, or whatever) to install
+the definition for psne and make it available. That was VERY
+clumsy.
-6.1. Downloading a local copy
------------------------------
-Place the point at hash in the URL below,
+From now on we will use \"psne\" as a verb: to psne a URL means
+to download a local copy of it into the right place, change to
+its directory and save its name into the file \"~/.psne.log\".
- http://www.youtube.com/watch?v=abcdefghijk
-and run `M-x find-youtubedl-links'; `find-youtubedl-links' will use
-the hash at point as a default for one of its arguments, will run
-something equivalent to this sexp,
- (find-youtubedl-links nil nil \"abcdefghijk\")
-and will create a buffer like this:
+3. The new way: `M-x brep'
+==========================
+Try to run this:
- ___________________________________________________________________________
- |# (find-youtubedl-links \"/tmp/\" \"{title}\" \"abcdefghijk\" \"{ext-}\"
\"{stem}\") |
- |# (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
|
- | |
- |# (find-youtubedl-links \"~/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
|
- |# (find-youtubedl-links \"~/videos/tech/\" nil \"abcdefghijk\" nil
\"{stem}\") |
- |# (find-youtubedl-links \"/tmp/videos/\" nil \"abcdefghijk\" nil
\"{stem}\") |
- |# (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
|
- |# (find-efunction 'find-youtubedl-links) |
- | |
- | (eepitch-shell2) |
- | (eepitch-kill) |
- | (eepitch-shell2) |
- |# http://www.youtube.com/watch?v=abcdefghijk |
- |# http://www.youtube.com/watch?v=abcdefghijk#t=0m00s |
- |# http://www.youtube.com/watch?v=abcdefghijk#t=0h00m00s |
- |cd /tmp/ |
- |youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk' |
- | |
- |# youtube-dl -t -F 'http://www.youtube.com/watch?v=abcdefghijk' |
- |# youtube-dl -t -f 18 'http://www.youtube.com/watch?v=abcdefghijk' |
- | |
- |# (find-es \"video\" \"youtube-dl\")
|
- |# (find-fline \"/tmp/\" \"abcdefghijk\")
|
- |# (find-fline \"/tmp/\" \"{title}-abcdefghijk\")
|
- |# (find-fline \"/tmp/\" \"{title}-abcdefghijk{ext-}\")
|
- |# (find-video \"/tmp/{title}-abcdefghijk{ext-}\")
|
- |# (find-video \"/tmp/{title}-abcdefghijk{ext-}.part\")
|
- |# (code-video \"{stem}video\" \"/tmp/{title}-abcdefghijk{ext-}\")
|
- |# (code-video \"{stem}video\" \"/tmp/{title}-abcdefghijk{ext-}.part\")
|
- |# (find-{stem}video) |
- |# (find-{stem}video \"0:00\")
|
- | |
- |# Error messages (for the player): |
- |# (find-ebuffer \"*Messages*\")
|
- | |
- | |
- |--:**- *Elisp hyperlinks* All L1 (Fundamental)----------------------|
- |___________________________________________________________________________|
+ (find-psne-links \"http://www.gnu.org/software/emacs/emacs-paper.html\")
-which has LOTS of things... the part
+or, equivalently, put the point on the URL below and then run
+`M-x brep':
- (eepitch-shell2)
- (eepitch-kill)
- (eepitch-shell2)
- cd /tmp/
- youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk'
+ http://www.gnu.org/software/emacs/emacs-paper.html
-is obvious: it is an eepitch script that downloads a local copy
-of the video from Youtube.
+You will get a temporary buffer for psne-ing the URL above. It
+will contain a `mkdir', a `cd', a `wget' and an `echo', plus an
+eepitch block and some elisp hyperlinks, and it can be executed
+with `F8's. Moral of the story: the \"new\" way to download a
+local copy of a url is to put the point on it, then run `M-x
+brep', then execute the resulting e-script. This does not require
+any patching of rcfiles, as the shell-function version of `psne'
+used to do.
-6.2. Guessing the title and extension
--------------------------------------
-Let's simulate what would happen after the eepitch script above -
-Execute this:
+4. The environment variable $S
+==============================
+If when eev is loaded by Emacs the environment variable $S is
+unset, it will be set to a default value - namely, to the
+expansion of \"$HOME/snarf\". Processes started from Emacs, such
+as shells created with `eepitch-shell' or `find-sh', or external
+terminals created by sexps like
- (find-sh0 \"rm -v /tmp/TITLE-abcdefghijk*\")
- (find-sh0 \"echo > /tmp/TITLE-abcdefghijk.mp4.part\")
+ (find-bgprocess \"xterm\")
+ (find-bgprocess \"gnome-terminal\")
+ (find-bgprocess \"eterm\")
-Now use `M-2 M-e' to compare the buffers generated by two calls
-to `find-youtubedl-links' below:
+will then inherit that value. Try it:
- (find-youtubedl-links nil nil \"abcdefghijk\")
- (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\")
+ (getenv \"S\")
+ (find-sh0 \"echo $S\")
-In the second one we get a buffer where all occurrences
-of \"{title}\" have been substituted by \"TITLE\", and all
-occurrences of \"{ext-}\" by \".mp4\". What happened was that
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+echo $S
- (ee-youtubedl-guess* \"/tmp/\" \"abcdefghijk\")
- --> (\"/tmp/TITLE-abcdefghijk.mp4.part\")
+Try also to create an external shell not from Emacs - for
+example, from your window manager's list of available
+applications, or from a text-mode login - and run \"echo $S\"
+there: you will notice that $S is unset.
-did find files what that hash string in their names in the
-directory \"/tmp/\", and the function `ee-youtubedl-split' has
-picked up the first of these file names and has split it into
-components:
+Old versions of eev used to require the user to run a script that
+would patch his rcfiles (i.e., ~/.bashrc, ~/.zshrc, etc) to set
+$S on startup. That turned out to be unreliable - it was better
+to teach people how to distinguish those processes that inherit
+$S from Emacs from those that don't, and let the experts patch
+their rcfiles by hand.
- (ee-youtubedl-split \"/tmp/TITLE-abcdefghijk.mp4.part\")
- --> (\"/tmp/\" \"TITLE\" \"abcdefghijk\" \".mp4\" \".mp4.part\")
-The last of these components is what we will call the \"ext\" -
-the \"full extension\" - and the previous one is the \"ext-\" -
-the \"extension minus its optional `.part'\". The first three
-components are the \"dir\", the \"title\", and the \"hash\".
+5. `browse-url' and friends
+===========================
+If you place the point on the URL below
+ http://www.gnu.org/software/emacs/emacs-paper.html
+and run `M-x browse-url', Emacs will make an external browser
+visit the remote version of that URL. One (bad) way to visit the
+local copy of that URL is to modify the URL above by hand to
+adjust it to your value of $S, until you obtain something like
+this:
-6.3. The first lines regenerate the buffer
-------------------------------------------
-The arguments to `find-youtubedl-links' are:
+ file:///home/edrx/snarf/http/www.gnu.org/software/emacs/emacs-paper.html
- (find-youtubedl-links DIR TITLE HASH EXT- STEM)
+and then run `M-x browse-url' on it.
-and we just saw how `ee-youtubedl-guess*' and
-`ee-youtubedl-split' can be used to guess TITLE, EXT and EXT-
-from DIR and HASH.
+One - rather primitive - way of visiting the local copy of that
+URL with find-file is to modify the URL by hand, replacing its
+\"http://\" with n \"$S/http/\", and then visit that file. For
+example:
-All the arguments to `find-youtubedl-links' have defaults,
-that are used when the received arguments are nil:
+ http://www.gnu.org/software/emacs/emacs-paper.html
+ (find-fline \"$S/http/www.gnu.org/software/emacs/emacs-paper.html\")
- * when HASH is nil, use the youtube hash around point,
- or \"{hash}\" if none;
- * when DIR is nil, use the value of `ee-youtubedl-dir',
- or \"{dir}\" if none;
- * when TITLE or EXT- are nil use the guessing method described
- above, and when they fail use \"{title}\" or \"{ext-}\";
- * when STEM is nil, use \"{stem}\".
+If you put the point on the URL and run `M-x brfl' on it you will
+visit the local copy \"as a file\", with `find-file' /
+`find-fline'. Visiting URLs - or their local copies - is
+something that we do so frequently that we need ways to do that
+with few keystrokes, which is why `brfl' has a short - and
+cryptic - name. The conventions are:
-The first two lines in a `find-youtubedl-links' regenerate the
-buffer, and are usually equivalent to one another. In the buffer
-generated by:
+ \"br\" is the common prefix for all the browse-url-like
+ functions in eev,
+ \"f\" means to use `find-fline' (or, equivalently, `find-file'),
+ \"l\" is an optional suffix meaning to use the local copy.
- (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\")
+The details on how to create these \"brxxx functions\" are here:
-they are:
+ (find-brxxx-intro)
- (find-youtubedl-links \"/tmp/\" \"TITLE\" \"abcdefghijk\" \".mp4\"
\"{stem}\")
- (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
-The first one has only non-nil arguments - all the rules for
-guesses and defaults have been applied - where in the second one
-TITLE and EXT- are made nil.
-6.4. Selecting a directory
---------------------------
-The second block of lines in the `find-youtubedl-links' buffer
-are used to let we switch the directory quickly. If we just
-execute `M-x find-youtubedl-links' with the point on our example
-hash, or, equivalently, if we do this,
+6. `ee-flip-psne-ness'
+======================
+Converting a \"non-psne URL\" to a \"psne URL\" by hand, like this,
- (find-youtubedl-links nil nil \"abcdefghijk\")
+
https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
+ ->
$S/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
-you will see that the first two lines will be:
+is error-prone and boring.
- (find-youtubedl-links \"~/videos/\" \"{title}\" \"abcdefghijk\" \"{ext-}\"
\"{stem}\")
- (find-youtubedl-links \"~/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
+Eev implements a command to do that, that works in both directions -
+it is called `ee-flip-psne-ness', and it searches for the next
+non-psne-or-psne URL and it \"flips its psne-ness\": it converts
+non-psne URLs to psne URLs and psne URLs to non-psne URLs.
-which means that the guessing process didn't find a downloaded
-copy, as TITLE is \"{title}\" and EXT- is \"{ext-}\". That's because
-we are using \"~/videos/\" as the DIR, and our file
+To try it you will have to run this:
- /tmp/TITLE-abcdefghijk.mp4.part
+ (define-key eev-mode-map \"\\M-s\" 'ee-flip-psne-ness)
-is elsewhere, and the guessing functions only search in one
-directory...
+because most people prefer to use the key `M-s' for their other
+things. Then try it by putting the cursor here and typing `M-s' four
+times. Watch the four psne-nesses below flip.
-The second block contains these sexps,
+ https://tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
+ $S/https/tannerlectures.utah.edu/_resources/documents/a-to-z/c/Coetzee99.pdf
+ http://www.gnu.org/software/emacs/emacs-paper.html
+ $S/http/www.gnu.org/software/emacs/emacs-paper.html
- (find-youtubedl-links \"~/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
- (find-youtubedl-links \"~/videos/tech/\" nil \"abcdefghijk\" nil \"{stem}\")
- (find-youtubedl-links \"/tmp/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
- (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
-and if we execute the last one we set DIR to \"/tmp/\".
-To change the dir strings \"~/videos/\", \"~/videos/tech/\", \"/tmp/videos/\",
-\"/tmp/\", that appear in the second block of `find-youtubedl-links'
-buffers, change the variables `ee-youtubedl-dir', `ee-youtubedl-dir2',
-`ee-youtubedl-dir3', `ee-youtubedl-dir4.'
+7. A historical note
+====================
+I wrote the first versions of \"psne\" in the late 1990s. At that point
+I was using a program called \"snarf\" to fetch files from the internet
+using FTP and HTTP, and I thought that it was natural to store the
+files downloaded with snarf into the directory \"~/snarf/\". Later I
+changed from snarf to wget, but I kept the directory as \"~/snarf/\".
+I tried using several languages for the part that converted a url into
+a directory. I still have the notes from my attempts to use Tcl and
+Awk to do that - but at one point I managed to write a script in Perl
+that was good enough and I stuck to that.
+The shell function that I could call as
-7. `code-psnevideo'
-===================
-If we execute these two sexps
+ psne $S/http/www.gnu.org/software/emacs/emacs-paper.html
- (code-psnevideo
- \"punchandjudy\"
-
\"http://angg.twu.net/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\"
- \"K6LmZ0A1s9U\")
+and it would run the four steps in
- (find-punchandjudyvideo \"1:27\")
+ mkdir -p http://www.gnu.org/software/emacs/
+ cd http://www.gnu.org/software/emacs/
+ wget $S/http/www.gnu.org/software/emacs/emacs-paper.html
+ echo 'http://www.gnu.org/software/emacs/emacs-paper.html' >> ~/.psne.log
-the `find-punchandjudyvideo' link will work in a way that is
-quite different from the one in the demo in section 4.3. It will
-open a temporary buffer in which the first line is a sexp - that
-calls `find-psnevideo-links' - that regenerates that buffer, and
-the second line is a low-level sexp like this, but in a single
-line,
+was called \"psne\" because it used a Perl script to obtain the
+directory name, then it ran \"snarf\" (later \"wget\"), and it \"echo\"ed
+the URL to the end of a log file. So \"p-sn-e\".
- (find-video
-
\"$S/http/angg.twu.net/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\"
- \"1:27\")
-that will play the local copy of the video starting from 1:27;
-this means to to use this sexp to play the video
- (find-punchandjudyvideo \"1:27\")
-you have to first execute it with `M-e', then type the <down> key
-to go the second line, then type `M-e' again.
-The last part of that buffer will either be just a message saying
+" rest)))
- # Local file found. No need to download it again.
+;; (find-enode "Command Index" "browse-url")
+;; (find-efunction 'browse-url)
+;; (find-elnode "System Environment")
+;; (find-enode "Environment")
+;; (find-eevfile \"eev.el\" \"$HOME/snarf\")
-or this message here,
+;; (find-psne-intro)
- # Local file not found!
- # You need to run this:
-followed by an eepitch block that you can you use to download the
-MP4 file, like the one here:
- (find-psne-intro \"1. Local copies of files from the internet\")
-The middle of that buffer will have other things, like a link
-like this
- http://www.youtube.com/watch?v=K6LmZ0A1s9U#t=1m27s
-to the video on youtube, and a call to `code-video' that will
-redefine `find-punchandjudyvideo' to make it play the video
-directly instead of creating a temporary buffer containing a link
-to play it.
+;;; _ _ __ _ _
+;;; __ _ _ _ __| (_) ___ / /_ _(_) __| | ___ ___
+;;; / _` | | | |/ _` | |/ _ \ / /\ \ / / |/ _` |/ _ \/ _ \
+;;; | (_| | |_| | (_| | | (_) / / \ V /| | (_| | __/ (_) |
+;;; \__,_|\__,_|\__,_|_|\___/_/ \_/ |_|\__,_|\___|\___/
+;;;
+;; «find-audiovideo-intro» (to ".find-audiovideo-intro")
+;; Skel: (find-intro-links "audiovideo")
-7.1. `code-eevvideo'
---------------------
-`code-eevvideo' is a variant of `code-psnevideo' that lets us use
-shorter sexps. If we call this,
+(defun find-audiovideo-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-audiovideo-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-audiovideo-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-audiovideo-intro\")
+More intros: (find-eev-quick-intro)
+ (find-eev-intro)
+ (find-videos-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
- (code-eevvideo \"eevnav\" \"M-x-list-packages-eev-nav\")
-it will add \"http://angg.twu.net/eev-videos/\" and \".mp4\" to
-the string \"M-x-list-packages-eev-nav\" and then call
-`code-psnevideo'. As the third argument was omitted it will be
-set to \"{youtubeid}\". I am using `code-eevvideo' as an
-experiment: when I need to send a short screencast to someone who
-uses eev I record the video, upload it to
-http://angg.twu.net/eev-videos/ - not to youtube - and send to
-the person a pair of sexps like these:
- (code-eevvideo \"eevnav\" \"M-x-list-packages-eev-nav\" \"kxBjiUo88_U\")
- (find-eevnavvideo \"0:00\")
+Prerequisite:
+ (find-pdf-like-intro)
+This intro is being rewritten.
-7.2. `find-eevvideo-links'
---------------------------
-It may be simpler to explain `code-eevvideo' in another order,
-starting from the function `find-eevvideo-links' - that, as its
-name suggests, is a hyperlink to a temporary buffer containing
-elisp hyperlinks (plus some parts generated by templates). A sexp
-like
+1. Time offsets
+===============
+Links to audio and video files are similar to links to pdf-like
+documents, but instead of page numbers we use \"time offsets\" to
+refer to positions. Time offsets are strings like 1:23, 12:34, or
+1:23:45. The sexp hyperlinks below should all work if you have the
+files that they refer to, and if you have mpv and xterm installed:
- (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\")
+ (find-audio \"/tmp/mysong.mp3\")
+ (find-audio \"/tmp/mysong.mp3\" \"1:23\")
+ (find-audio \"/tmp/mysong.mp3\" \"1:23\" \"comments are ignored\")
+ (find-video \"/tmp/myvideo.mp4\")
+ (find-video \"/tmp/myvideo.mp4\" \"1:23\")
+ (find-video \"/tmp/myvideo.mp4\" \"1:23\" \"comments are ignored\")
-generates a temporary buffer whose first line follows the
-convention that \"the first line regenerates the buffer\", and
-its second line is a link like
+Note that they work by invoking an external player - mpv, by
+default - and its error messages appear here:
- (find-video \"$S/http/angg.twu.net/eev-videos/emacsconf2020.mp4\")
+ (find-ebuffer \"*Messages*\")
-that plays the local copy of the video (if it exists). That
-temporary buffer also contains several \"help sexps\" that point
-to parts of this intro, and also a part like
+[Video links:]
+ (find-eev2020video \"6:25\" \"`find-video'\")
- # URL, local file, and a link to the directory of the local file:
- # http://angg.twu.net/eev-videos/emacsconf2020.mp4
- # $S/http/angg.twu.net/eev-videos/emacsconf2020.mp4
- # (find-fline \"$S/http/angg.twu.net/eev-videos/\")
- # Youtube:
- # (kill-new \"http://www.youtube.com/watch?v=hOAqBc42Gg8\")
- # http://www.youtube.com/watch?v=hOAqBc42Gg8
-that tries (!) to explain clearly how the URL and the file name
-of the local copy were generated from the argument
-\"emacsconf2020\" to `find-eevvideo-links', and how the youtube
-URL was generated by the argument \"hOAqBc42Gg8\"; and the
-temporary buffer also contains a last part with a script to
-download the .mp4 file, and a help sexp that explains that.
-That temporary buffer also contains a pair of sexps like
+2. `eev-avadj-mode'
+===================
+\"avadj-mode\" is a shorthand for \"audio/video adjust mode\".
+When `eev-avadj-mode' is active we get keys for adjusting time
+offsets quickly and for playing again the default audio or video
+file at a given time offset, all of this without moving the
+point. The keys are:
- (code-video \"eev2020video\"
\"$S/http/angg.twu.net/eev-videos/emacsconf2020.mp4\")
- (find-eev2020video)
+ M-- decrease the time offset by one second
+ M-+ increase the time offset by one second
+ M-= same as M-+, for convenience
+ M-p play the default audio/video file at a time offset
-that are easy to understand - the first one defines
-`find-eev2020video' as a short link to play the local copy of the
-.mp4 file.
+You can toggle eev-avadj-mode on and off with `M-x
+eev-avadj-mode', or with these sexps:
-If you compare the temporary buffers generated by these two
-sexps,
+ (eev-avadj-mode 0)
+ (eev-avadj-mode)
- (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\")
- (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\" \"17:20\")
+When it is on you will see an \"avadj\" at the mode line. Let's
+examine `M--' and `M-+' first. With eev-avadj-mode on, try typing
+several `M--'s and `M-+'s (or `M-='s) on the line below:
-you will see that the second sexp adds a time offset \"17:20\"s
-at several places, and adds a \"#t=17m20s\"s at the end of each
-youtube URL. These sexps and URLs can be used for _communication_
-- for example, if I am chatting with someone on an IRC channel I
-can say \"watch this:\", and then send these two lines:
+ This time offset - 9:59 - will change
- (find-eev2020video \"17:20\")
- http://www.youtube.com/watch?v=hOAqBc42Gg8#t=17m20s
+Now, as an exercise, try to use `M--'s and `M-+'s/`M-='s, plus
+`M-h M-2' (`ee-duplicate-this-line') and other more standard
+editing commands, to convert this line
-If I take the
+ (find-exampleaudio \"0:00\")
- (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\")
+into:
-and change it to
+ (find-exampleaudio \"0:00\")
+ (find-exampleaudio \"0:12\" \"blah\")
+ (find-exampleaudio \"0:30\" \"bleh\")
- (code-eevvideo \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\")
+That should give you an idea of how to index audio or video files
+- by creating elisp hyperlinks, with comments, to specific
+positions in them. Of course in a real-world situation we would
+execute these sexps occasionally to check if they are really
+pointing to the right places, and then make further adjustments;
+we are not doing that yet.
-this `code-eevvideo' sexps defines, or redefines,
-`find-eev2020video', to a \"version for communication\", such
-that
+The idea of a \"default audio/video file\" will be explained in
+section 4.4.
- (find-eev2020video \"17:20\")
-runs
- (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\" \"17:20\")
-that generates a temporary buffer with all the stuff described
-above, instead of playing the video file right away - to play the
-video file you have to execute the sexp
+3. The time-from-bol
+====================
+All the keys in eev-avadj-mode operate on the \"time-from-bol\"
+of the current line: the first occurrence, in the current line,
+of a string that looks like a time offset. Note that the search
+starts from the beginning of the line (\"-from-bol\"), and if
+there are several possibilities, the first one is chosen.
- (find-video \"$S/http/angg.twu.net/eev-videos/emacsconf2020.mp4\" \"17:20\")
+Remember that `M-e' has a variant that just highlights what would
+be executed, instead of evaluating a sexp:
-in the second line of the temporary buffer.
+ (find-eval-intro \"`M-0 M-e'\")
-There are some examples of `find-eevvideo-links' sexps here:
+`M-p' also has something like this: `M-0 M-p' highlights the
+time-from-bol and displays in the echo area the sexp that it
+would execute to invoke a player - instead of running that sexp.
+Try to evaluate these sexps:
- (find-videos-intro \"2. Some `find-eevvideo-links'\")
+ (code-audio \"sunwillset\" \"~/Zoe_Keating/Sun_Will_Set.ogg\")
+ (find-sunwillset)
+ ;; ^ don't worry if this fails - we are only calling it
+ ;; to set `ee-audiovideo-last'
-At this moment I don't have variants of `find-eevvideo-links' and
-`code-eevvideo' that point to other sides - see the comments
-here:
+and now try `M-0 M-p' on these lines:
- (find-eev \"eev-tlinks.el\" \"hardcoded-paths\")
+ ;; 4:19 blah
+ ;; 2:19
+For more realistic examples, see:
+ (find-videos-intro)
-" pos-spec-list)))
-;; (find-audiovideo-intro)
+4. Short hyperlinks to audio and video files
+============================================
+This sexp
+ (code-video \"ec2020video\" \"~/eev-videos/emacsconf2020.mp4\")
+defines a function `find-ec2020video'. The function `code-video'
+is similar to the functions `code-c-d' and `code-pdf-page', that
+we saw in:
+ (find-eev-quick-intro \"9. Shorter hyperlinks\")
+ (find-pdf-like-intro \"7. Shorter hyperlinks to PDF files\")
-;;; _ _ _ _ _
-;;; _ __ ___ _ _| | |_(_)_ _(_)_ __ __| | _____ __
-;;; | '_ ` _ \| | | | | __| \ \ /\ / / | '_ \ / _` |/ _ \ \ /\ / /
-;;; | | | | | | |_| | | |_| |\ V V /| | | | | (_| | (_) \ V V /
-;;; |_| |_| |_|\__,_|_|\__|_| \_/\_/ |_|_| |_|\__,_|\___/ \_/\_/
-;;;
-;; «find-multiwindow-intro» (to ".find-multiwindow-intro")
-;; Skel: (find-intro-links "multiwindow")
+After running the `(code-video ...)' above, this sexp
-(defun find-multiwindow-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-multiwindow-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-multiwindow-intro)
-Source code: (find-efunction 'find-multiwindow-intro)
-More intros: (find-eev-quick-intro)
- (find-eev-intro)
- (find-eval-intro)
- (find-eepitch-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
+ (find-ec2020video \"8:20\" \"defines several functions\")
+becomes a shorthand for:
+ (find-video \"~/eev-videos/emacsconf2020.mp4\" \"8:20\")
+Note that the string \"defines several functions\" is treated as a
+comment, and is ignored - as in `find-pdf-page'.
-1. Introduction
-===============
-In many situations - for example, when we want to script a
-debugger, or to test programs that have to talk to one another,
-or to control several external machines simultaneously - the
-default window setup for eepitch, which is this,
+If we run the second sexp below instead of the first one,
- ____________________
- | | |
- | | |
- | script | shell |
- | | |
- | | |
- |__________|_________|
+ (code-video \"ec2020video\" \"~/eev-videos/emacsconf2020.mp4\")
+ (find-code-video \"ec2020video\" \"~/eev-videos/emacsconf2020.mp4\")
-is not enough; other setups, like these,
+we get a temporary buffer with the code that the
+sexp `(code-video ...)' would execute. Try it - and note that the
+definition of `find-ec2020video' in the temporary buffer
+contains a line like this:
- ______________________
- | | | _________________________
- | | shell A | | | |
- | |___________| | script | GDB |
- | script | | | | |
- | | shell B | |____________|____________|
- | |___________| | | |
- | | | | program | program |
- | | shell C | | I/O | source |
- |__________|___________| |____________|____________|
+ (setq ee-audiovideo-last 'find-ec2020video)
-may be necessary. Eev comes with a few _low-level_ tools for
-creating these setups; they are not very smart, but they should
-be easy to understand and to tweak - and I have the impression
-that ideas for good high-level tools will only come from
-practical experimentation.
+This line will be explained in the section 4.4.
+[Video links:]
+ (find-eev2020video \"12:54\" \"This block is a kind of an index for that
video\")
+ (find-eev2020video \"13:30\" \"we can index video tutorials\")
-2. `find-wset'
-==============
-Suppose that we are in a buffer A, and we want to create a window
-configuration with A at the left, and with the buffers B and C
-stacked on one another at the right. That is:
- ___________ ___________
- | | | | |
- | | | | B |
- | A | --> | A |_____|
- | | | | |
- | | | | C |
- |___________| |_____|_____|
-To do that from the keyboard we could type this:
+4.1. `find-extra-file-links'
+----------------------------
+The easiest way to produce `code-audio' and `code-video'
+hyperlinks is with `M-h M-e', that runs `find-extra-file-links'.
+This an experimental feature whose behavior may change soon, but
+here is how it works now.
- C-x 3 C-x o C-x b B RET C-x 2 C-x o C-x b C RET
+If you run
-You can try that here (the initial `C-x 1' is an extra, for
-convenience):
+ (find-extra-file-links \"/tmp/foo.mp4\")
- (eek \"C-x 1 ;; delete-other-windows
- C-x 3 ;; split-window-horizontally (left/right)
- C-x o ;; other-window (-> right)
- C-x b B RET ;; switch to the buffer `B'
- C-x 2 ;; split-window-vertically (upper/lower)
- C-x o ;; other-window (-> lower right)
- C-x b C RET ;; switch to the buffer `C'
- \")
+you will get a temporary buffer whose first line is
-We can write something equivalent to that as a `progn', in a way
-that makes it easy to replace later the `C-x b B RET' and the
-`C-x b C RET' by arbitrary sexp hyperlinks. We get:
+ ;; (find-extra-file-links \"/tmp/foo.mp4\" \"{c}\")
- (progn (eek \"C-x 1 C-x 3 C-x o\")
- (find-ebuffer \"B\")
- (eek \"C-x 2 C-x o\")
- (find-ebuffer \"C\")
- (eek \"C-x o\")
- )
+and that contains several blocks like this one:
-When I started to rewrite my window configurations into that form
-I realized that the `eek's were being used in a very limited way
-- they only invoked a very small repertoire of window commands,
-all of them starting with `C-x'. So maybe I should have an
-interpreter for a simple language of window commands and sexp
-hyperlinks, in the which window setup above could be expressed
-like this:
+ ;; Links to a video file:
+ ;; (find-video \"/tmp/foo.mp4\")
+ (code-video \"{c}video\" \"/tmp/foo.mp4\")
+ ;; (find-{c}video)
+ ;; (find-{c}video \"0:00\")
- '(\"13o\"
- (find-ebuffer \"B\")
- \"2o\"
- (find-ebuffer \"C\")
- \"o\"
- )
+If you change the \"{c}\" in the first line to \"FOO\" and
+execute it you will get a buffer generated from the same
+template, but with all the \"{c}\"s replaced by \"FOO\"s. In that
+buffer the block above will become this:
-`find-wset' supports something like that, but with all the window
-command strings collapsed into a single one, with \"_\"s meaning
-\"execute the next sexp from the sexp list\". The corresponding
-call to `find-wset' is:
+ ;; Links to a video file:
+ ;; (find-video \"/tmp/foo.mp4\")
+ (code-video \"FOOvideo\" \"/tmp/foo.mp4\")
+ ;; (find-FOOvideo)
+ ;; (find-FOOvideo \"0:00\")
- (find-wset \"13o_2o_o\" '(find-ebuffer \"B\") '(find-ebuffer \"C\"))
+The typical way of using `find-extra-file-links' is from dired,
+by placing the cursor on the line of a file that you want to
+create links to, and then typing `M-h M-e'. `M-h M-e' is similar
+to the \"dired half\" of `M-h M-p' - see:
-For the full list of supported window command characters - and
-how to extend it - see the source:
+ (find-pdf-like-intro \"9. Generating three pairs\")
+ (find-pdf-like-intro \"9. Generating three pairs\" \"M-h M-p\")
- (find-eev \"eev-multiwindow.el\")
+but `M-h M-e' produces many more links.
+[Video links:]
+ (find-eevtemplvideo \"28:12\" \"6. `find-here-links' and
`find-extra-file-links'\")
+ (find-eevtemplvideo \"30:18\" \"`M-h M-e' runs `find-extra-file-links'\")
+ (find-eevtemplvideo \"30:42\" \"here is an example in Lisp\")
+ (find-eevtemplvideo \"31:06\" \"and I can change this {c}\")
+ (find-eevtemplvideo \"31:22\" \"Let me show a more realistic example\")
+ (find-eevtemplvideo \"31:28\" \"let's go to the directory with the video
file\")
+ (find-eevtemplvideo \"31:45\" \"this file is a video file\")
-3. High-level words
-===================
-Very often we want to create window setups like
- _______________ _______________
- | | | | | |
- | | | | | B |
- | A | B | or | A |_______| ;
- | | | | | |
- | | | | | C |
- |_______|_______| |_______|_______|
-there are shorthands for that. If you run
+4.2. `eewrap-audiovideo'
+------------------------
+And older, and clumsier, way of creating
- (find-2a sexpA sexpB)
+If you type `M-V' (`eewrap-audiovideo') on a line containing a
+shorthand word and a file name of an audio or video file, for
+example, here,
-that will create a window setting like the one at the left above,
-initially with two copies of the current buffer, then will run
-sexpA at the window \"A\" and sexpB at the window \"B\", and
-finally will select the window \"A\", i.e., leave the cursor at
-the window at the left; this
+ sunwillset ~/Zoe_Keating/Sun_Will_Set.ogg
- (find-2b sexpA sexpB)
+you will get something like this:
-will do exactly the same as the `(find-2a ...)' above, but will
-select the window \"B\" - the one at the right - at the end of
-the process. For three-window settings we have these:
+ ;; (find-fline \"~/Zoe_Keating/\")
+ (code-audio \"sunwillset\" \"~/Zoe_Keating/Sun_Will_Set.ogg\")
+ (code-video \"sunwillset\" \"~/Zoe_Keating/Sun_Will_Set.ogg\")
+ ;; (find-sunwillset)
+ ;; (find-sunwillset \"0:00\")
- (find-3a sexpA sexpB sexpC)
- (find-3b sexpA sexpB sexpC)
- (find-3c sexpA sexpB sexpC)
+you should delete the line with the wrong sexp by hand - in this
+case the wrong one is the one with `code-video', as we are
+working with a sound file - and execute the other one; this will
+define a function called `find-sunwillset', that plays the audio
+file with `find-audio'. Run this this sexp to inspect its code:
-all three create the three-window setting at the right above,
-initially with all three windows displaying the current buffer,
-then run sexpA at the window \"A\", sexpB at the window \"B\",
-and sexpC at the window \"C\"; the difference is that find-3a
-selects the window \"A\", find-3b the window \"B\", find-3c the
-window \"C\".
+ (find-code-audio \"sunwillset\" \"/tmp/Zoe_Keating__Sun_Will_Set.ogg\")
+you will notice that running `find-sunwillset' sets a variable,
+with:
+ (setq ee-audiovideo-last 'find-sunwillset)
+As we shall see soon, some operations play again the default
+audio or video file, starting from some given time offset. The
+default is always what is stored in `ee-audiovideo-last', and
+each call to a short hyperlink of the form `find-xxxaudio' or
+`find-xxxvideo' sets that variable.
-4. Several eepitch targets
-==========================
-If we try to build a window setup like this one, with two eepitch
-targets, with just `find-wset', we will run into problems -
- ________________________
- | | |
- | | *shell* |
- | script |_____________|
- | | |
- | | *shell 2* |
- |__________|_____________|
-because `(eepitch-shell)' and `(eepitch-shell2)' try to create a
-shell buffer and put it in an _another_ window, not the one we
-are in... one solution is to call the `(eepitch-*)' sexps inside
-an `ee-here', like this:
+4.3. A demo
+-----------
+Here's some code to test `find-video' and `code-video'. Make sure
+that you have mpv installed, and run this escript block:
- (ee-here '(eepitch-shell))
- (ee-here '(eepitch-shell2))
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ # http://www.youtube.com/watch?v=K6LmZ0A1s9U
+ # http://angg.twu.net/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4
+ mkdir ~/eev-videos/
+ cd ~/eev-videos/
+ wget -nc
http://angg.twu.net/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4
-where `ee-here' is a hack that runs a sexp in a way that
-preserves the current window configuration, then switches the
-buffer in the current selected window to the current eepitch
-target. We can use this to create the window setting above,
+It will download a copy of a video from youtube; I prepared the
+.mp4 by running \"youtube-dl -f 18\" on the youtube URL and
+renaming the result.
- (find-wset \"13o2_o_o\"
- ' (ee-here '(eepitch-shell))
- ' (ee-here '(eepitch-shell2))
- )
+Then try:
-This is too long - and would make a very bad one-liner - but
-there are two shorthands. First, \"e\" is a variant of \"_\" that
-runs its sexp inside an `(ee-here ...) - so this is equivalent
-the thing above,
+ (find-video \"~/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\")
+ (code-video \"punchandjudyvideo\"
\"~/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\")
+ (find-punchandjudyvideo)
+ (find-punchandjudyvideo \"0:00\")
+ (find-punchandjudyvideo \"0:10\" \"calls the baby\")
+ (find-punchandjudyvideo \"0:40\" \"where's the baby\")
+ (find-punchandjudyvideo \"1:04\" \"right position\")
+ (find-punchandjudyvideo \"1:17\" \"he will sing the baby to sleep\")
+ (find-punchandjudyvideo \"1:33\" \"1-2-3\")
+ (find-punchandjudyvideo \"1:48\" \"baby downstairs\")
+ (find-punchandjudyvideo \"3:12\" \"slaps\")
+ (find-punchandjudyvideo \"3:50\" \"1-2-3\")
+ (find-punchandjudyvideo \"4:34\" \"you keep an eye on mr Punch\")
+ (find-punchandjudyvideo \"4:46\" \"hat\")
+ (find-punchandjudyvideo \"5:03\" \"hat\")
+ (find-punchandjudyvideo \"5:25\" \"did you see him?\")
+ (find-punchandjudyvideo \"5:55\" \"clown\")
+ (find-punchandjudyvideo \"6:14\" \"slaps\")
+ (find-punchandjudyvideo \"6:52\" \"sausages\")
+ (find-punchandjudyvideo \"7:24\" \"crocodile\")
+ (find-punchandjudyvideo \"8:07\" \"crocodile + sausages\")
+ (find-punchandjudyvideo \"8:32\" \"another scene\")
+ (find-punchandjudyvideo \"8:39\" \"fight\")
+ (find-punchandjudyvideo \"9:03\" \"clown\")
+ (find-punchandjudyvideo \"9:45\" \"mr punch\")
- (find-wset \"13o2eoeo\"
- '(eepitch-shell)
- '(eepitch-shell2)
- )
-Second, these things are useful enough to deserve a high-level
-word, so this is equivalent to:
- (find-3ee '(eepitch-shell) '(eepitch-shell2))
+4.4. The default audio/video file
+---------------------------------
+One of the things that the function `find-punchandjudyvideo' does
+when executed is this:
+ (setq ee-audiovideo-last 'find-punchandjudyvideo)
+It sets the \"default audio/video file\" - more precisely, it
+sets the global variable `ee-audiovideo-last' that indicate that
+the way to play again the \"default audio/video file\" is by
+running the function `find-punchandjudyvideo'.
+This is similar to what the `find-xxxtext' functions do - they
+store some information about the last PDF opened with a
+`find-xxxtext' function into global variables. See:
-5. Restarting eepitch targets
-=============================
-Sometimes we want to do the same as above, but restarting both
-eepitch targets, i.e., something like this:
+ (find-pdf-like-intro \"11. How `M-h M-p' guesses everything\")
+ (find-pdf-like-intro \"11. How `M-h M-p' guesses everything\"
\"find-xxxtext\")
- (find-3ee '(progn (eepitch-shell) (eepitch-kill) (eepitch-shell))
- '(progn (eepitch-shell2) (eepitch-kill) (eepitch-shell2))
- )
+and, for more technical details:
-There's a variant of `ee-here' that does that: `ee-here-reset'.
-For example,
+ (find-eev-quick-intro \"9.1. `code-c-d'\")
+ (find-eev-quick-intro \"9.1. `code-c-d'\" \"find-code-c-d\")
+ (find-code-video \"punchandjudyvideo\"
+
\"~/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\")
- (ee-here-reset '(eepitch-shell2))
+In section 2 we mentioned that the key `M-p' in `eev-avadj-mode'
+does this:
-is equivalent to:
+ M-p play the default audio/video file at a time offset
- (ee-here '(progn (eepitch-shell2) (eepitch-kill) (eepitch-shell2)))
+Let's see in practice what this means. If we run these three
+sexps here,
-and the letter \"E\" is a variant of \"e\" that uses
-`ee-here-reset' instead of `ee-here'; also, `find-3EE' is a
-variant of `find-3ee' that restarts both targets. Let's adapt
-this example,
+ (code-video \"punchandjudyvideo\"
\"~/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\")
+ (find-punchandjudyvideo \"1:17\" \"he will sing the baby to sleep\")
+ (eev-avadj-mode 1)
- (find-eepitch-intro \"3. Other targets\")
+we will a) define `find-punchandjudyvideo', b) set the global
+variable `ee-audiovideo-last' to `find-punchandjudyvideo', c)
+turn `eev-avadj-mode' on. Now `M-p' should work! If you type
+`M-p' on any of the lines with timestamps below it will open the
+default audio/video file at that timestamp.
-to make it show the two eepitch targets at once in a three-window
-settings. It becomes:
+ 0:00
+ 0:10 calls the baby
+ 0:40 where's the baby
+ 1:04 right position
+ 1:17 he will sing the baby to sleep
+ 1:33 1-2-3
+ 1:48 baby downstairs
+ 3:12 slaps
+ 3:50 1-2-3
+ 4:34 you keep an eye on mr Punch
+ 4:46 hat
+ 5:03 hat
+ 5:25 did you see him?
+ 5:55 clown
+ 6:14 slaps
+ 6:52 sausages
+ 7:24 crocodile
+ 8:07 crocodile + sausages
+ 8:32 another scene
+ 8:39 fight
+ 9:03 clown
+ 9:45 mr punch
- (find-3EE '(eepitch-shell) '(eepitch-python))
- (eepitch-shell)
-echo Hello... > /tmp/o
- (eepitch-python)
-print(open(\"/tmp/o\").read())
- (eepitch-shell)
-echo ...and bye >> /tmp/o
- (eepitch-python)
-print(open(\"/tmp/o\").read())
- Now compare:
- (eek \"C-x 1\")
- (find-3ee '(eepitch-shell) '(eepitch-python))
- (find-3EE '(eepitch-shell) '(eepitch-python))
-6. Non-trivial examples
-=======================
-See:
+5. Passing options to mpv
+=========================
+By default mpv is called with just a few command-line options,
+besides the ones that tell it at what position to start playing -
+typically just these for videos,
- (find-eev-quick-intro \"6.2. Other targets\")
- (find-eev-quick-intro \"6.2. Other targets\" \"(find-3EE\")
- (find-rcirc-intro \"1. The example that I use in workshops\")
- (find-prepared-intro \"3. An `ee' for Python\")
- (find-prepared-intro \"4. `eepy'\")
+ -fs -osdlevel 2
-The examples with `find-3EE' were created using `M-#', as
-explained in the next section.
+to make it run in full-screen mode with an on-screen display
+showing the current position, and no options for audio.
+If you want to change this you should set the variable
+`ee-mpv-video-options'. See:
+ (find-efunction 'find-mpv-video)
+ (find-evariable 'ee-mpv-video-options)
+Here is an example of changing `'ee-mpv-video-options' temporarily:
-7. Eepitch blocks for two targets
-=================================
-An eepitch script with two targets uses several different kinds
-of red star lines - `(eepitch-target1)', `(eepitch-target2)',
-`(find-3EE ...)', `(find-3ee ...)', etc. We don't want to have to
-type all those by hand, so there is a hack similar to `M-T' that
-generates all those kinds from just \"target1\" and \"target2\"
-to let us just copy around the sexps we need.
+ (defun find-mpv-rot90-video (fname &optional pos &rest rest)
+ \"Like `find-mpv-video', but with the extra option '--video-rotate=90'.\"
+ (interactive \"sFile name: \")
+ (let ((ee-mpv-video-options
+ (cons \"--video-rotate=90\" ee-mpv-video-options)))
+ (find-mpv-video fname pos)))
-This key binding for this hack is `meta-shift-3' - that Emacs
-sees as `M-#' - but it is disabled by default. To enable it, do
-this:
- ;; See: (find-eevfile \"eev-mode.el\" \"eewrap-two-eepitches\")
- (define-key eev-mode-map \"\\M-#\" 'eewrap-two-eepitches)
-Now compare the result of typing `M-T' here,
-python
-with the result of typing `M-#' on this line,
+6. Youtube-dl
+=============
+Videos at Youtube are identified by unique 11-char codes that are
+assigned to them when they are uploaded. We will call those 11-char
+codes \"hashes\", even though the term is not totally adequade in this
+case, and we will explain the main ideas considering the case of an
+imaginary video whose title is just TITLE, and whose hash is
+\"abcdefghijk\". The URL to access that video at Youtube would be this:
-shell python
+ http://www.youtube.com/watch?v=abcdefghijk
+ \\---------/
+ its hash
-which yield this:
+If we execute this on a shell,
- (find-3EE '(eepitch-shell) '(eepitch-python))
- (find-3ee '(eepitch-shell) '(eepitch-python))
- (eepitch-shell)
- (eepitch-python)
+ cd /tmp/
+ youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk'
-Remember that The line with `find-3EE' restart the two targets,
-and the line with `find-3ee' just recreates the window setting
-with the two targets but without restarting them; so the line
-with `find-3EE' sort of works as two `eepitch-kill's.
+then youtube-dl would download a local copy of the video; due to the
+option \"-t\" (\"--title\"), the name of the local copy would have both
+the title of the video and its hash, and, if the video is in MP4
+format, that would be
+ /tmp/TITLE-abcdefghijk.mp4.part
+during the download, and would be renamed to
+ /tmp/TITLE-abcdefghijk.mp4
-8. Adding support for new characters in `find-wset'
-===================================================
-The standard characters supported by `find-wset' are these:
+as soon as the download is finished.
- char action key
- ---- ---------------------------- ---------
- `1' `delete-other-windows' (C-x C-1)
- `2' `split-window-vertically' (C-x C-2)
- `3' `split-window-horizontally' (C-x C-3)
- `s' `split-window-sensibly'
- `o' `other-window' (C-x o)
- `+' `balance-windows' (C-x +)
- `_' execute the next sexp
-but the action of each one is defined in a different function,
-and to add support for a new character, say, `=', we just need to
-define a function with the right name - in this case,
-`find-wset-='.
-The source code is simple enough, so take a look:
- (find-eev \"eev-multiwindow.el\" \"find-wset-_\")
+6.1. Downloading a local copy
+-----------------------------
+Place the point at hash in the URL below,
-" pos-spec-list)))
+ http://www.youtube.com/watch?v=abcdefghijk
-;; (find-multiwindow-intro)
+and run `M-x find-youtubedl-links'; `find-youtubedl-links' will use
+the hash at point as a default for one of its arguments, will run
+something equivalent to this sexp,
+ (find-youtubedl-links nil nil \"abcdefghijk\")
+and will create a buffer like this:
-;;; _
-;;; _ __ ___(_)_ __ ___
-;;; | '__/ __| | '__/ __|
-;;; | | | (__| | | | (__
-;;; |_| \___|_|_| \___|
-;;;
-;; «find-rcirc-intro» (to ".find-rcirc-intro")
-;; Skel: (find-intro-links "rcirc")
+ ___________________________________________________________________________
+ |# (find-youtubedl-links \"/tmp/\" \"{title}\" \"abcdefghijk\" \"{ext-}\"
\"{stem}\") |
+ |# (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
|
+ | |
+ |# (find-youtubedl-links \"~/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
|
+ |# (find-youtubedl-links \"~/videos/tech/\" nil \"abcdefghijk\" nil
\"{stem}\") |
+ |# (find-youtubedl-links \"/tmp/videos/\" nil \"abcdefghijk\" nil
\"{stem}\") |
+ |# (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
|
+ |# (find-efunction 'find-youtubedl-links) |
+ | |
+ | (eepitch-shell2) |
+ | (eepitch-kill) |
+ | (eepitch-shell2) |
+ |# http://www.youtube.com/watch?v=abcdefghijk |
+ |# http://www.youtube.com/watch?v=abcdefghijk#t=0m00s |
+ |# http://www.youtube.com/watch?v=abcdefghijk#t=0h00m00s |
+ |cd /tmp/ |
+ |youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk' |
+ | |
+ |# youtube-dl -t -F 'http://www.youtube.com/watch?v=abcdefghijk' |
+ |# youtube-dl -t -f 18 'http://www.youtube.com/watch?v=abcdefghijk' |
+ | |
+ |# (find-es \"video\" \"youtube-dl\")
|
+ |# (find-fline \"/tmp/\" \"abcdefghijk\")
|
+ |# (find-fline \"/tmp/\" \"{title}-abcdefghijk\")
|
+ |# (find-fline \"/tmp/\" \"{title}-abcdefghijk{ext-}\")
|
+ |# (find-video \"/tmp/{title}-abcdefghijk{ext-}\")
|
+ |# (find-video \"/tmp/{title}-abcdefghijk{ext-}.part\")
|
+ |# (code-video \"{stem}video\" \"/tmp/{title}-abcdefghijk{ext-}\")
|
+ |# (code-video \"{stem}video\" \"/tmp/{title}-abcdefghijk{ext-}.part\")
|
+ |# (find-{stem}video) |
+ |# (find-{stem}video \"0:00\")
|
+ | |
+ |# Error messages (for the player): |
+ |# (find-ebuffer \"*Messages*\")
|
+ | |
+ | |
+ |--:**- *Elisp hyperlinks* All L1 (Fundamental)----------------------|
+ |___________________________________________________________________________|
-(defun find-rcirc-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-rcirc-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-rcirc-intro)
-Source code: (find-efunction 'find-rcirc-intro)
-More intros: (find-eev-quick-intro)
- (find-eev-intro)
- (find-eval-intro)
- (find-eepitch-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
+which has LOTS of things... the part
+ (eepitch-shell2)
+ (eepitch-kill)
+ (eepitch-shell2)
+ cd /tmp/
+ youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk'
+is obvious: it is an eepitch script that downloads a local copy
+of the video from Youtube.
-Recent versions with Emacs come with two IRC clients built-in:
-Rcirc and ERC. I never understood ERC well enough, and I found
-rcirc quite easy to understand and to hack, so eev has some
-support for rcirc (and no support for ERC).
- (find-node \"(rcirc)Top\")
- (find-node \"(erc)Top\")
-The eev support for rcirc consists mainly of three high-level
-functions that connect to Freenode (the IRC server where most
-discussion of free software projects USED TO happen), and three
-high-level functions that connect to LiberaChat (the IRC server
-where most discussion of free software projects were moved to).
-These functions are called:
- `find-freenode', `find-freenode-2a' and `find-freenode-3a',
- `find-libera', `find-libera-2a' and `find-libera-3a'.
-
-For a good explanation of what IRC is, see:
-
- http://www.irchelp.org/faq/new2irc.html
+6.2. Guessing the title and extension
+-------------------------------------
+Let's simulate what would happen after the eepitch script above -
+Execute this:
+ (find-sh0 \"rm -v /tmp/TITLE-abcdefghijk*\")
+ (find-sh0 \"echo > /tmp/TITLE-abcdefghijk.mp4.part\")
+Now use `M-2 M-e' to compare the buffers generated by two calls
+to `find-youtubedl-links' below:
+ (find-youtubedl-links nil nil \"abcdefghijk\")
+ (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\")
-1. The example that I use in workshops
-======================================
-Let's start with an example. In
+In the second one we get a buffer where all occurrences
+of \"{title}\" have been substituted by \"TITLE\", and all
+occurrences of \"{ext-}\" by \".mp4\". What happened was that
- (setq rcirc-default-nick \"hakuryo\")
- (setq ee-libera-ichannels \"#eev\")
- (find-libera-3a \"#eev\")
+ (ee-youtubedl-guess* \"/tmp/\" \"abcdefghijk\")
+ --> (\"/tmp/TITLE-abcdefghijk.mp4.part\")
-the first sexp tells rcirc to use the nickname \"hakuryo\" when
-connecting to an IRC server; the second sets the set of \"initial
-channels\" on LiberaChat to just one channel, #eev - a channel
-that is usually empty, but that doesn't require authentication;
-the third sexp is a \"sexp hyperlink to the LiberaChat channel
-#eev\". The third sexp:
+did find files what that hash string in their names in the
+directory \"/tmp/\", and the function `ee-youtubedl-split' has
+picked up the first of these file names and has split it into
+components:
- 1) creates a window setting like this,
+ (ee-youtubedl-split \"/tmp/TITLE-abcdefghijk.mp4.part\")
+ --> (\"/tmp/\" \"TITLE\" \"abcdefghijk\" \".mp4\" \".mp4.part\")
- _________________________
- | | |
- | | LiberaChat |
- | | server |
- | | messages |
- | current |_____________|
- | buffer | |
- | | #eev |
- | | channel |
- | | |
- |___________|_____________|
+The last of these components is what we will call the \"ext\" -
+the \"full extension\" - and the previous one is the \"ext-\" -
+the \"extension minus its optional `.part'\". The first three
+components are the \"dir\", the \"title\", and the \"hash\".
- 2) tells rcirc to connect to LiberaChat and to the channel #eev
- in it,
- 3) makes the window at the left - window \"A\" in the
- terminology of eev-multiwindow.el - the active window. See:
- (find-multiwindow-intro \"3. High-level words\")
- (find-multiwindow-intro \"3. High-level words\" \"find-3a\")
-The connection process takes time - about 20 seconds at my
-machine - but you will be able to see in window \"B\" the server
-messages as they appear, and in window \"C\" the messages of the
-#eev channel. You can then use the window \"C\" to interact with
-the other users in #eev, and to experiment with commands. See:
+6.3. The first lines regenerate the buffer
+------------------------------------------
+The arguments to `find-youtubedl-links' are:
- (find-rcircnode \"Internet Relay Chat\" \"Once you have joined a channel\")
- (find-rcircnode \"Getting started with rcirc\" \"To talk in a channel\")
- (find-rcircnode \"rcirc commands\" \"/join #emacs\")
+ (find-youtubedl-links DIR TITLE HASH EXT- STEM)
+and we just saw how `ee-youtubedl-guess*' and
+`ee-youtubedl-split' can be used to guess TITLE, EXT and EXT-
+from DIR and HASH.
+All the arguments to `find-youtubedl-links' have defaults,
+that are used when the received arguments are nil:
+ * when HASH is nil, use the youtube hash around point,
+ or \"{hash}\" if none;
+ * when DIR is nil, use the value of `ee-youtubedl-dir',
+ or \"{dir}\" if none;
+ * when TITLE or EXT- are nil use the guessing method described
+ above, and when they fail use \"{title}\" or \"{ext-}\";
+ * when STEM is nil, use \"{stem}\".
-2. The two-window setting
-=========================
-Try this:
+The first two lines in a `find-youtubedl-links' regenerate the
+buffer, and are usually equivalent to one another. In the buffer
+generated by:
- (find-libera-2a \"#eev\")
+ (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\")
-It creates a window setting like
+they are:
- _________ ________
- | | |
- | | |
- | current | irc |
- | buffer | buffer |
- | | |
- |_________|________|
+ (find-youtubedl-links \"/tmp/\" \"TITLE\" \"abcdefghijk\" \".mp4\"
\"{stem}\")
+ (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
-which is nice for when you don't want to follow the irc server
-messages.
+The first one has only non-nil arguments - all the rules for
+guesses and defaults have been applied - where in the second one
+TITLE and EXT- are made nil.
+6.4. Selecting a directory
+--------------------------
+The second block of lines in the `find-youtubedl-links' buffer
+are used to let we switch the directory quickly. If we just
+execute `M-x find-youtubedl-links' with the point on our example
+hash, or, equivalently, if we do this,
-3. Tracking activity
-====================
-TODO: explain this:
+ (find-youtubedl-links nil nil \"abcdefghijk\")
- (find-rcircnode \"Channels\" \"M-x rcirc-track-minor-mode\")
+you will see that the first two lines will be:
-and how to use it as a one-window setting. Also:
+ (find-youtubedl-links \"~/videos/\" \"{title}\" \"abcdefghijk\" \"{ext-}\"
\"{stem}\")
+ (find-youtubedl-links \"~/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
- (find-efunctiondescr 'rcirc-track-minor-mode)
- (find-efunction 'rcirc-track-minor-mode)
- (find-evariable 'rcirc-track-minor-mode-map)
- (find-ekeymapdescr rcirc-track-minor-mode-map)
+which means that the guessing process didn't find a downloaded
+copy, as TITLE is \"{title}\" and EXT- is \"{ext-}\". That's because
+we are using \"~/videos/\" as the DIR, and our file
- (find-efunctiondescr 'rcirc-next-active-buffer)
- (find-efunction 'rcirc-next-active-buffer)
+ /tmp/TITLE-abcdefghijk.mp4.part
- (global-set-key [f2] 'rcirc-next-active-buffer)
+is elsewhere, and the guessing functions only search in one
+directory...
- (find-eev \"eev-elinks.el\" \"find-esetkey-links\")
- (find-eev \"eev-elinks.el\" \"find-esetkey-links\" \"video\")
- (find-esetkey-links (kbd \"<f2>\") 'rcirc-next-active-buffer)
+The second block contains these sexps,
+ (find-youtubedl-links \"~/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
+ (find-youtubedl-links \"~/videos/tech/\" nil \"abcdefghijk\" nil \"{stem}\")
+ (find-youtubedl-links \"/tmp/videos/\" nil \"abcdefghijk\" nil \"{stem}\")
+ (find-youtubedl-links \"/tmp/\" nil \"abcdefghijk\" nil \"{stem}\")
+and if we execute the last one we set DIR to \"/tmp/\".
+To change the dir strings \"~/videos/\", \"~/videos/tech/\", \"/tmp/videos/\",
+\"/tmp/\", that appear in the second block of `find-youtubedl-links'
+buffers, change the variables `ee-youtubedl-dir', `ee-youtubedl-dir2',
+`ee-youtubedl-dir3', `ee-youtubedl-dir4.'
-4. Commands with very short names
-=================================
-We can apply this idea
- (find-eev-quick-intro \"7.4. Commands with very short names\")
- (find-eev-quick-intro \"7.4. Commands with very short names\" \"(defun c
()\")
-to rcirc. If you connect occasionally to the channels #eev,
-#emacs, #git and #ruby, you can run this, or put these lines in
-your .emacs:
- (setq rcirc-default-nick \"hakuryo\")
- (defun e2 () (interactive) (find-libera-2a \"#eev\"))
- (defun e3 () (interactive) (find-libera-3a \"#eev\"))
- (defun m2 () (interactive) (find-libera-2a \"#emacs\"))
- (defun m3 () (interactive) (find-libera-3a \"#emacs\"))
- (defun g2 () (interactive) (find-libera-2a \"#git\"))
- (defun g3 () (interactive) (find-libera-3a \"#git\"))
- (defun r2 () (interactive) (find-libera-2a \"#ruby\"))
- (defun r3 () (interactive) (find-libera-3a \"#ruby\"))
+7. `code-psnevideo'
+===================
+If we execute these two sexps
+ (code-psnevideo
+ \"punchandjudy\"
+
\"http://angg.twu.net/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\"
+ \"K6LmZ0A1s9U\")
+ (find-punchandjudyvideo \"1:27\")
-5. `find-libera-links'
-======================
-You can generate lines like the ones above by running
-`find-libera-links'. For example:
+the `find-punchandjudyvideo' link will work in a way that is
+quite different from the one in the demo in section 4.3. It will
+open a temporary buffer in which the first line is a sexp - that
+calls `find-psnevideo-links' - that regenerates that buffer, and
+the second line is a low-level sexp like this, but in a single
+line,
- (find-libera-links \"e\" \"#eev\")
- (find-libera-links \"r\" \"#ruby\")
+ (find-video
+
\"$S/http/angg.twu.net/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4\"
+ \"1:27\")
+that will play the local copy of the video starting from 1:27;
+this means to to use this sexp to play the video
+ (find-punchandjudyvideo \"1:27\")
-6. Other servers
-================
-TODO: explain how to use find-rcirc-buffer and how to adapt
-find-libera-* to other servers. Example:
+you have to first execute it with `M-e', then type the <down> key
+to go the second line, then type `M-e' again.
- (find-rcirc-buffer-2a \"irc.debian.org\" \"#debian-live\" nil
\"#debian-live\")
- (find-rcirc-buffer-3a \"irc.debian.org\" \"#debian-live\" nil
\"#debian-live\")
+The last part of that buffer will either be just a message saying
-See:
+ # Local file found. No need to download it again.
- (find-eev \"eev-rcirc.el\" \"find-libera\")
+or this message here,
-" pos-spec-list)))
+ # Local file not found!
+ # You need to run this:
-;; (find-rcirc-intro)
+followed by an eepitch block that you can you use to download the
+MP4 file, like the one here:
+ (find-psne-intro \"1. Local copies of files from the internet\")
+The middle of that buffer will have other things, like a link
+like this
+ http://www.youtube.com/watch?v=K6LmZ0A1s9U#t=1m27s
+to the video on youtube, and a call to `code-video' that will
+redefine `find-punchandjudyvideo' to make it play the video
+directly instead of creating a temporary buffer containing a link
+to play it.
-;;; _ _ _
-;;; | |_ ___ _ __ ___ _ __ | | __ _| |_ ___ ___
-;;; | __/ _ \ '_ ` _ \| '_ \| |/ _` | __/ _ \/ __|
-;;; | || __/ | | | | | |_) | | (_| | || __/\__ \
-;;; \__\___|_| |_| |_| .__/|_|\__,_|\__\___||___/
-;;; |_|
-;;
-;; «find-templates-intro» (to ".find-templates-intro")
-;; Skel: (find-intro-links "templates")
-(defun find-templates-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-templates-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-templates-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-templates-intro\")
-More intros: (find-eev-quick-intro)
- (find-escripts-intro)
- (find-links-conv-intro)
- (find-eev-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
+7.1. `code-eevvideo'
+--------------------
+`code-eevvideo' is a variant of `code-psnevideo' that lets us use
+shorter sexps. If we call this,
+ (code-eevvideo \"eevnav\" \"M-x-list-packages-eev-nav\")
-This intro is being rewritten!
-The prerequisites for understand this are:
- (find-elisp-intro)
- (find-links-conv-intro \"3. Classification\")
+it will add \"http://angg.twu.net/eev-videos/\" and \".mp4\" to
+the string \"M-x-list-packages-eev-nav\" and then call
+`code-psnevideo'. As the third argument was omitted it will be
+set to \"{youtubeid}\". I am using `code-eevvideo' as an
+experiment: when I need to send a short screencast to someone who
+uses eev I record the video, upload it to
+http://angg.twu.net/eev-videos/ - not to youtube - and send to
+the person a pair of sexps like these:
+ (code-eevvideo \"eevnav\" \"M-x-list-packages-eev-nav\" \"kxBjiUo88_U\")
+ (find-eevnavvideo \"0:00\")
-1. Introduction
-===============
-In dec/2019 I sent this e-mail to the eev mailing list:
- https://lists.gnu.org/archive/html/eev/2019-12/msg00001.html
+7.2. `find-eevvideo-links'
+--------------------------
+It may be simpler to explain `code-eevvideo' in another order,
+starting from the function `find-eevvideo-links' - that, as its
+name suggests, is a hyperlink to a temporary buffer containing
+elisp hyperlinks (plus some parts generated by templates). A sexp
+like
-It was a kind of a call for help. It contained a very brief
-explanation of how the \"templated\" functions of eev, like
-`find-ekey-links' and `find-latex-links', are implemented, and
-showed how people can write their own templated functions as
-quick hacks.
+ (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\")
-If you want to learn how to _use_ templated functions, start by:
+generates a temporary buffer whose first line follows the
+convention that \"the first line regenerates the buffer\", and
+its second line is a link like
- (find-eev-quick-intro \"4.2. `find-ekey-links' and friends\")
- (find-eev-quick-intro \"7.5. `find-latex-links'\")
+ (find-video \"$S/http/angg.twu.net/eev-videos/emacsconf2020.mp4\")
-If you want to look at the source code of the existing templated
-functions, take a look at:
+that plays the local copy of the video (if it exists). That
+temporary buffer also contains several \"help sexps\" that point
+to parts of this intro, and also a part like
- (find-eev \"eev-elinks.el\")
- (find-eev \"eev-tlinks.el\")
+ # URL, local file, and a link to the directory of the local file:
+ # http://angg.twu.net/eev-videos/emacsconf2020.mp4
+ # $S/http/angg.twu.net/eev-videos/emacsconf2020.mp4
+ # (find-fline \"$S/http/angg.twu.net/eev-videos/\")
- (find-links-intro \"3. Elisp hyperlinks buffers conventions\")
+ # Youtube:
+ # (kill-new \"http://www.youtube.com/watch?v=hOAqBc42Gg8\")
+ # http://www.youtube.com/watch?v=hOAqBc42Gg8
-This tutorial is for people who want to learn how to _write_
-their own templated functions.
+that tries (!) to explain clearly how the URL and the file name
+of the local copy were generated from the argument
+\"emacsconf2020\" to `find-eevvideo-links', and how the youtube
+URL was generated by the argument \"hOAqBc42Gg8\"; and the
+temporary buffer also contains a last part with a script to
+download the .mp4 file, and a help sexp that explains that.
-To learn how to write your own templated functions you need to:
+That temporary buffer also contains a pair of sexps like
- 1) learn how to use `ee-template0' by reading its source code
- and playing with examples in the source and here,
+ (code-video \"eev2020video\"
\"$S/http/angg.twu.net/eev-videos/emacsconf2020.mp4\")
+ (find-eev2020video)
- 2) learn how to use `find-elinks' - same thing,
+that are easy to understand - the first one defines
+`find-eev2020video' as a short link to play the local copy of the
+.mp4 file.
- 3) learn how to use `find-find-links-links-new'.
+If you compare the temporary buffers generated by these two
+sexps,
+ (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\")
+ (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\" \"17:20\")
+you will see that the second sexp adds a time offset \"17:20\"s
+at several places, and adds a \"#t=17m20s\"s at the end of each
+youtube URL. These sexps and URLs can be used for _communication_
+- for example, if I am chatting with someone on an IRC channel I
+can say \"watch this:\", and then send these two lines:
+ (find-eev2020video \"17:20\")
+ http://www.youtube.com/watch?v=hOAqBc42Gg8#t=17m20s
+If I take the
-2. `ee-template0'
-=================
-See:
+ (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\")
- (find-efunction 'ee-template0)
- (find-eev \"eev-template0.el\")
+and change it to
-Try:
+ (code-eevvideo \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\")
- (ee-template00 \"a{(+ 2 3)}b\")
+this `code-eevvideo' sexps defines, or redefines,
+`find-eev2020video', to a \"version for communication\", such
+that
- (let ((hi \"Here: \")
- (a 22)
- (b 33))
- (ee-template00 \"{hi}{a}+{b}={(+ a b)}\"))
+ (find-eev2020video \"17:20\")
- (defun foo (a b) (ee-template00 \"{a}+{b}={(+ a b)}\"))
- (foo 22 33)
+runs
- (ee-template0 \"{<} a{(+ 2 3)} {>}\")
+ (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\" \"17:20\")
+that generates a temporary buffer with all the stuff described
+above, instead of playing the video file right away - to play the
+video file you have to execute the sexp
+ (find-video \"$S/http/angg.twu.net/eev-videos/emacsconf2020.mp4\" \"17:20\")
+in the second line of the temporary buffer.
-3. `find-elinks'
-================
-See:
+There are some examples of `find-eevvideo-links' sexps here:
- (find-efunction 'find-elinks)
- (find-eev \"eev-elinks.el\" \"find-elinks\")
+ (find-videos-intro \"2. Some `find-eevvideo-links'\")
-Now try these examples. They are multi-line versions with
-comments of the examples in the source file.
+At this moment I don't have variants of `find-eevvideo-links' and
+`code-eevvideo' that point to other sides - see the comments
+here:
- (find-elinks
- '((a sexp)
- \"a string\")
- )
+ (find-eev \"eev-tlinks.el\" \"hardcoded-paths\")
-Now try these examples. They are longer, multi-line versions of
-the examples in the source file.
- (find-elinks
- '((a sexp)
- \"a string\")
- )
- (find-elinks
- '((a sexp)
- \"a string\")
- \"st\")
- (find-elinks
- '((a sexp)
- \"a string\")
- \"st\" \"i\")
- (find-elinks
- '((a sexp)
- (another sexp)
- (sexps get comment signs)
- (strings in sexps: \"foo bar\")
- (newlines in strings in sexps get backslashed: \"\\n\")
- (ticks in sexps: 'a '(b c))
- (nils in sexps: nil () (nil nil))
- \"a string\"
- \"another string\"
- \"strings don't get comment signs\"
- \"empty strings become empty lines\"
- \"\"
- \"newlines in strings\\nbecome real newlines\"
- \"nils are dropped:\"
- nil
- \"see?\"
- \"\"
- (another sexp)
- )
- )
+" pos-spec-list)))
-Normally the first argument to `find-elinks' is backquoted. See:
+;; (find-audiovideo-intro)
- (find-elnode \"Backquote\")
-Try:
- `(foo ,(+ 2 3) bar)
- `(foo ,'(+ 2 3) bar)
- `(foo ,(list 2 3) bar)
- `(foo ,@(list 2 3) bar)
-See:
- (find-eev \"eev-elinks.el\" \"find-efunction-links\")
+;;; _ _ _ _ _
+;;; _ __ ___ _ _| | |_(_)_ _(_)_ __ __| | _____ __
+;;; | '_ ` _ \| | | | | __| \ \ /\ / / | '_ \ / _` |/ _ \ \ /\ / /
+;;; | | | | | | |_| | | |_| |\ V V /| | | | | (_| | (_) \ V V /
+;;; |_| |_| |_|\__,_|_|\__|_| \_/\_/ |_|_| |_|\__,_|\___/ \_/\_/
+;;;
+;; «find-multiwindow-intro» (to ".find-multiwindow-intro")
+;; Skel: (find-intro-links "multiwindow")
-The first argument to `find-elinks' is called LIST. Elements of
-LIST that are sexps are converted to strings using `ee-HS'. See:
+(defun find-multiwindow-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-multiwindow-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-multiwindow-intro)
+Source code: (find-efunction 'find-multiwindow-intro)
+More intros: (find-eev-quick-intro)
+ (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
- (find-eev \"eev-wrap.el\" \"ee-S\")
-4. Skels
-========
-Many functions in eev have comments that start with \";; Skel:\",
-like this:
+1. Introduction
+===============
+In many situations - for example, when we want to script a
+debugger, or to test programs that have to talk to one another,
+or to control several external machines simultaneously - the
+default window setup for eepitch, which is this,
- ;; Skel: (find-find-links-links-new \"fossil\" \"url subdir c\" \"\")
+ ____________________
+ | | |
+ | | |
+ | script | shell |
+ | | |
+ | | |
+ |__________|_________|
-A comment like that before a function means that I wrote that
-function by first running that sexp and then modifying the code
-that that sexp generated, that was a \"skeleton\".
+is not enough; other setups, like these,
-Try:
+ ______________________
+ | | | _________________________
+ | | shell A | | | |
+ | |___________| | script | GDB |
+ | script | | | | |
+ | | shell B | |____________|____________|
+ | |___________| | | |
+ | | | | program | program |
+ | | shell C | | I/O | source |
+ |__________|___________| |____________|____________|
- (find-find-links-links-new \"fossil\" \"url subdir c\" \"\")
- (find-eev \"eev-tlinks.el\" \"find-fossil-links\")
- (find-eevgrep \"grep --color -nH --null -e Skel: *.el\")
+may be necessary. Eev comes with a few _low-level_ tools for
+creating these setups; they are not very smart, but they should
+be easy to understand and to tweak - and I have the impression
+that ideas for good high-level tools will only come from
+practical experimentation.
+2. `find-wset'
+==============
+Suppose that we are in a buffer A, and we want to create a window
+configuration with A at the left, and with the buffers B and C
+stacked on one another at the right. That is:
+ ___________ ___________
+ | | | | |
+ | | | | B |
+ | A | --> | A |_____|
+ | | | | |
+ | | | | C |
+ |___________| |_____|_____|
-5. `find-find-links-links'
-==========================
-(Note: `find-find-links-links' is obsolete, and is superseded by
-`find-find-links-links-new')
+To do that from the keyboard we could type this:
-ALL my `find-*-links' started as quick hacks.
-SOME of them were useful enough to deserve being cleaned up.
-A FEW of them ended up in:
+ C-x 3 C-x o C-x b B RET C-x 2 C-x o C-x b C RET
- http://angg.twu.net/eev-current/eev-elinks.el.html
- http://angg.twu.net/eev-current/eev-tlinks.el.html
- (find-eev \"eev-elinks.el\")
- (find-eev \"eev-tlinks.el\")
+You can try that here (the initial `C-x 1' is an extra, for
+convenience):
-...but there are lots of other `find-*-links' functions in:
+ (eek \"C-x 1 ;; delete-other-windows
+ C-x 3 ;; split-window-horizontally (left/right)
+ C-x o ;; other-window (-> right)
+ C-x b B RET ;; switch to the buffer `B'
+ C-x 2 ;; split-window-vertically (upper/lower)
+ C-x o ;; other-window (-> lower right)
+ C-x b C RET ;; switch to the buffer `C'
+ \")
- http://angg.twu.net/.emacs.templates.html
+We can write something equivalent to that as a `progn', in a way
+that makes it easy to replace later the `C-x b B RET' and the
+`C-x b C RET' by arbitrary sexp hyperlinks. We get:
-They are trivial to write. I start with a skeleton that I obtain by
-running `M-x find-find-links-links', and then I modify the first line
-in that buffer, regenerate, modify, regenerate, and so on until happy.
-Run each of the sexps below with `M-2 M-e' to compare the buffers that
-they generate:
+ (progn (eek \"C-x 1 C-x 3 C-x o\")
+ (find-ebuffer \"B\")
+ (eek \"C-x 2 C-x o\")
+ (find-ebuffer \"C\")
+ (eek \"C-x o\")
+ )
- (find-find-links-links \"{k}\" \"{stem}\" \"{args}\")
- (find-find-links-links \"\\\\M-u\" \"{stem}\" \"{args}\")
- (find-find-links-links \"\\\\M-u\" \"macports\" \"{args}\")
- (find-find-links-links \"\\\\M-u\" \"macports\" \"pkgname\")
- (find-find-links-links \"\\\\M-u\" \"macports\" \"pkgname anotherarg\")
+When I started to rewrite my window configurations into that form
+I realized that the `eek's were being used in a very limited way
+- they only invoked a very small repertoire of window commands,
+all of them starting with `C-x'. So maybe I should have an
+interpreter for a simple language of window commands and sexp
+hyperlinks, in the which window setup above could be expressed
+like this:
+ '(\"13o\"
+ (find-ebuffer \"B\")
+ \"2o\"
+ (find-ebuffer \"C\")
+ \"o\"
+ )
+`find-wset' supports something like that, but with all the window
+command strings collapsed into a single one, with \"_\"s meaning
+\"execute the next sexp from the sexp list\". The corresponding
+call to `find-wset' is:
+ (find-wset \"13o_2o_o\" '(find-ebuffer \"B\") '(find-ebuffer \"C\"))
-So: start by running something like
+For the full list of supported window command characters - and
+how to extend it - see the source:
- (find-find-links-links \"\\\\M-u\" \"macports\" \"pkgname\")
- (find-find-links-links \"\\\\M-u\" \"homebrew\" \"pkgname\")
+ (find-eev \"eev-multiwindow.el\")
-then copy the
-\(define-key eev-mode-map \"\\M-h\\M-u\" 'find-macports-links)
-\(defun find-macports-links (&optional pkgname &rest pos-spec-list)
-\"Visit a temporary buffer containing hyperlinks for foo.\"
- (interactive)
- (setq pkgname (or pkgname \"{pkgname}\"))
- (apply 'find-elinks
- `((find-macports-links ,pkgname ,@pos-spec-list)
- ;; Convention: the first sexp always regenerates the buffer.
- (find-efunction 'find-macports-links)
- \"\"
- ,(ee-template0 \"\\
-\")
- )
- pos-spec-list))
-;; Test: (find-macports-links ___)
+3. High-level words
+===================
+Very often we want to create window setups like
-to your notes, replace the `(interactive)' by
+ _______________ _______________
+ | | | | | |
+ | | | | | B |
+ | A | B | or | A |_______| ;
+ | | | | | |
+ | | | | | C |
+ |_______|_______| |_______|_______|
- (interactive (list (ee-debpkgname-ask)))
+there are shorthands for that. If you run
-and start adding things to the string in (ee-template0 \"...\").
+ (find-2a sexpA sexpB)
-I will try to update this intro in the next days:
+that will create a window setting like the one at the left above,
+initially with two copies of the current buffer, then will run
+sexpA at the window \"A\" and sexpB at the window \"B\", and
+finally will select the window \"A\", i.e., leave the cursor at
+the window at the left; this
- (find-templates-intro)
- http://angg.twu.net/eev-intros/find-templates-intro.html
+ (find-2b sexpA sexpB)
+will do exactly the same as the `(find-2a ...)' above, but will
+select the window \"B\" - the one at the right - at the end of
+the process. For three-window settings we have these:
+ (find-3a sexpA sexpB sexpC)
+ (find-3b sexpA sexpB sexpC)
+ (find-3c sexpA sexpB sexpC)
+all three create the three-window setting at the right above,
+initially with all three windows displaying the current buffer,
+then run sexpA at the window \"A\", sexpB at the window \"B\",
+and sexpC at the window \"C\"; the difference is that find-3a
+selects the window \"A\", find-3b the window \"B\", find-3c the
+window \"C\".
-Etc:
- (find-links-conv-intro)
- (find-links-conv-intro \"3. Classification\")
- (find-eev \"eev-tlinks.el\" \"find-find-links-links\")
- (find-eev \"eev-tlinks.el\" \"find-intro-links\")
- (find-eev \"eev-wrap.el\" \"find-eewrap-links\")
-" rest)))
+4. Several eepitch targets
+==========================
+If we try to build a window setup like this one, with two eepitch
+targets, with just `find-wset', we will run into problems -
-;; (find-templates-intro)
+ ________________________
+ | | |
+ | | *shell* |
+ | script |_____________|
+ | | |
+ | | *shell 2* |
+ |__________|_____________|
+because `(eepitch-shell)' and `(eepitch-shell2)' try to create a
+shell buffer and put it in an _another_ window, not the one we
+are in... one solution is to call the `(eepitch-*)' sexps inside
+an `ee-here', like this:
+ (ee-here '(eepitch-shell))
+ (ee-here '(eepitch-shell2))
+where `ee-here' is a hack that runs a sexp in a way that
+preserves the current window configuration, then switches the
+buffer in the current selected window to the current eepitch
+target. We can use this to create the window setting above,
-;;; _
-;;; _ __ _ __ ___ _ __ __ _ _ __ ___ __| |
-;;; | '_ \| '__/ _ \ '_ \ / _` | '__/ _ \/ _` |
-;;; | |_) | | | __/ |_) | (_| | | | __/ (_| |
-;;; | .__/|_| \___| .__/ \__,_|_| \___|\__,_|
-;;; |_| |_|
-;;
-;; «find-prepared-intro» (to ".find-prepared-intro")
-;; (find-eev "eev-bounded.el")
+ (find-wset \"13o2_o_o\"
+ ' (ee-here '(eepitch-shell))
+ ' (ee-here '(eepitch-shell2))
+ )
-(defun find-prepared-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-prepared-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-prepared-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-prepared-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 is too long - and would make a very bad one-liner - but
+there are two shorthands. First, \"e\" is a variant of \"_\" that
+runs its sexp inside an `(ee-here ...) - so this is equivalent
+the thing above,
+ (find-wset \"13o2eoeo\"
+ '(eepitch-shell)
+ '(eepitch-shell2)
+ )
+Second, these things are useful enough to deserve a high-level
+word, so this is equivalent to:
-1. Prepared shells
-==================
-Long before eepitch had been created, eev had another way -
-technically much simpler, but clumsier from the user's point of
-view - to send commands to external shells (and other shell-like
-programs; but to simplify we will say just \"shells\"). Here is
-an overview of how it worked: if the user marked the three lines
-below,
+ (find-3ee '(eepitch-shell) '(eepitch-shell2))
- rm -Rv /tmp/foo
- mkdir /tmp/foo/
- cd /tmp/foo/
-and typed `M-x eev' (which stood for \"Emacs-execute-verbosely\")
-then Emacs would save those three lines into a temporary script
-file, usually \"~/.eev/ee.sh\"; that would be just half of
-\"sending commands to an external shell\", and for the other half
-the user would have to go to an external prepared shell - that
-would usually be running in an xterm, and totally independent
-from Emacs - and type \"ee\" there. The shell had to be
-\"prepared\" in the sense that it would understand the \"ee\"
-command correctly, as meaning: \"execute the commands in the
-temporary script as if the user were typing them at the prompt\".
-Technically, that would mean that instead of calling
-\"~/.eev/ee.sh\" as a shell script its contents would be
-\"sourced\" - i.e., executed in the current shell context - and
-in verbose mode.
-Usually we would prepare bash by patching the file ~/.bashrc and
-putting the definition for \"ee\" there. We will discuss how to
-do that later; now let's test a simple environment in which `M-x
-eev' and \"ee\" work. First execute these two sexps:
- (make-directory \"~/.eev/\" 'force)
- (eev \"rm -Rv /tmp/foo\\nmkdir /tmp/foo/\\ncd /tmp/foo/\\n\")
+5. Restarting eepitch targets
+=============================
+Sometimes we want to do the same as above, but restarting both
+eepitch targets, i.e., something like this:
-Now run this script
+ (find-3ee '(progn (eepitch-shell) (eepitch-kill) (eepitch-shell))
+ '(progn (eepitch-shell2) (eepitch-kill) (eepitch-shell2))
+ )
- (eepitch-bash)
- (eepitch-kill)
- (eepitch-bash)
-export PS1='$PWD# '
-function ee () { set -v; . ~/.eev/ee.sh; set +v; }
+There's a variant of `ee-here' that does that: `ee-here-reset'.
+For example,
+ (ee-here-reset '(eepitch-shell2))
+is equivalent to:
-2. `ee'
-=======
-\[Explain how several interpreters can be programmed to accept
-an `ee' command to execute temporary scripts\]
+ (ee-here '(progn (eepitch-shell2) (eepitch-kill) (eepitch-shell2)))
- http://angg.twu.net/eev-article.html#making-progs-receive-cmds
+and the letter \"E\" is a variant of \"e\" that uses
+`ee-here-reset' instead of `ee-here'; also, `find-3EE' is a
+variant of `find-3ee' that restarts both targets. Let's adapt
+this example,
- (find-eev \"eev-langs.el\")
- (find-eev \"eev-bounded.el\")
- (find-eev \"eev-rctool\")
+ (find-eepitch-intro \"3. Other targets\")
+to make it show the two eepitch targets at once in a three-window
+settings. It becomes:
+ (find-3EE '(eepitch-shell) '(eepitch-python))
+ (eepitch-shell)
+echo Hello... > /tmp/o
+ (eepitch-python)
+print(open(\"/tmp/o\").read())
+ (eepitch-shell)
+echo ...and bye >> /tmp/o
+ (eepitch-python)
+print(open(\"/tmp/o\").read())
+ Now compare:
+ (eek \"C-x 1\")
+ (find-3ee '(eepitch-shell) '(eepitch-python))
+ (find-3EE '(eepitch-shell) '(eepitch-python))
-3. An `ee' for Python
-=====================
-Here is a simple way to make Python execute commands saved in a
-temporary script when the user types `ee()' (note that it is not
-just `ee' - the `()' is needed). We will show first an example in
-which the temporary script is prepared by running \"cat\" from a
-shell - then we will explain a more user-friendly way to save a
-region from the current buffer as the temporary script.
-Note that the demo below uses `find-wset', which is an
-advanced (i.e., hackish) feature explained here:
- (find-multiwindow-intro \"Several eepitch targets\")
- (find-3EE '(eepitch-shell) '(eepitch-python))
- (find-3ee '(eepitch-shell) '(eepitch-python))
- (eepitch-python)
-import os
-def ee():
- exec(open(os.getenv(\"HOME\")+\"/.eev/ee.py\").read(), globals())
+6. Non-trivial examples
+=======================
+See:
- (eepitch-shell)
-cat > ~/.eev/ee.py <<'%%%'
-print(1+2)
-%%%
-
- (eepitch-python)
-ee()
-
- (eepitch-shell)
-cat > ~/.eev/ee.py <<'%%%'
-def foo (x):
- return x*x
+ (find-eev-quick-intro \"6.2. Other targets\")
+ (find-eev-quick-intro \"6.2. Other targets\" \"(find-3EE\")
+ (find-rcirc-intro \"1. The example that I use in workshops\")
+ (find-prepared-intro \"3. An `ee' for Python\")
+ (find-prepared-intro \"4. `eepy'\")
-print(foo(5))
-%%%
+The examples with `find-3EE' were created using `M-#', as
+explained in the next section.
- (eepitch-python)
-ee()
-print(foo(6))
-4. `eepy'
-=========
-The function `eev' receives three parameters, called `s', `e', and
-`altfile'; `e' and `altfile' are optional, and `s' should be either a
-string or a number. When `s' is a string, then the commands to be
-saved into the temporary script are taken from `s'; the numeric case
-will be discussed later.
+7. Eepitch blocks for two targets
+=================================
+An eepitch script with two targets uses several different kinds
+of red star lines - `(eepitch-target1)', `(eepitch-target2)',
+`(find-3EE ...)', `(find-3ee ...)', etc. We don't want to have to
+type all those by hand, so there is a hack similar to `M-T' that
+generates all those kinds from just \"target1\" and \"target2\"
+to let us just copy around the sexps we need.
-A call to
+This key binding for this hack is `meta-shift-3' - that Emacs
+sees as `M-#' - but it is disabled by default. To enable it, do
+this:
- (eev \"print(1+2)\" nil \"~/.eev/ee.py\")
+ ;; See: (find-eevfile \"eev-mode.el\" \"eewrap-two-eepitches\")
+ (define-key eev-mode-map \"\\M-#\" 'eewrap-two-eepitches)
-writes \"print(1+2)\" (with an added trailing newline, but that's
-a technical detail) into the \"alternative file\"
-\"~/.eev/ee.py\" - the default would be \"~/.eev/ee.sh\". We can
-use that to simplify our demo a bit:
+Now compare the result of typing `M-T' here,
- (eek \"C-x 1\")
- (eepitch-python)
- (eepitch-kill)
- (eepitch-python)
-import os
-def ee():
- exec(open(os.getenv(\"HOME\")+\"/.eev/ee.py\").read(), globals())
+python
- (eev \"print(1+2)\" nil \"~/.eev/ee.py\")
-ee()
- (eev \"def foo (x):\\n return x*x\\n\\nprint(foo(5))\" nil
\"~/.eev/ee.py\")
-ee()
-print(foo(6))
+with the result of typing `M-#' on this line,
+shell python
- In the example below the first line defines a `eepy' in a
- simplistic way:
+which yield this:
- (defun eepy (s &optional e) (eev s e \"~/.eev/ee.py\"))
- (eek \"C-x 1\")
- (eepitch-python)
- (eepitch-kill)
+ (find-3EE '(eepitch-shell) '(eepitch-python))
+ (find-3ee '(eepitch-shell) '(eepitch-python))
+ (eepitch-shell)
(eepitch-python)
-import os
-def ee():
- exec(open(os.getenv(\"HOME\")+\"/.eev/ee.py\").read(), globals())
-
- (eepy \"print(1+2)\")
-ee()
- (eepy \"def foo (x):\\n return x*x\\n\\nprint(foo(5))\")
-ee()
-print(foo(6))
-
-
-
-
-5. `M-x eepy' and `M-x eev'
-===========================
-Now let's define a more realistic `eepy' - one that can also be
-called interactively. We want `M-x eepy' to save the current
-_region_ into the temporary script; `eepy' has to be a _command_,
-and we will use the argument \"r\" to its `interactive' clause,
-to make the function `eepy' receive two numbers - the start and
-the end of the region - and it will pass these two numbers to
-`eev'.
-
- (defun eepy (s &optional e)
- \"Save the region between S and E (or the string S) into ~/.eev/ee.py .\"
- (interactive \"r\")
- (eev s e \"~/.eev/ee.py\"))
-
-When the first argument, `s', to `eev', is a number, not a
-string, then `eev' expects the second argument, `e', to also be a
-number - and then `s' and `e' are considered as the extremities
-of a region of text in the current buffer. This idea - that the
-first argument can be either a string or a number - comes from:
-
- (find-efunctiondescr 'write-region \"If START is a string\")
-But try these:
+Remember that The line with `find-3EE' restart the two targets,
+and the line with `find-3ee' just recreates the window setting
+with the two targets but without restarting them; so the line
+with `find-3EE' sort of works as two `eepitch-kill's.
- (ee-se-to-string \"foo\" nil)
- (ee-se-to-string-with-nl \"foo\" nil)
- (ee-se-to-string \"foo\\n\" nil)
- (ee-se-to-string-with-nl \"foo\\n\" nil)
- (ee-se-to-string (- (point) 5) (point))
- (ee-se-to-string-with-nl (- (point) 5) (point))
- (ee-se-to-string (point) (- (point) 5))
- (ee-se-to-string-with-nl (point) (- (point) 5))
+8. Adding support for new characters in `find-wset'
+===================================================
+The standard characters supported by `find-wset' are these:
-\[Garbage:\]
+ char action key
+ ---- ---------------------------- ---------
+ `1' `delete-other-windows' (C-x C-1)
+ `2' `split-window-vertically' (C-x C-2)
+ `3' `split-window-horizontally' (C-x C-3)
+ `s' `split-window-sensibly'
+ `o' `other-window' (C-x o)
+ `+' `balance-windows' (C-x +)
+ `_' execute the next sexp
- (find-elnode \"Defining Commands\")
- (find-defun-intro \"\\ninteractive\\n\")
- (find-efunction 'eev)
+but the action of each one is defined in a different function,
+and to add support for a new character, say, `=', we just need to
+define a function with the right name - in this case,
+`find-wset-='.
-" rest)))
+The source code is simple enough, so take a look:
-;; (find-prepared-intro)
+ (find-eev \"eev-multiwindow.el\" \"find-wset-_\")
-;; (find-bashnode "Bourne Shell Builtins" "current shell context")
+" pos-spec-list)))
+;; (find-multiwindow-intro)
-;;; _ _ _
-;;; | |__ ___ _ _ _ __ __| | ___ __| |
-;;; | '_ \ / _ \| | | | '_ \ / _` |/ _ \/ _` |
-;;; | |_) | (_) | |_| | | | | (_| | __/ (_| |
-;;; |_.__/ \___/ \__,_|_| |_|\__,_|\___|\__,_|
+;;; _
+;;; _ __ ___(_)_ __ ___
+;;; | '__/ __| | '__/ __|
+;;; | | | (__| | | | (__
+;;; |_| \___|_|_| \___|
;;;
-;; «find-bounded-intro» (to ".find-bounded-intro")
-;; Skel: (find-intro-links "bounded")
-(defun find-bounded-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-bounded-intro)*"))
+;; «find-rcirc-intro» (to ".find-rcirc-intro")
+;; Skel: (find-intro-links "rcirc")
+
+(defun find-rcirc-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-rcirc-intro)*"))
(apply 'find-eintro "\
-\(Re)generate: (find-bounded-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-bounded-intro\")
+\(Re)generate: (find-rcirc-intro)
+Source code: (find-efunction 'find-rcirc-intro)
More intros: (find-eev-quick-intro)
(find-eev-intro)
(find-eval-intro)
@@ -9607,607 +9488,710 @@ It is meant as both a tutorial and a sandbox.
-Note that you need to understand the concept of \"prepared
-shells\" quite well to be able to use this... see:
+Recent versions with Emacs come with two IRC clients built-in:
+Rcirc and ERC. I never understood ERC well enough, and I found
+rcirc quite easy to understand and to hack, so eev has some
+support for rcirc (and no support for ERC).
- (find-prepared-intro)
+ (find-node \"(rcirc)Top\")
+ (find-node \"(erc)Top\")
+The eev support for rcirc consists mainly of three high-level
+functions that connect to Freenode (the IRC server where most
+discussion of free software projects USED TO happen), and three
+high-level functions that connect to LiberaChat (the IRC server
+where most discussion of free software projects were moved to).
+These functions are called:
+ `find-freenode', `find-freenode-2a' and `find-freenode-3a',
+ `find-libera', `find-libera-2a' and `find-libera-3a'.
-Bad news: I've been using this feature very little, and I have
-not yet adapted the old, crappy docs to the new \"intro\"
-format... =\\ So this is just a bunch of notes!
+For a good explanation of what IRC is, see:
-Source code: \(find-eev \"eev-bounded.el\")
-Obsolete related code: \(find-eev \"eev-langs.el\")
-Old mentions to this: \(find-TH \"eev-article\" \"delimited-regions\")
- http://angg.twu.net/eev-article.html#delimited-regions
+ http://www.irchelp.org/faq/new2irc.html
-Delimited (\"bounded\") regions
-=============================
-Try:
+1. The example that I use in workshops
+======================================
+Let's start with an example. In
-#
-# (eev-bounded)
-cd
-echo At: $PWD
-cd /tmp/
-echo At: $PWD
+ (setq rcirc-default-nick \"hakuryo\")
+ (setq ee-libera-ichannels \"#eev\")
+ (find-libera-3a \"#eev\")
-#
-%
-% (eelatex-bounded)
+the first sexp tells rcirc to use the nickname \"hakuryo\" when
+connecting to an IRC server; the second sets the set of \"initial
+channels\" on LiberaChat to just one channel, #eev - a channel
+that is usually empty, but that doesn't require authentication;
+the third sexp is a \"sexp hyperlink to the LiberaChat channel
+#eev\". The third sexp:
-Hello
+ 1) creates a window setting like this,
-%
+ _________________________
+ | | |
+ | | LiberaChat |
+ | | server |
+ | | messages |
+ | current |_____________|
+ | buffer | |
+ | | #eev |
+ | | channel |
+ | | |
+ |___________|_____________|
+ 2) tells rcirc to connect to LiberaChat and to the channel #eev
+ in it,
-Defining new bounded functions
-==============================
-Try:
+ 3) makes the window at the left - window \"A\" in the
+ terminology of eev-multiwindow.el - the active window. See:
- (find-code-bounded 'eev-bounded 'eev \"\\n#\\n\")
- (find-code-bounded 'eev-bounded 'eev 'ee-delimiter-hash)
+ (find-multiwindow-intro \"3. High-level words\")
+ (find-multiwindow-intro \"3. High-level words\" \"find-3a\")
-as usual, when we remove the \"find-\"s the generated code is
-executed instead of displayed.
+The connection process takes time - about 20 seconds at my
+machine - but you will be able to see in window \"B\" the server
+messages as they appear, and in window \"C\" the messages of the
+#eev channel. You can then use the window \"C\" to interact with
+the other users in #eev, and to experiment with commands. See:
+ (find-rcircnode \"Internet Relay Chat\" \"Once you have joined a channel\")
+ (find-rcircnode \"Getting started with rcirc\" \"To talk in a channel\")
+ (find-rcircnode \"rcirc commands\" \"/join #emacs\")
-The default bounded function
-============================
-...is stored in the variable `ee-bounded-function', and can be
-re-run with `M-x ee-bounded-function' (i.e., there's a function
-with the same name as the variable). I used to bind `f3' to that,
-but in modern Emacsen this is bound to a macro key:
- (find-enode \"Basic Keyboard Macro\" \"<F3>\")
+2. The two-window setting
+=========================
+Try this:
-so you should do something like this, but for your favourite key:
+ (find-libera-2a \"#eev\")
- (define-key eev-mode-map [f3] 'ee-bounded-function)
-" pos-spec-list)))
+It creates a window setting like
-;; (find-bounded-intro)
+ _________ ________
+ | | |
+ | | |
+ | current | irc |
+ | buffer | buffer |
+ | | |
+ |_________|________|
+which is nice for when you don't want to follow the irc server
+messages.
-;;; _ _
-;;; ___| |__ __ _ _ __ _ __ ___| |___
-;;; / __| '_ \ / _` | '_ \| '_ \ / _ \ / __|
-;;; | (__| | | | (_| | | | | | | | __/ \__ \
-;;; \___|_| |_|\__,_|_| |_|_| |_|\___|_|___/
-;;;
-;; «find-channels-intro» (to ".find-channels-intro")
-;; Skel: (find-intro-links "channels")
-(defun find-channels-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-channels-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-channels-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-channels-intro\")
-More intros: (find-eev-quick-intro)
- (find-eev-intro)
- (find-eval-intro)
- (find-eepitch-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
+3. Tracking activity
+====================
+TODO: explain this:
+ (find-rcircnode \"Channels\" \"M-x rcirc-track-minor-mode\")
+and how to use it as a one-window setting. Also:
-1. Introduction
-===============
-Before eepitch had been invented eev had two other ways to send
-commands to external shell-like programs. The first way,
-described here,
+ (find-efunctiondescr 'rcirc-track-minor-mode)
+ (find-efunction 'rcirc-track-minor-mode)
+ (find-evariable 'rcirc-track-minor-mode-map)
+ (find-ekeymapdescr rcirc-track-minor-mode-map)
- (find-prepared-intro \"\\n`ee'\\n\")
+ (find-efunctiondescr 'rcirc-next-active-buffer)
+ (find-efunction 'rcirc-next-active-buffer)
-was technically very simple: running `M-x eev' would save a
-series of commands - usually the contents of the region - into a
-temporary script file, and then the user would type something
-like `ee' at the prompt of a (\"prepared\") shell; that would
-make it read the saved commands and execute them.
+ (global-set-key [f2] 'rcirc-next-active-buffer)
-Here we will describe the second of the Old Ways - one in which
-the target program, which is usually a shell running in an xterm,
-is sent a signal saying \"execute the command NOW\" as soon as a
-command is saved into a temporary file by Emacs. The difficulty
-is that this requires not only a directory for temporary files,
-but also an Expect script, which acts as an intermediary that
-listens to signals and handles them pretending that the saved
-commands came from the keyboard... and, as some people have said,
-this is \"a nightmare to set up\".
+ (find-eev \"eev-elinks.el\" \"find-esetkey-links\")
+ (find-eev \"eev-elinks.el\" \"find-esetkey-links\" \"video\")
+ (find-esetkey-links (kbd \"<f2>\") 'rcirc-next-active-buffer)
-Here we explain the protocol - that can be adapted to other
-cases too, like, for example, to make Emacs talk to SmallTalk
-environments and to computer algebra systems with GUIs - and we
-will present several tests that should help with troubleshooting.
+4. Commands with very short names
+=================================
+We can apply this idea
+ (find-eev-quick-intro \"7.4. Commands with very short names\")
+ (find-eev-quick-intro \"7.4. Commands with very short names\" \"(defun c
()\")
-2. Low-level tests
-==================
-Before we start the theory please try these low-level tests.
+to rcirc. If you connect occasionally to the channels #eev,
+#emacs, #git and #ruby, you can run this, or put these lines in
+your .emacs:
+ (setq rcirc-default-nick \"hakuryo\")
+ (defun e2 () (interactive) (find-libera-2a \"#eev\"))
+ (defun e3 () (interactive) (find-libera-3a \"#eev\"))
+ (defun m2 () (interactive) (find-libera-2a \"#emacs\"))
+ (defun m3 () (interactive) (find-libera-3a \"#emacs\"))
+ (defun g2 () (interactive) (find-libera-2a \"#git\"))
+ (defun g3 () (interactive) (find-libera-3a \"#git\"))
+ (defun r2 () (interactive) (find-libera-2a \"#ruby\"))
+ (defun r3 () (interactive) (find-libera-3a \"#ruby\"))
-2.1. Preparation
-----------------
-Have have to make sure that:
- 1) \"eev-channel.el\" has been loaded,
- 2) the \"$EEVDIR/eegchannel\" script exists and is executable,
- 3) we have expect installed - eegchannel depends on it,
- 4) the temporary directory \"$EEVTMPDIR/\" exists.
-Here is an e-script for that:
- (add-to-list 'load-path (ee-expand \"$EEVDIR\"))
- (require 'eev-channel)
+5. `find-libera-links'
+======================
+You can generate lines like the ones above by running
+`find-libera-links'. For example:
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
-sudo apt-get install expect
-echo $EEVDIR
-cd $EEVDIR
-pwd
-wget -nc http://angg.twu.net/eev-current/eegchannel
-chmod 755 eegchannel
-ls -lAF $EEVDIR/eegchannel
-expect -v
-$EEVDIR/eegchannel A echo ok
-echo $EEVTMPDIR
-mkdir -p $EEVTMPDIR/
+ (find-libera-links \"e\" \"#eev\")
+ (find-libera-links \"r\" \"#ruby\")
-# (find-eev \"eegchannel\")
+6. Other servers
+================
+TODO: explain how to use find-rcirc-buffer and how to adapt
+find-libera-* to other servers. Example:
+ (find-rcirc-buffer-2a \"irc.debian.org\" \"#debian-live\" nil
\"#debian-live\")
+ (find-rcirc-buffer-3a \"irc.debian.org\" \"#debian-live\" nil
\"#debian-live\")
-2.2. Test eegchannel
---------------------
-In this test we create a window setting like this,
+See:
- ______________________
- | | |
- | | shell |
- | this |___________|
- | intro | |
- | | shell 2 |
- |__________|___________|
+ (find-eev \"eev-rcirc.el\" \"find-libera\")
-and then:
+" pos-spec-list)))
- 1) we run \"eegchannel A python\" at the lower shell. This runs
- a python interpreter \"listening on channel A\";
+;; (find-rcirc-intro)
- 2) we use the top shell to send the lines \"print(2+3)\" and
- \"exit()\" \"through the channel A\". In low-level terms
- this means that for each line
- a) we save it into the file \"$EEVTMPDIR/eeg.A.str\",
- b) we send a signal SIGUSR1 to the process -
- \"eegchannel\" - whose PID is stored in the file
- \"$EEVTMPDIR/eeg.A.pid\".
- c) When the eegchannel listening on the channel A receives
- a SIGUSR1 it sends the line in \"$EEVTMPDIR/eeg.A.str\"
- to the process that it controls (that is \"python\") \"as
- if the user had typed it\".
-Here is the demo. Run it with <F8>s:
+;;; _ _ _
+;;; | |_ ___ _ __ ___ _ __ | | __ _| |_ ___ ___
+;;; | __/ _ \ '_ ` _ \| '_ \| |/ _` | __/ _ \/ __|
+;;; | || __/ | | | | | |_) | | (_| | || __/\__ \
+;;; \__\___|_| |_| |_| .__/|_|\__,_|\__\___||___/
+;;; |_|
+;;
+;; «find-templates-intro» (to ".find-templates-intro")
+;; Skel: (find-intro-links "templates")
- (find-3EE '(eepitch-shell) '(eepitch-shell2))
- (find-3ee '(eepitch-shell) '(eepitch-shell2))
- (eepitch-shell)
-# Optional clean-up:
-ls -lAF $EEVTMPDIR/eeg.A.*
-rm -fv $EEVTMPDIR/eeg.A.*
+(defun find-templates-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-templates-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-templates-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-templates-intro\")
+More intros: (find-eev-quick-intro)
+ (find-escripts-intro)
+ (find-links-conv-intro)
+ (find-eev-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
- (eepitch-shell2)
-# Start a python interpreter \"listening on channel A\":
-$EEVDIR/eegchannel A python3
- (eepitch-shell)
-# Check that eeg.A.pid exists and is very recent:
-date
-ls -lAF $EEVTMPDIR/eeg.A.*
-# Send lines to eegchannel:
-echo 'print(2+3)' > $EEVTMPDIR/eeg.A.str
-kill -USR1 $(cat $EEVTMPDIR/eeg.A.pid)
-echo 'exit()' > $EEVTMPDIR/eeg.A.str
-kill -USR1 $(cat $EEVTMPDIR/eeg.A.pid)
+This intro is being rewritten!
+The prerequisites for understand this are:
+ (find-elisp-intro)
+ (find-links-conv-intro \"3. Classification\")
-2.3. Test `eechannel'
----------------------
-TODO: write this.
-See:
- (find-eev \"eev-channels.el\" \"eechannel\")
+1. Introduction
+===============
+In dec/2019 I sent this e-mail to the eev mailing list:
+ https://lists.gnu.org/archive/html/eev/2019-12/msg00001.html
-2.4. Test `eexterm'
--------------------
-TODO: write this.
-See:
+It was a kind of a call for help. It contained a very brief
+explanation of how the \"templated\" functions of eev, like
+`find-ekey-links' and `find-latex-links', are implemented, and
+showed how people can write their own templated functions as
+quick hacks.
- (find-eev \"eev-channels.el\" \"eexterm\")
+If you want to learn how to _use_ templated functions, start by:
+ (find-eev-quick-intro \"4.2. `find-ekey-links' and friends\")
+ (find-eev-quick-intro \"7.5. `find-latex-links'\")
+If you want to look at the source code of the existing templated
+functions, take a look at:
+ (find-eev \"eev-elinks.el\")
+ (find-eev \"eev-tlinks.el\")
+ (find-links-intro \"3. Elisp hyperlinks buffers conventions\")
-3. The innards
-==============
-Let's start with a detailed low-level view of of what we have
-just summarized as to \"save a command into a temporary file,
-then send a signal to the external program etc etc\".
+This tutorial is for people who want to learn how to _write_
+their own templated functions.
-Warning: this document is still VERY INCOMPLETE, and some parts
-of it are just notes, drafts, and links that may not work for
-you... =(
+To learn how to write your own templated functions you need to:
- (find-eev \"eegchannel\")
- (find-eev \"anim/\")
- (find-eev \"anim/channels.anim\")
- http://angg.twu.net/eev-current/eegchannel.html
+ 1) learn how to use `ee-template0' by reading its source code
+ and playing with examples in the source and here,
+ 2) learn how to use `find-elinks' - same thing,
+ 3) learn how to use `find-find-links-links-new'.
-4. The protocol, in diagrams
-============================
-Here's a diagram that shows roughly what we have when X is
-running both an Emacs and an xterm, each in a separate window.
-Many details have been omitted - for examples, the real
-communication happens through fifos and ptys, that are not shown
-- but it's easy to build a complete diagram from this. The arrows
-indicate flow of information.
- keyboard mouse display
- | | ^
- v v |
- +----------------------------+
- | |
- | X |
- | |
- +----------------------------+
- key/mouse | ^ display key/mouse | ^ display
- events v | commands events v | commands
- +---------+ +---------+
- | | | |
- | emacs | | xterm |
- | | | |
- +---------+ +---------+
- chars and | ^ chars and
- signals v | signals
- +---------+
- | |
- | sh |
- | |
- +---------+
-To make the external shell at the right able to receive commands
-from Emacs we will insert a program between the \"xterm\" and the
-\"sh\" boxes - an Expect script called eechannel, that will
-usually be totally transparent, in the sense that it will let all
-the chars and signals that it receives pass through it without
-changes.
+2. `ee-template0'
+=================
+See:
-The trick is that \"eechannel\" will also be \"listening to
-commands from the outside\", according to the following protocol:
+ (find-efunction 'ee-template0)
+ (find-eev \"eev-template0.el\")
- 1) each instance of eechannel \"listens\" to a fixed, named
- \"channel\"; for simplicity, let's suppose that this name is
- \"A\".
+Try:
- 2) When an eechannel receives a signal SIGUSR1 it reads a
- string from the file \"eech.A.str\" and sends that to the
- shell, as if the user had typed that.
+ (ee-template00 \"a{(+ 2 3)}b\")
- 3) To make it simpler to send the signal, when eechannel starts
- up it saves its pid into the file \"eech.A.pid\".
+ (let ((hi \"Here: \")
+ (a 22)
+ (b 33))
+ (ee-template00 \"{hi}{a}+{b}={(+ a b)}\"))
-That protocol can be depicted as the four horizontal arrows
-below; the temporal order is from top to bottom.
+ (defun foo (a b) (ee-template00 \"{a}+{b}={(+ a b)}\"))
+ (foo 22 33)
- +-------------+
- | |
- | xterm |
- | |
- +-------------+
- +-----------+ | ^
- | | --> eeg.A.str v |
- | emacs | <-- eeg.A.pid +-------------+
- | | -----------------> | |
- +-----------+ eeg.A.str ---> | eechannel A |
- | |
- +-------------+
- | ^
- v |
- +-------------+
- | |
- | sh |
- | |
- +-------------+
+ (ee-template0 \"{<} a{(+ 2 3)} {>}\")
-When Emacs wants to send a line, say, \"cd /tmp/\", to eechannel,
-it does this:
- 1) \"--> eeg.A.str \" writes \"cd /tmp/\" into eech.A.str,
- 2) \"<-- eeg.A.pid \" reads eechannel's pid from eech.B.str,
- 3) \"----------------->\" sends a signal SIGUSR1 to that pid,
- 4) \" eeg.A.str --->\" ...and when eechannel receives a SIGUSR1
- it reads the contents of eech.A.str and
- sends that to its spawned shell.
-Actually there's something else - how these programs are started.
-If we run just \"xterm\", it behaves in its default way, and runs
-a shell. But if we run
- \"xterm -e eechannel A /bin/sh\"
+3. `find-elinks'
+================
+See:
-then xterm runs \"eechannel A /bin/sh\" instead of just
-\"/bin/sh\"; and \"eechannel A /bin/sh\" runs \"/bin/sh\".
+ (find-efunction 'find-elinks)
+ (find-eev \"eev-elinks.el\" \"find-elinks\")
-Also, evaluating this
+Now try these examples. They are multi-line versions with
+comments of the examples in the source file.
- (find-bgprocess \"xterm\")
+ (find-elinks
+ '((a sexp)
+ \"a string\")
+ )
-from Emacs runs an xterm, which runs a shell; evaluating either
-of these sexps,
+Now try these examples. They are longer, multi-line versions of
+the examples in the source file.
- (find-bgprocess \"xterm -e eechannel A /bin/sh\")
- (find-bgprocess \"xterm -e eechannel A $SHELL\")
+ (find-elinks
+ '((a sexp)
+ \"a string\")
+ )
-runs an xterm, which runs the \"eechannel\" script, which runs a
-shell. The sexp
+ (find-elinks
+ '((a sexp)
+ \"a string\")
+ \"st\")
- (eexterm \"A\")
+ (find-elinks
+ '((a sexp)
+ \"a string\")
+ \"st\" \"i\")
-is a shorthand for the one using \"$SHELL\". Also, note that
-\"eechannel A ...\" saves its pid into \"eech.A.pid\".
+ (find-elinks
+ '((a sexp)
+ (another sexp)
+ (sexps get comment signs)
+ (strings in sexps: \"foo bar\")
+ (newlines in strings in sexps get backslashed: \"\\n\")
+ (ticks in sexps: 'a '(b c))
+ (nils in sexps: nil () (nil nil))
+ \"a string\"
+ \"another string\"
+ \"strings don't get comment signs\"
+ \"empty strings become empty lines\"
+ \"\"
+ \"newlines in strings\\nbecome real newlines\"
+ \"nils are dropped:\"
+ nil
+ \"see?\"
+ \"\"
+ (another sexp)
+ )
+ )
-The diagram that shows what happens when we run `(eexterm \"A\")'
-is this one, below - note that the four arrows of the sending
-protocol are not shown.
+Normally the first argument to `find-elinks' is backquoted. See:
- +------------+
- | |
- | X |
- | |
- +------------+
- / ^ \\ ^
- v / v \\
- +-----------+ +-------------+
- | | initiates | |
- | emacs |:::::::::::>| xterm |
- | | | |
- +-----------+ +-------------+
- :: | ^
- \\/ v |
- +-------------+
- | |
- eeg.A.pid <-- | eechannel A |
- | |
- +-------------+
- :: | ^
- \\/ v |
- +-------------+
- | |
- | sh |
- | |
- +-------------+
+ (find-elnode \"Backquote\")
+Try:
+ `(foo ,(+ 2 3) bar)
+ `(foo ,'(+ 2 3) bar)
+ `(foo ,(list 2 3) bar)
+ `(foo ,@(list 2 3) bar)
-5. Downloading and testing eechannel
-====================================
-Here I'll suppose that the directory \"~/bin/\" exists and is in
-your PATH. Run this to download the \"eechannel\" script and make
-it executable:
+See:
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
-cd ~/bin/
-# See: http://angg.twu.net/bin/eechannel.html
-wget -n http://angg.twu.net/bin/eechannel
-chmod 755 eechannel
+ (find-eev \"eev-elinks.el\" \"find-efunction-links\")
-Now let's test - from Emacs - if a local copy of \"eechannel\"
-exists, is in your PATH, and can be executed (remember that it
-needs Expect). Calling \"eechannel\" with not enough arguments
-should yield a nice error message.
+The first argument to `find-elinks' is called LIST. Elements of
+LIST that are sexps are converted to strings using `ee-HS'. See:
- (find-fline \"~/bin/eechannel\")
- (find-sh \"~/bin/eechannel\")
- (find-sh \"eechannel\")
+ (find-eev \"eev-wrap.el\" \"ee-S\")
-It uses the environment variable EEVTMPDIR to decide where the
-temporary files - ee.CHANNELAME.pid, ee.CHANNELNAME.str - will
-be, so let's check that this directory exists:
- (getenv \"EEVTMPDIR\")
- (find-fline \"$EEVTMPDIR/\")
-Running eechannel with a first argument \"-v\" should show a lot
-of info, and then save the pid at eech.CHANNELAME.pid and run the
-given command. Let's try with a command that exits immediately.
+4. Skels
+========
+Many functions in eev have comments that start with \";; Skel:\",
+like this:
- (find-sh \"eechannel -v A /bin/true\")
- (find-fline \"$EEVTMPDIR/\" \"eech.A.pid\")
+ ;; Skel: (find-find-links-links-new \"fossil\" \"url subdir c\" \"\")
-Now let's verify - using just eepitch, without xterm at this
-moment - whether eechannel is being able to receive signals. In
-the eepitch script below, two `(find-sh0 \"kill ...\")'s should
-each make the controlled program receive a command - at the first
-\"kill\" an \"echo 2\", at the second an \"echo 3\".
+A comment like that before a function means that I wrote that
+function by first running that sexp and then modifying the code
+that that sexp generated, that was a \"skeleton\".
- (eepitch-comint \"A\" \"eechannel -v A /bin/sh\")
+Try:
+
+ (find-find-links-links-new \"fossil\" \"url subdir c\" \"\")
+ (find-eev \"eev-tlinks.el\" \"find-fossil-links\")
+ (find-eevgrep \"grep --color -nH --null -e Skel: *.el\")
+
+
+
+
+
+5. `find-find-links-links'
+==========================
+(Note: `find-find-links-links' is obsolete, and is superseded by
+`find-find-links-links-new')
+
+ALL my `find-*-links' started as quick hacks.
+SOME of them were useful enough to deserve being cleaned up.
+A FEW of them ended up in:
+
+ http://angg.twu.net/eev-current/eev-elinks.el.html
+ http://angg.twu.net/eev-current/eev-tlinks.el.html
+ (find-eev \"eev-elinks.el\")
+ (find-eev \"eev-tlinks.el\")
+
+...but there are lots of other `find-*-links' functions in:
+
+ http://angg.twu.net/.emacs.templates.html
+
+They are trivial to write. I start with a skeleton that I obtain by
+running `M-x find-find-links-links', and then I modify the first line
+in that buffer, regenerate, modify, regenerate, and so on until happy.
+Run each of the sexps below with `M-2 M-e' to compare the buffers that
+they generate:
+
+ (find-find-links-links \"{k}\" \"{stem}\" \"{args}\")
+ (find-find-links-links \"\\\\M-u\" \"{stem}\" \"{args}\")
+ (find-find-links-links \"\\\\M-u\" \"macports\" \"{args}\")
+ (find-find-links-links \"\\\\M-u\" \"macports\" \"pkgname\")
+ (find-find-links-links \"\\\\M-u\" \"macports\" \"pkgname anotherarg\")
+
+
+
+
+So: start by running something like
+
+ (find-find-links-links \"\\\\M-u\" \"macports\" \"pkgname\")
+ (find-find-links-links \"\\\\M-u\" \"homebrew\" \"pkgname\")
+
+then copy the
+
+\(define-key eev-mode-map \"\\M-h\\M-u\" 'find-macports-links)
+
+\(defun find-macports-links (&optional pkgname &rest pos-spec-list)
+\"Visit a temporary buffer containing hyperlinks for foo.\"
+ (interactive)
+ (setq pkgname (or pkgname \"{pkgname}\"))
+ (apply 'find-elinks
+ `((find-macports-links ,pkgname ,@pos-spec-list)
+ ;; Convention: the first sexp always regenerates the buffer.
+ (find-efunction 'find-macports-links)
+ \"\"
+ ,(ee-template0 \"\\
+\")
+ )
+ pos-spec-list))
+
+;; Test: (find-macports-links ___)
+
+to your notes, replace the `(interactive)' by
+
+ (interactive (list (ee-debpkgname-ask)))
+
+and start adding things to the string in (ee-template0 \"...\").
+
+I will try to update this intro in the next days:
+
+ (find-templates-intro)
+ http://angg.twu.net/eev-intros/find-templates-intro.html
+
+
+
+
+
+Etc:
+
+ (find-links-conv-intro)
+ (find-links-conv-intro \"3. Classification\")
+ (find-eev \"eev-tlinks.el\" \"find-find-links-links\")
+ (find-eev \"eev-tlinks.el\" \"find-intro-links\")
+ (find-eev \"eev-wrap.el\" \"find-eewrap-links\")
+
+" rest)))
+
+;; (find-templates-intro)
+
+
+
+
+;;; _
+;;; _ __ _ __ ___ _ __ __ _ _ __ ___ __| |
+;;; | '_ \| '__/ _ \ '_ \ / _` | '__/ _ \/ _` |
+;;; | |_) | | | __/ |_) | (_| | | | __/ (_| |
+;;; | .__/|_| \___| .__/ \__,_|_| \___|\__,_|
+;;; |_| |_|
+;;
+;; «find-prepared-intro» (to ".find-prepared-intro")
+;; (find-eev "eev-bounded.el")
+
+(defun find-prepared-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-prepared-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-prepared-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-prepared-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.
+
+
+
+1. Prepared shells
+==================
+Long before eepitch had been created, eev had another way -
+technically much simpler, but clumsier from the user's point of
+view - to send commands to external shells (and other shell-like
+programs; but to simplify we will say just \"shells\"). Here is
+an overview of how it worked: if the user marked the three lines
+below,
+
+ rm -Rv /tmp/foo
+ mkdir /tmp/foo/
+ cd /tmp/foo/
+
+and typed `M-x eev' (which stood for \"Emacs-execute-verbosely\")
+then Emacs would save those three lines into a temporary script
+file, usually \"~/.eev/ee.sh\"; that would be just half of
+\"sending commands to an external shell\", and for the other half
+the user would have to go to an external prepared shell - that
+would usually be running in an xterm, and totally independent
+from Emacs - and type \"ee\" there. The shell had to be
+\"prepared\" in the sense that it would understand the \"ee\"
+command correctly, as meaning: \"execute the commands in the
+temporary script as if the user were typing them at the prompt\".
+Technically, that would mean that instead of calling
+\"~/.eev/ee.sh\" as a shell script its contents would be
+\"sourced\" - i.e., executed in the current shell context - and
+in verbose mode.
+
+Usually we would prepare bash by patching the file ~/.bashrc and
+putting the definition for \"ee\" there. We will discuss how to
+do that later; now let's test a simple environment in which `M-x
+eev' and \"ee\" work. First execute these two sexps:
+
+ (make-directory \"~/.eev/\" 'force)
+ (eev \"rm -Rv /tmp/foo\\nmkdir /tmp/foo/\\ncd /tmp/foo/\\n\")
+
+Now run this script
+
+ (eepitch-bash)
(eepitch-kill)
- (eepitch-comint \"A\" \"eechannel -v A /bin/sh\")
-echo 1
+ (eepitch-bash)
+export PS1='$PWD# '
+function ee () { set -v; . ~/.eev/ee.sh; set +v; }
+
+
+
+2. `ee'
+=======
+\[Explain how several interpreters can be programmed to accept
+an `ee' command to execute temporary scripts\]
+
+ http://angg.twu.net/eev-article.html#making-progs-receive-cmds
+
+ (find-eev \"eev-langs.el\")
+ (find-eev \"eev-bounded.el\")
+ (find-eev \"eev-rctool\")
- (find-sh0 \" cat $EEVTMPDIR/eech.A.pid\")
- (find-sh0 \"echo 'echo 2' > $EEVTMPDIR/eech.A.str\")
- (find-sh0 \" cat $EEVTMPDIR/eech.A.str\")
- (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
-
- (find-sh0 \"echo 'echo 3' > $EEVTMPDIR/eech.A.str\")
- (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
-echo 4
-If the eepitched shell did run \"echo 1\", \"echo 2\", \"echo
-3\", \"echo 4\", then things are working - \"echo 1\" and \"echo
-4\" were sent through eepitch, but \"echo 3\" and \"echo 4\" were
-sent though channels.
-Now let's check if we can run an xterm, and if it can run an
-eechannel-ed shell instead of a plain shell. Check if the second
-sexp above starts an xterm, displays the info from \"eechannel
--v\", and then runs a shell:
- (find-bgprocess \"xterm\")
- (find-bgprocess \"xterm -e eechannel -v A $SHELL\")
- (find-bgprocess \"xterm -e eechannel A $SHELL\")
+3. An `ee' for Python
+=====================
+Here is a simple way to make Python execute commands saved in a
+temporary script when the user types `ee()' (note that it is not
+just `ee' - the `()' is needed). We will show first an example in
+which the temporary script is prepared by running \"cat\" from a
+shell - then we will explain a more user-friendly way to save a
+region from the current buffer as the temporary script.
-if that worked, run the four sexps below with <f8>,
+Note that the demo below uses `find-wset', which is an
+advanced (i.e., hackish) feature explained here:
- (find-sh0 \"echo 'echo 1' > $EEVTMPDIR/eech.A.str\")
- (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
- (find-sh0 \"echo 'echo 2' > $EEVTMPDIR/eech.A.str\")
- (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
+ (find-multiwindow-intro \"Several eepitch targets\")
-and check if the eechannel-ed shell in the xterm has received the
-commands \"echo 1\" and \"echo 2\". If it did, try the
-higher-level version below - but use <f9>s on each line instead
-of the <f8>s:
+ (find-3EE '(eepitch-shell) '(eepitch-python))
+ (find-3ee '(eepitch-shell) '(eepitch-python))
+ (eepitch-python)
+import os
+def ee():
+ exec(open(os.getenv(\"HOME\")+\"/.eev/ee.py\").read(), globals())
- (eexterm \"A\")
-echo 3
-echo 4
+ (eepitch-shell)
+cat > ~/.eev/ee.py <<'%%%'
+print(1+2)
+%%%
-If that worked, we're done. =)
+ (eepitch-python)
+ee()
+ (eepitch-shell)
+cat > ~/.eev/ee.py <<'%%%'
+def foo (x):
+ return x*x
+print(foo(5))
+%%%
-6. Several xterms
-=================
-http://angg.twu.net/eev-current/anim/channels.anim.html
+ (eepitch-python)
+ee()
+print(foo(6))
- (eexterm \"A\")
- (eexterm \"B\")
-# listen on port 1234
-netcat -l -p 1234
- (eexterm \"A\")
-# Send things to port 1234 (on localhost)
-{
- echo hi
- sleep 1
- echo bye
- sleep 1
-} | netcat -q O localhost 1234
+4. `eepy'
+=========
+The function `eev' receives three parameters, called `s', `e', and
+`altfile'; `e' and `altfile' are optional, and `s' should be either a
+string or a number. When `s' is a string, then the commands to be
+saved into the temporary script are taken from `s'; the numeric case
+will be discussed later.
+A call to
+ (eev \"print(1+2)\" nil \"~/.eev/ee.py\")
+writes \"print(1+2)\" (with an added trailing newline, but that's
+a technical detail) into the \"alternative file\"
+\"~/.eev/ee.py\" - the default would be \"~/.eev/ee.sh\". We can
+use that to simplify our demo a bit:
+ (eek \"C-x 1\")
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+import os
+def ee():
+ exec(open(os.getenv(\"HOME\")+\"/.eev/ee.py\").read(), globals())
-\[NOT DONE YET. The rest is (recyclable) garbage.\]
+ (eev \"print(1+2)\" nil \"~/.eev/ee.py\")
+ee()
+ (eev \"def foo (x):\\n return x*x\\n\\nprint(foo(5))\" nil
\"~/.eev/ee.py\")
+ee()
+print(foo(6))
+ In the example below the first line defines a `eepy' in a
+ simplistic way:
+ (defun eepy (s &optional e) (eev s e \"~/.eev/ee.py\"))
+ (eek \"C-x 1\")
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+import os
+def ee():
+ exec(open(os.getenv(\"HOME\")+\"/.eev/ee.py\").read(), globals())
+ (eepy \"print(1+2)\")
+ee()
+ (eepy \"def foo (x):\\n return x*x\\n\\nprint(foo(5))\")
+ee()
+print(foo(6))
-\(Old stuff:)
- emacs runs: (find-bgprocess \"xterm -T 'channel A' -e eegchannel A /bin/sh\")
- xterm runs: eegchannel A /bin/sh
- eegchannel saves its pid at ~/.eev/eeg.A.pid and runs: /bin/sh
-At this point the xterm is running a shell that is \"listening on
-channel A\"; eegchannel pretends to be transparent and passes all
-characters and signals in the vertical arrows transparently - but when
-it receives a certain signal (a SIGUSR1) it reads the contents from
-the file ~/.eev/eeg.A.str and passes it to the shell, as if those
-characters were coming from the xterm - i.e., as if the used had typed
-them.
+5. `M-x eepy' and `M-x eev'
+===========================
+Now let's define a more realistic `eepy' - one that can also be
+called interactively. We want `M-x eepy' to save the current
+_region_ into the temporary script; `eepy' has to be a _command_,
+and we will use the argument \"r\" to its `interactive' clause,
+to make the function `eepy' receive two numbers - the start and
+the end of the region - and it will pass these two numbers to
+`eev'.
-Here are the details of this \"protocol\":
-when we type F9 on a line containing \"echo foo\",
+ (defun eepy (s &optional e)
+ \"Save the region between S and E (or the string S) into ~/.eev/ee.py .\"
+ (interactive \"r\")
+ (eev s e \"~/.eev/ee.py\"))
- emacs saves the string \"echo foo\\n\" into ~/.eev/A.str,
- emacs reads the pid of eegchannel from ~/.eev/eeg.A.pid (say, \"1022\"),
- emacs runs \"kill -USR1 1022\",
- eegchannel reads the string from ~/.eev/A.str, and sends it to the shell.
+When the first argument, `s', to `eev', is a number, not a
+string, then `eev' expects the second argument, `e', to also be a
+number - and then `s' and `e' are considered as the extremities
+of a region of text in the current buffer. This idea - that the
+first argument can be either a string or a number - comes from:
-NOTE: one frequent question is: \"why are you using two normal files
-and SIGUSR1s for the communication between emacs and eegchannel,
-instead of making them talk through a fifo?\" - the answer is: try to
-explain the details of fifos - including creation - to someone who
-knows little about the inner workings of a *NIX kernel and who is
-uncomfortable to accept another kind of black box... The way with two
-files and SIGUSR1s is simpler, works well enough, and I've been able
-to write all the code for it in a few hours - and I still don't know
-enough about fifos to implement a fifo version of this.
+ (find-efunctiondescr 'write-region \"If START is a string\")
-and another one, that was mostly used to control external
-programs running in dedicated xterms. You can see an animation
-demonstrating it - and an explanation of what each line does -
-here:
+But try these:
- http://angg.twu.net/eev-current/anim/channels.anim.html
- http://angg.twu.net/eev-current/doc/shot-f9.png
+ (ee-se-to-string \"foo\" nil)
+ (ee-se-to-string-with-nl \"foo\" nil)
+ (ee-se-to-string \"foo\\n\" nil)
+ (ee-se-to-string-with-nl \"foo\\n\" nil)
+ (ee-se-to-string (- (point) 5) (point))
+ (ee-se-to-string-with-nl (- (point) 5) (point))
+ (ee-se-to-string (point) (- (point) 5))
+ (ee-se-to-string-with-nl (point) (- (point) 5))
-How to set it up
-================
-\[To be written\]
- ssh edrx@other.machine
- eegchannel A ssh edrx@other.machine
- (find-prepared-intro \"\\n`ee'\\n\")
- (find-eev \"anim/channels.anim\")
-" pos-spec-list)))
+\[Garbage:\]
-;; (find-channels-intro)
+ (find-elnode \"Defining Commands\")
+ (find-defun-intro \"\\ninteractive\\n\")
+ (find-efunction 'eev)
+" rest)))
+;; (find-prepared-intro)
+;; (find-bashnode "Bourne Shell Builtins" "current shell context")
-;;; _ _
-;;; __ _(_) __| | ___ ___ ___
-;;; \ \ / / |/ _` |/ _ \/ _ \/ __|
-;;; \ V /| | (_| | __/ (_) \__ \
-;;; \_/ |_|\__,_|\___|\___/|___/
-;;;
-;; «find-videos-intro» (to ".find-videos-intro")
-;; Skel: (find-intro-links "videos")
-(defun find-videos-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-videos-intro)*"))
+
+;;; _ _ _
+;;; | |__ ___ _ _ _ __ __| | ___ __| |
+;;; | '_ \ / _ \| | | | '_ \ / _` |/ _ \/ _` |
+;;; | |_) | (_) | |_| | | | | (_| | __/ (_| |
+;;; |_.__/ \___/ \__,_|_| |_|\__,_|\___|\__,_|
+;;;
+;; «find-bounded-intro» (to ".find-bounded-intro")
+;; Skel: (find-intro-links "bounded")
+(defun find-bounded-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-bounded-intro)*"))
(apply 'find-eintro "\
-\(Re)generate: (find-videos-intro)
-Source code: (find-efunction 'find-videos-intro)
+\(Re)generate: (find-bounded-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-bounded-intro\")
More intros: (find-eev-quick-intro)
(find-eev-intro)
(find-eval-intro)
@@ -10216,3676 +10200,3825 @@ This buffer is _temporary_ and _editable_.
It is meant as both a tutorial and a sandbox.
-This intro is being rewritten.
-Prerequisites:
- (find-psne-intro)
- (find-audiovideo-intro)
- (find-audiovideo-intro \"4. Short hyperlinks to audio and video files\")
- (find-audiovideo-intro \"7. `code-psnevideo'\")
- (find-audiovideo-intro \"7.1. `code-eevvideo'\")
+
+Note that you need to understand the concept of \"prepared
+shells\" quite well to be able to use this... see:
+
+ (find-prepared-intro)
+
+
+
+Bad news: I've been using this feature very little, and I have
+not yet adapted the old, crappy docs to the new \"intro\"
+format... =\\ So this is just a bunch of notes!
+
+Source code: \(find-eev \"eev-bounded.el\")
+Obsolete related code: \(find-eev \"eev-langs.el\")
+Old mentions to this: \(find-TH \"eev-article\" \"delimited-regions\")
+ http://angg.twu.net/eev-article.html#delimited-regions
+
+
+
+
+Delimited (\"bounded\") regions
+=============================
+Try:
+
+#
+# (eev-bounded)
+cd
+echo At: $PWD
+cd /tmp/
+echo At: $PWD
+
+#
+%
+% (eelatex-bounded)
+
+Hello
+
+%
+Defining new bounded functions
+==============================
+Try:
+ (find-code-bounded 'eev-bounded 'eev \"\\n#\\n\")
+ (find-code-bounded 'eev-bounded 'eev 'ee-delimiter-hash)
+as usual, when we remove the \"find-\"s the generated code is
+executed instead of displayed.
-1. Some videos
-==============
-At this moment I have these eight videos about eev (I am
-deliberately ignoring the ones that I consider obsolete!):
- 1. \"How to record executable notes with eev - and how to play them back\":
- http://angg.twu.net/emacsconf2019.html
- http://angg.twu.net/emacsconf2019.html#code-video
- http://angg.twu.net/eev-videos/emacsconf2019.mp4
- http://www.youtube.com/watch?v=86yiRG8YJD0
- (find-eev2019video)
- 2. \"On why most of the best features in eev look like 5-minute hacks\":
- http://angg.twu.net/emacsconf2020.html
- http://angg.twu.net/emacsconf2020.html#code-video
- http://angg.twu.net/eev-videos/emacsconf2020.mp4
- http://www.youtube.com/watch?v=hOAqBc42Gg8
- (find-eev2020video)
- 3. \"How to install eev with M-x list-packages and how to navigate its
tutorials\":
- http://angg.twu.net/2020-list-packages-eev-nav.html
- http://angg.twu.net/2020-list-packages-eev-nav.html#code-video
- http://angg.twu.net/eev-videos/2020-list-packages-eev-nav.mp4
- http://www.youtube.com/watch?v=kxBjiUo88_U
- (find-eevnavvideo)
+The default bounded function
+============================
+...is stored in the variable `ee-bounded-function', and can be
+re-run with `M-x ee-bounded-function' (i.e., there's a function
+with the same name as the variable). I used to bind `f3' to that,
+but in modern Emacsen this is bound to a macro key:
- 4. \"Some template-based functions of eev that are not five-minute hacks\":
- http://angg.twu.net/2020-some-template-based.html
- http://angg.twu.net/2020-some-template-based.html#code-video
- http://angg.twu.net/eev-videos/2020-some-template-based.mp4
- http://www.youtube.com/watch?v=91-9YfRPsuk
- (find-eevtemplvideo)
+ (find-enode \"Basic Keyboard Macro\" \"<F3>\")
- 5. \"How to create hyperlinks to \"here\" with `find-here-links'\":
- http://angg.twu.net/2020-find-here-links.html
- http://angg.twu.net/2020-find-here-links.html#code-video
- http://angg.twu.net/eev-videos/2020-find-here-links.mp4
- http://www.youtube.com/watch?v=8jtiBlaDor4
- (find-eevfherelvideo)
+so you should do something like this, but for your favourite key:
- 6. \"Using test blocks in eev\":
- http://angg.twu.net/2021-test-blocks.html
- http://angg.twu.net/eev-videos/2021-test-blocks.mp4
- http://www.youtube.com/watch?v=fpsF_M55W4o
- (find-eevtestblsvideo)
+ (define-key eev-mode-map [f3] 'ee-bounded-function)
+" pos-spec-list)))
- 7. \"Short videos about workflows - and how to upload them\":
- http://angg.twu.net/2021-ssr.html
- http://angg.twu.net/eev-videos/2021-ssr.mp4
- http://www.youtube.com/watch?v=_0_NLXTVhBk
+;; (find-bounded-intro)
- 8. \"How to use the `[Video links:]' blocks in the `intro's of eev\"
- http://angg.twu.net/2021-video-links.html
- http://angg.twu.net/eev-videos/2021-video-links.mp4
- http://www.youtube.com/watch?v=xQqWufQgzVY
- (find-eevvlinksvideo \"0:00\")
-The ones that I prepared for the two EmacsConfs are very
-well-rehearsed, the other ones are not.
-The links with #code-video, like
+;;; _ _
+;;; ___| |__ __ _ _ __ _ __ ___| |___
+;;; / __| '_ \ / _` | '_ \| '_ \ / _ \ / __|
+;;; | (__| | | | (_| | | | | | | | __/ \__ \
+;;; \___|_| |_|\__,_|_| |_|_| |_|\___|_|___/
+;;;
+;; «find-channels-intro» (to ".find-channels-intro")
+;; Skel: (find-intro-links "channels")
- http://angg.twu.net/emacsconf2019.html#code-video
+(defun find-channels-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-channels-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-channels-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-channels-intro\")
+More intros: (find-eev-quick-intro)
+ (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
-point to indexes of the videos made with sexp hyperlinks.
-The best way to watch them is to download local copies of their
-.mp4s and then use the short hyperlinks described in
- (find-audiovideo-intro \"4. Short hyperlinks to audio and video files\")
+1. Introduction
+===============
+Before eepitch had been invented eev had two other ways to send
+commands to external shell-like programs. The first way,
+described here,
-to jump to positions in them.
+ (find-prepared-intro \"\\n`ee'\\n\")
+
+was technically very simple: running `M-x eev' would save a
+series of commands - usually the contents of the region - into a
+temporary script file, and then the user would type something
+like `ee' at the prompt of a (\"prepared\") shell; that would
+make it read the saved commands and execute them.
+Here we will describe the second of the Old Ways - one in which
+the target program, which is usually a shell running in an xterm,
+is sent a signal saying \"execute the command NOW\" as soon as a
+command is saved into a temporary file by Emacs. The difficulty
+is that this requires not only a directory for temporary files,
+but also an Expect script, which acts as an intermediary that
+listens to signals and handles them pretending that the saved
+commands came from the keyboard... and, as some people have said,
+this is \"a nightmare to set up\".
+Here we explain the protocol - that can be adapted to other
+cases too, like, for example, to make Emacs talk to SmallTalk
+environments and to computer algebra systems with GUIs - and we
+will present several tests that should help with troubleshooting.
-2. Short links to eev video tutorials
-=====================================
-The \"short links to eev video tutorials\" are made to be trivial
-to use from the _htmlized_ versions of the intros; they are not
-so trivial from Emacs. If you open the htmlized version of this
-section in a browser - its URL is:
- http://angg.twu.net/eev-intros/find-videos-intro.html#2
-you will notice that links like
- (find-eev2020video \"6:25\" \"`find-video'\")
- \\---------------/ \\--/
- function name: time:
- points to here points to
- (this section) YouTube
+2. Low-level tests
+==================
+Before we start the theory please try these low-level tests.
-have two hyperlinks: the function name, \"find-eev2020video\",
-points to this section of this intro, and the timestamp,
-\"6:25\", points to YouTube; in this example, the \"6:25\" points
-to my presentation about eev in the EmacsConf2020, and it plays
-that video starting from 6:25.
-At this moment only these `find-eev*video' function are htmlized
-in this way:
+2.1. Preparation
+----------------
+Have have to make sure that:
- 1. \"How to record executable notes with eev - and how to play them back\"
- http://angg.twu.net/emacsconf2019.html
- (find-eev2019video \"0:00\")
+ 1) \"eev-channel.el\" has been loaded,
+ 2) the \"$EEVDIR/eegchannel\" script exists and is executable,
+ 3) we have expect installed - eegchannel depends on it,
+ 4) the temporary directory \"$EEVTMPDIR/\" exists.
- 2. \"On why most of the best features in eev look like 5-minute hacks\"
- http://angg.twu.net/emacsconf2020.html
- (find-eev2020video \"0:00\")
+Here is an e-script for that:
- 3. \"How to install eev with M-x list-packages and how to navigate its
tutorials\"
- http://angg.twu.net/2020-list-packages-eev-nav.html
- (find-eevnavvideo \"0:00\")
+ (add-to-list 'load-path (ee-expand \"$EEVDIR\"))
+ (require 'eev-channel)
- 4. \"Some template-based functions of eev that are not five-minute hacks\"
- http://angg.twu.net/2020-some-template-based.html
- (find-eevtemplvideo \"0:00\")
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+sudo apt-get install expect
+echo $EEVDIR
+cd $EEVDIR
+pwd
+wget -nc http://angg.twu.net/eev-current/eegchannel
+chmod 755 eegchannel
+ls -lAF $EEVDIR/eegchannel
+expect -v
+$EEVDIR/eegchannel A echo ok
+echo $EEVTMPDIR
+mkdir -p $EEVTMPDIR/
- 5. \"How to create hyperlinks to \"here\" with `find-here-links'\"
- http://angg.twu.net/2020-find-here-links.html
- (find-eevfherelvideo \"0:00\")
+# (find-eev \"eegchannel\")
- 6. \"Using test blocks in eev\":
- http://angg.twu.net/2021-test-blocks.html
- (find-eevtestblocksvideo \"0:00\")
- 7. \"How to use the `[Video links:]' blocks in the `intro's of eev\"
- http://angg.twu.net/2021-video-links.html
- (find-eevvlinksvideo \"0:00\")
-If you follow these `find-eev*video' sexp hyperlinks in Emacs you
-will _usually_ get a temporary buffer with links to that video...
-see the next section.
-...or for an explanation in video, see:
+2.2. Test eegchannel
+--------------------
+In this test we create a window setting like this,
- http://angg.twu.net/2021-video-links.html
- (find-eevvlinksvideo \"0:00\")
- http://www.youtube.com/watch?v=xQqWufQgzVY
+ ______________________
+ | | |
+ | | shell |
+ | this |___________|
+ | intro | |
+ | | shell 2 |
+ |__________|___________|
+and then:
+ 1) we run \"eegchannel A python\" at the lower shell. This runs
+ a python interpreter \"listening on channel A\";
+ 2) we use the top shell to send the lines \"print(2+3)\" and
+ \"exit()\" \"through the channel A\". In low-level terms
+ this means that for each line
+ a) we save it into the file \"$EEVTMPDIR/eeg.A.str\",
-3. Some `find-eevvideo-links'
-=============================
-When you run a sexp like this
+ b) we send a signal SIGUSR1 to the process -
+ \"eegchannel\" - whose PID is stored in the file
+ \"$EEVTMPDIR/eeg.A.pid\".
- (find-eev2020video \"0:00\")
+ c) When the eegchannel listening on the channel A receives
+ a SIGUSR1 it sends the line in \"$EEVTMPDIR/eeg.A.str\"
+ to the process that it controls (that is \"python\") \"as
+ if the user had typed it\".
-in Emacs it by default runs this,
+Here is the demo. Run it with <F8>s:
- (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\" \"0:00\")
+ (find-3EE '(eepitch-shell) '(eepitch-shell2))
+ (find-3ee '(eepitch-shell) '(eepitch-shell2))
+ (eepitch-shell)
+# Optional clean-up:
+ls -lAF $EEVTMPDIR/eeg.A.*
+rm -fv $EEVTMPDIR/eeg.A.*
-that creates a temporary buffer containing commands for doing
-several things - like downloading a local copy of that video,
-playing the local copy, and overriding the definition of
-`find-eev2020video' with another one, that plays the local copy
-straight away without creating a temporary buffer.
+ (eepitch-shell2)
+# Start a python interpreter \"listening on channel A\":
+$EEVDIR/eegchannel A python3
-That temporary buffer is a bit hard to understand, and I need to
-make a video explaining how to use each part of it (TODO!
-Urgent)...
+ (eepitch-shell)
+# Check that eeg.A.pid exists and is very recent:
+date
+ls -lAF $EEVTMPDIR/eeg.A.*
-The \"short links to eev video tutorials\" listed above call
-these `find-eevvideo-links' sexps:
+# Send lines to eegchannel:
+echo 'print(2+3)' > $EEVTMPDIR/eeg.A.str
+kill -USR1 $(cat $EEVTMPDIR/eeg.A.pid)
+echo 'exit()' > $EEVTMPDIR/eeg.A.str
+kill -USR1 $(cat $EEVTMPDIR/eeg.A.pid)
- 1. (find-eevvideo-links \"eev2019\" \"emacsconf2019\" \"86yiRG8YJD0\")
- 2. (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\")
- 3. (find-eevvideo-links \"eevnav\" \"2020-list-packages-eev-nav\"
\"kxBjiUo88_U\")
- 4. (find-eevvideo-links \"eevtempl\" \"2020-some-template-based\"
\"91-9YfRPsuk\")
- 5. (find-eevvideo-links \"eevfherel\" \"2020-find-here-links\"
\"8jtiBlaDor4\")
- 6. (find-eevvideo-links \"eevtestblocks\" \"2021-test-blocks\"
\"fpsF_M55W4o\")
- 7. (find-eevvideo-links \"2021ssr\" \"2021-ssr\" \"_0_NLXTVhBk\")
-They are htmlized in a nice way - see:
- http://angg.twu.net/eev-intros/find-videos-intro.html#3
+2.3. Test `eechannel'
+---------------------
+TODO: write this.
+See:
-The function `find-eevvideo-links' is explained here:
+ (find-eev \"eev-channels.el\" \"eechannel\")
- (find-audiovideo-intro \"7.2. `find-eevvideo-links'\")
-" pos-spec-list)))
+2.4. Test `eexterm'
+-------------------
+TODO: write this.
+See:
-;; (find-videos-intro)
+ (find-eev \"eev-channels.el\" \"eexterm\")
-;;; _ _ _ _ _
-;;; __ _(_) __| | ___ ___ | (_)_ __ | | _____
-;;; \ \ / / |/ _` |/ _ \/ _ \ _____| | | '_ \| |/ / __|
-;;; \ V /| | (_| | __/ (_) |_____| | | | | | <\__ \
-;;; \_/ |_|\__,_|\___|\___/ |_|_|_| |_|_|\_\___/
-;;;
-;; «find-video-links-intro» (to ".find-video-links-intro")
-;; Skel: (find-intro-links "video-links")
-;; Test: (find-video-links-intro)
+3. The innards
+==============
+Let's start with a detailed low-level view of of what we have
+just summarized as to \"save a command into a temporary file,
+then send a signal to the external program etc etc\".
-(defun find-video-links-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-video-links-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-video-links-intro)
-Source code: (find-efunction 'find-video-links-intro)
-More intros: (find-eev-quick-intro)
- (find-eev-intro)
- (find-eepitch-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
+Warning: this document is still VERY INCOMPLETE, and some parts
+of it are just notes, drafts, and links that may not work for
+you... =(
+ (find-eev \"eegchannel\")
+ (find-eev \"anim/\")
+ (find-eev \"anim/channels.anim\")
+ http://angg.twu.net/eev-current/eegchannel.html
-1. Introduction
-===============
-Many of the tutorials of eev have \"[Video links:]\" blocks.
-For example:
- (find-eev-quick-intro \"4. Creating Elisp Hyperlinks\")
- (find-eev-quick-intro \"4. Creating Elisp Hyperlinks\" \"[Video links:]\")
- (find-eev-quick-intro \"6. Controlling shell-like programs\")
- (find-eev-quick-intro \"6. Controlling shell-like programs\" \"[Video
links:]\")
-They contain links like these,
+4. The protocol, in diagrams
+============================
+Here's a diagram that shows roughly what we have when X is
+running both an Emacs and an xterm, each in a separate window.
+Many details have been omitted - for examples, the real
+communication happens through fifos and ptys, that are not shown
+- but it's easy to build a complete diagram from this. The arrows
+indicate flow of information.
- (find-eevnavvideo \"10:36\" \"if I type <f8> six times here\")
- (find-eev2019video \"15:11\" \"Demo: the eepitch block (in red star lines)\")
- (find-eevtestblsvideo \"2:33\" \"if I run f8 here I start a new Lua
interpreter\")
+ keyboard mouse display
+ | | ^
+ v v |
+ +----------------------------+
+ | |
+ | X |
+ | |
+ +----------------------------+
+ key/mouse | ^ display key/mouse | ^ display
+ events v | commands events v | commands
+ +---------+ +---------+
+ | | | |
+ | emacs | | xterm |
+ | | | |
+ +---------+ +---------+
+ chars and | ^ chars and
+ signals v | signals
+ +---------+
+ | |
+ | sh |
+ | |
+ +---------+
-that are \"short links to eev video tutorials\". These functions
-with names like `find-eev*video' are _sort of_ expanded to
-functions that specify explicitly which video on youtube to play,
-and where the local copy of the video can be found if we prefer
-to play the local copy. For the general idea of how this
-expansion is implemented, see:
+To make the external shell at the right able to receive commands
+from Emacs we will insert a program between the \"xterm\" and the
+\"sh\" boxes - an Expect script called eechannel, that will
+usually be totally transparent, in the sense that it will let all
+the chars and signals that it receives pass through it without
+changes.
- (find-eev-quick-intro \"9. Shorter hyperlinks\")
- (find-eev-quick-intro \"9.1. `code-c-d'\")
- (find-eev-quick-intro \"9.1. `code-c-d'\" \"{c}\")
+The trick is that \"eechannel\" will also be \"listening to
+commands from the outside\", according to the following protocol:
-The strings \"eevnav\", \"eev2019\", and \"eevtestbls\" in the
-names of the functions correspond to the argument \"c\" of
-`code-c-d'.
+ 1) each instance of eechannel \"listens\" to a fixed, named
+ \"channel\"; for simplicity, let's suppose that this name is
+ \"A\".
+ 2) When an eechannel receives a signal SIGUSR1 it reads a
+ string from the file \"eech.A.str\" and sends that to the
+ shell, as if the user had typed that.
+ 3) To make it simpler to send the signal, when eechannel starts
+ up it saves its pid into the file \"eech.A.pid\".
+That protocol can be depicted as the four horizontal arrows
+below; the temporal order is from top to bottom.
-2. From the HTML
-================
-The \"intros\" of eev can be read both from Emacs and from a
-browser. For example, the HTMLized version of this intro is at:
+ +-------------+
+ | |
+ | xterm |
+ | |
+ +-------------+
+ +-----------+ | ^
+ | | --> eeg.A.str v |
+ | emacs | <-- eeg.A.pid +-------------+
+ | | -----------------> | |
+ +-----------+ eeg.A.str ---> | eechannel A |
+ | |
+ +-------------+
+ | ^
+ v |
+ +-------------+
+ | |
+ | sh |
+ | |
+ +-------------+
- http://angg.twu.net/eev-intros/find-video-links-intro.html
+When Emacs wants to send a line, say, \"cd /tmp/\", to eechannel,
+it does this:
-In the HTMLized version each \"short link to a video tutorial\"
-has two hyperlinks, like this:
+ 1) \"--> eeg.A.str \" writes \"cd /tmp/\" into eech.A.str,
+ 2) \"<-- eeg.A.pid \" reads eechannel's pid from eech.B.str,
+ 3) \"----------------->\" sends a signal SIGUSR1 to that pid,
+ 4) \" eeg.A.str --->\" ...and when eechannel receives a SIGUSR1
+ it reads the contents of eech.A.str and
+ sends that to its spawned shell.
- (find-eev2020video \"6:25\" \"`find-video'\")
- \\---------------/ \\--/
- function name: time:
- points to here points to
- (this section) YouTube
+Actually there's something else - how these programs are started.
+If we run just \"xterm\", it behaves in its default way, and runs
+a shell. But if we run
-the function name, \"find-eev2020video\", points to a place -
-this section! - with help about how these links work, and the
-timestamp, \"6:25\", points to YouTube; in this example, the
-\"6:25\" points to my presentation about eev in the
-EmacsConf2020, and it plays that video starting from 6:25. More
-precisely, the \"6:25\" points to:
+ \"xterm -e eechannel A /bin/sh\"
- https://www.youtube.com/watch?v=hOAqBc42Gg8#t=6m25s
- \\---------/ \\---/
- \"hash\" time
+then xterm runs \"eechannel A /bin/sh\" instead of just
+\"/bin/sh\"; and \"eechannel A /bin/sh\" runs \"/bin/sh\".
-We call the string \"hOAqBc42Gg8\" the \"hash\" of the video;
-calling it the \"youtube id\" of the video would be more precise,
-but longer. The \"6:25\" is converted to a \"#t=6m25s\", that
-makes youtube start playing the video from the right position.
+Also, evaluating this
+ (find-bgprocess \"xterm\")
+from Emacs runs an xterm, which runs a shell; evaluating either
+of these sexps,
+ (find-bgprocess \"xterm -e eechannel A /bin/sh\")
+ (find-bgprocess \"xterm -e eechannel A $SHELL\")
-3. `find-youtube-video'
-=======================
-In some situations - see the section 7 - running
+runs an xterm, which runs the \"eechannel\" script, which runs a
+shell. The sexp
- (find-eev2020video \"6:25\" \"`find-video'\")
+ (eexterm \"A\")
-makes Emacs run this:
+is a shorthand for the one using \"$SHELL\". Also, note that
+\"eechannel A ...\" saves its pid into \"eech.A.pid\".
- (find-youtube-video \"hOAqBc42Gg8\" \"6:25\")
+The diagram that shows what happens when we run `(eexterm \"A\")'
+is this one, below - note that the four arrows of the sending
+protocol are not shown.
-Note that running this sexp
+ +------------+
+ | |
+ | X |
+ | |
+ +------------+
+ / ^ \\ ^
+ v / v \\
+ +-----------+ +-------------+
+ | | initiates | |
+ | emacs |:::::::::::>| xterm |
+ | | | |
+ +-----------+ +-------------+
+ :: | ^
+ \\/ v |
+ +-------------+
+ | |
+ eeg.A.pid <-- | eechannel A |
+ | |
+ +-------------+
+ :: | ^
+ \\/ v |
+ +-------------+
+ | |
+ | sh |
+ | |
+ +-------------+
- (ee-find-youtube-video \"hOAqBc42Gg8\" \"6:25\")
-returns one of these sexps,
- (find-googlechrome \"http://www.youtube.com/watch?v=hOAqBc42Gg8#t=6m25s\")
- (find-firefox \"http://www.youtube.com/watch?v=hOAqBc42Gg8#t=6m25s\")
+5. Downloading and testing eechannel
+====================================
+Here I'll suppose that the directory \"~/bin/\" exists and is in
+your PATH. Run this to download the \"eechannel\" script and make
+it executable:
-according to the variable `ee-find-youtube-video-program'; you
-can configure it to use one of the most common browsers with:
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+cd ~/bin/
+# See: http://angg.twu.net/bin/eechannel.html
+wget -n http://angg.twu.net/bin/eechannel
+chmod 755 eechannel
- (setq ee-find-youtube-video-program 'find-googlechrome)
- (setq ee-find-youtube-video-program 'find-firefox)
+Now let's test - from Emacs - if a local copy of \"eechannel\"
+exists, is in your PATH, and can be executed (remember that it
+needs Expect). Calling \"eechannel\" with not enough arguments
+should yield a nice error message.
+ (find-fline \"~/bin/eechannel\")
+ (find-sh \"~/bin/eechannel\")
+ (find-sh \"eechannel\")
+It uses the environment variable EEVTMPDIR to decide where the
+temporary files - ee.CHANNELAME.pid, ee.CHANNELNAME.str - will
+be, so let's check that this directory exists:
+ (getenv \"EEVTMPDIR\")
+ (find-fline \"$EEVTMPDIR/\")
-4. Configuring the browser
-==========================
-The variables `ee-firefox-program' and `ee-googlechrome-program'
-determine the programs that `find-firefox' and
-`find-googlechrome' should try to execute. You can test if they
-are correct by trying:
+Running eechannel with a first argument \"-v\" should show a lot
+of info, and then save the pid at eech.CHANNELAME.pid and run the
+given command. Let's try with a command that exits immediately.
- (find-firefox \"http://www.lua.org/start.html\")
- (find-googlechrome \"http://www.lua.org/start.html\")
+ (find-sh \"eechannel -v A /bin/true\")
+ (find-fline \"$EEVTMPDIR/\" \"eech.A.pid\")
-Typically on GNU/Linux systems the right values are:
+Now let's verify - using just eepitch, without xterm at this
+moment - whether eechannel is being able to receive signals. In
+the eepitch script below, two `(find-sh0 \"kill ...\")'s should
+each make the controlled program receive a command - at the first
+\"kill\" an \"echo 2\", at the second an \"echo 3\".
- (setq ee-firefox-program \"firefox\")
- (setq ee-googlechrome-program \"google-chrome\")
+ (eepitch-comint \"A\" \"eechannel -v A /bin/sh\")
+ (eepitch-kill)
+ (eepitch-comint \"A\" \"eechannel -v A /bin/sh\")
+echo 1
-and on M$ Windows typically what works is something like:
+ (find-sh0 \" cat $EEVTMPDIR/eech.A.pid\")
+ (find-sh0 \"echo 'echo 2' > $EEVTMPDIR/eech.A.str\")
+ (find-sh0 \" cat $EEVTMPDIR/eech.A.str\")
+ (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
+
+ (find-sh0 \"echo 'echo 3' > $EEVTMPDIR/eech.A.str\")
+ (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
+echo 4
- (setenv \"FIREFOXDIR\" \"c:/Program Files/Mozilla Firefox\")
- (setenv \"GOOGLECHROMEDIR\" \"c:/Program Files/Google/Chrome/Application\")
- (setq ee-firefox-program \"$FIREFOXDIR/firefox.exe\")
- (setq ee-googlechrome-program \"$GOOGLECHROMEDIR/chrome.exe\")
+If the eepitched shell did run \"echo 1\", \"echo 2\", \"echo
+3\", \"echo 4\", then things are working - \"echo 1\" and \"echo
+4\" were sent through eepitch, but \"echo 3\" and \"echo 4\" were
+sent though channels.
-but people usually have to adjust the paths by hand. One way to
-test if the paths are right is to open the directories in dired
-and see if the files \"firefox.exe\" and \"chrome.exe\" are there
-- i.e., run these sexps and see if they find the right files in
-the right directories:
+Now let's check if we can run an xterm, and if it can run an
+eechannel-ed shell instead of a plain shell. Check if the second
+sexp above starts an xterm, displays the info from \"eechannel
+-v\", and then runs a shell:
- (find-fline \"$FIREFOXDIR/\" \"firefox.exe\")
- (find-fline \"$GOOGLECHROMEDIR/\" \"chrome.exe\")
+ (find-bgprocess \"xterm\")
+ (find-bgprocess \"xterm -e eechannel -v A $SHELL\")
+ (find-bgprocess \"xterm -e eechannel A $SHELL\")
-If you've never heard of dired, then read this:
+if that worked, run the four sexps below with <f8>,
- (find-enode \"Dired\")
+ (find-sh0 \"echo 'echo 1' > $EEVTMPDIR/eech.A.str\")
+ (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
+ (find-sh0 \"echo 'echo 2' > $EEVTMPDIR/eech.A.str\")
+ (find-sh0 \"kill -USR1 $(cat $EEVTMPDIR/eech.A.pid)\")
+and check if the eechannel-ed shell in the xterm has received the
+commands \"echo 1\" and \"echo 2\". If it did, try the
+higher-level version below - but use <f9>s on each line instead
+of the <f8>s:
+ (eexterm \"A\")
+echo 3
+echo 4
+If that worked, we're done. =)
-5. Local copies
-===============
-In some situations - see section 7 - a sexp like
- (find-eev2020video \"6:25\" \"`find-video'\")
-will try to play a local copy of the video file. In the case of
-`find-eev2020video' this means a local copy of this file,
+6. Several xterms
+=================
+http://angg.twu.net/eev-current/anim/channels.anim.html
- http://angg.twu.net/eev-videos/emacsconf2020.mp4
+ (eexterm \"A\")
+ (eexterm \"B\")
+# listen on port 1234
+netcat -l -p 1234
-downloaded by `psne'-ing, as explained here:
+ (eexterm \"A\")
+# Send things to port 1234 (on localhost)
+{
+ echo hi
+ sleep 1
+ echo bye
+ sleep 1
+} | netcat -q O localhost 1234
- (find-psne-intro)
-The local copy will be played with Mpv, with:
- (find-mpv-video \"$S/http/angg.twu.net/eev-videos/emacsconf2020.mp4\"
\"6:25\")
+\[NOT DONE YET. The rest is (recyclable) garbage.\]
-6. Configuring Mpv
-==================
-After installing Mpv you may have to configure its path. On
-GNU/Linux this typically works,
- (setq ee-mpv-program \"mpv\")
-and on M$ Windows you will need something like this, but you will
-have to adjust the path:
- (setenv \"MPVDIR\" \"c:/Users/myusername/path/to/mpv\")
- (setq ee-mpv-program \"$MPVDIR/mpv.exe\")
-You can test if the path is right with the two sexps below. Note
-that the first is for M$ Windows only, and that the second one
-will display the basic command-line options of mpv.
- (find-fline \"$MPVDIR/\" \"mpv.exe\")
- (find-callprocess `(,ee-mpv-program \"--help\"))
+\(Old stuff:)
+ emacs runs: (find-bgprocess \"xterm -T 'channel A' -e eegchannel A /bin/sh\")
+ xterm runs: eegchannel A /bin/sh
+ eegchannel saves its pid at ~/.eev/eeg.A.pid and runs: /bin/sh
+At this point the xterm is running a shell that is \"listening on
+channel A\"; eegchannel pretends to be transparent and passes all
+characters and signals in the vertical arrows transparently - but when
+it receives a certain signal (a SIGUSR1) it reads the contents from
+the file ~/.eev/eeg.A.str and passes it to the shell, as if those
+characters were coming from the xterm - i.e., as if the used had typed
+them.
+Here are the details of this \"protocol\":
+when we type F9 on a line containing \"echo foo\",
-7. `find-eev-video'
-===================
-All the standard functions for short links to video tutorials are
-implemented using a function called `find-eev-video'. For
-example, `find-eev2020video' is defined as:
+ emacs saves the string \"echo foo\\n\" into ~/.eev/A.str,
+ emacs reads the pid of eegchannel from ~/.eev/eeg.A.pid (say, \"1022\"),
+ emacs runs \"kill -USR1 1022\",
+ eegchannel reads the string from ~/.eev/A.str, and sends it to the shell.
- ;; For the real definition, see:
- ;; (find-eev \"eev-audiovideo.el\" \"video-tutorials\")
- ;; (find-eev \"eev-audiovideo.el\" \"video-tutorials\" \"eev2020\")
- ;;
- (defun find-eev2020video (&optional time &rest rest)
- \"[Long docstring omitted]\"
- (interactive)
- (find-eev-video \"emacsconf2020\" \"hOAqBc42Gg8\" time))
+NOTE: one frequent question is: \"why are you using two normal files
+and SIGUSR1s for the communication between emacs and eegchannel,
+instead of making them talk through a fifo?\" - the answer is: try to
+explain the details of fifos - including creation - to someone who
+knows little about the inner workings of a *NIX kernel and who is
+uncomfortable to accept another kind of black box... The way with two
+files and SIGUSR1s is simpler, works well enough, and I've been able
+to write all the code for it in a few hours - and I still don't know
+enough about fifos to implement a fifo version of this.
-Calling:
+and another one, that was mostly used to control external
+programs running in dedicated xterms. You can see an animation
+demonstrating it - and an explanation of what each line does -
+here:
- (find-eev2020video \"6:25\" \"`find-video'\")
+ http://angg.twu.net/eev-current/anim/channels.anim.html
+ http://angg.twu.net/eev-current/doc/shot-f9.png
-runs:
- (find-eev-video \"emacsconf2020\" \"hOAqBc42Gg8\" \"6:25\")
-that runs one of these sexps, depending on the current settings:
+How to set it up
+================
+\[To be written\]
- (find-youtube-video \"hOAqBc42Gg8\" \"6:25\")
- (find-eevlocal-video \"emacsconf2020\" \"hOAqBc42Gg8\" \"6:25\")
- (find-eevlinks-video \"emacsconf2020\" \"hOAqBc42Gg8\" \"6:25\")
+ ssh edrx@other.machine
+ eegchannel A ssh edrx@other.machine
+ (find-prepared-intro \"\\n`ee'\\n\")
+ (find-eev \"anim/channels.anim\")
+" pos-spec-list)))
-The one with `find-eevlocal-video' plays the local copy of
+;; (find-channels-intro)
- http://angg.twu.net/eev-videos/emacsconf2020.mp4
-if it has already been downloaded, and if the local copy is not
-found it displays a temporary buffer with links and an e-script
-for downloading - i.e., psne-ing - the video from the URL above.
-The sexp with `find-eevlinks-video' works very similarly to the
-one with `find-eevlocal-video', but it always displays the
-temporary buffer with links and an e-script.
-You can select the behavior of `find-eev-video' - and thus the
-behavior of all short links to video tutorials, as they all call
-`find-eev-video' - by running one of the `setq's below:
- (setq ee-find-eev-video-function 'find-eevyoutube-video)
- (setq ee-find-eev-video-function 'find-eevlocal-video)
- (setq ee-find-eev-video-function 'find-eevlinks-video)
-`find-eevyoutube-video' is like `find-eev-video', but it discards
-its first argument.
+;;; _ _
+;;; __ _(_) __| | ___ ___ ___
+;;; \ \ / / |/ _` |/ _ \/ _ \/ __|
+;;; \ V /| | (_| | __/ (_) \__ \
+;;; \_/ |_|\__,_|\___|\___/|___/
+;;;
+;; «find-videos-intro» (to ".find-videos-intro")
+;; Skel: (find-intro-links "videos")
-The default is `find-eevlocal-video', but for Windows users
-starting with `find-eevyoutube-video' makes more sense. The
-user-friendly way to select one of these behaviors is with these
-sexps:
+(defun find-videos-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-videos-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-videos-intro)
+Source code: (find-efunction 'find-videos-intro)
+More intros: (find-eev-quick-intro)
+ (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
- (ee-use-local-videos)
- (ee-use-youtube-videos)
-You can also run them with `M-x ee-use-local-videos' and `M-x
-ee-use-youtube-videos'.
+This intro is being rewritten.
+Prerequisites:
+ (find-psne-intro)
+ (find-audiovideo-intro)
+ (find-audiovideo-intro \"4. Short hyperlinks to audio and video files\")
+ (find-audiovideo-intro \"7. `code-psnevideo'\")
+ (find-audiovideo-intro \"7.1. `code-eevvideo'\")
-8. Windows
-==========
-This is my n-th different implementation of the innards of the
-short links to video tutorials. This one - from nov/2021 - was
-inspired by feedback of the Windows users that participated in
-this workshop:
- https://lists.gnu.org/archive/html/help-gnu-emacs/2021-10/msg00037.html
- https://lists.gnu.org/archive/html/help-gnu-emacs/2021-10/msg00045.html
- http://angg.twu.net/2021-oficina.html (<- in Portuguese)
+1. Some videos
+==============
+At this moment I have these eight videos about eev (I am
+deliberately ignoring the ones that I consider obsolete!):
-My original implementation - from may/2021 - was the one
-described here:
+ 1. \"How to record executable notes with eev - and how to play them back\":
+ http://angg.twu.net/emacsconf2019.html
+ http://angg.twu.net/emacsconf2019.html#code-video
+ http://angg.twu.net/eev-videos/emacsconf2019.mp4
+ http://www.youtube.com/watch?v=86yiRG8YJD0
+ (find-eev2019video)
- http://angg.twu.net/2021-video-links.html
+ 2. \"On why most of the best features in eev look like 5-minute hacks\":
+ http://angg.twu.net/emacsconf2020.html
+ http://angg.twu.net/emacsconf2020.html#code-video
+ http://angg.twu.net/eev-videos/emacsconf2020.mp4
+ http://www.youtube.com/watch?v=hOAqBc42Gg8
+ (find-eev2020video)
-I'm trying to making the short links to video tutorials work from
-Emacs _in a way that is convenient for both long-time users and
-total beginners_. This is quite a challenge - especially because
-since oct/2021 my notion of \"total beginners\" includes \"people
-who use Windows and who have never used terminals in their
-lives\". If you are one of those \"total beginners\" my
-recommendation is: start by this tutorial - it will force you to
-learn how to configure paths and how to test if Emacs knows how
-to call a given external program - and then follow this one:
+ 3. \"How to install eev with M-x list-packages and how to navigate its
tutorials\":
+ http://angg.twu.net/2020-list-packages-eev-nav.html
+ http://angg.twu.net/2020-list-packages-eev-nav.html#code-video
+ http://angg.twu.net/eev-videos/2020-list-packages-eev-nav.mp4
+ http://www.youtube.com/watch?v=kxBjiUo88_U
+ (find-eevnavvideo)
- (find-windows-beginner-intro)
+ 4. \"Some template-based functions of eev that are not five-minute hacks\":
+ http://angg.twu.net/2020-some-template-based.html
+ http://angg.twu.net/2020-some-template-based.html#code-video
+ http://angg.twu.net/eev-videos/2020-some-template-based.mp4
+ http://www.youtube.com/watch?v=91-9YfRPsuk
+ (find-eevtemplvideo)
+ 5. \"How to create hyperlinks to \"here\" with `find-here-links'\":
+ http://angg.twu.net/2020-find-here-links.html
+ http://angg.twu.net/2020-find-here-links.html#code-video
+ http://angg.twu.net/eev-videos/2020-find-here-links.mp4
+ http://www.youtube.com/watch?v=8jtiBlaDor4
+ (find-eevfherelvideo)
+ 6. \"Using test blocks in eev\":
+ http://angg.twu.net/2021-test-blocks.html
+ http://angg.twu.net/eev-videos/2021-test-blocks.mp4
+ http://www.youtube.com/watch?v=fpsF_M55W4o
+ (find-eevtestblsvideo)
+ 7. \"Short videos about workflows - and how to upload them\":
+ http://angg.twu.net/2021-ssr.html
+ http://angg.twu.net/eev-videos/2021-ssr.mp4
+ http://www.youtube.com/watch?v=_0_NLXTVhBk
-9. First-class videos
-=====================
-I store videos of several kinds in:
+ 8. \"How to use the `[Video links:]' blocks in the `intro's of eev\"
+ http://angg.twu.net/2021-video-links.html
+ http://angg.twu.net/eev-videos/2021-video-links.mp4
+ http://www.youtube.com/watch?v=xQqWufQgzVY
+ (find-eevvlinksvideo \"0:00\")
- http://angg.twu.net/eev-videos/
-The presentations and tutorials on eev are the \"first-class
-citizens\" of that directory - mainly in the sense that a lot of
-information about them is available and easy to find. Let's look
-at one example in details. Try:
+The ones that I prepared for the two EmacsConfs are very
+well-rehearsed, the other ones are not.
- (find-efunctiondescr 'find-eev2019video)
- (find-efunction 'find-eev2019video)
- (find-efunctionpp 'find-eev2019video)
- (find-1stclassvideo-links \"eev2019\")
+The links with #code-video, like
-All these sexps \"work\" - they point to meaningful places.
+ http://angg.twu.net/emacsconf2019.html#code-video
-The data about these first-class videos is kept in the variable
-`ee-1stclassvideos-info', that is defined here:
+point to indexes of the videos made with sexp hyperlinks.
- (find-eev \"eev-videolinks.el\" \"ee-1stclassvideos-info\")
+The best way to watch them is to download local copies of their
+.mp4s and then use the short hyperlinks described in
+ (find-audiovideo-intro \"4. Short hyperlinks to audio and video files\")
+to jump to positions in them.
-10. Second-class videos
-=======================
-I will refer to the videos in
- http://angg.twu.net/eev-videos/
-that are not \"first-class citizens\" as - ta-da! - \"second
-class citizens\". When I want to show something in one of those
-videos to a person who uses eev I send her sexps like these:
+2. Short links to eev video tutorials
+=====================================
+The \"short links to eev video tutorials\" are made to be trivial
+to use from the _htmlized_ versions of the intros; they are not
+so trivial from Emacs. If you open the htmlized version of this
+section in a browser - its URL is:
- (code-eevvideo \"eevhydras\" \"2021-05-20_hydra_ei\")
- (find-eevhydrasvideo \"0:00\")
- (find-eevhydrasvideo \"0:50\")
+ http://angg.twu.net/eev-intros/find-videos-intro.html#2
-If you run the sexps above and then these ones,
+you will notice that links like
- (find-efunctiondescr 'find-eevhydrasvideo)
- (find-efunction 'find-eevhydrasvideo)
- (find-efunctionpp 'find-eevhydrasvideo)
- (find-1stclassvideo-links \"eevhydras\")
+ (find-eev2020video \"6:25\" \"`find-video'\")
+ \\---------------/ \\--/
+ function name: time:
+ points to here points to
+ (this section) YouTube
-you will see `find-eevhydrasvideo' is \"not documented\", that
-Emacs \"Do(es)n't know where `find-eevhydrasvideo' is defined\",
-that the pretty-printed version of `find-eevhydrasvideo' doesn't
-have a docstring after its argument list, and that many of the
-links in the temporary buffer created by
-`find-1stclassvideo-links' don't work.
+have two hyperlinks: the function name, \"find-eev2020video\",
+points to this section of this intro, and the timestamp,
+\"6:25\", points to YouTube; in this example, the \"6:25\" points
+to my presentation about eev in the EmacsConf2020, and it plays
+that video starting from 6:25.
-For more information on `code-eevvideo' see the comments in its
-source code, here:
+At this moment only these `find-eev*video' function are htmlized
+in this way:
- (find-eev \"eev-videolinks.el\" \"second-class-videos\")
- (find-eev \"eev-videolinks.el\" \"code-eevvideo\")
+ 1. \"How to record executable notes with eev - and how to play them back\"
+ http://angg.twu.net/emacsconf2019.html
+ (find-eev2019video \"0:00\")
+ 2. \"On why most of the best features in eev look like 5-minute hacks\"
+ http://angg.twu.net/emacsconf2020.html
+ (find-eev2020video \"0:00\")
+ 3. \"How to install eev with M-x list-packages and how to navigate its
tutorials\"
+ http://angg.twu.net/2020-list-packages-eev-nav.html
+ (find-eevnavvideo \"0:00\")
+ 4. \"Some template-based functions of eev that are not five-minute hacks\"
+ http://angg.twu.net/2020-some-template-based.html
+ (find-eevtemplvideo \"0:00\")
-11. Hardcoded paths
-===================
-Practically all the functions defined above have `eev' in their
-names, and they all convert the \"{stem}\" of a video to a URL
-like this:
+ 5. \"How to create hyperlinks to \"here\" with `find-here-links'\"
+ http://angg.twu.net/2020-find-here-links.html
+ (find-eevfherelvideo \"0:00\")
- http://angg.twu.net/eev-videos/{stem}.mp4
+ 6. \"Using test blocks in eev\":
+ http://angg.twu.net/2021-test-blocks.html
+ (find-eevtestblocksvideo \"0:00\")
-The conversion from \"{stem}\" to
-\"http://angg.twu.net/eev-videos/{stem}.mp4\" is hardcoded in
-these functions, and AT THIS MOMENT there isn't an easy way to
-implement other similar conversions - pointing to other
-repositories of videos - without changing a lot of code by hand.
-This is mainly because I don't know anyone else who is putting
-their videos on places from which they are easy to wget. If you
-know something like this, please get in touch!
+ 7. \"How to use the `[Video links:]' blocks in the `intro's of eev\"
+ http://angg.twu.net/2021-video-links.html
+ (find-eevvlinksvideo \"0:00\")
-" pos-spec-list)))
+If you follow these `find-eev*video' sexp hyperlinks in Emacs you
+will _usually_ get a temporary buffer with links to that video...
+see the next section.
-;; (find-video-links-intro)
+...or for an explanation in video, see:
+ http://angg.twu.net/2021-video-links.html
+ (find-eevvlinksvideo \"0:00\")
+ http://www.youtube.com/watch?v=xQqWufQgzVY
-;;; _ __
-;;; __| | ___ / _|_ _ _ __
-;;; / _` |/ _ \ |_| | | | '_ \
-;;; | (_| | __/ _| |_| | | | |
-;;; \__,_|\___|_| \__,_|_| |_|
-;;;
-;; «find-defun-intro» (to ".find-defun-intro")
-;; Skel: (find-intro-links "defun")
+3. Some `find-eevvideo-links'
+=============================
+When you run a sexp like this
-(defun find-defun-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-defun-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-defun-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-defun-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.
+ (find-eev2020video \"0:00\")
+in Emacs it by default runs this,
-Note: this intro needs to be integrated with:
- (find-elisp-intro)
-I wrote it for a mini-tutorial on Lisp that I gave.
-It complements this:
- (find-eev-quick-intro \"2. Evaluating Lisp\")
- (find-eval-intro \"3. What to execute, and in what order\")
- (find-eval-intro \"3. What to execute, and in what order\" \"defun\")
+ (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\" \"0:00\")
+that creates a temporary buffer containing commands for doing
+several things - like downloading a local copy of that video,
+playing the local copy, and overriding the definition of
+`find-eev2020video' with another one, that plays the local copy
+straight away without creating a temporary buffer.
+That temporary buffer is a bit hard to understand, and I need to
+make a video explaining how to use each part of it (TODO!
+Urgent)...
+The \"short links to eev video tutorials\" listed above call
+these `find-eevvideo-links' sexps:
-Simple examples
-===============
+ 1. (find-eevvideo-links \"eev2019\" \"emacsconf2019\" \"86yiRG8YJD0\")
+ 2. (find-eevvideo-links \"eev2020\" \"emacsconf2020\" \"hOAqBc42Gg8\")
+ 3. (find-eevvideo-links \"eevnav\" \"2020-list-packages-eev-nav\"
\"kxBjiUo88_U\")
+ 4. (find-eevvideo-links \"eevtempl\" \"2020-some-template-based\"
\"91-9YfRPsuk\")
+ 5. (find-eevvideo-links \"eevfherel\" \"2020-find-here-links\"
\"8jtiBlaDor4\")
+ 6. (find-eevvideo-links \"eevtestblocks\" \"2021-test-blocks\"
\"fpsF_M55W4o\")
+ 7. (find-eevvideo-links \"2021ssr\" \"2021-ssr\" \"_0_NLXTVhBk\")
- (* 5 5)
- (* 6 6)
- (defun foo (a) (* a a))
- (foo 5)
- (foo 6)
+They are htmlized in a nice way - see:
- (+ 5 5)
- (defun foo (a) (+ a a))
- (foo 5)
+ http://angg.twu.net/eev-intros/find-videos-intro.html#3
- (symbol-function 'foo)
- ((lambda (a) (* a a)) 5)
- ((lambda (a) (+ a a)) 5)
+The function `find-eevvideo-links' is explained here:
-See:
- (find-elnode \"Function Cells\")
- (find-elnode \"Defining Functions\")
+ (find-audiovideo-intro \"7.2. `find-eevvideo-links'\")
+" pos-spec-list)))
+;; (find-videos-intro)
-Several arguments
-=================
- (defun foo (a b) (+ (* a a) (* b b)))
- (foo 10 2)
- (foo 5)
- (defun foo () (+ (* 2 3) (* 4 5)))
- (foo 10 2)
- (foo 5)
- (foo)
-progn and prog1
-===============
-The body of a \"defun\" works like a \"progn\".
-See: (find-elnode \"Index\" \"* progn:\")
+;;; _ _ _ _ _
+;;; __ _(_) __| | ___ ___ | (_)_ __ | | _____
+;;; \ \ / / |/ _` |/ _ \/ _ \ _____| | | '_ \| |/ / __|
+;;; \ V /| | (_| | __/ (_) |_____| | | | | | <\__ \
+;;; \_/ |_|\__,_|\___|\___/ |_|_|_| |_|_|\_\___/
+;;;
+;; «find-video-links-intro» (to ".find-video-links-intro")
+;; Skel: (find-intro-links "video-links")
+;; Test: (find-video-links-intro)
- (defun foo (a b) (* a b))
- (defun foo (a b) (+ a b) (* a b))
- (defun foo (a b) (* a b) (+ a b))
- (defun foo (a b) (+ a b))
- (foo 5 6)
+(defun find-video-links-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-video-links-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-video-links-intro)
+Source code: (find-efunction 'find-video-links-intro)
+More intros: (find-eev-quick-intro)
+ (find-eev-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
- (progn (* 5 6) (+ 5 6))
- (progn \"ignored\" (+ 5 6) \"result\")
- (progn)
- (prog1 (* 5 6) (+ 5 6))
- (prog1 \"result\" (+ 5 6) \"ignored\")
- (prog1)
+1. Introduction
+===============
+Many of the tutorials of eev have \"[Video links:]\" blocks.
+For example:
-Docstrings
-==========
-Note that a string in a (progn ...) does nothing - unless it is
-the last BODY-FORM.
+ (find-eev-quick-intro \"4. Creating Elisp Hyperlinks\")
+ (find-eev-quick-intro \"4. Creating Elisp Hyperlinks\" \"[Video links:]\")
+ (find-eev-quick-intro \"6. Controlling shell-like programs\")
+ (find-eev-quick-intro \"6. Controlling shell-like programs\" \"[Video
links:]\")
-But see: (find-elnode \"Documentation\")
+They contain links like these,
-Try:
+ (find-eevnavvideo \"10:36\" \"if I type <f8> six times here\")
+ (find-eev2019video \"15:11\" \"Demo: the eepitch block (in red star lines)\")
+ (find-eevtestblsvideo \"2:33\" \"if I run f8 here I start a new Lua
interpreter\")
- (defun foo (a b) \"IGNORED\" (+ a b))
- (defun foo (a b) \"This is the description of `foo'\" (+ a b))
- (defun foo (a b) \"This is the docstring of `foo'\" (+ a b))
- (defun foo (a b) \"This function returns (* A B). Note the italics!\" (+ a
b))
- (find-efunctiondescr 'foo)
+that are \"short links to eev video tutorials\". These functions
+with names like `find-eev*video' are _sort of_ expanded to
+functions that specify explicitly which video on youtube to play,
+and where the local copy of the video can be found if we prefer
+to play the local copy. For the general idea of how this
+expansion is implemented, see:
+ (find-eev-quick-intro \"9. Shorter hyperlinks\")
+ (find-eev-quick-intro \"9.1. `code-c-d'\")
+ (find-eev-quick-intro \"9.1. `code-c-d'\" \"{c}\")
+The strings \"eevnav\", \"eev2019\", and \"eevtestbls\" in the
+names of the functions correspond to the argument \"c\" of
+`code-c-d'.
-&optional and &rest
-===================
-See: (find-elnode \"Argument List\")
-Try:
- (defun foo (a &optional b c) (list \"a,b,c:\" a b c))
- (foo 11 22 33)
- (foo 11 22)
- (foo 11)
- (foo)
- (foo 11 22 33 44)
- (defun foo (a &optional b c &rest r) (list \"a,b,c,r:\" a b c r))
- (foo 11 22 33 44 55 66)
- (foo 11 22 33 44 55)
- (foo 11 22 33 44)
- (foo 11 22 33)
- (foo 11 22)
- (foo 11)
- (foo)
- (defun foo (a &rest r) (list \"a,r:\" a r))
- (foo 11 22 33 44)
- (foo 11 22 33)
- (foo 11 22)
- (foo 11)
- (foo)
+2. From the HTML
+================
+The \"intros\" of eev can be read both from Emacs and from a
+browser. For example, the HTMLized version of this intro is at:
+ http://angg.twu.net/eev-intros/find-video-links-intro.html
+In the HTMLized version each \"short link to a video tutorial\"
+has two hyperlinks, like this:
-A tool: my-insert
-=================
-See: (find-elnode \"Formatting Strings\")
-Try:
+ (find-eev2020video \"6:25\" \"`find-video'\")
+ \\---------------/ \\--/
+ function name: time:
+ points to here points to
+ (this section) YouTube
- (format \"<%s>\" \"hello\")
- (format \"<%s>\" \"123\")
- (format \"<%s>\" 123)
- (format \"<%s>\" 'hello)
- (format \"<%s>\" '(+ 2 3))
+the function name, \"find-eev2020video\", points to a place -
+this section! - with help about how these links work, and the
+timestamp, \"6:25\", points to YouTube; in this example, the
+\"6:25\" points to my presentation about eev in the
+EmacsConf2020, and it plays that video starting from 6:25. More
+precisely, the \"6:25\" points to:
- (format \"<%S>\" \"hello\")
- (format \"<%S>\" \"123\")
- (format \"<%S>\" 123)
- (format \"<%S>\" 'hello)
- (format \"<%S>\" '(+ 2 3))
+ https://www.youtube.com/watch?v=hOAqBc42Gg8#t=6m25s
+ \\---------/ \\---/
+ \"hash\" time
-Now define:
+We call the string \"hOAqBc42Gg8\" the \"hash\" of the video;
+calling it the \"youtube id\" of the video would be more precise,
+but longer. The \"6:25\" is converted to a \"#t=6m25s\", that
+makes youtube start playing the video from the right position.
- (defun my-insert (obj)
- \"Print (insert) OBJ in the current buffer.\"
- (insert (format \"\\n ;; \\\\--> %S\" obj)))
-Try:
- (my-insert 123)
- (my-insert \"123\")
- (my-insert \"hello\")
- (my-insert 'hello)
- (my-insert '(+ 2 3))
- (my-insert nil)
- (my-insert '())
- (my-insert ())
-See also:
- (find-elnode \"Character Type\")
- (find-elnode \"Basic Char Syntax\")
- (find-elnode \"Basic Char Syntax\" \"?\\\\n\")
- (find-elnode \"General Escape Syntax\")
+3. `find-youtube-video'
+=======================
+In some situations - see the section 7 - running
+ (find-eev2020video \"6:25\" \"`find-video'\")
+makes Emacs run this:
-interactive
-===========
-Not all Emacs functions are callable with `M-x' - only those that
-are \"commands\" are callable in this way. And only \"commands\"
-can be bound to keys...
+ (find-youtube-video \"hOAqBc42Gg8\" \"6:25\")
-See:
- (find-elnode \"Defining Functions\" \"the first two of the BODY-FORMS\")
- (find-elnode \"Defining Commands\")
- (find-elnode \"Command Overview\")
+Note that running this sexp
-When you execute an `(interactive ...)' it does nothing - it
-simply ignores its arguments (which aren't even evaluated!) and
-returns nil. But just as
+ (ee-find-youtube-video \"hOAqBc42Gg8\" \"6:25\")
+returns one of these sexps,
- (defun my-insert (obj) (insert (format \"\\n ;; \\\\--> %S\" obj)))
+ (find-googlechrome \"http://www.youtube.com/watch?v=hOAqBc42Gg8#t=6m25s\")
+ (find-firefox \"http://www.youtube.com/watch?v=hOAqBc42Gg8#t=6m25s\")
- (find-efunctiondescr 'interactive)
+according to the variable `ee-find-youtube-video-program'; you
+can configure it to use one of the most common browsers with:
- (eek \"M-x foo\")
- (commandp 'foo)
+ (setq ee-find-youtube-video-program 'find-googlechrome)
+ (setq ee-find-youtube-video-program 'find-firefox)
- (defun foo (&rest rest) (interactive) (bar rest))
- (eek \"M-x foo\")
- (defun foo (&rest rest) (bar rest))
- (defun foo (&rest rest) (interactive \"P\") (bar rest))
- (eek \" M-x foo\")
- (eek \"M-1 M-x foo\")
- (eek \"M-1 M-2 M-3 M-x foo\")
- (eek \"M-- M-2 M-3 M-x foo\")
- (defun foo (&rest rest) (interactive \"R\") (bar rest))
- (eek \"M-x foo\")
+4. Configuring the browser
+==========================
+The variables `ee-firefox-program' and `ee-googlechrome-program'
+determine the programs that `find-firefox' and
+`find-googlechrome' should try to execute. You can test if they
+are correct by trying:
-" rest)))
+ (find-firefox \"http://www.lua.org/start.html\")
+ (find-googlechrome \"http://www.lua.org/start.html\")
-;; (find-defun-intro)
-;; (find-defun-intro "&rest")
-;; (find-defun-intro "\ninteractive\n")
-;; (find-defun-intro "Defining Commands")
+Typically on GNU/Linux systems the right values are:
+ (setq ee-firefox-program \"firefox\")
+ (setq ee-googlechrome-program \"google-chrome\")
+and on M$ Windows typically what works is something like:
+ (setenv \"FIREFOXDIR\" \"c:/Program Files/Mozilla Firefox\")
+ (setenv \"GOOGLECHROMEDIR\" \"c:/Program Files/Google/Chrome/Application\")
+ (setq ee-firefox-program \"$FIREFOXDIR/firefox.exe\")
+ (setq ee-googlechrome-program \"$GOOGLECHROMEDIR/chrome.exe\")
-;;; _ _
-;;; ___ _ __ ___ __ _ ___ ___ (_)_ __ | |_ _ __ ___
-;;; / _ \ '_ ` _ \ / _` |/ __/ __|_____| | '_ \| __| '__/ _ \
-;;; | __/ | | | | | (_| | (__\__ \_____| | | | | |_| | | (_) |
-;;; \___|_| |_| |_|\__,_|\___|___/ |_|_| |_|\__|_| \___/
-;;;
-;; «find-emacs-intro» (to ".find-emacs-intro")
-;; Skel: (find-intro-links "emacs")
+but people usually have to adjust the paths by hand. One way to
+test if the paths are right is to open the directories in dired
+and see if the files \"firefox.exe\" and \"chrome.exe\" are there
+- i.e., run these sexps and see if they find the right files in
+the right directories:
-(defun find-emacs-intro (&rest rest) (interactive)
- (let ((ee-buffer-name "*(find-emacs-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-emacs-intro)
-Source code: (find-eev \"eev-intro.el\" \"find-emacs-intro\")
-More intros: (find-eev-quick-intro)
- (find-emacs-keys-intro)
- (find-eev-intro)
- (find-eval-intro)
- (find-eepitch-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
+ (find-fline \"$FIREFOXDIR/\" \"firefox.exe\")
+ (find-fline \"$GOOGLECHROMEDIR/\" \"chrome.exe\")
+If you've never heard of dired, then read this:
+ (find-enode \"Dired\")
-THIS INTRO IS OBSOLETE, and has been superseded by:
- (find-emacs-keys-intro)
-Basic keys (eev)
-================
-The most basic keys of eev are:
- M-e - to follow a hyperlink, see: (find-eval-intro \"Elisp hyperlinks\")
- M-k - to go back, see: (find-eval-intro \"\\nGoing back\")
- M-j - to jump to certain predefined places - in particular,
- `M-j' takes you to the list of jump targets.
- `M-2j' takes you to this help page.
- `M-5j' takes you to: (find-eev-intro)
- See: (find-eev-quick-intro \"7.1. `eejump'\")
- (find-eejump-intro \"Families\")
- M-h M-h - hyperlinks to here, plus help.
- See: (find-links-intro \"`find-here-links'\")
+5. Local copies
+===============
+In some situations - see section 7 - a sexp like
+ (find-eev2020video \"6:25\" \"`find-video'\")
-The mnemonics are:
- M-e - evaluate/execute
- M-j - jump
- M-k - kill buffer
+will try to play a local copy of the video file. In the case of
+`find-eev2020video' this means a local copy of this file,
-It is possible to start learning Emacs and eev by remembering
-only that `M-j' jumps to an index; when you're lost, type `M-j',
-and will see a reminder of the main keys and of the main jump
-targets - after that you can learn how to use `M-k' to kill the
-top buffer, and `M-e' to follow elisp hyperlinks. The other keys
-are explained in \"intros\" like this one.
+ http://angg.twu.net/eev-videos/emacsconf2020.mp4
+downloaded by `psne'-ing, as explained here:
+ (find-psne-intro)
+The local copy will be played with Mpv, with:
-Files, Buffers, Windows, Frames, Display, etc
-=============================================
-Emacs can edit several files at the same time, each one
-in a \"buffer\".
+ (find-mpv-video \"$S/http/angg.twu.net/eev-videos/emacsconf2020.mp4\"
\"6:25\")
- (find-enode \"Files\")
- (find-enode \"Buffers\")
- (find-enode \"Windows\")
- (find-enode \"Frames\")
-The display of Emacs looks like this (asciified):
- __ _ _
- ______________emacs_______\\/|-|X|
- / | | \\
- | | bla. | | Emacs
-Window | | | | calls this
-managers | | | | a \"window\".
-call | | | /
-this a | |--:** foo.txt (Fundamental) ----| <-- Its \"modeline\".
-\"window\". / | | \\
-Emacs \\ | bla bla. | | Another
-calls | | bleh | | window.
-this a | | | |
-\"frame\". | | | /
- | |--:** bar.txt (Fundamental) ----| <-- Its modeline.
- \\ |Find file: ~/bletch.txt_ ________| <-- The minibuffer.
-The bottom line of a frame is sometimes the \"echo area\",
-sometimes the \"minibuffer\". The minibuffer acts like a
-window when it is active, and `C-x o' can be used to move
-from it to the \"normal windows\" and back. You can also
-use the mouse to move between windows.
- (find-enode \"Echo Area\")
- (find-enode \"Minibuffer\")
- (find-enode \"Other Window\")
+6. Configuring Mpv
+==================
+After installing Mpv you may have to configure its path. On
+GNU/Linux this typically works,
-By default there's also a \"menu bar\" (with textual entries) and
-a \"tool bar\" (with icons) at the top of each frame, but
-advanced users usually disable them.
+ (setq ee-mpv-program \"mpv\")
- (find-enode \"Menu Bar\")
- (find-enode \"Tool Bars\")
+and on M$ Windows you will need something like this, but you will
+have to adjust the path:
+ (setenv \"MPVDIR\" \"c:/Users/myusername/path/to/mpv\")
+ (setq ee-mpv-program \"$MPVDIR/mpv.exe\")
+You can test if the path is right with the two sexps below. Note
+that the first is for M$ Windows only, and that the second one
+will display the basic command-line options of mpv.
+ (find-fline \"$MPVDIR/\" \"mpv.exe\")
+ (find-callprocess `(,ee-mpv-program \"--help\"))
-Basic keys (Emacs)
-==================
-\(find-enode \"Keys\" \"key sequence\")
-\(find-enode \"User Input\" \"`Control-a'\" \"usually written `C-a'\")
-\(find-enode \"User Input\" \"<META> key\")
-\(find-enode \"Completion\" \"<TAB>\")
-<ESC> <ESC> <ESC> (find-enode \"Quitting\")
-C-g keyboard-quit (find-enode \"Quitting\" \"`C-g'\")
-M-x execute-extended-command (find-enode \"M-x\" \"Running Commands by
Name\")
+7. `find-eev-video'
+===================
+All the standard functions for short links to video tutorials are
+implemented using a function called `find-eev-video'. For
+example, `find-eev2020video' is defined as:
+ ;; For the real definition, see:
+ ;; (find-eev \"eev-audiovideo.el\" \"video-tutorials\")
+ ;; (find-eev \"eev-audiovideo.el\" \"video-tutorials\" \"eev2020\")
+ ;;
+ (defun find-eev2020video (&optional time &rest rest)
+ \"[Long docstring omitted]\"
+ (interactive)
+ (find-eev-video \"emacsconf2020\" \"hOAqBc42Gg8\" time))
-Cutting & pasting
-=================
-The \"region\" where cut & copy operate is always what is between
-the \"point\" and the \"mark\":
+Calling:
- (find-enode \"Point\")
- (find-enode \"Mark\")
+ (find-eev2020video \"6:25\" \"`find-video'\")
-You can do cut, copy and paste by using the icons in the toolbar
-or by using the menu bar (the relevant options are under
-\"Edit\"), but the keys are worth learning:
+runs:
- C-SPC -- set-mark-command (find-enode \"Setting Mark\")
- C-x C-x -- exchange-point-and-mark (find-enode \"Setting Mark\" \"C-x
C-x\")
- C-w -- kill-region (cut) (find-enode \"Other Kill Commands\")
- M-w -- kill-ring-save (copy) (find-enode \"Kill Ring\")
- C-y -- yank (paste) (find-enode \"Kill Ring\")
+ (find-eev-video \"emacsconf2020\" \"hOAqBc42Gg8\" \"6:25\")
+that runs one of these sexps, depending on the current settings:
+ (find-youtube-video \"hOAqBc42Gg8\" \"6:25\")
+ (find-eevlocal-video \"emacsconf2020\" \"hOAqBc42Gg8\" \"6:25\")
+ (find-eevlinks-video \"emacsconf2020\" \"hOAqBc42Gg8\" \"6:25\")
-Undoing
-=======
-C-/ -- undo (find-enode \"Basic Undo\")
-C-_ -- undo (find-enode \"Basic Undo\")
- (find-enode \"Undo\")
+The one with `find-eevlocal-video' plays the local copy of
+ http://angg.twu.net/eev-videos/emacsconf2020.mp4
-Windows
-=======
-See: (find-enode \"Frames\")
- (find-enode \"Windows\")
-C-x o -- other-window (find-enode \"Other Window\")
-C-x 0 -- delete-window (find-enode \"Change Window\")
-C-x 1 -- delete-other-windows (\"1 window\") (find-enode \"Change Window\")
-C-x 2 -- split-window-vertically (Abv/Blw) (find-enode \"Split Window\")
-C-x 3 -- split-window-horizontally (L|R) (find-enode \"Split Window\")
+if it has already been downloaded, and if the local copy is not
+found it displays a temporary buffer with links and an e-script
+for downloading - i.e., psne-ing - the video from the URL above.
+The sexp with `find-eevlinks-video' works very similarly to the
+one with `find-eevlocal-video', but it always displays the
+temporary buffer with links and an e-script.
+You can select the behavior of `find-eev-video' - and thus the
+behavior of all short links to video tutorials, as they all call
+`find-eev-video' - by running one of the `setq's below:
+ (setq ee-find-eev-video-function 'find-eevyoutube-video)
+ (setq ee-find-eev-video-function 'find-eevlocal-video)
+ (setq ee-find-eev-video-function 'find-eevlinks-video)
-Other keys / reference
-======================
-M-x -- execute-extended-command (find-enode \"M-x\")
- more about the minibuffer: (find-enode \"Minibuffer\")
-TAB -- for completion: (find-enode \"Completion\")
- for indentation: (find-enode \"Indentation\")
- in programming modes: (find-enode \"Basic Indent\")
+`find-eevyoutube-video' is like `find-eev-video', but it discards
+its first argument.
- (find-enode \"Dired\")
-C-x C-f -- find-file (find-enode \"Visiting\")
-C-x C-s -- save-buffer (find-enode \"Saving\")
-C-x C-c -- save-buffers-kill-emacs (find-enode \"Saving\")
-C-x b -- switch-to-buffer (find-enode \"Select Buffer\")
-C-x k -- kill-buffer (find-enode \"Kill Buffer\")
+The default is `find-eevlocal-video', but for Windows users
+starting with `find-eevyoutube-video' makes more sense. The
+user-friendly way to select one of these behaviors is with these
+sexps:
-C-a -- beginning-of-line (find-enode \"Moving Point\")
-C-e -- end-of-line (find-enode \"Moving Point\")
-M-< -- beginning-of-buffer (find-enode \"Moving Point\")
-M-> -- end-of-buffer (find-enode \"Moving Point\")
+ (ee-use-local-videos)
+ (ee-use-youtube-videos)
-M-q -- fill-paragraph (find-enode \"Fill Commands\")
+You can also run them with `M-x ee-use-local-videos' and `M-x
+ee-use-youtube-videos'.
-C-s -- isearch-forward (find-enode \"Incremental Search\")
-C-r -- isearch-backward (find-enode \"Incremental Search\")
-M-C-s -- isearch-forward-regexp (find-enode \"Regexp Search\")
-M-C-r -- isearch-backward-regexp (find-enode \"Regexp Search\")
-M-% -- query-replace (find-enode \"Replace\")
-C-x ( -- start-kbd-macro (find-enode \"Keyboard Macros\")
-C-x ) -- end-kbd-macro (find-enode \"Keyboard Macros\")
-C-x e -- call-last-kbd-macro (find-enode \"Keyboard Macros\")
-" rest)))
-;; (find-emacs-intro)
-;; (find-TH "emacs" "short-emacs-tutorial")
+8. Windows
+==========
+This is my n-th different implementation of the innards of the
+short links to video tutorials. This one - from nov/2021 - was
+inspired by feedback of the Windows users that participated in
+this workshop:
+ https://lists.gnu.org/archive/html/help-gnu-emacs/2021-10/msg00037.html
+ https://lists.gnu.org/archive/html/help-gnu-emacs/2021-10/msg00045.html
+ http://angg.twu.net/2021-oficina.html (<- in Portuguese)
+My original implementation - from may/2021 - was the one
+described here:
+ http://angg.twu.net/2021-video-links.html
+I'm trying to making the short links to video tutorials work from
+Emacs _in a way that is convenient for both long-time users and
+total beginners_. This is quite a challenge - especially because
+since oct/2021 my notion of \"total beginners\" includes \"people
+who use Windows and who have never used terminals in their
+lives\". If you are one of those \"total beginners\" my
+recommendation is: start by this tutorial - it will force you to
+learn how to configure paths and how to test if Emacs knows how
+to call a given external program - and then follow this one:
-;; «find-org-intro» (to ".find-org-intro")
-;; Skel: (find-intro-links "org")
+ (find-windows-beginner-intro)
-(defun find-org-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-org-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-org-intro)
-Source code: (find-efunction 'find-org-intro)
-More intros: (find-eev-quick-intro)
- (find-eev-intro)
- (find-eval-intro)
- (find-eepitch-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
-Eev does some things similar to Org, but using a different
-approach and different design principles. This sandboxed tutorial
-is a _first attempt_ to show to Org users how to use Org and eev
-at the same time, in the same files (or buffers).
+9. First-class videos
+=====================
+I store videos of several kinds in:
-Note: I wrote this after giving a presentation about eev in the
-EmacsConf 2019 and getting some help from Org users there (mainly
-Amin Bandali). Link:
+ http://angg.twu.net/eev-videos/
- http://angg.twu.net/emacsconf2019.html
+The presentations and tutorials on eev are the \"first-class
+citizens\" of that directory - mainly in the sense that a lot of
+information about them is available and easy to find. Let's look
+at one example in details. Try:
+ (find-efunctiondescr 'find-eev2019video)
+ (find-efunction 'find-eev2019video)
+ (find-efunctionpp 'find-eev2019video)
+ (find-1stclassvideo-links \"eev2019\")
+All these sexps \"work\" - they point to meaningful places.
+The data about these first-class videos is kept in the variable
+`ee-1stclassvideos-info', that is defined here:
-1. Preparation
-==============
-Run these sexps:
+ (find-eev \"eev-videolinks.el\" \"ee-1stclassvideos-info\")
- (code-c-d \"org\" (ee-locate-library \"org.el\") \"org\" :gz)
- (require 'org)
- (require 'ob-sh)
- ;; or: (require 'ob-shell)
- (require 'ob-python)
-2. Toggling org-mode on and off
-===============================
-Use these sexps,
+10. Second-class videos
+=======================
+I will refer to the videos in
- (org-mode)
- (fundamental-mode)
+ http://angg.twu.net/eev-videos/
-or `M-x org-mode' and `M-x fundamental-mode'.
+that are not \"first-class citizens\" as - ta-da! - \"second
+class citizens\". When I want to show something in one of those
+videos to a person who uses eev I send her sexps like these:
+ (code-eevvideo \"eevhydras\" \"2021-05-20_hydra_ei\")
+ (find-eevhydrasvideo \"0:00\")
+ (find-eevhydrasvideo \"0:50\")
+If you run the sexps above and then these ones,
-3. Comment blocks
-=================
-If you are using an org file that is meant for exporting you can
-mark as comments the more eev-ish parts in it, like this...
+ (find-efunctiondescr 'find-eevhydrasvideo)
+ (find-efunction 'find-eevhydrasvideo)
+ (find-efunctionpp 'find-eevhydrasvideo)
+ (find-1stclassvideo-links \"eevhydras\")
-# (find-orgnode \"Comment lines\")
-# (find-orgnode \"Exporting\")
+you will see `find-eevhydrasvideo' is \"not documented\", that
+Emacs \"Do(es)n't know where `find-eevhydrasvideo' is defined\",
+that the pretty-printed version of `find-eevhydrasvideo' doesn't
+have a docstring after its argument list, and that many of the
+links in the temporary buffer created by
+`find-1stclassvideo-links' don't work.
-#+BEGIN_COMMENT
-# Run the eepitch block below to download a copy of my messy
-# notes on org. See:
-# (find-eev-quick-intro \"6. Controlling shell-like programs\")
+For more information on `code-eevvideo' see the comments in its
+source code, here:
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
-cd /tmp/
-rm -fv org.e
-wget http://angg.twu.net/e/org.e
+ (find-eev \"eev-videolinks.el\" \"second-class-videos\")
+ (find-eev \"eev-videolinks.el\" \"code-eevvideo\")
-#+END_COMMENT
+11. Hardcoded paths
+===================
+Practically all the functions defined above have `eev' in their
+names, and they all convert the \"{stem}\" of a video to a URL
+like this:
-4. Running code from my org.e
-=============================
-The code in comments in the previous section downloads a local
-copy of my executable notes (i.e., my \"e-scripts\") on Org. Run
-it, and compare:
+ http://angg.twu.net/eev-videos/{stem}.mp4
-# http://angg.twu.net/e/org.e.html#git
-# (find-anchor \"/tmp/org.e\" \"git\")
+The conversion from \"{stem}\" to
+\"http://angg.twu.net/eev-videos/{stem}.mp4\" is hardcoded in
+these functions, and AT THIS MOMENT there isn't an easy way to
+implement other similar conversions - pointing to other
+repositories of videos - without changing a lot of code by hand.
+This is mainly because I don't know anyone else who is putting
+their videos on places from which they are easy to wget. If you
+know something like this, please get in touch!
-The URL above points to my notes on downloading Org from git and
-compiling its docs. The sexp hyperlinks below it lets you execute
-these notes.
+" pos-spec-list)))
+;; (find-video-links-intro)
-5. Evaluating source blocks
-===========================
-You can execute a source block in Org and display its results
-with `C-c C-c'. See:
-# (find-orgnode \"Working with source code\")
-# (find-orgnode \"Evaluating code blocks\")
-# (find-orgnode \"Evaluating code blocks\" \":results output\")
-# (find-orgnode \"Results of evaluation\" \":results output\")
-# (find-orgnode \"results\" \"output\")
-Try it here:
-#+BEGIN_SRC sh :results output
-seq 200 204
-#+END_SRC
+;;; _ __
+;;; __| | ___ / _|_ _ _ __
+;;; / _` |/ _ \ |_| | | | '_ \
+;;; | (_| | __/ _| |_| | | | |
+;;; \__,_|\___|_| \__,_|_| |_|
+;;;
+;; «find-defun-intro» (to ".find-defun-intro")
+;; Skel: (find-intro-links "defun")
-Compare that with:
+(defun find-defun-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-defun-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-defun-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-defun-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.
-# (find-sh \"seq 200 204\")
-and compare
+Note: this intro needs to be integrated with:
+ (find-elisp-intro)
+I wrote it for a mini-tutorial on Lisp that I gave.
+It complements this:
+ (find-eev-quick-intro \"2. Evaluating Lisp\")
+ (find-eval-intro \"3. What to execute, and in what order\")
+ (find-eval-intro \"3. What to execute, and in what order\" \"defun\")
-#+BEGIN_SRC python :results output
-def square (x):
- return x*x
-print(square(5))
-#+END_SRC
-with:
-#+BEGIN_COMMENT
- (eepitch-python)
- (eepitch-kill)
- (eepitch-python)
-def square (x):
- return x*x
+Simple examples
+===============
-print(square(5))
+ (* 5 5)
+ (* 6 6)
+ (defun foo (a) (* a a))
+ (foo 5)
+ (foo 6)
-#+END_COMMENT
+ (+ 5 5)
+ (defun foo (a) (+ a a))
+ (foo 5)
+ (symbol-function 'foo)
+ ((lambda (a) (* a a)) 5)
+ ((lambda (a) (+ a a)) 5)
+See:
+ (find-elnode \"Function Cells\")
+ (find-elnode \"Defining Functions\")
-5. Sectioning
-=============
-Not yet!
-How do I mark a section as \"don't export this\"?
- (find-orgnode \"Headlines\")
- (find-orgnode \"Global and local cycling\")
- (find-efunctiondescr 'org-mode \"TAB\" \"org-cycle\")
- (find-efunctiondescr 'org-shifttab)
+Several arguments
+=================
+ (defun foo (a b) (+ (* a a) (* b b)))
+ (foo 10 2)
+ (foo 5)
+ (defun foo () (+ (* 2 3) (* 4 5)))
+ (foo 10 2)
+ (foo 5)
+ (foo)
-" pos-spec-list)))
-;; (find-org-intro)
+progn and prog1
+===============
+The body of a \"defun\" works like a \"progn\".
+See: (find-elnode \"Index\" \"* progn:\")
+ (defun foo (a b) (* a b))
+ (defun foo (a b) (+ a b) (* a b))
+ (defun foo (a b) (* a b) (+ a b))
+ (defun foo (a b) (+ a b))
+ (foo 5 6)
+ (progn (* 5 6) (+ 5 6))
+ (progn \"ignored\" (+ 5 6) \"result\")
+ (progn)
+ (prog1 (* 5 6) (+ 5 6))
+ (prog1 \"result\" (+ 5 6) \"ignored\")
+ (prog1)
-;;; _ _
-;;; ___ ___ ___ _ __(_)_ __ | |_ ___
-;;; / _ \_____/ __|/ __| '__| | '_ \| __/ __|
-;;; | __/_____\__ \ (__| | | | |_) | |_\__ \
-;;; \___| |___/\___|_| |_| .__/ \__|___/
-;;; |_|
-;; «find-escripts-intro» (to ".find-escripts-intro")
-;; Skel: (find-intro-links "escripts")
+Docstrings
+==========
+Note that a string in a (progn ...) does nothing - unless it is
+the last BODY-FORM.
-(defun find-escripts-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-escripts-intro)*"))
- (apply 'find-eintro "\
-\(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'.
+But see: (find-elnode \"Documentation\")
+Try:
+ (defun foo (a b) \"IGNORED\" (+ a b))
+ (defun foo (a b) \"This is the description of `foo'\" (+ a b))
+ (defun foo (a b) \"This is the docstring of `foo'\" (+ a b))
+ (defun foo (a b) \"This function returns (* A B). Note the italics!\" (+ a
b))
+ (find-efunctiondescr 'foo)
-This intro will be merged with
- (find-here-links-intro)
-at some point...
+&optional and &rest
+===================
+See: (find-elnode \"Argument List\")
+Try:
-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\".
+ (defun foo (a &optional b c) (list \"a,b,c:\" a b c))
+ (foo 11 22 33)
+ (foo 11 22)
+ (foo 11)
+ (foo)
+ (foo 11 22 33 44)
-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:
+ (defun foo (a &optional b c &rest r) (list \"a,b,c,r:\" a b c r))
+ (foo 11 22 33 44 55 66)
+ (foo 11 22 33 44 55)
+ (foo 11 22 33 44)
+ (foo 11 22 33)
+ (foo 11 22)
+ (foo 11)
+ (foo)
- 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'.
+ (defun foo (a &rest r) (list \"a,r:\" a r))
+ (foo 11 22 33 44)
+ (foo 11 22 33)
+ (foo 11 22)
+ (foo 11)
+ (foo)
+A tool: my-insert
+=================
+See: (find-elnode \"Formatting Strings\")
+Try:
-1. Prehistory
-=============
-Eev 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,
+ (format \"<%s>\" \"hello\")
+ (format \"<%s>\" \"123\")
+ (format \"<%s>\" 123)
+ (format \"<%s>\" 'hello)
+ (format \"<%s>\" '(+ 2 3))
- (find-file \"/usr/share/emacs/19.24/lisp/\")
- (find-file \"/usr/share/emacs/19.24/lisp/files.el\")
+ (format \"<%S>\" \"hello\")
+ (format \"<%S>\" \"123\")
+ (format \"<%S>\" 123)
+ (format \"<%S>\" 'hello)
+ (format \"<%S>\" '(+ 2 3))
-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
+Now define:
- (eev \"man tar\")
+ (defun my-insert (obj)
+ \"Print (insert) OBJ in the current buffer.\"
+ (insert (format \"\\n ;; \\\\--> %S\" obj)))
-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.
+Try:
-RMS himself answered.
+ (my-insert 123)
+ (my-insert \"123\")
+ (my-insert \"hello\")
+ (my-insert 'hello)
+ (my-insert '(+ 2 3))
+ (my-insert nil)
+ (my-insert '())
+ (my-insert ())
-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.
+See also:
+ (find-elnode \"Character Type\")
+ (find-elnode \"Basic Char Syntax\")
+ (find-elnode \"Basic Char Syntax\" \"?\\\\n\")
+ (find-elnode \"General Escape Syntax\")
-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)
+interactive
+===========
+Not all Emacs functions are callable with `M-x' - only those that
+are \"commands\" are callable in this way. And only \"commands\"
+can be bound to keys...
+See:
+ (find-elnode \"Defining Functions\" \"the first two of the BODY-FORMS\")
+ (find-elnode \"Defining Commands\")
+ (find-elnode \"Command Overview\")
+When you execute an `(interactive ...)' it does nothing - it
+simply ignores its arguments (which aren't even evaluated!) and
+returns nil. But just as
-2. E-scripts
-============
-The 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
+ (defun my-insert (obj) (insert (format \"\\n ;; \\\\--> %S\" obj)))
-Some of my files are \"pure e-scripts\": they are mostly made of
-\"e-script blocks\" like the ones described here:
+ (find-efunctiondescr 'interactive)
- (find-eev-quick-intro \"8.4. Creating e-script blocks\")
+ (eek \"M-x foo\")
+ (commandp 'foo)
-Here are two examples structured like this:
+ (defun foo (&rest rest) (interactive) (bar rest))
+ (eek \"M-x foo\")
- http://angg.twu.net/e/emacs.e.html
- http://angg.twu.net/e/lua5.e.html
+ (defun foo (&rest rest) (bar rest))
+ (defun foo (&rest rest) (interactive \"P\") (bar rest))
+ (eek \" M-x foo\")
+ (eek \"M-1 M-x foo\")
+ (eek \"M-1 M-2 M-3 M-x foo\")
+ (eek \"M-- M-2 M-3 M-x foo\")
-Each of these \"e-script blocks\" is an \"executable log\" of
-something that I was trying to understand, or trying to do.
+ (defun foo (&rest rest) (interactive \"R\") (bar rest))
+ (eek \"M-x foo\")
+" rest)))
+;; (find-defun-intro)
+;; (find-defun-intro "&rest")
+;; (find-defun-intro "\ninteractive\n")
+;; (find-defun-intro "Defining Commands")
-3. Sharing
-==========
-One 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\".
+;;; _ _
+;;; ___ _ __ ___ __ _ ___ ___ (_)_ __ | |_ _ __ ___
+;;; / _ \ '_ ` _ \ / _` |/ __/ __|_____| | '_ \| __| '__/ _ \
+;;; | __/ | | | | | (_| | (__\__ \_____| | | | | |_| | | (_) |
+;;; \___|_| |_| |_|\__,_|\___|___/ |_|_| |_|\__|_| \___/
+;;;
+;; «find-emacs-intro» (to ".find-emacs-intro")
+;; Skel: (find-intro-links "emacs")
- 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.
+(defun find-emacs-intro (&rest rest) (interactive)
+ (let ((ee-buffer-name "*(find-emacs-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-emacs-intro)
+Source code: (find-eev \"eev-intro.el\" \"find-emacs-intro\")
+More intros: (find-eev-quick-intro)
+ (find-emacs-keys-intro)
+ (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
- (...)
- 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.
+THIS INTRO IS OBSOLETE, and has been superseded by:
+ (find-emacs-keys-intro)
- 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:
+Basic keys (eev)
+================
+The most basic keys of eev are:
+ M-e - to follow a hyperlink, see: (find-eval-intro \"Elisp hyperlinks\")
+ M-k - to go back, see: (find-eval-intro \"\\nGoing back\")
+ M-j - to jump to certain predefined places - in particular,
+ `M-j' takes you to the list of jump targets.
+ `M-2j' takes you to this help page.
+ `M-5j' takes you to: (find-eev-intro)
+ See: (find-eev-quick-intro \"7.1. `eejump'\")
+ (find-eejump-intro \"Families\")
+ M-h M-h - hyperlinks to here, plus help.
+ See: (find-links-intro \"`find-here-links'\")
- a) executable logs make us more productive,
- b) our notes/logs can, and should, be shared.
-What it *did not* say explicitly was:
+The mnemonics are:
+ M-e - evaluate/execute
+ M-j - jump
+ M-k - kill buffer
- 5) that *not sharing* should be *immoral*,
- 6) one of my main objectives with eev was REVENGE.
+It is possible to start learning Emacs and eev by remembering
+only that `M-j' jumps to an index; when you're lost, type `M-j',
+and will see a reminder of the main keys and of the main jump
+targets - after that you can learn how to use `M-k' to kill the
+top buffer, and `M-e' to follow elisp hyperlinks. The other keys
+are explained in \"intros\" like this one.
-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.
+Files, Buffers, Windows, Frames, Display, etc
+=============================================
+Emacs can edit several files at the same time, each one
+in a \"buffer\".
+
+ (find-enode \"Files\")
+ (find-enode \"Buffers\")
+ (find-enode \"Windows\")
+ (find-enode \"Frames\")
+The display of Emacs looks like this (asciified):
+ __ _ _
+ ______________emacs_______\\/|-|X|
+ / | | \\
+ | | bla. | | Emacs
+Window | | | | calls this
+managers | | | | a \"window\".
+call | | | /
+this a | |--:** foo.txt (Fundamental) ----| <-- Its \"modeline\".
+\"window\". / | | \\
+Emacs \\ | bla bla. | | Another
+calls | | bleh | | window.
+this a | | | |
+\"frame\". | | | /
+ | |--:** bar.txt (Fundamental) ----| <-- Its modeline.
+ \\ |Find file: ~/bletch.txt_ ________| <-- The minibuffer.
+The bottom line of a frame is sometimes the \"echo area\",
+sometimes the \"minibuffer\". The minibuffer acts like a
+window when it is active, and `C-x o' can be used to move
+from it to the \"normal windows\" and back. You can also
+use the mouse to move between windows.
+ (find-enode \"Echo Area\")
+ (find-enode \"Minibuffer\")
+ (find-enode \"Other Window\")
-4. How to read an e-script
-==========================
-The 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.
+By default there's also a \"menu bar\" (with textual entries) and
+a \"tool bar\" (with icons) at the top of each frame, but
+advanced users usually disable them.
+ (find-enode \"Menu Bar\")
+ (find-enode \"Tool Bars\")
- --snip, snip--
- # Index:
- # «.lua5.1-debian» (to \"lua5.1-debian\")
- # «.lua-tutorial» (to \"lua-tutorial\")
+Basic keys (Emacs)
+==================
+\(find-enode \"Keys\" \"key sequence\")
+\(find-enode \"User Input\" \"`Control-a'\" \"usually written `C-a'\")
+\(find-enode \"User Input\" \"<META> key\")
+\(find-enode \"Completion\" \"<TAB>\")
- #####
- #
- # The main Debian packages for Lua 5.1
- # 2018jun02
- #
- #####
+<ESC> <ESC> <ESC> (find-enode \"Quitting\")
+C-g keyboard-quit (find-enode \"Quitting\" \"`C-g'\")
- # «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
+M-x execute-extended-command (find-enode \"M-x\" \"Running Commands by
Name\")
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- sudo apt-get install lua5.1 lua5.1-doc
+Cutting & pasting
+=================
+The \"region\" where cut & copy operate is always what is between
+the \"point\" and the \"mark\":
+ (find-enode \"Point\")
+ (find-enode \"Mark\")
- #####
- #
- # Downloading and opening an eev-based Lua tutorial
- # 2018jun02
- #
- #####
+You can do cut, copy and paste by using the icons in the toolbar
+or by using the menu bar (the relevant options are under
+\"Edit\"), but the keys are worth learning:
- # «lua-tutorial» (to \".lua-tutorial\")
- # http://angg.twu.net/e/lua-intro.e.html
- # http://angg.twu.net/e/lua-intro.e
+ C-SPC -- set-mark-command (find-enode \"Setting Mark\")
+ C-x C-x -- exchange-point-and-mark (find-enode \"Setting Mark\" \"C-x
C-x\")
+ C-w -- kill-region (cut) (find-enode \"Other Kill Commands\")
+ M-w -- kill-ring-save (copy) (find-enode \"Kill Ring\")
+ C-y -- yank (paste) (find-enode \"Kill Ring\")
- (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--
+Undoing
+=======
+C-/ -- undo (find-enode \"Basic Undo\")
+C-_ -- undo (find-enode \"Basic Undo\")
+ (find-enode \"Undo\")
+Windows
+=======
+See: (find-enode \"Frames\")
+ (find-enode \"Windows\")
+C-x o -- other-window (find-enode \"Other Window\")
+C-x 0 -- delete-window (find-enode \"Change Window\")
+C-x 1 -- delete-other-windows (\"1 window\") (find-enode \"Change Window\")
+C-x 2 -- split-window-vertically (Abv/Blw) (find-enode \"Split Window\")
+C-x 3 -- split-window-horizontally (L|R) (find-enode \"Split Window\")
-4.1. Anchors and `to'
----------------------
-The two lines below
- # «.foo» (to \"foo\")
- # «foo» (to \".foo\")
+Other keys / reference
+======================
+M-x -- execute-extended-command (find-enode \"M-x\")
+ more about the minibuffer: (find-enode \"Minibuffer\")
+TAB -- for completion: (find-enode \"Completion\")
+ for indentation: (find-enode \"Indentation\")
+ in programming modes: (find-enode \"Basic Indent\")
-\"point to one another\". This is explained here:
+ (find-enode \"Dired\")
+C-x C-f -- find-file (find-enode \"Visiting\")
+C-x C-s -- save-buffer (find-enode \"Saving\")
+C-x C-c -- save-buffers-kill-emacs (find-enode \"Saving\")
+C-x b -- switch-to-buffer (find-enode \"Select Buffer\")
+C-x k -- kill-buffer (find-enode \"Kill Buffer\")
- (find-eev-quick-intro \"8. Anchors\")
+C-a -- beginning-of-line (find-enode \"Moving Point\")
+C-e -- end-of-line (find-enode \"Moving Point\")
+M-< -- beginning-of-buffer (find-enode \"Moving Point\")
+M-> -- end-of-buffer (find-enode \"Moving Point\")
-We used this in Example 1 to create an index. Compare with:
+M-q -- fill-paragraph (find-enode \"Fill Commands\")
- # Index:
- # «.one» (to \"one\")
- # «.two» (to \"two\")
+C-s -- isearch-forward (find-enode \"Incremental Search\")
+C-r -- isearch-backward (find-enode \"Incremental Search\")
+M-C-s -- isearch-forward-regexp (find-enode \"Regexp Search\")
+M-C-r -- isearch-backward-regexp (find-enode \"Regexp Search\")
+M-% -- query-replace (find-enode \"Replace\")
- ###
- ## Stuff in block \"one\"
- ###
+C-x ( -- start-kbd-macro (find-enode \"Keyboard Macros\")
+C-x ) -- end-kbd-macro (find-enode \"Keyboard Macros\")
+C-x e -- call-last-kbd-macro (find-enode \"Keyboard Macros\")
+" rest)))
- # «one» (to \".one\")
- (...)
+;; (find-emacs-intro)
+;; (find-TH "emacs" "short-emacs-tutorial")
- ###
- ## Stuff in block \"two\"
- ###
- # «two» (to \".two\")
-4.2. Debian hyperlinks
-----------------------
-The 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/\")
+;; «find-org-intro» (to ".find-org-intro")
+;; Skel: (find-intro-links "org")
-are equivalent to:
+(defun find-org-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-org-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-org-intro)
+Source code: (find-efunction 'find-org-intro)
+More intros: (find-eev-quick-intro)
+ (find-eev-intro)
+ (find-eval-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
- (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\\\"\")
+Eev does some things similar to Org, but using a different
+approach and different design principles. This sandboxed tutorial
+is a _first attempt_ to show to Org users how to use Org and eev
+at the same time, in the same files (or buffers).
+Note: I wrote this after giving a presentation about eev in the
+EmacsConf 2019 and getting some help from Org users there (mainly
+Amin Bandali). Link:
+ http://angg.twu.net/emacsconf2019.html
-4.3. URL hyperlinks
--------------------
-The 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\")
+1. Preparation
+==============
+Run these sexps:
-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.
+ (code-c-d \"org\" (ee-locate-library \"org.el\") \"org\" :gz)
+ (require 'org)
+ (require 'ob-sh)
+ ;; or: (require 'ob-shell)
+ (require 'ob-python)
-4.4. Eepitch blocks
--------------------
-This
+2. Toggling org-mode on and off
+===============================
+Use these sexps,
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- sudo apt-get install lua5.1 lua5.1-doc
+ (org-mode)
+ (fundamental-mode)
-is an \"eepitch block\", as explained here:
+or `M-x org-mode' and `M-x fundamental-mode'.
- (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!
+3. Comment blocks
+=================
+If you are using an org file that is meant for exporting you can
+mark as comments the more eev-ish parts in it, like this...
+# (find-orgnode \"Comment lines\")
+# (find-orgnode \"Exporting\")
-4.5. Htmlized e-scripts
------------------------
-The \"Eev Manifesto\" in section 3 above has this:
+#+BEGIN_COMMENT
+# Run the eepitch block below to download a copy of my messy
+# notes on org. See:
+# (find-eev-quick-intro \"6. Controlling shell-like programs\")
- 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.
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+cd /tmp/
+rm -fv org.e
+wget http://angg.twu.net/e/org.e
-The \"public place\" is here:
+#+END_COMMENT
- 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
+4. Running code from my org.e
+=============================
+The code in comments in the previous section downloads a local
+copy of my executable notes (i.e., my \"e-scripts\") on Org. Run
+it, and compare:
- # http://angg.twu.net/e/lua-intro.e.html
+# http://angg.twu.net/e/org.e.html#git
+# (find-anchor \"/tmp/org.e\" \"git\")
-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.
+The URL above points to my notes on downloading Org from git and
+compiling its docs. The sexp hyperlinks below it lets you execute
+these notes.
-4.6. The `rm' in the eepitch block
-----------------------------------
-When we execute this eepitch block a first time,
+5. Evaluating source blocks
+===========================
+You can execute a source block in Org and display its results
+with `C-c C-c'. See:
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- cd /tmp/
- rm -v lua-intro.e
- wget http://angg.twu.net/e/lua-intro.e
+# (find-orgnode \"Working with source code\")
+# (find-orgnode \"Evaluating code blocks\")
+# (find-orgnode \"Evaluating code blocks\" \":results output\")
+# (find-orgnode \"Results of evaluation\" \":results output\")
+# (find-orgnode \"results\" \"output\")
-the \"rm\" gives an error:
+Try it here:
- rm: cannot remove 'lua-intro.e': No such file or directory
+#+BEGIN_SRC sh :results output
+seq 200 204
+#+END_SRC
-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.
+Compare that with:
-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
+# (find-sh \"seq 200 204\")
- rm -v lua-intro.e
+and compare
-does not give an error - and I got used to ignoring the error
-when it's run for the first time.
+#+BEGIN_SRC python :results output
+def square (x):
+ return x*x
-Most e-scripts in
+print(square(5))
+#+END_SRC
- http://angg.twu.net/e/
+with:
-follow these conventions:
+#+BEGIN_COMMENT
+ (eepitch-python)
+ (eepitch-kill)
+ (eepitch-python)
+def square (x):
+ return x*x
- 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.
+print(square(5))
+#+END_COMMENT
-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. Sectioning
+=============
+Not yet!
+How do I mark a section as \"don't export this\"?
+ (find-orgnode \"Headlines\")
+ (find-orgnode \"Global and local cycling\")
+ (find-efunctiondescr 'org-mode \"TAB\" \"org-cycle\")
+ (find-efunctiondescr 'org-shifttab)
+" pos-spec-list)))
+;; (find-org-intro)
-5. Tools for writing e-scripts
-==============================
-One 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\".
+;; «find-escripts-intro» (to ".find-escripts-intro")
+;; Skel: (find-intro-links "escripts")
-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\"?
+(defun find-escripts-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-escripts-intro)*"))
+ (apply 'find-eintro "\
+\(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'.
- 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.
+This intro will be merged with
+ (find-here-links-intro)
+at some point...
-The next sections discuss those tricks.
+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'.
-5.1. Anchors-to pairs and e-script blocks
------------------------------------------
-Anchor-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>
+1. Prehistory
+=============
+Eev 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,
-yields this pair of anchor-to lines:
+ (find-file \"/usr/share/emacs/19.24/lisp/\")
+ (find-file \"/usr/share/emacs/19.24/lisp/files.el\")
- # «.bletch» (to \"bletch\")
- # «bletch» (to \".bletch\")
+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
-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:
+ (eev \"man tar\")
- (find-eev \"eev-blinks.el\" \".eek\")
- (find-eev \"eev-blinks.el\" \"eek\")
+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.
-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.
+RMS himself answered.
-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.
+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.
-In the e-script files in
+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)
- 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
+2. E-scripts
+============
+The 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:
-See:
+ http://angg.twu.net/LATEX/dednat6/eoo.lua.html#Vector
- (find-eev-quick-intro \"8.4. Creating e-script blocks\")
- (find-eev-quick-intro \"8.4. Creating e-script blocks\" \"`M-B'\")
+Some of my files are \"pure e-scripts\": they are mostly made of
+\"e-script blocks\" like the ones described here:
-The to-forward line still has to be moved to the index by cut and
-paste by hand.
+ (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.
-5.2. Debian hyperlinks
-----------------------
-The 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/\")
+3. Sharing
+==========
+One of my first public texts about eev was the \"Eev Manifesto\":
-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':
+ http://angg.twu.net/eev-manifesto.html
-bash
-lua5.1
-lua5.1-doc
+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.
-5.3. URL hyperlinks
--------------------
-I usually \"write\" URLs in Emacs by copying them from a browser
-to Emacs.
+ 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
-5.4. Eepitch blocks
--------------------
-We saw in
+ 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:
- (find-eev-quick-intro \"6.3. Creating eepitch blocks: `M-T'\")
+ a) executable logs make us more productive,
+ b) our notes/logs can, and should, be shared.
-how to create eepitch blocks with `M-T'. Try that on the line
-that says \"lua51\" below:
+What it *did not* say explicitly was:
-lua51
+ 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.
-5.5. `rm/mkdir/cd' triples
---------------------------
-Try typing `M-R' on the line with the \"/tmp/foo/\" below:
+They had to be stripped of their status.
-/tmp/foo/
-5.6. Hyperlinks to files, directories, and info nodes
------------------------------------------------------
-One practical way to create a `find-fline' hyperlink is with
-`M-F' (`eewrap-find-fline'). Try it here:
+4. How to read an e-script
+==========================
+The 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.
-/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:
+ --snip, snip--
- (find-vldifile \"lua5.1-doc.list\")
- (find-vldifile \"lua5.1-doc.list\" \"/usr/share/doc/lua5.1-doc/test\")
+ # Index:
+ # «.lua5.1-debian» (to \"lua5.1-debian\")
+ # «.lua-tutorial» (to \"lua-tutorial\")
-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.
+ #####
+ #
+ # 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
-6. Tutorials
-============
-All the tutorials in eev follow these four principles:
- 1. All the examples in them are very easy to run,
- 2. The links to documentation are easy to follow,
- 3. All the \"sub-examples\" are easy to run,
- 4. The links to related documentation - including links to
- primary sources - are easy to follow.
+ #####
+ #
+ # Downloading and opening an eev-based Lua tutorial
+ # 2018jun02
+ #
+ #####
-I used to believe that all these four principles would be
-immediately obvious to everyone who had played a bit with the
-tutorials of eev, and I thought that people would realize that
-these are very good principles, that they should follow too...
-and so these people would start to apply these principles to
-their own e-scripts, and they would adapt them to other
-environments that are not Emacs-based, and these ideas would
-spread (sort of) naturally. Well, I was totally wrong - and I
-only discovered that in 2021, when I chatted with some relatively
-advanced eev users to whom those ideas were not obvious at all.
-So let me try to be explain these principles clearly - especially
-the principles 3 and 4 - and show how they can be applied to
-other contexts besides tutorials.
+ # «lua-tutorial» (to \".lua-tutorial\")
+ # http://angg.twu.net/e/lua-intro.e.html
+ # http://angg.twu.net/e/lua-intro.e
-The idea of \"making sub-examples very easy to run\" is
-especially easy to see in the elisp tutorials. In this
-introduction
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ cd /tmp/
+ rm -v lua-intro.e
+ wget http://angg.twu.net/e/lua-intro.e
- (find-elisp-intro \"1. Introduction\")
+ # (find-fline \"/tmp/lua-intro.e\")
+ # (find-anchor \"/tmp/lua-intro.e\" \"intro:types\")
+ # (defun eejump-71 () (find-fline \"/tmp/lua-intro.e\"))
-we have first this sexp,
+ --snip, snip--
- (+ (* 2 3) (* 4 5))
-and then these ones:
- 2
- 3
- (* 2 3)
- 4
- 5
- (* 4 5)
- (+ (* 2 3) (* 4 5))
- (list (* 2 3) (* 4 5))
-In the first sexp people _could_ execute the subsexps (* 2 3)
-and (* 4 5) by typing `M-E' in the right places... remember:
+4.1. Anchors and `to'
+---------------------
+The two lines below
- (find-eval-intro \"2. The end of line and `M-e'\")
- (find-eval-intro \"2. The end of line and `M-e'\" \"without moving\")
+ # «.foo» (to \"foo\")
+ # «foo» (to \".foo\")
-...but it is much easier to see the sub-sexps, and to execute
-them, when they are in different lines. This example also serves
-to stress to beginners than number, like 4, are sexps too, and
-they can be evaluated - the result of evaluating 4 is 4.
+\"point to one another\". This is explained here:
-In a sequence of sub-sexps, like the one above, I usually try to
-arrange the sexps in a didactic order: to understand the result
-of (+ (* 2 3) (* 4 5)) we need to understand first the results
-of (* 2 3) and (* 4 5). Also, the best way to understand the new
-idea that appears in
+ (find-eev-quick-intro \"8. Anchors\")
- (list (* 2 3) (* 4 5))
+We used this in Example 1 to create an index. Compare with:
-is to compare it with this other sexp, that appears just before
-it and is conceptually simpler:
+ # Index:
+ # «.one» (to \"one\")
+ # «.two» (to \"two\")
- (+ (* 2 3) (* 4 5))
+ ###
+ ## Stuff in block \"one\"
+ ###
-I try to apply this principle - \"make sub-examples very easy to
-run\" - to tutorials for other languages, too. At this moment the
-only tutorial for another language that I have that is in a
-_reasonably_ organized form is this one,
+ # «one» (to \".one\")
+ (...)
- http://angg.twu.net/e/lua-intro.e.html
- (find-wgeta \"http://angg.twu.net/e/lua-intro.e\")
- (find-wgeta \"http://angg.twu.net/e/lua-intro.e\" \"intro:for\")
+ ###
+ ## Stuff in block \"two\"
+ ###
-but parts of it were written in 2004, when these principles were
-not yet very clear to me. I am revising it, and I am also trying
-to convince some students to work together with me on tutorials
-for shell and Python, but they are not very enthusiastic (yet).
+ # «two» (to \".two\")
-The \"links to related documentation\" can also be arranged in a
-didactical order. For example, here,
- (find-eev-quick-intro \"6.4. Red stars\")
- (find-eev-quick-intro \"6.4. Red stars\" \"bullet\")
- (find-eepitch-bullet-links)
-the first link points to a section of a tutorial that most people
-should have stumbled on; the second link points to technical a
-point in it that most people ignore on a first reading, and the
-third one points to something much more technical,
-containing (executable!) source code.
+4.2. Debian hyperlinks
+----------------------
+The 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/\")
-(TO DO: mention test blocks)
+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\\\"\")
-7. Sequences of links
-=====================
-A good part of my executable notes consists of sequences of links
-in which in practically all cases the new link \"refines\" the
-previous one in some sense; the notion of \"refining\" explained
-here is just one of these senses:
- (find-refining-intro \"1. Pos-spec-lists\")
-Let me compare two styles: 1. textual, 2. executable notes.
+4.3. URL hyperlinks
+-------------------
+The lines
- 1. The section 2 of the tutorial `find-eev-quick-intro'
- mentions that `M-e' accepts several different numerical
- prefixes, but it only explains one case: `M-0 M-e'. One way
- to discover what the other numerical prefixes do is to use
- `M-h M-k', that is explained in the section 4.2 of
- `find-eev-quick-intro', on `M-e', and then follow the link
- in the temporary buffer that starts with `find-efunction'.
- The key `M-e' is bound to `ee-eval-sexp-eol', and one of
- lines in the docstring of `ee-eval-sexp-eol' says this:
+ # 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
- 3: same as 2, but also switch to the new window
+are URL hyperlinks. Here's how to follow them:
- If we follow the source code we see that `M-3 M-e' executes
- `ee-eval-last-sexp-3', that calls a function called
- `find-wset', that is defined in eev-multiwindow.el. Some
- functions in eev-multiwindow.el call functions like
- `split-window-horizontally', that are mentioned in section 6
- of `(find-emacs-keys-intro)'.
+ (find-eev-quick-intro \"3.1. Non-elisp hyperlinks\")
- The comments at the top of eev-multiwindow.el say that the
- functions in that file are explained in a tutorial called
- `find-multiwindow-intro'. It turns out that the first
- argument of `find-wset' is a string that is interpreted as
- series of commands in a mini-language in which each
- character means a certain operation on windows.
+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.
-Now let's see the second style: executable notes. I wrote the
-block below by following the idea described here:
- (find-here-links-intro \"1. Alternating between \\\"task\\\" and
\\\"notes\\\"\")
-Every time that I found something interesting I would save a link
-to it in my notes, and these are my notes with only very minor
-clean-ups.
+4.4. Eepitch blocks
+-------------------
+This
- 2. (find-eev-quick-intro \"2. Evaluating Lisp\")
- (find-eev-quick-intro \"2. Evaluating Lisp\" \"M-0 M-e\")
- (find-eev-quick-intro \"4.2. `find-ekey-links' and friends\")
- (eek \"M-h M-k M-e\")
- (eek \"M-h M-k M-e ;; ee-eval-sexp-eol\")
- (find-eek \"M-h M-k M-e ;; ee-eval-sexp-eol\")
- (find-eek \"M-h M-k M-e ;; ee-eval-sexp-eol\" \"(find-efunction ')\")
- (find-efunction 'ee-eval-sexp-eol)
- (find-efunction 'ee-eval-sexp-eol \"3:\")
- (eek \"2*<up> M-3 M-e\")
- (find-efunction 'ee-eval-last-sexp)
- (find-efunction 'ee-eval-last-sexp-3)
- (find-efunction 'ee-eval-last-sexp-3 \"find-wset\")
- (find-efunction 'find-wset)
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ sudo apt-get install lua5.1 lua5.1-doc
- (find-emacs-keys-intro \"6. Windows\")
- (find-emacs-keys-intro \"6. Windows\" \"L|R\")
+is an \"eepitch block\", as explained here:
- (find-eev-intro)
- (find-eev-intro \"M-5 M-0 M-j\")
- (find-eev-intro \"(find-multiwindow-intro)\")
- (find-multiwindow-intro)
+ (find-eev-quick-intro \"6. Controlling shell-like programs\")
+ (find-eev-quick-intro \"6.1. The main key: <F8>\")
- (find-wset \"13o_2o2o23oo33ooo\" '(find-ebuffer \"B\"))
- (find-wset \"13o_2o2o23oo33ooo+\" '(find-ebuffer \"B\"))
- (find-2a nil '(find-efunction 'ee-eval-sexp-eol))
- (find-2b nil '(find-efunction 'ee-eval-sexp-eol))
+Note that it will only work if you delete the whitespace before
+the \"\"s!
-The notes in the style 1 are a translation to English to the
-notes in the style 2. I wrote the notes in style 2 first.
-Some people _PANIC_ when they see notes written in the second
-style, and most of us are conditioned to believe that a) we have
-to try to write notes that are readable by everyone - even though
-that is impossible if we take the \"everyone\" literally, b)
-notes in the second style can't be shared in public. However:
- a) It is good karma to make our notes publically available even
- if very few people will be able to read them,
+4.5. Htmlized e-scripts
+-----------------------
+The \"Eev Manifesto\" in section 3 above has this:
- b) we are our main readers - and we need to try to make our
- notes easily to read by ourselves,
+ 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.
- c) _executability_ helps in _readability_,
+The \"public place\" is here:
- d) people are experimenting with ways of writing executable
- notes, and even the most popular styles of doing that -
- Jupyter Notebooks, I guess? - are not yet really hugely
- popular.
+ http://angg.twu.net/e/
-One of my intents with eev is to encourage people to experiment
-with ways of writing executable notes. This involves learning the
-functions and techniques that already exist, and inventing new
-ones - and, hopefully, sharing them.
+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
-8. IRC
-======
-(TO DO: explain this:)
+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.
- (find-efunction 'ee-0x0-upload-region)
- (find-efunction 'ee-0x0-upload-region \"aliased to `u0'\")
-9. Git
-======
-Example:
- (progn
+4.6. The `rm' in the eepitch block
+----------------------------------
+When we execute this eepitch block a first time,
- ;; Links to the git repository:
- ;; https://github.com/edrx/emacs-lua
- ;; https://github.com/edrx/emacs-lua/blob/main/tests.e
- ;; https://raw.githubusercontent.com/edrx/emacs-lua/main/tests.e
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ cd /tmp/
+ rm -v lua-intro.e
+ wget http://angg.twu.net/e/lua-intro.e
- (setq ee-emluagit-base
- \"https://raw.githubusercontent.com/edrx/emacs-lua/main/\")
- (defun find-emluagitfile (fname &rest rest)
- (apply 'find-wget (format \"%s%s\" ee-emluagit-base fname) rest))
- (defun find-emluagit (fname &rest rest)
- (apply 'find-wgeta (format \"%s%s\" ee-emluagit-base fname) rest))
+the \"rm\" gives an error:
- ;; Tests:
- ;; (find-emluagit \"tests.e\")
- ;; (find-emluagit \"tests.e\" \"find-angg-and-find-es\")
- ;; (find-emluagit \"tests.e\" \"find-angg-and-find-es\" \"Tests:\")
- ;; (find-emluagitfile \"tests.e\" \"Warning:\")
+ rm: cannot remove 'lua-intro.e': No such file or directory
- ;; Links to a local copy of the git repository:
- ;; (find-git-links \"https://github.com/edrx/emacs-lua\" \"emlua\")
- ;; (setq ee-git-dir \"~/usrc/\")
- ;;
- ;; (find-code-c-d \"emlua\" \"~/usrc/emacs-lua/\" :anchor)
- (code-c-d \"emlua\" \"~/usrc/emacs-lua/\" :anchor)
- ;;
- ;; Tests:
- ;; (find-emlua \"\")
- ;; (find-emlua \"tests.e\")
- ;; (find-emlua \"tests.e\" \"find-angg-and-find-es\")
- ;; (find-emlua \"tests.e\" \"find-angg-and-find-es\" \"Tests:\")
- ;; (find-emluafile \"tests.e\" \"Warning:\")
+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.
- ;; Compare:
- ;; (find-emluagit \"tests.e\" \"find-angg-and-find-es\")
- ;; (find-emlua \"tests.e\" \"find-angg-and-find-es\")
+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.
-" pos-spec-list)))
+Most e-scripts in
-;; (find-escripts-intro)
+ 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.
-;;; ____ _ _
-;;; / ___(_) |_
-;;; | | _| | __|
-;;; | |_| | | |_
-;;; \____|_|\__|
-;;;
-;; «find-git-intro» (to ".find-git-intro")
-;; Skel: (find-intro-links "git")
-(defun find-git-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-git-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-git-intro)
-Source code: (find-efunction 'find-git-intro)
-More intros: (find-eev-quick-intro)
- (find-eev-intro)
- (find-eepitch-intro)
-This buffer is _temporary_ and _editable_.
-It is meant as both a tutorial and a sandbox.
+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)
-At this moment this is a call for help -
-not an intro.
-0. Introduction
-===============
-Git is extremely popular, and I've heard that the two packages
-that attract most new users to Emacs are Org and Magit:
- https://github.com/magit/magit
- https://melpa.org/#/magit
- (find-epackage 'magit)
-At this moment eev offers only a trivial hack to help people
-download git repositories. If you put the point on the github url
-above and type `M-h g' or `M-x find-git-links' you will get the
-same effect as running the sexp below:
- (find-git-links \"https://github.com/magit/magit\" \"magit\")
+5. Tools for writing e-scripts
+==============================
+One 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_.
-You will get a temporary buffer with an e-script for downloading
-(\"cloning\") that git repository and inspecting it in a handful
-of ways.
+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:
-I found git VERY hard to learn. To test most concepts you need a
-repository with tags and branches and a second repository that
-\"pulls\" from it, and no books or tutorials that I know of come
-with a sequence of commands that set that up in a way that makes
-the tests easy to reproduce. To make things worse, when I was
-trying to set up a git repository for eev on github for the first
-time I did some things wrong on the github side of the repository
-that I did not know how to undo... after spending some days
-trying to fix that I gave up, deleted that repository, created a
-new one, and decided that I would always do LOTS of local tests
-before messing up my public repository again.
+ (find-enode \"Visiting\" \"Visiting Files\")
-This intro is about doing these local tests - but it is in a VERY
-early draft.
+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.
-1. Preparation
-==============
-Download the second URL below with `M-x brep',
+ 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.
- https://github.com/pluralsight/git-internals-pdf/
-
https://github.com/pluralsight/git-internals-pdf/releases/download/v2.0/peepcode-git.pdf
+The next sections discuss those tricks.
-and do the same for the fourth URL below here:
- https://git-scm.com/book/en/v2
- https://github.com/progit/progit2
- https://github.com/progit/progit2/releases
- https://github.com/progit/progit2/releases/download/2.1.277/progit.pdf
-Then run this eepitch block,
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- rm -Rfv /tmp/git-test/
- mkdir /tmp/git-test/
- cd /tmp/git-test/
- # http://angg.twu.net/bin/git-defs.html
- wget http://angg.twu.net/bin/git-defs
- cp -v
$S/https/github.com/pluralsight/git-internals-pdf/releases/download/v2.0/peepcode-git.pdf
.
- cp -v
$S/https/github.com/progit/progit2/releases/download/2.1.277/progit.pdf .
-and this prog1:
+5.1. Anchors-to pairs and e-script blocks
+-----------------------------------------
+Anchor-to pairs can be generated easily using `M-A':
- (prog1
- (code-pdf-page \"gitinternals\" \"/tmp/git-test/peepcode-git.pdf\")
- (code-pdf-text \"gitinternals\" \"/tmp/git-test/peepcode-git.pdf\")
- (code-pdf-page \"progit\" \"/tmp/git-test/progit.pdf\")
- (code-pdf-text \"progit\" \"/tmp/git-test/progit.pdf\")
- (code-c-d \"gitdoc\" \"/usr/share/doc/git-doc/\")
- )
+ (find-eev-quick-intro \"8.3. Creating index/section anchor pairs\")
+ (find-eev-quick-intro \"8.3. Creating index/section anchor pairs\" \"M-A\")
-If can test if everything works by running the six sexps below:
+Typing `M-A' on this line:
- (find-fline \"/tmp/git-test/git-defs\")
- (find-gitinternalspage)
- (find-gitinternalstext)
- (find-progitpage)
- (find-progittext)
- (find-gitdocfile \"\")
+ # <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:
-2. A first repository
-=====================
-The manpage of git-revisions
+ (find-eev \"eev-blinks.el\" \".eek\")
+ (find-eev \"eev-blinks.el\" \"eek\")
- (find-man \"7 git-revisions\")
- (find-man \"7 git-revisions\" \"Here is an illustration\")
- (find-gitdocfile \"revisions.txt\" \"illustration, by Jon Loeliger\")
+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.
-has this example, in which the commits have this structure:
+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.
- G H I J
- \\ / \\ /
- D E F
- \\ | / \\
- \\ | / |
- \\|/ |
- B C
- \\ /
- \\ /
- A
+In the e-script files in
-Here is an e-script that creates it:
+ http://angg.twu.net/e/
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- rm -Rfv /tmp/git-test/repo1/
- mkdir /tmp/git-test/repo1/
- cd /tmp/git-test/repo1/
- . /tmp/git-test/git-defs
- # (find-fline \"/tmp/git-test/git-defs\")
+I follow another convention - \"e-script blocks\". The title
+above each to-backward line is written like this:
- git init
- Modify file1; Modify file2; git add file1 file2
- Commit A; git branch brAC
- Modify file1; Commit B; git branch brBDG
- git checkout brAC
- Modify file1; Commit C
- git checkout brBDG
- Modify file1; Commit D
- git checkout HEAD^ -b brE
- Modify file1; Commit E
- git checkout HEAD^
- git merge -s ours brAC -m F
- git branch brFI
- git checkout brBDG
- Modify file1; Commit G
- git checkout HEAD^ -b brH
- Modify file1; Commit H
- git checkout brFI
- Modify file1; Commit I
- git checkout HEAD^ -b brJ
- Modify file1; Commit J
- Diagram
+ #####
+ #
+ # Long description for the section Bletch
+ # 2016feb29
+ #
+ #####
- # (find-gitk \"/tmp/git-test/repo1/\")
+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:
-Actually it creates the structure below - where, for example, the
-node \"G,brBDG\" is a commit with message \"G\" and a branch
-called \"brBDG\" pointing to it; I call that branch \"brBDG\"
-because when it was created it pointed to the commit with message
-\"B\", then it moved to the commit \"D\", then to \"G\".
+ bletch Long description for the section Bletch
- I,brFI J,brJ
- | /
- G,brBDG H,brH | /
- \\ / | /
- D E,brE F
- \\ | / \\
- \\ | / |
- \\ | / |
- B C,brAC
- \\ /
- \\ /
- A
+See:
-Here's a video showing the script above in action:
+ (find-eev-quick-intro \"8.4. Creating e-script blocks\")
+ (find-eev-quick-intro \"8.4. Creating e-script blocks\" \"`M-B'\")
- http://angg.twu.net/eev-videos/2020-doubt-about-merging.mp4
- (code-eevvideo \"merg\" \"2020-doubt-about-merging\")
- (find-mergvideo \"0:00\")
- (find-mergvideo \"0:20\")
+The to-forward line still has to be moved to the index by cut and
+paste by hand.
-NEXT STEPS: explain how to use git merge both from the command
-line and from magit; explain HEAD, master, and tags. Point to man
-pages in man and text format and to sections in Scott Chacon's
-book. I NEED LOTS OF HELP HERE.
- (find-man \"git-merge\")
- (find-gitinternalspage)
- (find-gitinternalstext)
+5.2. Debian hyperlinks
+----------------------
+The key `M-D' converts a line with the name of a Debian package,
+like this,
+lua5.1-doc
+to these three hyperlinks,
-3. A second repository
-======================
-HELP PLEEEASEEEE
+# (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':
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- rm -Rfv /tmp/git-test/repo2/
- mkdir /tmp/git-test/repo2/
- cd /tmp/git-test/repo2/
- . /tmp/git-test/git-defs
- # (find-fline \"/tmp/git-test/git-defs\")
+bash
+lua5.1
+lua5.1-doc
- git clone /tmp/git-test/repo1/ .
- ls -lAF
- # (find-gitk \"/tmp/git-test/repo2/\")
- # (find-fline \"/tmp/git-test/repo2/\")
- # (find-fline \"/tmp/git-test/repo2/.git/\")
- # (find-fline \"/tmp/git-test/repo2/.git/config\")
- # (find-man \"1 git-remote\")
- # (find-progitpage (+ 24 36) \"Adding Remote Repositories\")
- # (find-progittext (+ 24 36) \"Adding Remote Repositories\")
-" pos-spec-list)))
+5.3. URL hyperlinks
+-------------------
+I usually \"write\" URLs in Emacs by copying them from a browser
+to Emacs.
-;; (find-git-intro)
+5.4. Eepitch blocks
+-------------------
+We 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
-;;; __ ___ _ _
-;;; \ \ / / | | |__ ___ __ _(_)_ __ _ __ ___ _ __
-;;; \ \ /\ / / __)_____| '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|
-;;; \ V V /\__ \_____| |_) | __/ (_| | | | | | | | | __/ |
-;;; \_/\_/ ( / |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|
-;;; |_| |___/
-;;
-;; «find-windows-beginner-intro» (to ".find-windows-beginner-intro")
-;; Skel: (find-intro-links "windows-beginner")
-(defun find-windows-beginner-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-windows-beginner-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-windows-beginner-intro)
-Source code: (find-efunction 'find-windows-beginner-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.
-The quickest way to open or recreate this is with `M-3 M-j'.
+5.5. `rm/mkdir/cd' triples
+--------------------------
+Try typing `M-R' on the line with the \"/tmp/foo/\" below:
+/tmp/foo/
-This is a tutorial on how to install Emacs and eev on M$ Windows,
-and on the basic steps for learning Emacs and eev after
-installing them. If you're a W$ user you should start by reading
-this tutorial online in a browser, at
- http://angg.twu.net/eev-intros/find-windows-beginner-intro.html
-while you run Emacs in another window (see section 1). After
-getting eev installed on your machine (see section 3) you will be
-able to access this tutorial from Emacs by typing `M-3 M-j'.
+5.6. Hyperlinks to files, directories, and info nodes
+-----------------------------------------------------
+One practical way to create a `find-fline' hyperlink is with
+`M-F' (`eewrap-find-fline'). Try it here:
-The main tutorial on eev is this one,
+/usr/share/doc/lua5.1-doc/test/
+/usr/share/doc/lua5.1-doc/test/README
+/usr/share/doc/lua5.1-doc/test/fibfor.lua
- (find-eev-quick-intro)
- http://angg.twu.net/eev-intros/find-eev-quick-intro.html
+Note that the three lines above were copied from:
-The sections from 5.6 onwards were written in nov/2021 and they
-cover how to install some external programs to make almost all
-features of eev work on M$ Windows. Feedback on them would be
-greatly appreciated!
+ (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.
+(...)
-0. Introduction
-===============
-My favorite exposition of what eev is is this presentation,
-called \"How to record executable notes with eev - and how to
-play them back\":
- http://angg.twu.net/emacsconf2019.html
- http://angg.twu.net/LATEX/2019emacsconf.pdf (slides)
- http://www.youtube.com/watch?v=86yiRG8YJD0 (video)
-The video ends with a demo that shows a non-trivial example of
-\"executable notes\". The most interesting part of that demo
-shows how to use eev to send commands to an external program - a
-unix shell, being run in interactive mode. Here's a link to that
-part of the video on youtube, plus two related links that are
-harder to explain:
+6. Tutorials
+============
+All the tutorials in eev follow these four principles:
- http://www.youtube.com/watch?v=86yiRG8YJD0#t=15m11s
- (find-eev2019video \"15:11\" \"Demo: the eepitch block\")
- (find-angg \".emacs.videos\" \"eev2019\")
+ 1. All the examples in them are very easy to run,
+ 2. The links to documentation are easy to follow,
+ 3. All the \"sub-examples\" are easy to run,
+ 4. The links to related documentation - including links to
+ primary sources - are easy to follow.
-I don't have easy access to Windows machines, so I have to rely
-on friends to test some things for me. I also don't have easy
-access to people who use Windows and who do have experience using
-terminals, so from time to time I give workshops for \"total
-beginners\" like the one described here,
+I used to believe that all these four principles would be
+immediately obvious to everyone who had played a bit with the
+tutorials of eev, and I thought that people would realize that
+these are very good principles, that they should follow too...
+and so these people would start to apply these principles to
+their own e-scripts, and they would adapt them to other
+environments that are not Emacs-based, and these ideas would
+spread (sort of) naturally. Well, I was totally wrong - and I
+only discovered that in 2021, when I chatted with some relatively
+advanced eev users to whom those ideas were not obvious at all.
+So let me try to be explain these principles clearly - especially
+the principles 3 and 4 - and show how they can be applied to
+other contexts besides tutorials.
- (find-video-links-intro \"8. Windows\")
+The idea of \"making sub-examples very easy to run\" is
+especially easy to see in the elisp tutorials. In this
+introduction
-and I see that the people on those workshops get stuck on ideas
-that I thought that were obvious, and I change my approach, and I
-rewrite lots of things.
+ (find-elisp-intro \"1. Introduction\")
-This is my N-th attempt to rewrite this tutorial.
+we have first this sexp,
-Version of these instructions: 2021nov13.
+ (+ (* 2 3) (* 4 5))
+and then these ones:
+ 2
+ 3
+ (* 2 3)
+ 4
+ 5
+ (* 4 5)
+ (+ (* 2 3) (* 4 5))
+ (list (* 2 3) (* 4 5))
+In the first sexp people _could_ execute the subsexps (* 2 3)
+and (* 4 5) by typing `M-E' in the right places... remember:
-1. Download and install Emacs
-=============================
-Read the README below and then install Emacs using either the
-link to the .exe or the link to the .zip:
+ (find-eval-intro \"2. The end of line and `M-e'\")
+ (find-eval-intro \"2. The end of line and `M-e'\" \"without moving\")
-http://alpha.gnu.org/gnu/emacs/pretest/windows/emacs-28/
-http://alpha.gnu.org/gnu/emacs/pretest/windows/emacs-28/README-windows-binaries
-http://alpha.gnu.org/gnu/emacs/pretest/windows/emacs-28/emacs-28.0.50-snapshot-2021-01-15-installer.exe
-http://alpha.gnu.org/gnu/emacs/pretest/windows/emacs-28/emacs-28.0.50-snapshot-2021-01-15.zip
+...but it is much easier to see the sub-sexps, and to execute
+them, when they are in different lines. This example also serves
+to stress to beginners than number, like 4, are sexps too, and
+they can be evaluated - the result of evaluating 4 is 4.
-You may need to create a desktop icon or shortcut to
-<emacsdir>/bin/runemacs.exe.
+In a sequence of sub-sexps, like the one above, I usually try to
+arrange the sexps in a didactic order: to understand the result
+of (+ (* 2 3) (* 4 5)) we need to understand first the results
+of (* 2 3) and (* 4 5). Also, the best way to understand the new
+idea that appears in
+ (list (* 2 3) (* 4 5))
+is to compare it with this other sexp, that appears just before
+it and is conceptually simpler:
+ (+ (* 2 3) (* 4 5))
-2. Key sequences and how to quit
-================================
-Most people who use Emacs do many things by using key sequences - for
-example `C-x C-s' to save the current file.
+I try to apply this principle - \"make sub-examples very easy to
+run\" - to tutorials for other languages, too. At this moment the
+only tutorial for another language that I have that is in a
+_reasonably_ organized form is this one,
-`C-x C-s' is the Emacs notation for \"control-x control-s\". This
-notation is explained here:
+ http://angg.twu.net/e/lua-intro.e.html
+ (find-wgeta \"http://angg.twu.net/e/lua-intro.e\")
+ (find-wgeta \"http://angg.twu.net/e/lua-intro.e\" \"intro:for\")
- (find-enode \"User Input\" \"<Ctrl>\" \"a\" \"C-a\")
- (find-enode \"User Input\" \"<Meta>-a\" \"M-a\" \"<Alt>\")
+but parts of it were written in 2004, when these principles were
+not yet very clear to me. I am revising it, and I am also trying
+to convince some students to work together with me on tutorials
+for shell and Python, but they are not very enthusiastic (yet).
-The best way to learn key sequences when you are a beginner is by
-using the menu bar:
+The \"links to related documentation\" can also be arranged in a
+didactical order. For example, here,
- (find-enode \"Menu Bar\")
+ (find-eev-quick-intro \"6.4. Red stars\")
+ (find-eev-quick-intro \"6.4. Red stars\" \"bullet\")
+ (find-eepitch-bullet-links)
-for example, in the \"File\" menu the last option is:
+the first link points to a section of a tutorial that most people
+should have stumbled on; the second link points to technical a
+point in it that most people ignore on a first reading, and the
+third one points to something much more technical,
+containing (executable!) source code.
- Quit C-x C-c
+(TO DO: mention test blocks)
-If you type just `C-x' and wait the `C-x' will be displayed in the
-\"Echo area\" at the bottom of the screen. This is explained here:
- (find-enode \"Echo Area\")
- The line at the very bottom of the frame is the \"echo area\". It is
- used to display small amounts of text for various purposes.
- The echo area is so-named because one of the things it is used
- for is \"echoing\", which means displaying the characters of a
- multi-character command as you type. Single-character commands are
- not echoed. Multi-character commands (*note Keys) are echoed if you
- pause for more than a second in the middle of a command. Emacs then
- echoes all the characters of the command so far, to prompt you for
- the rest. Once echoing has started, the rest of the command echoes
- immediately as you type it. This behavior is designed to give
- confident users fast response, while giving hesitant users maximum
- feedback.
+7. Sequences of links
+=====================
+A good part of my executable notes consists of sequences of links
+in which in practically all cases the new link \"refines\" the
+previous one in some sense; the notion of \"refining\" explained
+here is just one of these senses:
- The echo area is also used to display an \"error message\" when a
- command cannot do its job. Error messages may be accompanied by
- beeping or by flashing the screen.
+ (find-refining-intro \"1. Pos-spec-lists\")
-There are several ways to abort a key sequence in the middle. They
-are explained here,
+Let me compare two styles: 1. textual, 2. executable notes.
- (find-enode \"Quitting\")
+ 1. The section 2 of the tutorial `find-eev-quick-intro'
+ mentions that `M-e' accepts several different numerical
+ prefixes, but it only explains one case: `M-0 M-e'. One way
+ to discover what the other numerical prefixes do is to use
+ `M-h M-k', that is explained in the section 4.2 of
+ `find-eev-quick-intro', on `M-e', and then follow the link
+ in the temporary buffer that starts with `find-efunction'.
+ The key `M-e' is bound to `ee-eval-sexp-eol', and one of
+ lines in the docstring of `ee-eval-sexp-eol' says this:
-but what I recommend to beginners is: if you are stuck in the middle
-of a key sequence and don't know how to abort it, just go to the
-\"File\" menu, use the option \"Quit\", and restart Emacs.
+ 3: same as 2, but also switch to the new window
+ If we follow the source code we see that `M-3 M-e' executes
+ `ee-eval-last-sexp-3', that calls a function called
+ `find-wset', that is defined in eev-multiwindow.el. Some
+ functions in eev-multiwindow.el call functions like
+ `split-window-horizontally', that are mentioned in section 6
+ of `(find-emacs-keys-intro)'.
+ The comments at the top of eev-multiwindow.el say that the
+ functions in that file are explained in a tutorial called
+ `find-multiwindow-intro'. It turns out that the first
+ argument of `find-wset' is a string that is interpreted as
+ series of commands in a mini-language in which each
+ character means a certain operation on windows.
+Now let's see the second style: executable notes. I wrote the
+block below by following the idea described here:
-3. Using M-x and installing eev
-===============================
-We can run commands by name by using `M-x'. `M-x' uses the last line
-of the screen as a \"minibuffer\" - see:
+ (find-here-links-intro \"1. Alternating between \\\"task\\\" and
\\\"notes\\\"\")
- (find-enode \"Minibuffer\")
- (find-enode \"Basic Minibuffer\" \"it appears in the echo area\")
- (find-enode \"M-x\" \"Running Commands by Name\")
+Every time that I found something interesting I would save a link
+to it in my notes, and these are my notes with only very minor
+clean-ups.
-To install eev, do this:
- 1. run `M-x package-initialize',
- 2. run `M-x list-packages',
- 3. select \"eev\" at the list of packages,
- 4. click on \"install\".
+ 2. (find-eev-quick-intro \"2. Evaluating Lisp\")
+ (find-eev-quick-intro \"2. Evaluating Lisp\" \"M-0 M-e\")
+ (find-eev-quick-intro \"4.2. `find-ekey-links' and friends\")
+ (eek \"M-h M-k M-e\")
+ (eek \"M-h M-k M-e ;; ee-eval-sexp-eol\")
+ (find-eek \"M-h M-k M-e ;; ee-eval-sexp-eol\")
+ (find-eek \"M-h M-k M-e ;; ee-eval-sexp-eol\" \"(find-efunction ')\")
+ (find-efunction 'ee-eval-sexp-eol)
+ (find-efunction 'ee-eval-sexp-eol \"3:\")
+ (eek \"2*<up> M-3 M-e\")
+ (find-efunction 'ee-eval-last-sexp)
+ (find-efunction 'ee-eval-last-sexp-3)
+ (find-efunction 'ee-eval-last-sexp-3 \"find-wset\")
+ (find-efunction 'find-wset)
-To load eev and enter its tutorial, run
- `M-x eev-beginner'.
+ (find-emacs-keys-intro \"6. Windows\")
+ (find-emacs-keys-intro \"6. Windows\" \"L|R\")
-The tutorial looks like this:
- (find-eev-quick-intro)
+ (find-eev-intro)
+ (find-eev-intro \"M-5 M-0 M-j\")
+ (find-eev-intro \"(find-multiwindow-intro)\")
+ (find-multiwindow-intro)
-There's a video about these basic steps here:
+ (find-wset \"13o_2o2o23oo33ooo\" '(find-ebuffer \"B\"))
+ (find-wset \"13o_2o2o23oo33ooo+\" '(find-ebuffer \"B\"))
+ (find-2a nil '(find-efunction 'ee-eval-sexp-eol))
+ (find-2b nil '(find-efunction 'ee-eval-sexp-eol))
- \"How to install eev with M-x list-packages and how to navigate its
tutorials\"
- http://angg.twu.net/eev-videos/2020-list-packages-eev-nav.mp4
- http://angg.twu.net/2020-list-packages-eev-nav.html
- http://www.youtube.com/watch?v=kxBjiUo88_U
+The notes in the style 1 are a translation to English to the
+notes in the style 2. I wrote the notes in style 2 first.
+Some people _PANIC_ when they see notes written in the second
+style, and most of us are conditioned to believe that a) we have
+to try to write notes that are readable by everyone - even though
+that is impossible if we take the \"everyone\" literally, b)
+notes in the second style can't be shared in public. However:
+ a) It is good karma to make our notes publically available even
+ if very few people will be able to read them,
+ b) we are our main readers - and we need to try to make our
+ notes easily to read by ourselves,
+ c) _executability_ helps in _readability_,
-4. Understanding buffers and the mode line
-==========================================
-It's good to be able to interpret the mode line - it gives a lot of
-information about where we are. See:
+ d) people are experimenting with ways of writing executable
+ notes, and even the most popular styles of doing that -
+ Jupyter Notebooks, I guess? - are not yet really hugely
+ popular.
- (find-enode \"Mode Line\")
+One of my intents with eev is to encourage people to experiment
+with ways of writing executable notes. This involves learning the
+functions and techniques that already exist, and inventing new
+ones - and, hopefully, sharing them.
-For example, after running `M-x eev-beginner' the mode line says this:
- -:**- *(find-eev-quick-intro)* Top L1 (Fundamental eev) ---
-The best way to understand what each component means is by moving the
-mouse pointer onto it and looking at the help that is displayed. The
-main components in this case are:
- \"**\" - this buffer is read-write and has been modified. See:
+8. IRC
+======
+(TO DO: explain this:)
- (find-enode \"Mode Line\" \"**\")
+ (find-efunction 'ee-0x0-upload-region)
+ (find-efunction 'ee-0x0-upload-region \"aliased to `u0'\")
- \"*(find-eev-quick-intro)*\" - the name of this buffer.
- A curiosity: this buffer is not associated to a file! If you
- try to save it with `C-x C-s' or with the \"Save\" option in the
- \"File\" menu you will get a prompt in the minibuffer that starts
- with:
+9. Git
+======
+Example:
- File to save in:
+ (progn
- For more information on buffers and files, see:
+ ;; Links to the git repository:
+ ;; https://github.com/edrx/emacs-lua
+ ;; https://github.com/edrx/emacs-lua/blob/main/tests.e
+ ;; https://raw.githubusercontent.com/edrx/emacs-lua/main/tests.e
- (find-enode \"Mode Line\" \" BUF \" \"name of the buffer\")
- (find-enode \"Buffers\" \"Most buffers are made by visiting files\")
- (find-enode \"Basic Files\")
+ (setq ee-emluagit-base
+ \"https://raw.githubusercontent.com/edrx/emacs-lua/main/\")
+ (defun find-emluagitfile (fname &rest rest)
+ (apply 'find-wget (format \"%s%s\" ee-emluagit-base fname) rest))
+ (defun find-emluagit (fname &rest rest)
+ (apply 'find-wgeta (format \"%s%s\" ee-emluagit-base fname) rest))
- \"Top L1\" - see:
+ ;; Tests:
+ ;; (find-emluagit \"tests.e\")
+ ;; (find-emluagit \"tests.e\" \"find-angg-and-find-es\")
+ ;; (find-emluagit \"tests.e\" \"find-angg-and-find-es\" \"Tests:\")
+ ;; (find-emluagitfile \"tests.e\" \"Warning:\")
- (find-enode \"Mode Line\" \"Top\")
- (find-enode \"Mode Line\" \"line number at point\")
- (find-enode \"Point\")
+ ;; Links to a local copy of the git repository:
+ ;; (find-git-links \"https://github.com/edrx/emacs-lua\" \"emlua\")
+ ;; (setq ee-git-dir \"~/usrc/\")
+ ;;
+ ;; (find-code-c-d \"emlua\" \"~/usrc/emacs-lua/\" :anchor)
+ (code-c-d \"emlua\" \"~/usrc/emacs-lua/\" :anchor)
+ ;;
+ ;; Tests:
+ ;; (find-emlua \"\")
+ ;; (find-emlua \"tests.e\")
+ ;; (find-emlua \"tests.e\" \"find-angg-and-find-es\")
+ ;; (find-emlua \"tests.e\" \"find-angg-and-find-es\" \"Tests:\")
+ ;; (find-emluafile \"tests.e\" \"Warning:\")
- \"(Fundamental eev)\" - see:
+ ;; Compare:
+ ;; (find-emluagit \"tests.e\" \"find-angg-and-find-es\")
+ ;; (find-emlua \"tests.e\" \"find-angg-and-find-es\")
- (find-enode \"Mode Line\" \"(MAJOR MINOR)\")
- (find-enode \"Mode Line\" \"major mode\")
- (find-enode \"Mode Line\" \"minor modes\")
+ )
+" pos-spec-list)))
+;; (find-escripts-intro)
-5. More on modes
-================
-The \"eev\" in the mode line means that the key bindings defined by eev
-are \"active\". The main key bindings of eev are listed here,
- (find-emacs-keys-intro \"1. Basic keys (eev)\")
-and if you want more details about what is an \"active keymap\" you can
-read these sections of the manual:
+;;; ____ _ _
+;;; / ___(_) |_
+;;; | | _| | __|
+;;; | |_| | | |_
+;;; \____|_|\__|
+;;;
+;; «find-git-intro» (to ".find-git-intro")
+;; Skel: (find-intro-links "git")
- (find-enode \"Key Bindings\")
- (find-enode \"Keymaps\")
- (find-enode \"Local Keymaps\")
+(defun find-git-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-git-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-git-intro)
+Source code: (find-efunction 'find-git-intro)
+More intros: (find-eev-quick-intro)
+ (find-eev-intro)
+ (find-eepitch-intro)
+This buffer is _temporary_ and _editable_.
+It is meant as both a tutorial and a sandbox.
-The five main major modes that beginners need to learn about are the
-Fundamental Mode, the Help Mode, the Info Mode, Dired Mode, and Shell
-mode. In the Fundamental Mode most \"basic\" keys are interpreted as
-editing keys - see:
- (find-enode \"Major Modes\" \"Fundamental mode\")
- (find-enode \"Keymaps\" \"self-inserting character\")
+At this moment this is a call for help -
+not an intro.
-5.1. Eev mode
--------------
-The three main keys of Eev Mode are these ones:
- M-e - to follow a hyperlink. Mnemonic: \"(e)valuate\"/\"(e)xecute\".
- See: (find-eev-quick-intro \"2. Evaluating Lisp\")
- (find-eev-quick-intro \"3. Elisp hyperlinks\")
- M-j - to jump to certain predefined places. In particular,
- `M-j' takes you to a buffer with basic help and a
- list of jump targets. See:
- (find-eev-quick-intro \"7.2. The list of eejump targets\")
- `M-2 M-j' takes you to this help page.
- `M-5 M-j' takes you to: (find-eev-quick-intro)
- M-k - to go back. Mnemonic: \"(k)ill buffer\".
- See: (find-eev-quick-intro \"3. Elisp hyperlinks\" \"M-k\")
+0. Introduction
+===============
+Git is extremely popular, and I've heard that the two packages
+that attract most new users to Emacs are Org and Magit:
-The text above was taken from:
+ https://github.com/magit/magit
+ https://melpa.org/#/magit
+ (find-epackage 'magit)
- (find-emacs-keys-intro \"1. Basic keys (eev)\")
+At this moment eev offers only a trivial hack to help people
+download git repositories. If you put the point on the github url
+above and type `M-h g' or `M-x find-git-links' you will get the
+same effect as running the sexp below:
-From this point onwards I will suppose that the reader knows how to
-use at least `M-e' and `M-j'.
+ (find-git-links \"https://github.com/magit/magit\" \"magit\")
-Note the Eev mode is a global minor mode. The next subsections are
-about the other four main major modes - besides Fundamental mode.
+You will get a temporary buffer with an e-script for downloading
+(\"cloning\") that git repository and inspecting it in a handful
+of ways.
+I found git VERY hard to learn. To test most concepts you need a
+repository with tags and branches and a second repository that
+\"pulls\" from it, and no books or tutorials that I know of come
+with a sequence of commands that set that up in a way that makes
+the tests easy to reproduce. To make things worse, when I was
+trying to set up a git repository for eev on github for the first
+time I did some things wrong on the github side of the repository
+that I did not know how to undo... after spending some days
+trying to fix that I gave up, deleted that repository, created a
+new one, and decided that I would always do LOTS of local tests
+before messing up my public repository again.
+This intro is about doing these local tests - but it is in a VERY
+early draft.
-5.2. Help Mode
---------------
-Most help commands in Emacs display buffers in Help Mode. For
-example, if you run `C-h f Info-mode' or execute one of the sexps
-below
- (find-efunctiondescr 'Info-mode)
- (find-efunctiondescr 'help-mode)
- (find-efunctiondescr 'dired-mode)
-you will get buffers in Help Mode - they are read-only, and if you
-type `q' in them this be interpreted as `quit' rather than as \"insert
-the character `q'\".
+1. Preparation
+==============
+Download the second URL below with `M-x brep',
+ https://github.com/pluralsight/git-internals-pdf/
+
https://github.com/pluralsight/git-internals-pdf/releases/download/v2.0/peepcode-git.pdf
+and do the same for the fourth URL below here:
-5.3. Info Mode
---------------
-The key sequence `C-h r' opens the Emacs manual in Info Mode. This is
-a read-only mode like Help Mode, but more keys become navigation keys.
-The main ones are:
+ https://git-scm.com/book/en/v2
+ https://github.com/progit/progit2
+ https://github.com/progit/progit2/releases
+ https://github.com/progit/progit2/releases/download/2.1.277/progit.pdf
- q Quit Info: reselect previously selected buffer.
- RET Follow a node reference near point.
- n Move to the \"next\" node of this node.
- p Move to the \"previous\" node of this node.
- u Move \"up\" from this node.
+Then run this eepitch block,
-Also, the tool bar changes completely, and it shows icons
-corresponding to the main navigation keys. See:
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ rm -Rfv /tmp/git-test/
+ mkdir /tmp/git-test/
+ cd /tmp/git-test/
+ # http://angg.twu.net/bin/git-defs.html
+ wget http://angg.twu.net/bin/git-defs
+ cp -v
$S/https/github.com/pluralsight/git-internals-pdf/releases/download/v2.0/peepcode-git.pdf
.
+ cp -v
$S/https/github.com/progit/progit2/releases/download/2.1.277/progit.pdf .
- (find-enode \"Tool Bars\")
+and this prog1:
+ (prog1
+ (code-pdf-page \"gitinternals\" \"/tmp/git-test/peepcode-git.pdf\")
+ (code-pdf-text \"gitinternals\" \"/tmp/git-test/peepcode-git.pdf\")
+ (code-pdf-page \"progit\" \"/tmp/git-test/progit.pdf\")
+ (code-pdf-text \"progit\" \"/tmp/git-test/progit.pdf\")
+ (code-c-d \"gitdoc\" \"/usr/share/doc/git-doc/\")
+ )
+If can test if everything works by running the six sexps below:
-5.4. Dired Mode
----------------
-Dired Mode lets you navigate the directory structure. You can enter
-it by typing `C-x C-f RET'. If you type `RET' on a line that shows a
-directory this will be interpreted as \"enter that directory\", and
-`RET' on a line that shows a file is interpreted as \"open that file\".
-See:
+ (find-fline \"/tmp/git-test/git-defs\")
+ (find-gitinternalspage)
+ (find-gitinternalstext)
+ (find-progitpage)
+ (find-progittext)
+ (find-gitdocfile \"\")
- (find-enode \"Dired\")
- (find-enode \"Dired Enter\" \"C-x C-f\")
- (find-enode \"ls in Lisp\")
-5.5. Shell Mode
----------------
-Emacs can run terminals inside its buffers - and by default that
-terminal runs the default shell. In Windows the default shell is
-\"cmd.exe\", that is reminiscent of MS-DOS, and is VERY clumsly. See:
+2. A first repository
+=====================
+The manpage of git-revisions
- https://en.wikipedia.org/wiki/Windows_Console
- https://en.wikipedia.org/wiki/Command-line_interface
- https://en.wikipedia.org/wiki/MS-DOS#Windows_command-line_interface
- https://en.wikipedia.org/wiki/Cmd.exe
- https://en.wikipedia.org/wiki/Batch_file
- https://en.wikipedia.org/wiki/Terminal_emulator
+ (find-man \"7 git-revisions\")
+ (find-man \"7 git-revisions\" \"Here is an illustration\")
+ (find-gitdocfile \"revisions.txt\" \"illustration, by Jon Loeliger\")
-If you run `M-x shell' you will get a shell buffer. See:
+has this example, in which the commits have this structure:
- (find-enode \"Interactive Shell\")
+ G H I J
+ \\ / \\ /
+ D E F
+ \\ | / \\
+ \\ | / |
+ \\|/ |
+ B C
+ \\ /
+ \\ /
+ A
-especially this part of the first paragraph:
+Here is an e-script that creates it:
- To give input to the subshell, go to the end of the buffer and type
- the input, terminated by <RET>.
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ rm -Rfv /tmp/git-test/repo1/
+ mkdir /tmp/git-test/repo1/
+ cd /tmp/git-test/repo1/
+ . /tmp/git-test/git-defs
+ # (find-fline \"/tmp/git-test/git-defs\")
-As an exercise, try to give these commands to the Windows shell:
+ git init
+ Modify file1; Modify file2; git add file1 file2
+ Commit A; git branch brAC
+ Modify file1; Commit B; git branch brBDG
+ git checkout brAC
+ Modify file1; Commit C
+ git checkout brBDG
+ Modify file1; Commit D
+ git checkout HEAD^ -b brE
+ Modify file1; Commit E
+ git checkout HEAD^
+ git merge -s ours brAC -m F
+ git branch brFI
+ git checkout brBDG
+ Modify file1; Commit G
+ git checkout HEAD^ -b brH
+ Modify file1; Commit H
+ git checkout brFI
+ Modify file1; Commit I
+ git checkout HEAD^ -b brJ
+ Modify file1; Commit J
+ Diagram
- dir
- cd
- cd ..
- dir
+ # (find-gitk \"/tmp/git-test/repo1/\")
+Actually it creates the structure below - where, for example, the
+node \"G,brBDG\" is a commit with message \"G\" and a branch
+called \"brBDG\" pointing to it; I call that branch \"brBDG\"
+because when it was created it pointed to the commit with message
+\"B\", then it moved to the commit \"D\", then to \"G\".
+ I,brFI J,brJ
+ | /
+ G,brBDG H,brH | /
+ \\ / | /
+ D E,brE F
+ \\ | / \\
+ \\ | / |
+ \\ | / |
+ B C,brAC
+ \\ /
+ \\ /
+ A
-5.6. Eshell
------------
-The manual of Eshell - here,
+Here's a video showing the script above in action:
- (find-node \"(eshell)Top\")
+ http://angg.twu.net/eev-videos/2020-doubt-about-merging.mp4
+ (code-eevvideo \"merg\" \"2020-doubt-about-merging\")
+ (find-mergvideo \"0:00\")
+ (find-mergvideo \"0:20\")
-describes it as: \"Eshell is a shell-like command interpreter
-implemented in Emacs Lisp\".
+NEXT STEPS: explain how to use git merge both from the command
+line and from magit; explain HEAD, master, and tags. Point to man
+pages in man and text format and to sections in Scott Chacon's
+book. I NEED LOTS OF HELP HERE.
-This feature of eev:
+ (find-man \"git-merge\")
+ (find-gitinternalspage)
+ (find-gitinternalstext)
- (find-psne-intro \"1. Local copies of files from the internet\")
-needs to run wget on a unix-like shell, and it turns out that
-this can be achieved easily using Eshell. For a discussion of the
-tecnhical details, see:
- https://lists.gnu.org/archive/html/help-gnu-emacs/2021-10/msg00051.html
- https://lists.gnu.org/archive/html/help-gnu-emacs/2021-10/msg00058.html
- https://lists.gnu.org/archive/html/help-gnu-emacs/2021-10/msg00126.html
+3. A second repository
+======================
+HELP PLEEEASEEEE
-6. Video links
-==============
-If you're on Windows you need to start by configuring your
-browser and the path to it, as described here:
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ rm -Rfv /tmp/git-test/repo2/
+ mkdir /tmp/git-test/repo2/
+ cd /tmp/git-test/repo2/
+ . /tmp/git-test/git-defs
+ # (find-fline \"/tmp/git-test/git-defs\")
- (find-video-links-intro)
- (find-video-links-intro \"3. `find-youtube-video'\")
- (find-video-links-intro \"4. Configuring the browser\")
+ git clone /tmp/git-test/repo1/ .
+ ls -lAF
-and by making `find-eev-video' use the browser to play the
-videos. For that you need to run this sexp,
+ # (find-gitk \"/tmp/git-test/repo2/\")
+ # (find-fline \"/tmp/git-test/repo2/\")
+ # (find-fline \"/tmp/git-test/repo2/.git/\")
+ # (find-fline \"/tmp/git-test/repo2/.git/config\")
- (ee-use-youtube-videos)
+ # (find-man \"1 git-remote\")
+ # (find-progitpage (+ 24 36) \"Adding Remote Repositories\")
+ # (find-progittext (+ 24 36) \"Adding Remote Repositories\")
-as explained here:
+" pos-spec-list)))
- (find-video-links-intro \"7. `find-eev-video'\")
+;; (find-git-intro)
-Also install the Mpv video player, configure its path, and check
-that Emacs can find it. This is explained here:
- (find-video-links-intro \"6. Configuring Mpv\")
-The next sections of this tutorial will suppose that you know how
-to configure that path to external programs, and how to test
-them.
-IMPORTANT: save the sexps with `setenv' that you used to
-configure the paths to your notes. See:
- (find-here-links-intro \"4. `find-here-links-3'\")
- (find-here-links-intro \"4. `find-here-links-3'\" \"~/TODO\")
+;;; __ ___ _ _
+;;; \ \ / / | | |__ ___ __ _(_)_ __ _ __ ___ _ __
+;;; \ \ /\ / / __)_____| '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|
+;;; \ V V /\__ \_____| |_) | __/ (_| | | | | | | | | __/ |
+;;; \_/\_/ ( / |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|
+;;; |_| |___/
+;;
+;; «find-windows-beginner-intro» (to ".find-windows-beginner-intro")
+;; Skel: (find-intro-links "windows-beginner")
+(defun find-windows-beginner-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-windows-beginner-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-windows-beginner-intro)
+Source code: (find-efunction 'find-windows-beginner-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.
+The quickest way to open or recreate this is with `M-3 M-j'.
-7. eev-on-windows.el
-====================
-The file eev-on-windows.el contains several functions that will
-be used in the next sections. It is not loaded by default, so you
-need to do this:
- (require 'eev-on-windows)
-If you are on Windows you will also need to download some
-\".exe\" files by running the sexps below. Each of the sexps that
-start with `ee-download-with-eww' may take several seconds to
-complete, and it's better to wait until it sends a message like
-\"Saved (filename.exe)\" to the echo area before executing other
-sexps with `M-e'.
+This is a tutorial on how to install Emacs and eev on M$ Windows,
+and on the basic steps for learning Emacs and eev after
+installing them. If you're a W$ user you should start by reading
+this tutorial online in a browser, at
- (mkdir \"~/bin/\" t)
- (delete-file \"~/bin/wget.exe\")
- (delete-file \"~/bin/pdftotext.exe\")
- (delete-file \"~/bin/lua52.exe\")
- (delete-file \"~/bin/lua52.dll\")
- (ee-download-with-eww \"http://angg.twu.net/2021-oficina/wget.exe\"
\"~/bin/\")
- (ee-download-with-eww \"http://angg.twu.net/2021-oficina/pdftotext.exe\"
\"~/bin/\")
- (ee-download-with-eww \"http://angg.twu.net/2021-oficina/lua52.exe\"
\"~/bin/\")
- (ee-download-with-eww \"http://angg.twu.net/2021-oficina/lua52.dll\"
\"~/bin/\")
+ http://angg.twu.net/eev-intros/find-windows-beginner-intro.html
-The sexps in the block above only need to be executed once - you
-don't need to execute them at each Emacs session. You can test if
-they worked by running the sexps below:
+while you run Emacs in another window (see section 1). After
+getting eev installed on your machine (see section 3) you will be
+able to access this tutorial from Emacs by typing `M-3 M-j'.
- (find-fline \"~/bin/\" \"wget.exe\")
- (find-fline \"~/bin/\" \"pdftotext.exe\")
- (find-fline \"~/bin/\" \"lua52.exe\")
- (find-callprocess `(\"~/bin/wget.exe\" \"--help\"))
- (find-callprocess `(\"~/bin/pdftotext.exe\" \"--help\"))
- (find-callprocess `(\"~/bin/lua52.exe\" \"--help\"))
+The main tutorial on eev is this one,
+ (find-eev-quick-intro)
+ http://angg.twu.net/eev-intros/find-eev-quick-intro.html
+The sections from 5.6 onwards were written in nov/2021 and they
+cover how to install some external programs to make almost all
+features of eev work on M$ Windows. Feedback on them would be
+greatly appreciated!
-7.1. `ee-use-windows'
----------------------
-If you are on Windows you should run this:
- (ee-use-windows)
-Its source code is here:
- (find-eev \"eev-on-windows.el\" \"ee-use-windows\")
-Most of what it does is explained in the next sections.
+0. Introduction
+===============
+My favorite exposition of what eev is is this presentation,
+called \"How to record executable notes with eev - and how to
+play them back\":
+ http://angg.twu.net/emacsconf2019.html
+ http://angg.twu.net/LATEX/2019emacsconf.pdf (slides)
+ http://www.youtube.com/watch?v=86yiRG8YJD0 (video)
+The video ends with a demo that shows a non-trivial example of
+\"executable notes\". The most interesting part of that demo
+shows how to use eev to send commands to an external program - a
+unix shell, being run in interactive mode. Here's a link to that
+part of the video on youtube, plus two related links that are
+harder to explain:
+ http://www.youtube.com/watch?v=86yiRG8YJD0#t=15m11s
+ (find-eev2019video \"15:11\" \"Demo: the eepitch block\")
+ (find-angg \".emacs.videos\" \"eev2019\")
-7.2. Testing wget.exe
----------------------
-Try to run this eepitch block with <f8>s:
+I don't have easy access to Windows machines, so I have to rely
+on friends to test some things for me. I also don't have easy
+access to people who use Windows and who do have experience using
+terminals, so from time to time I give workshops for \"total
+beginners\" like the one described here,
- (eepitch-eshell)
- (eepitch-kill)
- (eepitch-eshell)
- rm --help
- ls --help
- rm -fv $S/http/www.gnu.org/software/emacs/emacs-paper.html
- ls -l $S/http/www.gnu.org/software/emacs/emacs-paper.html
- #
- mkdir -p $S/http/www.gnu.org/software/emacs/
- cd $S/http/www.gnu.org/software/emacs/
- wget -nc 'http://www.gnu.org/software/emacs/emacs-paper.html'
- echo 'http://www.gnu.org/software/emacs/emacs-paper.html' >> ~/.psne.log
- #
- ls -l $S/http/www.gnu.org/software/emacs/emacs-paper.html
- rm -fv $S/http/www.gnu.org/software/emacs/emacs-paper.html
+ (find-video-links-intro \"8. Windows\")
-Now try to follow the instructions here to download the same URL
-with `M-x brep':
+and I see that the people on those workshops get stuck on ideas
+that I thought that were obvious, and I change my approach, and I
+rewrite lots of things.
- (find-psne-intro \"3. The new way: `M-x brep'\")
+This is my N-th attempt to rewrite this tutorial.
-`M-x brep' uses `eepitch-shell', that on Windows runs cmd.exe by
-default, but in the last section we ran `ee-use-windows', that
-redefines `eepitch-shell' to makes it use Eshell instead of
-cmd.exe - and it also makes the command \"wget\" in eshell run
-~/bin/wget.exe.
+Version of these instructions: 2021nov13.
-Eev also uses wget in the function `find-wget' and its variants
-`find-wgeta', `find-wget-elisp', and `find-wgeta-elisp'. Try the
-tests here, and check that they work:
- (find-eev \"eev-plinks.el\" \"find-wget\")
- (find-eev \"eev-plinks.el\" \"find-wget\" \"Tests:\")
+1. Download and install Emacs
+=============================
+Read the README below and then install Emacs using either the
+link to the .exe or the link to the .zip:
+http://alpha.gnu.org/gnu/emacs/pretest/windows/emacs-28/
+http://alpha.gnu.org/gnu/emacs/pretest/windows/emacs-28/README-windows-binaries
+http://alpha.gnu.org/gnu/emacs/pretest/windows/emacs-28/emacs-28.0.50-snapshot-2021-01-15-installer.exe
+http://alpha.gnu.org/gnu/emacs/pretest/windows/emacs-28/emacs-28.0.50-snapshot-2021-01-15.zip
-7.3. Lua
---------
-`ee-use-windows' also redefine `eepitch-lua51' to make it run
-~/bin/lua52.exe, that you downloaded in section 7, and it runs
-`ee-use-youtube-videos', that you've run explicitly in section 6.
-Try this link to a video:
+You may need to create a desktop icon or shortcut to
+<emacsdir>/bin/runemacs.exe.
- (find-eevtestblsvideo \"2:33\" \"if I run f8 here I start a new Lua
interpreter\")
-it should play the video in a browser. The video shows what
-happens when we run an eepitch block that calls Lua and
-everything works correctly. Check that these two eepitch blocks
-work as expected:
- (eepitch-lua51)
- (eepitch-kill)
- (eepitch-lua51)
- print(2+3)
- os.exit()
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- ~/bin/lua52.exe -i
- print(2+3)
- os.exit()
+2. Key sequences and how to quit
+================================
+Most people who use Emacs do many things by using key sequences - for
+example `C-x C-s' to save the current file.
+`C-x C-s' is the Emacs notation for \"control-x control-s\". This
+notation is explained here:
+ (find-enode \"User Input\" \"<Ctrl>\" \"a\" \"C-a\")
+ (find-enode \"User Input\" \"<Meta>-a\" \"M-a\" \"<Alt>\")
+The best way to learn key sequences when you are a beginner is by
+using the menu bar:
-7.4. Downloading videos
------------------------
-The default behavior for a video link like this one
+ (find-enode \"Menu Bar\")
- (find-eevtestblsvideo \"2:33\" \"if I run f8 here\")
+for example, in the \"File\" menu the last option is:
-is to download a local copy of the video if it hasn't been
-already downloaded, and then play the local copy with mpv. The
-downloading is not automatic; the user has to \"psne\" it - see
-the section 7.2 and this video:
+ Quit C-x C-c
- (find-eevvlinksvideo \"6:09\" \"if I execute this `find-eevtestblsvideo'\")
- (find-eevvlinksvideo \"6:15\" \"the last line says `Local file NOT found'\")
+If you type just `C-x' and wait the `C-x' will be displayed in the
+\"Echo area\" at the bottom of the screen. This is explained here:
-Now that you understand psne-ing, try the three standard
-behaviors for video links. First make sure that we don't have a
-local copy of the \"eevtestbls\" video, by running this:
+ (find-enode \"Echo Area\")
- (eepitch-shell)
- (eepitch-kill)
- (eepitch-shell)
- rm -fv $S/http/angg.twu.net/eev-videos/2021-test-blocks.mp4
- ls -l $S/http/angg.twu.net/eev-videos/2021-test-blocks.mp4
+ The line at the very bottom of the frame is the \"echo area\". It is
+ used to display small amounts of text for various purposes.
-Then run these sexps:
+ The echo area is so-named because one of the things it is used
+ for is \"echoing\", which means displaying the characters of a
+ multi-character command as you type. Single-character commands are
+ not echoed. Multi-character commands (*note Keys) are echoed if you
+ pause for more than a second in the middle of a command. Emacs then
+ echoes all the characters of the command so far, to prompt you for
+ the rest. Once echoing has started, the rest of the command echoes
+ immediately as you type it. This behavior is designed to give
+ confident users fast response, while giving hesitant users maximum
+ feedback.
- (ee-use-local-videos)
- (find-eevtestblsvideo \"2:33\" \"if I run f8 here\")
+ The echo area is also used to display an \"error message\" when a
+ command cannot do its job. Error messages may be accompanied by
+ beeping or by flashing the screen.
- (setq ee-find-eev-video-function 'find-eevlinks-video)
- (find-eevtestblsvideo \"2:33\" \"if I run f8 here\")
+There are several ways to abort a key sequence in the middle. They
+are explained here,
- (ee-use-youtube-videos)
- (find-eevtestblsvideo \"2:33\" \"if I run f8 here\")
+ (find-enode \"Quitting\")
-The three behaviors are explained here:
+but what I recommend to beginners is: if you are stuck in the middle
+of a key sequence and don't know how to abort it, just go to the
+\"File\" menu, use the option \"Quit\", and restart Emacs.
- (find-video-links-intro \"7. `find-eev-video'\")
- (find-video-links-intro \"The default is `find-eevlocal-video', but\")
-7.5. Downloading PDFs
----------------------
-Now try all the tests in the sections 1-5 and 7 of:
+3. Using M-x and installing eev
+===============================
+We can run commands by name by using `M-x'. `M-x' uses the last line
+of the screen as a \"minibuffer\" - see:
- (find-pdf-like-intro)
+ (find-enode \"Minibuffer\")
+ (find-enode \"Basic Minibuffer\" \"it appears in the echo area\")
+ (find-enode \"M-x\" \"Running Commands by Name\")
-This test in section 2 will not work,
+To install eev, do this:
+ 1. run `M-x package-initialize',
+ 2. run `M-x list-packages',
+ 3. select \"eev\" at the list of packages,
+ 4. click on \"install\".
- (find-sh0 \"ls -l ~/Coetzee99.pdf\")
+To load eev and enter its tutorial, run
+ `M-x eev-beginner'.
-because it requires a Unix-style `ls'. It works in Eshell,
-though. Try:
+The tutorial looks like this:
+ (find-eev-quick-intro)
- (eepitch-eshell)
- (eepitch-kill)
- (eepitch-eshell)
- ls --help
- ls -l ~/Coetzee99.pdf
+There's a video about these basic steps here:
-That's because eshell defines its `ls' in Lisp. See:
+ \"How to install eev with M-x list-packages and how to navigate its
tutorials\"
+ http://angg.twu.net/eev-videos/2020-list-packages-eev-nav.mp4
+ http://angg.twu.net/2020-list-packages-eev-nav.html
+ http://www.youtube.com/watch?v=kxBjiUo88_U
- (find-eshellnode \"Built-ins\")
-Also, the tests in section 6 don't work on Windows - one of the
-things that `ee-use-windows' does is to make `find-pdf-page' use
-a browser to open PDFs, and section 6 uses a PDF viewer called
-\"xpdf\". Take a look:
- (find-pdf-like-intro \"6. How the external programs are called\")
-So: check that everything in sections 1-5 and 7 work, except for
-the test that uses `ls'. The links to pages of PDFs converted to
-text should work - the conversion to text will be done by
-~/bin/pdftotext.exe, that you downloaded and tested in section 7.
+4. Understanding buffers and the mode line
+==========================================
+It's good to be able to interpret the mode line - it gives a lot of
+information about where we are. See:
+ (find-enode \"Mode Line\")
+For example, after running `M-x eev-beginner' the mode line says this:
-7.6. Saving your settings
--------------------------
-If all the tests above worked then you can save your settings.
-I will refer to the block below as the \"Windows setting block\":
+ -:**- *(find-eev-quick-intro)* Top L1 (Fundamental eev) ---
- ;; See: (find-windows-beginner-intro \"8. Summary\")
- ;; (find-video-links-intro \"4. Configuring the browser\")
- ;; (find-video-links-intro \"6. Configuring Mpv\")
- (require 'beginner)
- (require 'eev-on-windows)
- (ee-use-windows)
- (setenv \"FIREFOXDIR\" \"c:/Program Files/Mozilla Firefox\")
- (setenv \"GOOGLECHROMEDIR\" \"c:/Program Files/Google/Chrome/Application\")
- (setenv \"MPVDIR\" \"c:/Users/myusername/path/to/mpv\")
- ;;
- ;; Choose one:
- (ee-use-googlechrome)
- ;;(ee-use-firefox)
+The best way to understand what each component means is by moving the
+mouse pointer onto it and looking at the help that is displayed. The
+main components in this case are:
-Copy that block to your ~/TODO, but with the right paths in the
-`setenv's. I will refer to that modified copy as the \"Windows
-setting block in ~/TODO\".
+ \"**\" - this buffer is read-write and has been modified. See:
+ (find-enode \"Mode Line\" \"**\")
+ \"*(find-eev-quick-intro)*\" - the name of this buffer.
-7.7. Testing your settings
---------------------------
-The best way to test your \"Windows setting block in ~/TODO\" is
-by doing this. Start a second Emacs without closing this one, and
-on that second Emacs run:
+ A curiosity: this buffer is not associated to a file! If you
+ try to save it with `C-x C-s' or with the \"Save\" option in the
+ \"File\" menu you will get a prompt in the minibuffer that starts
+ with:
- 1. `M-x eev-beginner',
- 2. `M-1 M-j' (to access your ~/TODO),
- 3. type `M-e' on each line of your \"Windows setting block in
- ~/TODO\" _that is not commented with with a \";;\".
+ File to save in:
-Then... [TODO: complete this!]
+ For more information on buffers and files, see:
+ (find-enode \"Mode Line\" \" BUF \" \"name of the buffer\")
+ (find-enode \"Buffers\" \"Most buffers are made by visiting files\")
+ (find-enode \"Basic Files\")
+ \"Top L1\" - see:
-7.8. Saving your settings to your ~/.emacs
-------------------------------------------
-See:
+ (find-enode \"Mode Line\" \"Top\")
+ (find-enode \"Mode Line\" \"line number at point\")
+ (find-enode \"Point\")
- (find-elnode \"Init File\" \".emacs\")
+ \"(Fundamental eev)\" - see:
-A quick way to visit your ~/.emacs is with `M-5 M-5 M-j'. It runs
-this:
+ (find-enode \"Mode Line\" \"(MAJOR MINOR)\")
+ (find-enode \"Mode Line\" \"major mode\")
+ (find-enode \"Mode Line\" \"minor modes\")
- (find-fline \"~/.emacs\")
-8. Summary
-==========
+5. More on modes
+================
+The \"eev\" in the mode line means that the key bindings defined by eev
+are \"active\". The main key bindings of eev are listed here,
-[Unfinished!!!]
+ (find-emacs-keys-intro \"1. Basic keys (eev)\")
+and if you want more details about what is an \"active keymap\" you can
+read these sections of the manual:
+ (find-enode \"Key Bindings\")
+ (find-enode \"Keymaps\")
+ (find-enode \"Local Keymaps\")
+The five main major modes that beginners need to learn about are the
+Fundamental Mode, the Help Mode, the Info Mode, Dired Mode, and Shell
+mode. In the Fundamental Mode most \"basic\" keys are interpreted as
+editing keys - see:
-" pos-spec-list)))
+ (find-enode \"Major Modes\" \"Fundamental mode\")
+ (find-enode \"Keymaps\" \"self-inserting character\")
-;; (find-windows-beginner-intro)
-;;; _____ _
-;;; | ____|_ _____ _ __ ___(_)___ ___ ___
-;;; | _| \ \/ / _ \ '__/ __| / __|/ _ \/ __|
-;;; | |___ > < __/ | | (__| \__ \ __/\__ \
-;;; |_____/_/\_\___|_| \___|_|___/\___||___/
-;;;
-;; «find-eev-exercises-intro» (to ".find-eev-exercises-intro")
-;; Skel: (find-intro-links "eev-exercises")
-;; Test: (find-eev-exercises-intro)
+5.1. Eev mode
+-------------
+The three main keys of Eev Mode are these ones:
-(defun find-eev-exercises-intro (&rest pos-spec-list) (interactive)
- (let ((ee-buffer-name "*(find-eev-exercises-intro)*"))
- (apply 'find-eintro "\
-\(Re)generate: (find-eev-exercises-intro)
-Source code: (find-efunction 'find-eev-exercises-intro)
-More intros: (find-eev-quick-intro)
- (find-here-links-intro)
- (find-refining-intro)
- (find-escripts-intro)
- (find-eev-intro)
- (find-eepitch-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-x ex',
-but you will need to run this:
- (defun ex () (interactive) (find-eev-exercises-intro))
+ M-e - to follow a hyperlink. Mnemonic: \"(e)valuate\"/\"(e)xecute\".
+ See: (find-eev-quick-intro \"2. Evaluating Lisp\")
+ (find-eev-quick-intro \"3. Elisp hyperlinks\")
+ M-j - to jump to certain predefined places. In particular,
+ `M-j' takes you to a buffer with basic help and a
+ list of jump targets. See:
+ (find-eev-quick-intro \"7.2. The list of eejump targets\")
+ `M-2 M-j' takes you to this help page.
+ `M-5 M-j' takes you to: (find-eev-quick-intro)
+ M-k - to go back. Mnemonic: \"(k)ill buffer\".
+ See: (find-eev-quick-intro \"3. Elisp hyperlinks\" \"M-k\")
+The text above was taken from:
+ (find-emacs-keys-intro \"1. Basic keys (eev)\")
+From this point onwards I will suppose that the reader knows how to
+use at least `M-e' and `M-j'.
-This is a set of exercises that I am preparing for this workshop:
+Note the Eev mode is a global minor mode. The next subsections are
+about the other four main major modes - besides Fundamental mode.
- http://angg.twu.net/2021-workshop.html
-THIS IS A WORK AND PROGRESS AND CURRENTLY A MESS.
+5.2. Help Mode
+--------------
+Most help commands in Emacs display buffers in Help Mode. For
+example, if you run `C-h f Info-mode' or execute one of the sexps
+below
-0. Prerequisites
-================
-I will suppose:
+ (find-efunctiondescr 'Info-mode)
+ (find-efunctiondescr 'help-mode)
+ (find-efunctiondescr 'dired-mode)
- a. that the people doing the workshop will have Emacs 27 or
- 28 (pretest) installed,
+you will get buffers in Help Mode - they are read-only, and if you
+type `q' in them this be interpreted as `quit' rather than as \"insert
+the character `q'\".
- b. that they have watched the \"installation and navigation\"
- video and tried everything on it, especially this part:
- (find-eevnavvideo \"6:28\" \"M-j: you can forget practically
everything...\")
- (find-eevnavvideo \"6:41\" \"if you type just M-j\")
- (find-eevnavvideo \"6:48\" \"has a header that is beginner-friendly\")
- The beginner-friendly header generated by `M-j' has changed
- since I recorded that video, and now it shows these three
- ways of opening the file where we will put our notes instead
- of showing just the first one:
+5.3. Info Mode
+--------------
+The key sequence `C-h r' opens the Emacs manual in Info Mode. This is
+a read-only mode like Help Mode, but more keys become navigation keys.
+The main ones are:
- M-1 M-j runs: (find-fline \"~/TODO\")
- M-2 M-1 M-j shows the file ~/TODO in the right window
- M-3 M-1 M-j opens ~/TODO in the right window
+ q Quit Info: reselect previously selected buffer.
+ RET Follow a node reference near point.
+ n Move to the \"next\" node of this node.
+ p Move to the \"previous\" node of this node.
+ u Move \"up\" from this node.
- I will suppose that people have tried `M-21j' and `M-31j'
- and understood what they do.
-
- c. I will also suppose that everyone is running Emacs \"in a
- way in which the standard keys should work\". For example,
- Doom Emacs redefines many keys, including M-1, M-2, etc,
- that we will use a lot, so Doom Emacs is \"bad\". I think
- that the modes that make Emacs use vi-like keybindings will
- also interfere with keys that we will use, so they're
- \"bad\" too. Besides that some window managers capture keys
- combinations like Alt-Shift-<letter>, so if you use a window
- manager like that please install another one that captures
- few keys and learn how switch between your favorite
- (\"bad\") WM and the one that you will use in the workshop.
- Also, one person that attended another workshop that I gave
- was trying to use Emacs in a terminal on a Raspberry Pi 0...
- she said that many things didn't work but gave few details,
- so I'll considered that _for the purposes of this workshop_
- terminal Emacs is \"bad\" and GUI Emacs is \"good\".
+Also, the tool bar changes completely, and it shows icons
+corresponding to the main navigation keys. See:
- d. In some parts of the workshop I will suppose that people can
- switch between an Emacs window and a browser window; in
- particular, I will suppose that they can follow links to
- videos, and for beginners this is much easier to do on a
- browser. For example, you can \"follow\" the link
+ (find-enode \"Tool Bars\")
- (find-eev2020video \"2:53\" \"pos-spec-lists\")
- using a browser by opening the HTMLized version of this
- intro using this URL,
- http://angg.twu.net/eev-intros/find-eev-exercises-intro.html
+5.4. Dired Mode
+---------------
+Dired Mode lets you navigate the directory structure. You can enter
+it by typing `C-x C-f RET'. If you type `RET' on a line that shows a
+directory this will be interpreted as \"enter that directory\", and
+`RET' on a line that shows a file is interpreted as \"open that file\".
+See:
- locating the link to the video there, and clicking on the
- link in its timestamp.
+ (find-enode \"Dired\")
+ (find-enode \"Dired Enter\" \"C-x C-f\")
+ (find-enode \"ls in Lisp\")
- e. I will _sort of_ suppose that the people on the workshop
- have read these sections of two basic tutorials and
- have tried to do the exercises in them:
- (find-eev-quick-intro)
- (find-eev-quick-intro \"1. Installing eev\")
- (find-eev-quick-intro \"2. Evaluating Lisp\")
- (find-eev-quick-intro \"3. Elisp hyperlinks\")
- (find-eev-quick-intro \"4. Creating Elisp Hyperlinks\")
- (find-eev-quick-intro \"4.1. `find-here-links'\")
- (find-eev-quick-intro \"4.2. `find-ekey-links' and friends\")
- (find-eev-quick-intro \"5. Links to Emacs documentation\")
- (find-eev-quick-intro \"5.1. Navigating the Emacs manuals\")
- (find-eev-quick-intro \"5.2. Cutting and pasting\")
- (find-windows-beginner-intro)
- (find-windows-beginner-intro \"1. Download and install Emacs\")
- (find-windows-beginner-intro \"2. Key sequences and how to quit\")
- (find-windows-beginner-intro \"3. Using M-x and installing eev\")
- (find-windows-beginner-intro \"4. Understanding buffers and the mode
line\")
- (find-refining-intro)
- (find-refining-intro \"1. Pos-spec-lists\")
-The prerequisites are just the ones above. The previous workshop
-that I gave required installing external programs, but this one
-will not be like that. For more info on that previous workshop,
-see:
+5.5. Shell Mode
+---------------
+Emacs can run terminals inside its buffers - and by default that
+terminal runs the default shell. In Windows the default shell is
+\"cmd.exe\", that is reminiscent of MS-DOS, and is VERY clumsly. See:
- http://angg.twu.net/2021-workshop.html#november
+ https://en.wikipedia.org/wiki/Windows_Console
+ https://en.wikipedia.org/wiki/Command-line_interface
+ https://en.wikipedia.org/wiki/MS-DOS#Windows_command-line_interface
+ https://en.wikipedia.org/wiki/Cmd.exe
+ https://en.wikipedia.org/wiki/Batch_file
+ https://en.wikipedia.org/wiki/Terminal_emulator
+If you run `M-x shell' you will get a shell buffer. See:
+ (find-enode \"Interactive Shell\")
+especially this part of the first paragraph:
+ To give input to the subshell, go to the end of the buffer and type
+ the input, terminated by <RET>.
-1. The base cases
-=================
-Watch this video first:
+As an exercise, try to give these commands to the Windows shell:
- [Video links:]
- (find-2021workshop1video \"0:22\" \"The base case 1 is described here\")
- (find-2021workshop1video \"0:52\" \"The instructions are here\")
- (find-2021workshop1video \"1:24\" \"The base case 2\")
- (find-2021workshop1video \"1:39\" \"What I need to do is slightly\")
- (find-2021workshop1video \"1:55\" \"This is not yet the link that I
want\")
+ dir
+ cd
+ cd ..
+ dir
-1.1. The base case 1
---------------------
-We are going to start by something that we will refer to as the
-\"base case 1\", and we will treat the other cases as variations
-of the base case 1. Here it is:
- You realize that this buffer is interesting and you want to
- save a link to it to your notes. Let's refer to this buffer as
- the \"target buffer\", as the link will point to it. You run
- this,
+5.6. Eshell
+-----------
+The manual of Eshell - here,
- (eek \"M-h M-3 ;; find-here-links-3\")
+ (find-node \"(eshell)Top\")
- and you get a 3-window configuration like this one:
+describes it as: \"Eshell is a shell-like command interpreter
+implemented in Emacs Lisp\".
- _______________ _____________________ ________________
- | | | | | | |
- | | | | elinks | | |
- | | | | buffer | | |
- | target | M-h M-3 | target |__________| M-h M-1 | target |
- | buffer | ------> | buffer | | ------> | buffer |
- | | | | notes | | |
- | | | | buffer | | |
- |_______________| |__________|__________| |________________|
+This feature of eev:
- you select the line of the \"elinks buffer\" that contains an
- elisp hyperlink that points to the \"target buffer\", you copy
- that line your \"notes buffer\" - that contains the file ~/TODO
- - and you run this
+ (find-psne-intro \"1. Local copies of files from the internet\")
- (eek \"M-h M-1 ;; find-here-links-1\")
+needs to run wget on a unix-like shell, and it turns out that
+this can be achieved easily using Eshell. For a discussion of the
+tecnhical details, see:
- to go back to the original window configuration in which only
- the target buffer was being shown.
+ https://lists.gnu.org/archive/html/help-gnu-emacs/2021-10/msg00051.html
+ https://lists.gnu.org/archive/html/help-gnu-emacs/2021-10/msg00058.html
+ https://lists.gnu.org/archive/html/help-gnu-emacs/2021-10/msg00126.html
-What you did can be summarized as:
- create (the elisp hyperlinks buffer)
- select (the correct elisp hyperlink)
- copy (it to the notes buffer)
- go back (to the previous window configuration)
-or:
- create / select / copy / go back
+6. Video links
+==============
+If you're on Windows you need to start by configuring your
+browser and the path to it, as described here:
-[Video links:]
- (find-2021workshop1video \"0:22\" \"The base case 1 is described here\")
- (find-2021workshop1video \"0:52\" \"The instructions are here\")
+ (find-video-links-intro)
+ (find-video-links-intro \"3. `find-youtube-video'\")
+ (find-video-links-intro \"4. Configuring the browser\")
+and by making `find-eev-video' use the browser to play the
+videos. For that you need to run this sexp,
+
+ (ee-use-youtube-videos)
+as explained here:
+ (find-video-links-intro \"7. `find-eev-video'\")
+Also install the Mpv video player, configure its path, and check
+that Emacs can find it. This is explained here:
-1.2. The base case 2
---------------------
-The \"base case 2\" is similar to the base case 1, but in the
-base case 2 we will create a link with a pos-spec-list containing
-the name of this section. Pos-spec-lists are explained here:
+ (find-video-links-intro \"6. Configuring Mpv\")
- (find-eev2020video \"2:53\" \"pos-spec-lists\")
+The next sections of this tutorial will suppose that you know how
+to configure that path to external programs, and how to test
+them.
-The sequence of steps in the base case 2 will include two new
-steps:
+IMPORTANT: save the sexps with `setenv' that you used to
+configure the paths to your notes. See:
- save (the name of this section to the kill ring) <- new!
- create (the elisp hyperlinks buffer)
- select (the correct elisp hyperlink)
- refine (add the name of the section to the pos-spec-list) <- new!
- copy (it to the notes buffer)
- go back (to the previous window configuration)
+ (find-here-links-intro \"4. `find-here-links-3'\")
+ (find-here-links-intro \"4. `find-here-links-3'\" \"~/TODO\")
-so:
- save / create / select / refine / copy / go back
-instead of:
- create / select / copy / go back
+7. eev-on-windows.el
+====================
+The file eev-on-windows.el contains several functions that will
+be used in the next sections. It is not loaded by default, so you
+need to do this:
-The diagram will be this one,
+ (require 'eev-on-windows)
- _______________ _____________________ ________________
- | | | | | | |
- | | | target | elinks | | |
- | | | buffer | buffer | | |
- | | | M-w | M-hy :: | | |
- | target | M-h M-3 | |______::__| M-h M-1 | target |
- | buffer | ------> | | \\/ | ------> | buffer |
- | | | | | | buffer |
- | | | | notes | | |
- | | | | buffer | | |
- |_______________| |__________|__________| |________________|
+If you are on Windows you will also need to download some
+\".exe\" files by running the sexps below. Each of the sexps that
+start with `ee-download-with-eww' may take several seconds to
+complete, and it's better to wait until it sends a message like
+\"Saved (filename.exe)\" to the echo area before executing other
+sexps with `M-e'.
-The dotted arrow indicates a copy and paste from the elinks
-buffer to the notes buffer, and the `M-hy' at the left of the
-dotted arrow indicated the we will have to type `M-hy' - that is
-an abbreviation for `M-h M-y' at some point; the placement of the
-`M-hy' suggests that it is typed before the cut and paste.
+ (mkdir \"~/bin/\" t)
+ (delete-file \"~/bin/wget.exe\")
+ (delete-file \"~/bin/pdftotext.exe\")
+ (delete-file \"~/bin/lua52.exe\")
+ (delete-file \"~/bin/lua52.dll\")
+ (ee-download-with-eww \"http://angg.twu.net/2021-oficina/wget.exe\"
\"~/bin/\")
+ (ee-download-with-eww \"http://angg.twu.net/2021-oficina/pdftotext.exe\"
\"~/bin/\")
+ (ee-download-with-eww \"http://angg.twu.net/2021-oficina/lua52.exe\"
\"~/bin/\")
+ (ee-download-with-eww \"http://angg.twu.net/2021-oficina/lua52.dll\"
\"~/bin/\")
- (find-refining-intro \"2. Refining hyperlinks\")
- (find-refining-intro \"2. Refining hyperlinks\" \"M-h M-y\")
+The sexps in the block above only need to be executed once - you
+don't need to execute them at each Emacs session. You can test if
+they worked by running the sexps below:
-[Video links:]
- (find-2021workshop1video \"1:24\" \"The base case 2\")
- (find-2021workshop1video \"1:39\" \"What I need to do is slightly\")
- (find-2021workshop1video \"1:55\" \"This is not yet the link that I want\")
+ (find-fline \"~/bin/\" \"wget.exe\")
+ (find-fline \"~/bin/\" \"pdftotext.exe\")
+ (find-fline \"~/bin/\" \"lua52.exe\")
+ (find-callprocess `(\"~/bin/wget.exe\" \"--help\"))
+ (find-callprocess `(\"~/bin/pdftotext.exe\" \"--help\"))
+ (find-callprocess `(\"~/bin/lua52.exe\" \"--help\"))
+7.1. `ee-use-windows'
+---------------------
+If you are on Windows you should run this:
-1.3. The base case 3
---------------------
-The base case 3 will only make sense to people who understand
-anchors, short hyperlinks and anchors, using `M-1 M-h M-w' to
-copy the preceding tag to the kill ring, and using `M-h M--' to
-shrink a hyperlink to make it point to an anchor. You can learn
-these extra prerequisites here:
+ (ee-use-windows)
- (find-eev-quick-intro \"8. Anchors\")
- (find-eev-quick-intro \"8.1. Introduction: `to'\")
- (find-eev-quick-intro \"8.5. Hyperlinks to anchors in other files\")
- (find-eev-quick-intro \"9. Shorter hyperlinks\")
- (find-eev-quick-intro \"9.1. `code-c-d'\")
- (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\")
- (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\" \":anchor\")
- (find-eev-quick-intro \"9.2. Extra arguments to `code-c-d'\" \":anchor\"
\"3)\")
- (find-anchors-intro \"2. Shrinking\")
- (find-anchors-intro \"3. The preceding tag\")
+Its source code is here:
- _______________ _____________________ ________________
- | | | | | | |
- | | | target | elinks | | |
- | | | buffer | buffer | | |
- | target | | M-1hw | M-h2 :: | | target |
- | buffer | | | M-hy :: | | buffer |
- | | | | M-h- :: | | |
- | | M-h M-3 | |______::__| M-h M-1 | |
- | | ------> | | \\/ | ------> | |
- | | | | | | |
- | | | | notes | | |
- | | | | buffer | | |
- |_______________| |__________|__________| |________________|
+ (find-eev \"eev-on-windows.el\" \"ee-use-windows\")
-Exercise: watch this video and try to reproduce what happens in it:
+Most of what it does is explained in the next sections.
- (find-2021workshop7video \"0:00\")
-Use this to go to the target that appears in the video:
- (find-eev \"eev-videolinks.el\" \"ee-1stclassvideos-field\")
+7.2. Testing wget.exe
+---------------------
+Try to run this eepitch block with <f8>s:
+
+ (eepitch-eshell)
+ (eepitch-kill)
+ (eepitch-eshell)
+ rm --help
+ ls --help
+ rm -fv $S/http/www.gnu.org/software/emacs/emacs-paper.html
+ ls -l $S/http/www.gnu.org/software/emacs/emacs-paper.html
+ #
+ mkdir -p $S/http/www.gnu.org/software/emacs/
+ cd $S/http/www.gnu.org/software/emacs/
+ wget -nc 'http://www.gnu.org/software/emacs/emacs-paper.html'
+ echo 'http://www.gnu.org/software/emacs/emacs-paper.html' >> ~/.psne.log
+ #
+ ls -l $S/http/www.gnu.org/software/emacs/emacs-paper.html
+ rm -fv $S/http/www.gnu.org/software/emacs/emacs-paper.html
+Now try to follow the instructions here to download the same URL
+with `M-x brep':
-2. Copy from left to right
-==========================
+ (find-psne-intro \"3. The new way: `M-x brep'\")
-2.1. Two basic exercises
-------------------------
-In the diagrams below the names of the buffers are abbreviated:
+`M-x brep' uses `eepitch-shell', that on Windows runs cmd.exe by
+default, but in the last section we ran `ee-use-windows', that
+redefines `eepitch-shell' to makes it use Eshell instead of
+cmd.exe - and it also makes the command \"wget\" in eshell run
+~/bin/wget.exe.
- [EX] - (find-eev-exercises-intro)
- [J] - (find-eejumps)
- [N] - notes, i.e., (find-fline \"~/TODO\")
- [EK] - (find-emacs-keys-intro)
+Eev also uses wget in the function `find-wget' and its variants
+`find-wgeta', `find-wget-elisp', and `find-wgeta-elisp'. Try the
+tests here, and check that they work:
- ________ _______ ______________ ________
- | | | | | | | | |
- | [EX] | M-j | [J] | M-21j | [J] | [N] | C-x 1 M-K* | [EX] |
- | | ----> | | -----> | M-w ::> C-y | ----------> | |
- |________| |_______| |_______|______| |________|
+ (find-eev \"eev-plinks.el\" \"find-wget\")
+ (find-eev \"eev-plinks.el\" \"find-wget\" \"Tests:\")
- ________ _______ ______________ ________
- | | | | | | | | |
- | [EX] | M-2j | [EK] | M-21j | [EK] | [N] | C-x 1 M-K* | [EX] |
- | | ----> | | -----> | M-w ::> C-y | ----------> | |
- |________| |_______| |_______|______| |________|
-`M-21j' is `M-2 M-1 M-j' written in an abbreviated form -
- mnemonic: \"hold the meta key, type 21j, lift meta\" - and
- `M-K*' means \"type M-K as many times as needed\".
-Watch this video and try to reproduce what happens in it:
- (find-2021workshop5video \"0:00\")
+7.3. Lua
+--------
+`ee-use-windows' also redefine `eepitch-lua51' to make it run
+~/bin/lua52.exe, that you downloaded in section 7, and it runs
+`ee-use-youtube-videos', that you've run explicitly in section 6.
+Try this link to a video:
+ (find-eevtestblsvideo \"2:33\" \"if I run f8 here I start a new Lua
interpreter\")
+it should play the video in a browser. The video shows what
+happens when we run an eepitch block that calls Lua and
+everything works correctly. Check that these two eepitch blocks
+work as expected:
+ (eepitch-lua51)
+ (eepitch-kill)
+ (eepitch-lua51)
+ print(2+3)
+ os.exit()
-2.2. `find-extra-file-links'
-----------------------------
-Here you will need to understand `code-c-d' and
-`find-extra-file-links'. See:
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ ~/bin/lua52.exe -i
+ print(2+3)
+ os.exit()
- (find-eev-quick-intro \"9. Shorter hyperlinks\")
- (find-eev-quick-intro \"9.1. `code-c-d'\")
- (find-audiovideo-intro \"4.1. `find-extra-file-links'\")
-The diagram will be this one:
- ________ _______ _______ ______________
________
- | | | | | | | | |
| |
- | [EX] | | [D] | M-he | [EH] | M-21j | [EH] | [N] | C-x 1 M-K*
| [EX] |
- | | --> | | ----> | | -----> | M-w ::> C-y | ---------->
| |
- |________| |_______| |_______| |_______|______|
|________|
-Where [D] is a dired buffer. Watch this video and try to
-reproduce what happens in it:
+7.4. Downloading videos
+-----------------------
+The default behavior for a video link like this one
- (find-2021workshop6video \"0:00\")
+ (find-eevtestblsvideo \"2:33\" \"if I run f8 here\")
-Do this twice. In the first time you should create elisp
-hyperlinks pointing to this directory and this file,
+is to download a local copy of the video if it hasn't been
+already downloaded, and then play the local copy with mpv. The
+downloading is not automatic; the user has to \"psne\" it - see
+the section 7.2 and this video:
- (find-efile \"play/\")
- (find-efile \"play/\" \"life.el\")
+ (find-eevvlinksvideo \"6:09\" \"if I execute this `find-eevtestblsvideo'\")
+ (find-eevvlinksvideo \"6:15\" \"the last line says `Local file NOT found'\")
-and in the second time you should create elisp hyperlinks to a
-directory and a file that you find interesting.
+Now that you understand psne-ing, try the three standard
+behaviors for video links. First make sure that we don't have a
+local copy of the \"eevtestbls\" video, by running this:
+ (eepitch-shell)
+ (eepitch-kill)
+ (eepitch-shell)
+ rm -fv $S/http/angg.twu.net/eev-videos/2021-test-blocks.mp4
+ ls -l $S/http/angg.twu.net/eev-videos/2021-test-blocks.mp4
+Then run these sexps:
+ (ee-use-local-videos)
+ (find-eevtestblsvideo \"2:33\" \"if I run f8 here\")
+ (setq ee-find-eev-video-function 'find-eevlinks-video)
+ (find-eevtestblsvideo \"2:33\" \"if I run f8 here\")
-2.3. Invisible text
--------------------
-Run this sexp:
+ (ee-use-youtube-videos)
+ (find-eevtestblsvideo \"2:33\" \"if I run f8 here\")
- (eek \"3*<up> C-a C-SPC C-e\")
+The three behaviors are explained here:
-and then use `M-w' to copy the region to the kill ring and `M-hy'
-to yank it into this sexp:
+ (find-video-links-intro \"7. `find-eev-video'\")
+ (find-video-links-intro \"The default is `find-eevlocal-video', but\")
- (insert \"\\n\")
-Instead of getting the first sexp below you will get the second
-one:
- (insert \"\\n\" \"2.3. Invisible text\")
- (insert \"\\n\" \"2.3. Invisible text\\n-------------------\")
+7.5. Downloading PDFs
+---------------------
+Now try all the tests in the sections 1-5 and 7 of:
-That's becase when you type `C-e' on the title of a section of an
-\"intro\" the `C-e' takes you to the right of the line _after_
-the invisible text. If you type `<left> <right>' there this moves
-the point to a position before the invisible text.
+ (find-pdf-like-intro)
-Exercise: create a pair of elisp hyperlinks, the first one
-pointing to this intro and the second pointing to this section,
-and copy the pair to your notes. You'll have to watch the video
-to understand some tricky points and you will have to follow the
-diagram below.
+This test in section 2 will not work,
- ________ _______ _______________ ________
- | | | | | | | | |
- | [EX] | M-hh | [EH] | M-21j | [EH] | [N] | C-x 1 M-K* | [EX] |
- | M-w | ----> | | -----> | M-h2 ::> C-y | ----------> | |
- | | | | | M-hy | | | |
- |________| |_______| |________|______| |________|
+ (find-sh0 \"ls -l ~/Coetzee99.pdf\")
-[Video links:]
- (find-2021workshop4video \"0:00\")
+because it requires a Unix-style `ls'. It works in Eshell,
+though. Try:
+ (eepitch-eshell)
+ (eepitch-kill)
+ (eepitch-eshell)
+ ls --help
+ ls -l ~/Coetzee99.pdf
+That's because eshell defines its `ls' in Lisp. See:
+ (find-eshellnode \"Built-ins\")
+Also, the tests in section 6 don't work on Windows - one of the
+things that `ee-use-windows' does is to make `find-pdf-page' use
+a browser to open PDFs, and section 6 uses a PDF viewer called
+\"xpdf\". Take a look:
+ (find-pdf-like-intro \"6. How the external programs are called\")
-[The rest is old]
+So: check that everything in sections 1-5 and 7 work, except for
+the test that uses `ls'. The links to pages of PDFs converted to
+text should work - the conversion to text will be done by
+~/bin/pdftotext.exe, that you downloaded and tested in section 7.
+7.6. Saving your settings
+-------------------------
+If all the tests above worked then you can save your settings.
+I will refer to the block below as the \"Windows setting block\":
-3.3. Copy from `find-ekey-links'
---------------------------------
-One of the lines in your notes buffer is this one,
+ ;; See: (find-windows-beginner-intro \"8. Summary\")
+ ;; (find-video-links-intro \"4. Configuring the browser\")
+ ;; (find-video-links-intro \"6. Configuring Mpv\")
+ (require 'beginner)
+ (require 'eev-on-windows)
+ (ee-use-windows)
+ (setenv \"FIREFOXDIR\" \"c:/Program Files/Mozilla Firefox\")
+ (setenv \"GOOGLECHROMEDIR\" \"c:/Program Files/Google/Chrome/Application\")
+ (setenv \"MPVDIR\" \"c:/Users/myusername/path/to/mpv\")
+ ;;
+ ;; Choose one:
+ (ee-use-googlechrome)
+ ;;(ee-use-firefox)
- ;; M-5 M-j runs: (find-eev-quick-intro)
+Copy that block to your ~/TODO, but with the right paths in the
+`setenv's. I will refer to that modified copy as the \"Windows
+setting block in ~/TODO\".
-and the section 4.2 in (find-eev-quick-intro) is:
- (find-eev-quick-intro \"4.2. `find-ekey-links' and friends\")
-Exercise:
+7.7. Testing your settings
+--------------------------
+The best way to test your \"Windows setting block in ~/TODO\" is
+by doing this. Start a second Emacs without closing this one, and
+on that second Emacs run:
- 1. use M-5j to go to (find-eev-quick-intro) - a.k.a. \"the main
- tutorial\",
- 2. go to the section 4.2 in that main tutorial, and find where it
- says \"Try the eek links below\",
- 3. run the eek link that says:
+ 1. `M-x eev-beginner',
+ 2. `M-1 M-j' (to access your ~/TODO),
+ 3. type `M-e' on each line of your \"Windows setting block in
+ ~/TODO\" _that is not commented with with a \";;\".
- (eek \"M-h M-k C-s ;; isearch-forward\")
+Then... [TODO: complete this!]
- 4. it should open a temporary buffer whose buffer name is \"*Elisp
- hyperlinks*\". Find the two lines in that buffer that say:
- # (Info-goto-emacs-command-node 'isearch-forward)
- # (find-enode \"Command Index\" \"* isearch-forward:\")
- 5. mark and copy those lines,
- 6. use `M-21j' or `M-31j' to open your notes buffer in the right
- window,
- 7. paste those lines to your notes buffer.
+7.8. Saving your settings to your ~/.emacs
+------------------------------------------
+See:
-In a diagram:
+ (find-elnode \"Init File\" \".emacs\")
- __________ __________ ________________
- | | | | | | |
- M-5j | [MT] | M-e | [EH] | M-21j | [EH] | [N] |
- -----> | sec. 4.2 | ----> | | ---------> | ::> |
- | | | | or M-31j | | |
- |__________| |__________| |________|_______|
+A quick way to visit your ~/.emacs is with `M-5 M-5 M-j'. It runs
+this:
+ (find-fline \"~/.emacs\")
-3.4. A variant
---------------
-Someone who knows how to use `M-h M-k' (`find-ekey-links') and
-who doesn't need to split windows can do essentially the same as
-we did in the previous section with fewer keystrokes. Let's see
-how.
-Exercise:
- 1. Type `M-hk C-s' to open a temporary buffer with elisp
- hyperlinks on the key `C-s',
- 2. mark, and copy with `M-w', the lines that say:
+8. Summary
+==========
- # (Info-goto-emacs-command-node 'isearch-forward)
- # (find-enode \"Command Index\" \"* isearch-forward:\")
+[Unfinished!!!]
- 3. use `M-1j' to go to your notes buffer,
- 4. paste those lines to your notes buffer with `C-y'.
-In a diagram:
- ___________ ___________
- | | | |
- M-hk C-s | [EH] | M-1j | [N] |
- ---------> | mark, M-w | -----> | C-y |
- | | | |
- |___________| |___________|
+" pos-spec-list)))
+;; (find-windows-beginner-intro)
-2.1. Variants of `save'
------------------------
+;;; _____ _
+;;; | ____|_ _____ _ __ ___(_)___ ___ ___
+;;; | _| \ \/ / _ \ '__/ __| / __|/ _ \/ __|
+;;; | |___ > < __/ | | (__| \__ \ __/\__ \
+;;; |_____/_/\_\___|_| \___|_|___/\___||___/
+;;;
+;; «find-eev-exercises-intro» (to ".find-eev-exercises-intro")
+;; Skel: (find-intro-links "eev-exercises")
+;; Test: (find-eev-exercises-intro)
-2.2. Variants of `create'
--------------------------
+(defun find-eev-exercises-intro (&rest pos-spec-list) (interactive)
+ (let ((ee-buffer-name "*(find-eev-exercises-intro)*"))
+ (apply 'find-eintro "\
+\(Re)generate: (find-eev-exercises-intro)
+Source code: (find-efunction 'find-eev-exercises-intro)
+More intros: (find-eev-quick-intro)
+ (find-here-links-intro)
+ (find-refining-intro)
+ (find-escripts-intro)
+ (find-eev-intro)
+ (find-eepitch-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-x ex',
+but you will need to run this:
+ (defun ex () (interactive) (find-eev-exercises-intro))
- (eek \"M-h M-k M-j ;; eejump\")
- M-2 M-j runs: (find-emacs-keys-intro)
- M-5 M-j runs: (find-eev-quick-intro)
- (eek \"M-h M-k M-h M-k ;; find-ekey-links\")
- (eek \"M-h M-k M-h M-f ;; find-efunction-links\")
- (eek \"M-h M-k M-h M-h ;; find-here-links\")
- (eek \"M-h M-k M-h M-3 ;; find-here-links-3\")
-2.3. How to learn to `select'
------------------------------
-2.4. Variants of `refine'
--------------------------
- (find-refining-intro \"2. Refining hyperlinks\")
- (find-refining-intro \"2. Refining hyperlinks\" \"M-h M-y\")
- (find-anchors-intro \"2. Shrinking\")
- (find-anchors-intro \"2. Shrinking\" \"`M-h M--'\")
-2.5. Variants of `copy'
------------------------
- (find-here-links-intro \"6. Copying the hyperlink\" \"M-h M-w\")
+This is part of the material the I prepared for this workshop:
+ http://angg.twu.net/2021-workshop.html
+The rest was moved to:
+ (find-saving-links-intro)
-2.6. Variants of `go back'
---------------------------
- (eek \"M-h M-k M-h M-1 ;; find-here-links-1\")
- (find-eval-intro \"5. Going back\" \"`M-K' instead of `M-k'\")
+0. Prerequisites
+================
+I will suppose:
-3. A two-window setting
-=======================
-Exercise: copy the diagram below to your notes,
+ a. that you have Emacs 27 or 28 (pretest) installed,
- ____________ _____________ ____________
_____________
- | | | | | | | | | | |
|
- | [EX] | [T] | M-hh | [EX] | [EH] | M-21j | [EH] | [N] | M-K* | [EH] |
[EX] |
- | | M-w | ----> | | M-h2 | -----> | | C-y | ---> | |
|
- | | | | | M-hy | | | | | |
|
- | | | | | M-w | | | | | |
|
- |______|_____| |______|______| |______|_____|
|______|______|
+ b. that you have watched the \"installation and navigation\"
+ video and tried everything on it. Two points are especially
+ important: first, you should start eev with
-then come back here and type `C-x 1 C-x 3' to split the window.
-In the window at the right, go this directory,
+ M-x eev-beginner
- (find-efile \"\")
+ until you are no longer a beginner - `M-x eev-beginner'
+ makes sure that all modules of eev were loaded. Second,
+ `M-j' will be very important. The video explains it at:
-find the subdirectory \"play\", enter it, find the file
-\"life.el\", and inside the file \"life.el\" find the line that
-starts with this string, with a space at its end:
+ (find-eevnavvideo \"6:28\" \"M-j: you can forget practically
everything...\")
+ (find-eevnavvideo \"6:41\" \"if you type just M-j\")
+ (find-eevnavvideo \"6:48\" \"has a header that is beginner-friendly\")
- \"(defun life \"
+ The beginner-friendly header generated by `M-j' has changed
+ since I recorded that video, and now it shows these three
+ ways of opening the file where we will put our notes instead
+ of showing just the first one:
-Then follow the instructions in the diagram above to create a
-link to the file \"life.el\". Refine that link to make it point
-to the first occurrence of the string \"(defun life \" inside the
-file \"life.el\", and copy the original link and the refined one
-to your notes.
+ M-1 M-j runs: (find-fline \"~/TODO\")
+ M-2 M-1 M-j shows the file ~/TODO in the right window
+ M-3 M-1 M-j opens ~/TODO in the right window
-[Video links:]
- (find-2021workshop2video \"0:00\")
+ I will suppose that you have tried `M-21j' and `M-31j' and
+ that you understood what they do.
+
+ c. I will also suppose that you are running Emacs \"in a way in
+ which the standard keys should work\". For example, Doom
+ Emacs redefines many keys, including M-1, M-2, etc, that we
+ will use a lot, so Doom Emacs is \"bad\". I have the
+ impression that all the modes that make Emacs use vi-like
+ keybindings also interfere with keys that we will use, so
+ they're \"bad\" too. Besides that some window managers
+ capture keys combinations like Alt-Shift-<letter>, so
+ they're \"bad\"; if you use a window manager like that
+ please install another one that captures few keys and learn
+ how switch between your favorite (\"bad\") WM and the one
+ that you will use in the workshop. Also, one person that
+ attended the workshop that I gave in november was trying to
+ use Emacs in a terminal on a Raspberry Pi 0... she said that
+ many things didn't work but gave few details, so I'll
+ considered that _for the purposes of this workshop_ terminal
+ Emacs is \"bad\" and GUI Emacs is \"good\".
+ d. In some parts of the workshop I will suppose that people can
+ switch between an Emacs window and a browser window; in
+ particular, I will suppose that they can follow links to
+ videos, and for beginners this is much easier to do on a
+ browser. For example, you can \"follow\" the link
+ (find-eev2020video \"2:53\" \"pos-spec-lists\")
+ using a browser by opening the HTMLized version of this
+ intro using this URL,
+ http://angg.twu.net/eev-intros/find-eev-exercises-intro.html
-1. Saving interesting links
-===========================
-The documentation of eev says at several places that people
-should \"save all interesting links to their notes\". It is
-easier to learn that if we split it into these tasks:
+ locating the link to the video there, and clicking on the
+ link in its timestamp.
- a. save links to your notes
- b. test these links
- c. mark the links that you don't understand
- d. undestand what each link does (with M-h M-f)
- e. recognize which links are interesting
+ e. I will _sort of_ suppose that the people on the workshop
+ have read these sections of two basic tutorials and
+ have tried to do the exercises in them:
+
+ (find-eev-quick-intro)
+ (find-eev-quick-intro \"1. Installing eev\")
+ (find-eev-quick-intro \"2. Evaluating Lisp\")
+ (find-eev-quick-intro \"3. Elisp hyperlinks\")
+ (find-eev-quick-intro \"4. Creating Elisp Hyperlinks\")
+ (find-eev-quick-intro \"4.1. `find-here-links'\")
+ (find-eev-quick-intro \"4.2. `find-ekey-links' and friends\")
+ (find-eev-quick-intro \"5. Links to Emacs documentation\")
+ (find-eev-quick-intro \"5.1. Navigating the Emacs manuals\")
+ (find-eev-quick-intro \"5.2. Cutting and pasting\")
+ (find-windows-beginner-intro)
+ (find-windows-beginner-intro \"1. Download and install Emacs\")
+ (find-windows-beginner-intro \"2. Key sequences and how to quit\")
+ (find-windows-beginner-intro \"3. Using M-x and installing eev\")
+ (find-windows-beginner-intro \"4. Understanding buffers and the mode
line\")
+ (find-refining-intro)
+ (find-refining-intro \"1. Pos-spec-lists\")
+The prerequisites are just the ones above. The previous workshop
+that I gave required installing external programs, but this one
+will not be like that. For more info on that previous workshop,
+see:
-2. Some abbreviations
-=====================
-Sequences of keys like `M-2 M-1 M-j' can be typed by keeping the meta
-key pressed and then typing `2', `1', and 'j'. We will sometimes write
-these keys sequences in an abbreviated form, like this: `M-21j'.
+ http://angg.twu.net/2021-workshop.html#november
-Some intros, like this one,
- (find-here-links-intro \"4. `find-here-links-3'\")
-draw window configurations like this:
- _____________________
- | | |
- | | elinks |
- | | buffer |
- | target |__________|
- | buffer | |
- | | notes |
- | | buffer |
- |__________|__________|
-we will often use abbreviations like [T], [E], and [N] for the
-descriptions of the buffers in the windows.
" pos-spec-list)))
diff --git a/eev.el b/eev.el
index 7ff9b52..359cafa 100644
--- a/eev.el
+++ b/eev.el
@@ -6,7 +6,7 @@
;; Package-Requires: ((emacs "24.4"))
;; Keywords: lisp e-scripts
;; URL: http://angg.twu.net/#eev
-;; Version: 20211204
+;; Version: 20211205
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/eev cdbbd6d: Added (find-saving-links-intro).,
ELPA Syncer <=