|
Eev @ EmacsConf 2020
This is what I presented at the EmacsConf 2020.
Here are links to the full schedule of the conference and to my talk in it.
Title:
On why most of the best features in eev look like 5-minute
hacks
Abstract:
In the last months there were several hundreds of messages in
emacs-devel in threads with names like "A proposal for a friendlier
Emacs", "How to make Emacs popular again", and "Interactive guide
for new users". On the one hand I am absolutely sure that eev is a
very good answer to all these themes; on the other hand I know that
eev is based on some design decisions that offend most people used
to modern, "user-friendly" interfaces - and I feel that at this
moment mentions to eev in those discussions in emacs-devel would not
be welcome.
In this talk I will start by presenting very quickly the main
"killer features" of eev - namely:
- Elisp hyperlinks,
- interactive tutorials that can be navigated with just three keys,
- non-invasiveness - people can easily turn eev on for only five
minutes each week, play with it a bit, and then turn it off,
- high discoverability factor,
- a way to create "hyperlinks to here",
- hyperlinks to specific points in PDF documents and video files -
i.e., to specific pages, strings, and timemarks,
- a way to control shell-like programs ("eepitch"), and
- an Elisp tutorial,
and after that I will present the design decisions behind eev, in two
parts:
- eev is a very thin layer above Emacs-the-Lisp-environment; it is
as simple as possible, but in the sense of "simple" that was used
in Forth, and that is not very familiar today.
- Very often when I am using Emacs - which is my main interface
with the system - I realize that I can automate some task that I
just did by hand twice of thrice; and that I should do that,
because automating that would be both easy and fun. Over the
years I experimented with several ways of automating tasks,
refined some of these ways a lot, and found a certain "best"
style that, again, usually offends people who are accustomed with
the modern ideas of user-friendliness. In this style, used in
most template-based functions in eev, both textual documentation
and error-handling are kept to a minimum. I will show how, and
why, eev makes this style works so well, and how users can create
their own templated functions very quickly - as "5-minute hacks".
The best way to watch the video is to download a copy of it and its
subtitles with wget and then play it with mpv. You can do that
with the two "wget"s and the "mpv" in the beige block below,
...but you can also watch the video on Youtube (of course!). The
lines below are a mini-index - click on the timestamps to open the
video on Youtube starting from that position.
Links to some points of the video:
0:00 Title page
0:22 1.1. M-e and M-k
3:34 1.2. Hyperlinks that don't create new buffers
10:22 1.3. Shorter hyperlinks to PDFs and videos
14:43 1.4. How the functions that define shorter hyperlinks are implemented
18:47 1.5. M-j
21:02 1.5.2. M-j itself
29:39 2. A tale of two `describe-key's
32:05 inspecting text properties
37:45 3. Killer features
40:18 3.5. A way to create "hyperlinks to here"
42:05 4. A tale of several "The User"s
43:49 (find-emacs-tangents-links)
The video does not explain properly how to create "hyperlinks to here".
This is explained is these tutorials:
(find-here-links-intro)
(find-refining-intro)
This is a follow-up to my presentation at
the EmacsConf 2019, whose title was:
"How to record executable notes with eev - and how to play them back".
My presentation from 2019 is more accessible, this one is more technical.
More videos:
I am recording some videos to complement this one. This first four are:
"How to install eev with `M-x
list-packages' and how to navigate its tutorials"
"Some template-based functions
of eev that are not five-minute hacks"
"How to create hyperlinks to "here"
with `find-here-links'"
"Short videos about workflows - and how to
upload them"
See:
(find-videos-intro "1. Some videos")
The video of my presentation is here:
http://anggtwu.net/eev-videos/emacsconf2020.mp4
http://www.youtube.com/watch?v=hOAqBc42Gg8
https://emacsconf.org/2020/talks/21/
If you have eev with can download and play a local copy of the video with mpv with:
;; (find-audiovideo-intro "7. `code-psnevideo'")
;; (find-audiovideo-intro "7.1. `code-eevvideo'")
;; (find-eevvideo-links "eev2020" "emacsconf2020" "hOAqBc42Gg8")
(code-video "eev2020video" "$S/http/anggtwu.net/eev-videos/emacsconf2020.mp4")
(find-eev2020video "0:00" "Title")
(find-eev2020video "0:22" "1.1. `M-e' and `M-k'")
(find-eev2020video "3:34" "1.2. Hyperlinks that don't create new buffers")
(find-eev2020video "3:47" "hyperlink to the result of running the shell command `date'")
(find-eev2020video "3:59" "result in the echo area")
(find-eev2020video "4:25" "result in a new buffer")
(find-eev2020video "4:32" "`find-googlechrome' calls an external program")
(find-eev2020video "4:52" "`find-pdf-page' calls an external program")
(find-eev2020video "5:26" "`find-pdf-text' converts the PDF to text and")
(find-eev2020video "6:25" "`find-video'")
(find-eev2020video "6:50" "hyperlinks that work like buttons")
(find-eev2020video "7:18" "`eek' executes a series of keys")
(find-eev2020video "7:45" "buttons that define new functions")
(find-eev2020video "8:20" "`code-c-d' defines several new functions at the same time")
(find-eev2020video "8:34" "the result is the name of one of the functions that is defines")
(find-eev2020video "8:45" "`find-orggitfile'")
(find-eev2020video "9:09" "prepends this string")
(find-eev2020video "9:40" "`find-orggitnode'")
(find-eev2020video "10:22" "1.3. Shorter hyperlinks to PDFs and videos")
(find-eev2020video "10:45" "`code-pdf-page' creates a short hyperlink function for a PDF")
(find-eev2020video "11:38" "let's try...")
(find-eev2020video "11:55" "`find-fongspivatext'")
(find-eev2020video "12:25" "This block is a kind of an index for that book")
(find-eev2020video "12:54" "This block is a kind of an index for that video")
(find-eev2020video "13:30" "we can index video tutorials")
(find-eev2020video "14:08" "magit-status")
(find-eev2020video "14:32" "Rainer Koenig's tutorials on org-mode")
(find-eev2020video "14:43" "1.4. How the functions that define shorter hyperlinks are implemented")
(find-eev2020video "15:34" "macroexpand")
(find-eev2020video "16:50" "Let's compare")
(find-eev2020video "17:20" "find-code-c-d shows the code that code-c-d would execute")
(find-eev2020video "18:47" "1.5. `M-j'")
(find-eev2020video "19:03" "commands with very short names")
(find-eev2020video "21:02" "1.5.2. `M-j' itself")
(find-eev2020video "21:07" "commands with very short numbers")
(find-eev2020video "21:19" "M-j jumps to predefined places")
(find-eev2020video "21:40" "M-5 M-j jumps to (find-eev-quick-intro)")
(find-eev2020video "22:13" "the part of the tutorial that explains M-j")
(find-eev2020video "22:24" "here is the header and here is the rest")
(find-eev2020video "22:35" "the header is very beginner-friendly")
(find-eev2020video "23:10" "The header has several elisp hyperlinks")
(find-eev2020video "23:39" "what the numeric prefixes do")
(find-eev2020video "25:51" "use M-j to go to the sandboxed tutorials")
(find-eev2020video "26:00" "we can copy links to the tutorials to our notes")
(find-eev2020video "26:49" "1.5.3. `M-J' (meta-uppercase-J)")
(find-eev2020video "26:58" "transforms the current line")
(find-eev2020video "27:37" "into a defun of a function with a very short name")
(find-eev2020video "28:13" "1.5.4. `M-uppercaseletter'")
(find-eev2020video "28:39" "into a link to a file")
(find-eev2020video "28:48" "into a link to a manpage")
(find-eev2020video "28:56" "into a link to the result of a shell command")
(find-eev2020video "29:39" "2. A tale of two `describe-key's")
(find-eev2020video "30:24" "the standard `describe-key'")
(find-eev2020video "30:40" "their targets are not visible")
(find-eev2020video "31:31" "the problem with the standard `describe-key'")
(find-eev2020video "32:05" "inspect text properties")
(find-eev2020video "33:50" "find-ebufferandpos")
(find-eev2020video "35:07" "My variant: `find-ekey-links'")
(find-eev2020video "37:00" "how `find-ekey-links' generates its links")
(find-eev2020video "37:14" "hacker-friendly in the way that I wanted")
(find-eev2020video "37:45" "3. Killer features")
(find-eev2020video "40:18" "3.5. A way to create \"hyperlinks to here\"")
(find-eev2020video "42:05" "4. A tale of several \"The User\"s")
(find-eev2020video "42:34" "the one that really blew my mind")
(find-eev2020video "42:44" "the user as someone external")
(find-eev2020video "43:27" "user-friendly and hacker-friendly at the same time")
(find-eev2020video "43:49" "(find-emacs-tangents-links)")
(find-eev2020video "44:25" "but I had to use a template for that")
(find-eev2020video "44:43" "but if we run this sexp here")
(find-eev2020video "45:15" "this one opens the post in the mailing list")
(find-eev2020video "45:22" "sometimes I want to Org source of that")
(find-eev2020video "45:37" "and I take this stem")
(find-eev2020video "45:47" "then I get this script that downloads the Org source")
(find-eev2020video "46:34" "this one line thing here is a hyperlink to...")
See also:
(find-es "emacsconf2020" "video-script")
(find-es "emacsconf2020" "full-video-index")
On Forth:
On simplicity in Forth:
http://anggtwu.net/miniforth-article.html#why-forth
It is possible to implement the ideas of MiniForth in Elisp,
and some of
the little languages in eev are descendants of
my experiments with MiniForth. For example, the "bytecode"
from this
section can be implemented as below; here the
"address" of the first DOCOL is the pair (SQUARE 0) .
(setq FORTHDICT
'((SQUARE (DOCOL DUP * EXIT))
(CUBE (DOCOL DUP SQUARE * EXIT))
))
|
Very few of these experiments became part of the core of eev.
For example, I implemented several control structures on
red-star
lines in eepitch - and after some months I discarded
most of them... I only kept ee-copy-rest, and I reimplemented
the rest of the logic using templated functions.
The full subtitles in Lua for this video are here.
The rest of this page contains a conversion of the subtitles in Lua
to a slightly more readable format.
00:00 Hi! My name is Eduardo Ochs.
00:02 I'm this person here,
00:03 and the title of this talk is:
00:06 "On why most of the best features
00:09 in eev look like 5-minute hacks".
00:11 And this is a presentation at the
00:13 EmacsConf 20202,
00:15 happening in november 28 and 29.
00:18 2020.
1.1. `M-e' and `M-k'
00:23 So this is part one of the presentation,
00:25 and here I'm going to explain some
00:27 ideas that are prerequisites for
00:29 understanding the rest of the
00:31 presentation.
00:32 The three main keys of eev are `M-e',
00:35 `M-k' and `M-j', and I'm going to start by
00:37 explaining `M-e' and `M-k'.
00:42 `M-e' is used to follow a hyperlink, and
00:44 technically it is
00:46 essentially just a `C-e' to move to the
00:49 end of the line and then a `C-x C-e'
00:51 to execute the sexp before point
00:53 at the end of the line...
00:58 and the thing is that Emacs comes with
01:00 many functions that can be used as sexp
01:03 hyperlinks.
01:05 We can consider that they "point" to
01:06 somewhere. I'm going to refer to that as
01:09 the "target" of the hyperlink, and if we
01:11 execute these sexp hyperlinks we
01:12 "go to" that target.
01:15 For example, this one
01:17 is a hyperlink that points to a buffer
01:20 with the man page for cat,
01:22 and usually, but not always, after
01:25 following the hyperlink
01:26 we can go back by just killing the
01:28 current buffer...
01:29 that the hyperlink created -
01:32 the "target" of the hyperlink.
01:34 But this example here is badly
01:36 behaved.
01:38 If we execute it it creates a new frame,
01:41 and to go back to the previous situation
01:43 we have to either
01:44 click here or type `C-x 5 0'.
01:54 So, here are some examples of sexp
01:57 hyperlinks using standard Emacs functions.
02:00 This third one is badly behaved in a
02:03 different way.
02:04 If we executed it the target is created
02:08 in the same window
02:09 as we are now, but it also shows a lot of
02:13 garbage here in the echo area, so
02:16 the current frame becomes a bit
02:20 messy...
02:23 and, well, one of the first things that I
02:26 did when I was creating eev
02:28 many many years ago was that I created
02:30 variants
02:31 of all these functions that were better
02:34 behaved...
02:36 and they were better behaved in two
02:38 senses: the obvious one
02:40 was that they all created the target
02:43 in the same window as before, so I could
02:45 go back by just typing `M-k',
02:48 which essentially just killed this
02:51 buffer...
02:52 But I also implemented
02:55 something extra, that are the
02:56 "pos-spec-lists"... for example,
02:58 these extra arguments here
03:00 are a pos-spec-list,
03:03 and these extra arguments specify
03:06 a position in the target buffer.
03:09 And in this example this pos-spec-list
03:13 means: starting from the
03:16 beginning of the buffer,
03:18 search for the first occurrence of this
03:20 string, "C-x C-e", after that -
03:22 after the beginning of the buffer -
03:24 and then search for the first occurrence
03:26 of this string, "eval-last-sexp",
03:29 after that.
1.2. Hyperlinks that don't create new buffers
03:33 Eev also defines some hyperlinks that do
03:36 not create new buffers.
03:38 Here is the first example: if I execute
03:41 this one... this one is a hyperlink to the
03:45 result of running this shell command,
03:47 "date"...
03:50 but instead of showing the result in a
03:52 new buffer the result is shown here...
03:54 so if execute this hyperlink the result
03:58 of "date"... the output of "date" is
04:01 shown in the echo area, and if I execute
04:04 it again
04:07 it shows the result again, and the result
04:09 changes every second.
04:11 So this is a variant of `find-sh'...
04:18 `find-sh0' is the variant that
04:21 just shows the output in the echo area,
04:24 and `find-sh' shows the output in
04:28 a new buffer.
04:31 And here is an example of a hyperlink
04:35 that calls an external program.
04:37 If I execute this it
04:41 calls Google Chrome to open a
04:43 certain URL.
04:46 Here it is. Let's go back to Emacs...
04:51 if execute this hyperlink here
04:55 it invokes my favorite PDF viewer, which
04:58 is xpdf... it makes xpdf
05:02 open this PDF in this page...
05:07 and these other arguments are ignored.
05:10 Let me show how it works.
05:15 Here it is. This is an excerpt from a
05:19 book... so page 3 in the PDF corresponds
05:22 to page 113 in the book... and
05:26 this variant here of the hyperlink above...
05:29 it opens the PDF in a different way.
05:31 It runs a program called pdftotext on
05:34 this PDF here,
05:36 and Emacs takes the output of running
05:39 pdftotext on this PDF here,
05:42 and displays it in a buffer... and now this
05:46 pos-spec-list is interpreted in a different
05:49 way: this thing is interpreted as a
05:51 number of a page... Emacs goes to page 3
05:53 by counting formfeeds in the
05:56 converted version of the PDF,
06:00 and then it searches for this string
06:02 and this string.
06:04 So let's execute this to see what
06:06 happens... here it is. It opened
06:08 the same page as before...
06:14 it starts with "Lecture I", so
06:18 the other hyperlink searched for this
06:20 string and for this string here.
06:25 And this thing here is a hyperlink to
06:28 a video.
06:29 When I executed it it is going to open
06:32 this video here, at this timestamp.
06:36 Let's see... one, two, three...
06:39 ONE, TWO, THREE! THAT'S THE WAY TO DO IT!
06:49 And also some hyperlinks that I
06:52 defined... hm,
06:53 they don't work like usual hyperlinks,
06:56 they work more like browser buttons,
07:01 these buttons that appear in web pages...
07:06 In the sense that these buttons usually
07:09 don't open a new page, they usually
07:11 just do something to change the current
07:13 page. If I execute this,
07:16 the action of this function, `eek' is to...
07:22 it interprets this string as a series of
07:24 keys, and it acts as if the user had typed
07:26 all these keys, so...
07:30 if I executed it I get a "HELLO!"
07:33 in the next line, and if I execute it
07:34 again I get another "HELLO!"
07:36 another "HELLO!", another "HELLO!", etc...
07:39 Let me undo this mess.
07:44 And here is another kind of button,
07:47 that defines a new function. If I execute
07:51 this sexp here, `(o)'...
07:54 at this moment the `o' is not defined,
07:55 and if I execute this Emacs is going to
07:57 show me a message saying
08:00 "Symbol's function cell is not defined",
08:03 something like this...
08:05 but if I execute the `defun',
08:09 the action of this function `o' here
08:12 is to run this, which opens a certain
08:16 directory...
08:18 let me go back. And here is another
08:21 button that defines
08:23 several functions at the same time.
08:25 If I execute this...
08:32 note that the result of executing
08:35 this expression, (code-c-d ...),
08:36 is the name of one of the functions that
08:38 it defined,
08:40 that is this one here, and let me explain
08:43 these examples. One of the functions
08:46 that this thing here defined
08:48 is called `find-orggitfile', where
08:51 this "orggit" in the middle of its name
08:54 is exactly this first argument
08:56 to `code-c-d'...
08:59 and the action of running
09:02 `find-orggitfile' on a string like this
09:04 is that `find-orggitfile' takes this string
09:06 and prepends this string to it...
09:13 this one here, which is the second
09:15 argument to `code-c-d'...
09:17 and then it executes `find-fline'
09:21 on the result, which is this one...
09:25 and `find-fline' is my variant of
09:28 `find-file' that supports pos-spec-lists.
09:32 And this function here, that I'm
09:36 referring to as a "button", it also
09:39 defines a function called
09:41 `find-orggitnode' here, where the "orggit"
09:44 is the same string as here,
09:46 and this function opens a node
09:50 of an info manual. This sexp here
09:54 opens this node in the Org manual...
10:00 it is equivalent to this sexp here...
10:03 so in the passage from this line to this
10:06 line we prepended to the node name
10:08 the name of the manual - here...
10:12 and `find-node' is my variant of this
10:15 standard Emacs function here, `info',
10:17 but `find-node' also supports
10:20 pos-spec-lists.
1.3. Shorter hyperlinks to PDFs and videos
10:23 Eev also defines some functions that
10:26 define shorter hyperlinks to PDFs and
10:28 videos.
10:30 Remember that this thing here is a
10:32 shorter hyperlink to a
10:34 to a file, and this thing here is a
10:37 shorter hyperlink to a node in an
10:39 Emacs manual... in an info manual.
10:43 If we run this thing here - this
10:46 `code-pdf-page'
10:47 this acts like a button that defines a
10:50 certain function,
10:52 and this other sexp here
10:56 defines another function. The first
10:58 one defines the function
11:00 `find-fongspivakpage', and
11:03 the second one defines the function
11:05 `find-fongspivaktext'. When we run
11:09 `find-fongspivaktext' it opens
11:13 this pdf here... the name is
11:17 quite long...
11:20 this example opens this pdf at page 8
11:23 and searches for the string "Contents".
11:26 Oops, sorry, in this case
11:28 it just ignores this string
11:31 here, it only considers
11:33 the number of the page. Let's try.
11:37 Aaaah!
11:42 Here it is. The contents of a book
11:45 that is freely available...
11:48 here is another page of the book...
11:51 and if we execute this hyperlink here,
11:55 `find-fongspivaktext', it converts the
11:58 PDF to text and it searches
12:00 for the page 8 in it, and then
12:03 for the string... this
12:05 string here in page 8.
12:08 It takes a few seconds...
12:12 here it is. So this is the
12:16 ascii version of this "Contents" page
12:20 here. Note that this block here
12:25 is a kind of an index to that book...
12:28 I have the full index somewhere, but
12:31 it's very long, so I just copied a few
12:33 lines here...
12:34 so this is a link to the
12:38 Section 1, oops, Chapter 1...
12:41 this is the section 1.1,
12:45 section 1.1.1, and so on...
12:48 and here is a link to the index,
12:54 And here is a part of my index
12:58 of positions in the video that we just
13:02 saw that i think that are especially
13:05 relevant.
13:07 So this
13:10 hyperlink is a kind of a button that
13:12 defines this function here,
13:14 `find-punchandjudyvideo'... let's try.
13:27 And we can also use this for video
13:31 tutorials. For example,
13:33 this is a very good tutorial on magit.
13:37 if we execute this
13:40 then these functions are going to be
13:42 defined, and these functions open
13:44 this tutorial on magit, and
13:48 these are some of the positions in the
13:50 tutorial that I found especially
13:51 relevant. This is a very dense
13:53 tutorial, I had to take notes of
13:55 everything,
13:56 and I had to watch everything
13:58 several times...
14:00 and for example, this is a link to the
14:03 position in the tutorial that explains
14:06 how in Spacemacs magit
14:12 interprets `SPC g s' as `magit-status'.
14:17 let's see...
14:25 and here are some examples that I
14:28 took from somewhere else... the video
14:32 tutorials from
14:34 Ralph Koenig about Org mode.
1.4. How the functions that define shorter hyperlinks are implemented
14:43 Now let me show how the functions that
14:45 define these shorter hyperlinks are
14:47 implemented.
14:48 The standard way in Emacs to define
14:51 functions that define
14:52 other functions would be with macros.
14:55 Let's see an example. This is a standard
14:58 function that
14:59 defines new functions...
15:02 and if we execute it
15:06 its result is the last function that it
15:09 defined, which is `ee-glyph',
15:10 which is here...
15:13 it's implemented as a macro, we can
15:16 look at the result of `macro-expand',
15:19 which is going to show us the result
15:21 of the expansion of this...
15:25 instead of expanding and executing it
15:28 expands and shows us the result.
15:33 Here - the result is a bit messy,
15:36 it is too big for
15:37 humans to understand, but we can run
15:40 this other sexp here, that takes that
15:44 result and pretty-prints it.
15:47 So this is the pretty-printed version of
15:50 this macro here.
15:54 We can see that it defines
15:57 several functions here...
16:01 For example, this one...
16:06 and this, just as a curiosity, is a link
16:09 to the definition of `cl-defstruct'...
16:13 and note that the code is huge...
16:16 well, it's very well commented,
16:19 but it has lots of special cases,
16:23 it supports lots of constructions...
16:26 and so it's huge and it's very difficult
16:27 to understand. I mean,
16:30 I found it very difficult to understand.
16:33 And here's a link to the documentation
16:35 of `cl-defstruct'...
16:37 here in the manual for `cl',
16:42 which is a kind of support for some
16:46 features of Common Lisp in Emacs.
16:50 So let's compare this standard way of
16:53 defining
16:54 functions that define new functions,
16:56 which is with macros...
16:58 with this. I'm going to use a slogan
17:01 repeatedly - the slogan is
17:04 "I am a very bad programmer".
17:06 I'm a very bad programmer, so when i was
17:08 trying to create functions that would
17:10 define new functions
17:12 I found it easier to generate
17:14 Lisp code as text
17:16 and then run `read' and `eval' in it.
17:20 The `code-c-d' that we saw in the
17:23 previous section...
17:24 we can see the the code that it produces
17:28 by making a copy of this line and
17:31 prepending this string here, "find-",
17:33 to the name of the function...
17:34 so instead of running `code-c-d' we run
17:36 `find-code-c-d',
17:38 and it creates a new temporary buffer
17:41 with the code that
17:44 `code-c-d' would execute.
17:47 So it's a series of `defun's and a few
17:50 `setq's... and this thing is implemented
17:55 mostly as a template. The low-level...
17:59 there's an inner function called
18:04 `ee-code-c-d-base' that receives just
18:06 these two arguments, and it essentially
18:09 just runs the function `ee-template0'
18:10 on this string here, and
18:14 the things between curly braces are
18:16 substituted by the values
18:18 of these arguments - here.
18:23 There's one part of the tutorial - here -
18:25 that explains all these things,
18:28 except for the rationale for some
18:31 design decisions...
18:32 and those design decisions are one of
18:35 the many motivations for this talk,
18:37 but I'm only going to explain these
18:39 things in detail at the end -
18:42 which is kind of soon. =)
1.5. `M-j'
18:48 In the beginning I said that the three
18:50 main keys of eev
18:51 are `M-e', `M-k' and `M-j'...
18:56 let's see now what `M-j' does.
19:00 But I need to start with some
19:01 motivation.
19:03 The motivation is that we can define
19:05 commands with very short names, and
19:07 actually I became kind of addicted to
19:09 that...
19:10 this is an example of `defun' that
19:13 defines a command with a very short name.
19:15 Its name is just one letter, `e',
19:18 and I can invoke it with `M-x e'.
19:21 If I type `M-x e' now
19:24 it opens a LaTeX file that I'm
19:27 working on,
19:32 and I create most of my LaTeX files
19:35 using template-based functions, like
19:39 the implementation of `code-c-d' above...
19:43 and these template-based functions create
19:46 files with the extension .tex
19:49 that start with a series of `defun's
19:51 in comments. For example...
19:53 Let's look at this example here. If I
19:56 execute `find-latex-links' with this
19:58 argument, it's going to do several
20:02 things for creating a file called
20:03 "/tmp/foo.tex"...
20:08 and the header of that file is going to
20:11 be this, which starts with three `defun's
20:16 with functions with very short
20:19 names in comments.
20:21 Let's compare with the situation here...
20:27 in my file "2020favorite-conventions.tex"
20:32 I have this header here, in which I
20:34 define six functions with very short
20:37 names...
20:39 and in this case here, that is even
20:41 explained in the tutorial...
20:43 we have mnemonics for these short names here:
20:48 `c' is "compile", `d' is "display",
20:51 I mean, display the PDF...
20:54 and `e' is "edit", in the sense of:
20:57 make Emacs visit that file.
1.5.2. `M-j' itself
21:02 Okay, now I can explain what is `M-j'
21:05 itself. We just saw command with
21:07 very short _names_, and the idea
21:09 behind `M-j' is that we
21:12 can define commands with very short
21:14 _numbers_.
21:16 Let me explain this.
21:19 The short explanation for what `M-j' does
21:22 is that it jumps to certain
21:25 predefined places...
21:26 in particular a `M-j' without a numeric
21:29 argument takes us to a buffer with
21:31 the basic help and the list of
21:34 the current eejump targets...
21:37 and this is something that is a bit
21:39 simpler to understand:
21:41 if we type `M-5 M-j' then `M-j' runs
21:44 this sexp here, (find-eev-quick-intro),
21:47 that is associated to
21:51 the argument 5... I say that the target
21:55 for the argument 5 is this one.
21:59 And if the argument is 2 then the
22:01 target associated to the 2 is this
22:03 sexp here, that opens...
22:07 well, this one opens the main tutorial of
22:09 eev, and this one opens another tutorial.
22:13 This is a link to one of the tutorials
22:15 of eev, to the part that explains `M-j'...
22:20 I've copied the the main part of the
22:22 text here.
22:24 The header - the header that `M-j' shows;
22:28 let me show it very quickly...
22:31 here is the header and here is the rest -
22:36 the header is very beginner friendly, and
22:39 if you're a beginner who only knows how to
22:40 `M-e' to execute and `M-k' to go back,
22:48 then you can, and should, use that header...
22:52 I mean this header here -
22:56 as your main starting point, and every
22:59 time that you feel lost
23:00 you can type `M-j' and to go back to
23:03 that header...
23:04 and you can use its links to navigate to
23:07 the documentation for Emacs and eev.
23:09 Let me explain that.
23:11 This header here has several elisp
23:14 hyperlinks...
23:15 one here, one here,
23:19 one here, one here, and so on...
23:22 these ones are links to the "intro"s,
23:25 which are the tutorials...
23:29 (find-eev-quick-intro) is the main
23:30 tutorial, and (find-eev-keys-intro)
23:32 is a kind of tutorial that is
23:35 an index of the main keys...
23:40 and after that we have an explanation of
23:42 what some numeric prefixes do...
23:45 so if we type `M-1 M-j' the effect of that
23:48 is exactly the same as executing this,
23:52 and we can execute this with `M-e' also.
24:00 `M-2 M-j' runs this sexp,
24:03 I can also execute it with `M-e'...
24:06 here it is, it's this intro, this
24:14 sandboxed tutorial... and
24:18 here is another sandboxed tutorial.
24:24 Let me go back... and then the
24:27 documentation says that that header -
24:30 the header that is beginner-friendly -
24:31 is followed by a section that is very
24:33 beginner UN-friendly,
24:35 that contains a series of `defun's like
24:37 these ones, here...
24:40 the last line of the header is this
24:43 comment here, and then we have
24:45 several `defun's like this.
24:48 Let me explain how these things work.
24:51 Technically, what happens when we type
24:53 `M-j' without any arguments is that it
24:57 runs `eejump' with the argument nil,
25:00 and then this runs `find-eejumps'.
25:04 When I run `M-j' with a numeric
25:06 argument, for example
25:08 with argument 5, it runs (eejump 5),
25:11 and (eejump 5) concatenates this 5
25:17 to make a name of a function - this
25:20 function here...
25:21 and it executes this function,
25:24 `eejump-5'... and (eejump-5)
25:31 executes (find-eev-quick-intro).
25:35 If I execute just `M-j'
25:39 this section that shows the current
25:41 eejump targets
25:43 has a line for eejump-5, this is
25:47 exactly the thing that I was explaining
25:52 before. So we can use `M-j' to navigate
25:54 the tutorials, and we can copy
25:59 links to the tutorials to our notes...
26:07 oh, sorry this has some typos...
26:11 for example, if I execute this
26:14 I go to a section of this tutorial here
26:18 that explains the main keys of eev,
26:20 and these things are hyperlinks... I can
26:24 mark a hyperlink like this, it is just
26:26 plain text, and I can copy it to my notes...
26:27 and the idea is that every time
26:31 that I find something that is
26:33 interesting I can create a hyperlink to
26:35 it, and i can put these links in my notes,
26:38 so I can navigate back
26:40 to all the interesting positions
26:42 very quickly.
1.5.3. `M-J' (meta-uppercase-J)
26:48 Ok, next feature; if we type
26:51 `M-J' (meta-uppercase-j), then...
26:58 this is a function that transforms the
27:00 current line in a certain way.
27:03 Let me give an example. Let me isolate
27:06 this, and let me duplicate
27:07 this line to make clear what happens.
27:11 If I type `M-J' here
27:14 this line here becomes a `defun' for
27:16 `ee-jump6', and the target of this
27:20 eejump is exactly this sexp here.
27:24 Let me undo this mess.
27:28 And if the first word in the line is not
27:31 a number - for example, here...
27:32 let me do the same thing,
27:36 duplicate the line and type `M-J'...
27:41 then `M-J' converts that to a defun
27:44 that defines a function with a very
27:46 short name,
27:49 and this function with a very short name
27:52 opens this file here, in the directory
27:56 with the copy of the the git repository
27:59 for Org mode.
28:01 Let me undo the mess again.
1.5.4. `M-uppercaseletter'
28:14 `M-J' is a particular case
28:17 of something that I use a lot in eev.
28:21 Eev has lots of key sequences
28:28 that are like meta-uppercaseletter, and
28:33 almost all of them operate on the
28:35 current line, and transform the current
28:37 line in a certain way.
28:38 For example, this is a file name,
28:42 and if I type `M-F' here
28:45 it becomes a link to that file...
28:48 this is the name of a manpage,
28:50 and if I type `M-M' here
28:53 it converts that to a link to a manpage,
28:55 and this is a shell command,
28:58 and if i type `M-S' here
29:01 it converts that to a link to a
29:04 to `find-sh'...
29:08 and until a few years ago these
29:11 functions with meta-uppercaseletter
29:12 were half of my main ways
29:16 of creating sexps
29:18 with few key strokes. In the beginning, of
29:21 course, I had to create my
29:22 sexp hyperlinks by typing each character,
29:25 but after some time I decided that
29:28 i needed something more efficient.
29:31 So this is the end of Part 1 of the
29:34 presentation.
2. A tale of two `describe-key's
29:38 So, this is Part 2 of the presentation,
29:40 and the main theme here
29:41 is the standard `describe-key'
29:44 function that comes with Emacs,
29:46 and my variant of it. The thing is that
29:49 the standard `describe-key' in Emacs
29:50 is user friendly but it is
29:53 hacker-unfriendly... well, I felt so,
29:55 and when I tried to complement it by
29:58 writing a hacker-friendly version of it
30:00 that produced the sexp hyperlinks that I
30:03 needed I got something that I found really
30:05 lovely, and
30:07 several of the main designs decisions
30:09 of eev can be seen there...
30:12 but when I showed my variants to other
30:14 people they hated it -
30:15 they felt that it was totally against
30:17 their notions of
30:19 user-friendliness.
30:23 Ok, so let's see the standard
30:25 `describe-key'. If I run
30:26 this hyperlink here I get
30:30 the result of running `describe-key'
30:32 on the key ...
30:34 and this is a big buffer with some
30:36 things in italics,
30:38 and some hyperlinks - here. These
30:41 hyperlinks are standard, in the sense that
30:43 their targets are not visible and they are
30:46 implemented using buttons in Emacs Lisp.
30:47 This section of the Emacs manual describes
30:51 how buttons work,
30:56 and the the source code is
31:00 quite difficult... I mean, when I was
31:03 starting to try to decipher this,
31:06 when I was a beginner using Emacs 19.34
31:07 I felt that this `describe-key' was
31:12 very difficult to understand,
31:15 and I felt that the the people who wrote it
31:20 were sacrificing too much of the
31:23 hacker-friendliness that I was expecting
31:26 from it to make it beginner-friendly.
31:31 Let me explain what are the the problems
31:33 with the standard `describe-key'.
31:35 If we think that hyperlinks
31:37 are things like this,
31:38 with the TARGET and the TEXT, then in the
31:41 button-hyperlinks of `describe-key'
31:43 these three bad things happen. First;
31:47 it is hard to extract the target from
31:49 the hyperlink. Second: it is hard to
31:51 recreate Lisp code that would go to that
31:55 target, and third: it is hard to copy the
31:57 full hyperlink, including the target,
31:59 to other buffers -
32:01 I already knew how to copy the text.
32:04 When I was trying to decipher what
32:07 `describe-key' was doing
32:09 I created lots of hyperlinks like this
32:11 to inspect the text properties and
32:14 things like that...
32:16 for example, in the description of the
32:18 key , here...
32:20 we have a button that points to
32:23 simple.el...
32:26 the text of that button is "simple.el",
32:29 this hyperlink goes to the middle of this
32:33 button-hyperlink here,
32:35 this hyperlink here goes to the middle
32:39 of this button-hyperlink and then inspects
32:43 its text properties, and then goes to
32:47 this section here of the description...
32:51 so this is a high-level description of
32:53 the text properties... I mean,
32:56 the text properties that make it
32:58 a button... and this is a
32:59 lower-level description of these text
33:02 properties.
33:04 And the button whose text
33:12 is "forward line", this one,
33:14 is slightly different...
33:16 this hyperlink here goes to the middle
33:19 of that button,
33:21 and this hyperlink goes to the middle
33:24 of that button, inspects its
33:25 text properties, and goes to
33:28 the section of this help,
33:32 uh, buffer, here that describe the the
33:35 button and the lower-level view
33:37 of the text properties.
33:41 So, I started with things like these to
33:45 understand what these buttons were doing,
33:48 and I was able to figure out how these
33:50 things are implemented, and `describe-key',
33:52 and similar help functions in Emacs...
33:55 and I discovered that one of the main
33:57 lower-level functions that Emacs used
34:00 for this is a function called
34:02 `find-function-noselect'...
34:05 if I run `find-function-noselect' on
34:08 'next-line, it returns a pair...
34:14 a cons made of a buffer and a position.
34:18 So I created functions that would
34:21 follow this, that would open that buffer
34:25 in that position, and then this is a
34:28 pos-spec-list...
34:29 so we could go to these positions and
34:31 then search for this string, and another
34:33 string, and another string, and so on...
34:36 so this goes to the definition of
34:40 `function-efunction' and then to a
34:44 string after it, and I use these things to
34:47 implement my own functions
34:49 that pointed to the same targets as the
34:52 button hyperlinks of `describe-key'...
34:59 Again, let me show the comparison...
35:02 this is the standard `describe-key' here,
35:07 and this is my variant...
35:10 it creates a buffer with elisp hyperlinks
35:14 about this key.
35:17 We get this, so each one of these
35:20 functions is either a blank line
35:22 or an elisp hyperlink...
35:28 here is a slight variant of the function
35:32 `find-ekey-links' above. In this variant
35:35 the argument is a string that has to be
35:38 processed by `read-kbd-macro' to convert it
35:40 to the lower-level format...
35:45 and note that these functions here that
35:48 I wrote...
35:49 they display temporary buffers with no
35:51 help at all.
35:53 To be honest there's a link to a
35:57 tutorial here, but
35:58 this is a recent addition, so let's ignore
36:01 this...
36:03 they display temporary buffers
36:06 with no help at all, just lots of
36:08 hyperlinks,
36:09 and these hyperlinks can be... they are
36:11 very hacker friendly, in the sense that
36:13 they can be followed with
36:15 `M-e', they can be copied to other
36:17 buffers, because they are plain text,
36:19 because they are just sexps...
36:23 and they can be inspected, in the sense
36:26 that... for example, here
36:32 we have a hyperlink to a function that
36:35 it may be difficult to figure out what
36:37 this function does...
36:39 but we can go to that position and then
36:42 type `C-h f' to see the
36:45 description of this function...
36:48 and here is a hyperlink that does that
36:56 in my syntax, say.
37:00 And these lists of hyperlinks were
37:02 generated by this code here,
37:04 that just uses backquote to generate
37:11 lists of sexps.
37:14 And I felt that this function here,
37:18 that just generated this list
37:20 was very easy to understand and to
37:22 modify, so this was hacker-friendly
37:24 in the way that I wanted.
37:28 And so I started using this...
37:31 and this idea of using buffers with
37:34 sexp hyperlinks and no help violated
37:36 all the notions of user-friendliness
37:38 that I knew, so I was
37:40 exploring something new at that time.
37:42 And this is the end of Part 2.
3. Killer features
37:46 Part 3 of this presentation is
37:49 about the killer features of eev, or:
37:52 Why everybody should use eev, or at least
37:54 have eev installed, even if they think
37:57 that eev is too weird.
37:59 So: this is a very quick listing.
3.1. Elisp hyperlinks
38:01 3.1. Eev has elisp hyperlinks, which are
38:03 super nice;
3.2. Lots of tutorials!
38:04 3.2. It comes with lots of tutorials.
38:06 The main one, here, explains all the
38:07 main features...
38:10 there's also a tutorial that is
38:14 an index of
38:15 all the other tutorials, here...
38:18 many, many, many tutorials.
38:20 If we forget everything we can
38:22 just type `M-j', and remember that
38:24 this this part here is
38:27 beginner-friendly and the rest is
38:29 beginner-unfriendly;
38:32 there's a tutorial on Emacs Lisp, here...
38:38 it mainly explains how to understand
38:41 elisp code, which is much easier than...
38:44 it's much easier to understand elisp code
38:47 then to understand how to program elisp,
38:49 and most people are only going to need
38:51 this.
3.3. Easy to install, and non-invasive
38:53 3.3. Eev is very easy to install.
38:55 It's in ELPA, so we just need to do
38:58 this thing here, and it's very
39:00 non-invasive...
39:03 several years ago it was a very invasive
39:06 package, but then I changed everything.
39:08 Now if we toggle eev-mode on and off
39:13 what's going to happen is just that the
39:16 eev key map becomes activated or
39:20 deactivated, and when we
39:23 (require 'eev-load) the only things that
39:28 happen globally are these things here:
39:32 several functions and variables become
39:34 defined - all of them have
39:36 standard prefixes, except for one;
39:39 three characters are changed in the
39:43 standard display table to make them
39:45 appear as colored glyphs:
39:47 the red star and
39:49 tha open double angle brackets and
39:53 the closed double angle brackets;
39:58 and two environment variables are set.
40:01 and this is a trivial technicality...
40:04 we just run a `defadvice'
40:07 around one function that is used by man.
40:10 Just this.
3.4. High discoverability factor
40:12 3.4. Also, eev has a
40:15 very high discoverability factor, and
3.5. A way to create "hyperlinks to here"
40:18 3.5. there's a very easy
40:21 way to create a hyperlink to "here".
40:25 I do not have time to show this now,
40:27 but for example, if I'm
40:29 here in a tutorial and I think that this
40:34 section is something interesting, and i
40:36 want to create a hyperlink to it
40:39 i just have to type a certain key
40:41 sequence - `M-h M-h' - here...
40:43 and here I got a hyperlink that I can
40:46 copy to my notes, and this hyperlink goes
40:50 to that section.
3.6. Hyperlinks to specific points in PDF documents and video files
40:58 3.6. We have hyperlinks that point to
41:00 specific positions in
41:02 PDF documents and in video files... here,
41:05 this one opens a PDF and displays it,
41:09 this one opens a PDF
41:10 and converts it to text,
41:13 and this one opens a video in a
41:16 certain position.
3.7. A way to control shell-like programs ("eepitch")
41:18 And we also have a way to control
41:20 shell-like programs.
41:22 In my presentation of the last year I
41:25 spent one third of the presentation
41:27 explaining this, and
41:28 i think that I gave a very good
41:30 demonstration there...
41:31 the demonstration is here:
41:35 we can go to the web page, and go to
41:38 this section of the web page,
41:41 and start by this point...
41:47 and here we have an explanation,
41:51 and so on, whatever...
3.8. Elisp tutorial
41:55 3.8. and i've already mentioned this
41:58 before... eev comes with a very nice
41:59 elisp tutorial.
42:02 So that's it, this is the end of part 3.
4. A tale of several "The User"s
42:05 So this is the last part of my
42:07 presentation, and it's about the title
42:09 of the presentation...
42:11 I called the presentation "Why
42:13 most of the best features in eev look
42:16 like 5-minute hacks". I've already
42:20 run out of time, so I have to skip this
42:23 first part here, in which i describe how I
42:28 was exposed to several different notions
42:31 of user friendliness...
42:33 and how the one that really blew my mind
42:35 was the one in
42:37 a certain Forth environment...
42:41 and let me make the long story
42:44 very, very short.
42:46 In all this process I switched from
42:49 the belief that the "User" was always
42:51 someone else, someone external, and that
42:53 I always had to write my programs for
42:57 this external "User"... I switched
43:00 from that to the belief that _I_ am
43:02 the "User",
43:03 and I can play with the interfaces that
43:05 I want, I can write programs that
43:10 only I am going to understand, I can
43:12 experiment with hundreds of interfaces
43:14 and then select the best ones,
43:16 and document them, and then share them
43:18 with other people
43:20 who are also experimenting with
43:23 interfaces in their own ways...
43:26 and so eev has lots of things that are
43:30 user-friendly in these unusual ways that
43:32 I've explained before...
43:34 and if we disconsider that this
43:37 notion of user-friendliness is valid,
43:40 then these things that eev
43:44 implement they are user-friendly and
43:46 hacker-friendly at the same time.
43:48 And let me show one example. This is one
43:51 that really took me one only five
43:54 minutes to implement.
43:56 At one point, a few months ago,
43:59 I discovered
44:00 that Sacha Chua's weekly posts about
44:04 Emacs News were also
44:07 being posted to a mailing list that is
44:09 stored at
44:11 lists.gnu.org, and it's called
44:14 emacs-tangents...
44:16 and I found a way to create
44:19 the links to to the posts in both places,
44:25 but I had to use a template for that...
44:28 so what we are seeing here now
44:30 is a template with the default
44:32 values - so this means that we have not
44:36 set the year correctly, we have not set
44:39 the month correctly,
44:40 or the day correctly, but if we run this
44:44 sexp here...
44:46 let me do something else before...
44:50 if we run this sexp here
44:55 we change some of these entries
45:00 in the template, and we get these links
45:04 here... they all work.
45:06 For example, this one opens
45:09 the blog post in Sacha Chua's site,
45:12 and this one
45:16 opens it in the mailing list...
45:21 and sometimes I want the Org source of
45:23 that, and the easiest way to get the
45:25 Org source is to
45:27 look at this link here, that has an
45:30 attachment...
45:31 and if I take this
45:35 link here, and I take this
45:38 stem that points to the attachment,
45:42 and I put it here, and I generate this
45:44 page again
45:45 with all this data, then I get
45:49 a script - here -
45:50 that downloads... let me switch to a
45:53 smaller font -
45:54 it downloads this attachment,
45:58 and it renames that attachment to
46:00 something-emacs-news.org.
46:13 Here - the file is already here,
46:16 already with the right name, so I can
46:19 open it with just this hyperlink...
46:20 let me go to the big font again -
46:25 and now i have the Org source for that
46:28 hyperlink...
46:29 sorry, for that blog post,
46:33 and so this one-line thing here
46:37 is, in a sense, a hyperlink to
46:42 this blog post in all its formats...
46:45 if I execute this I get links to
46:48 to all the places where it is posted,
46:52 and I get a script to
46:54 download a local copy of the
46:56 Org source of it... and that's it.
47:00 Well, I'm already out of time, so let me
47:03 finish here.
47:04 Thanks! Bye! =)
|