|
Some template-based functions of eev that are not five-minute hacks (2020)
My presentation at the EmacsConf 2020 was titled "On why most of the best features in eev look like
5-minute hacks"; this is a complement to it.
You can watch this video on youtube here, but
Youtube always converts my videos to a format that is blurry at some
points... the best way to watch it is by running the two "wget"s
and the "mpv" below; then you can use these keys to
make mpv play it in high speed.
In most cases when I record "executable notes" on how to perform
tasks (see my talk at the EmacsConf 2019!) I
record them as plain text, but in a few cases I prefer to use
functions that generate text from templates. This video is about some
non-trivial cases of functions that use templates to generate
"executable notes" that can then be executed in several different
ways.
For more on eev see http://angg.twu.net/#eev.
I recorded this video without rehearsing it first, so it's a
bit messy... sorry!
The "script" that I used in the video is here.
Its thread on reddit is here (but it has 0 comments).
Index of the video (elisp here):
0:00 Title
0:17 the reason for this title
0:18 1. `find-find-links-links-new'
1:29 generated again with these values
1:50 the implementation is very simple
2:00 in five minutes because ... generates skeletons
5:03 2. `M-x brep'
5:43 a way to download local copies
7:11 The new way: `M-x brep'
8:15 by typing `M-x brep'
8:50 and then we get this buffer here
9:17 3. The function that defines brep
9:38 `code-brurl' is a variant of `code-c-d'
10:07 find-code-url shows the code instead of executing it
11:26 this is explained in the main tutorial
12:12 accept extra arguments
12:34 if we run just this
12:40 one of the reasons for using text: comments
13:03 if we run just this with extra arguments
14:10 code-brurl executes this code here
14:20 4. `find-esetkey-links'
15:20 a big header with lots of help
16:28 I have these keybindings, for toggling
17:06 I realized that I use `M-x wrap' very often
18:18 in the emacs-devel mailing list
18:32 users should not be forced to see lisp
19:23 5. `find-youtubedl-links'
19:43 if we twist the notion user enough
20:02 user-friendly to me
20:05 The documentation is in this tutorial:
21:36 its code is here
21:55 Let me show a demo
22:15 I never type these rm -Rv/mkdir/cd by hand
22:48 let me show how to download ... the hash is here
23:25 they regenerate this buffer in slightly different ways
24:03 a video with this hash. If I visit the directory
24:32 my magic functions have to
24:50 if I run this sexp here with nil
25:00 it tries to guess the title
25:28 and if I change this {stem} here I get short links
26:14 has very long lines, but if I type super-w
26:28 I get a buffer that shows the code for find-preadingvideo
26:50 if I execute this I play the video
27:15 make a copy of this that points to the right position
27:53 summary: this is how I download videos from youtube
28:12 6. `find-here-links' and `find-extra-file-links'
28:20 it deserves another presentation just to itself
28:32 the central idea of eev
29:17 it is bound to `M-h M-h'
29:25 generates a temporary buffer with hyperlinks to here
29:30 help and a link to the tutorial in which I was
29:45 not very well documented yet
30:05 it is explained in this section of the tutorial
30:18 if we type `M-h M-e' this runs `find-extra-file-links'
30:42 here is an example in Lisp
31:06 and I can change this {c}
31:22 Let me show a more realistic example of how to use it
31:28 let's go to the directory with the video file
31:45 this file is a video file
32:00 (a glitch)
33:03 these were the things that I wanted to show
The full subtitles in Lua for the 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, and this is a
00:03 quite technical talk about eev, so I'm
00:05 going to suppose that everyone knows
00:07 what is the Emacs and what is eev.
00:10 The title of this talk is:
00:13 "Some template-based functions of eev
00:15 that are not 5-minute hacks"
00:17 and the reason for this title is that
00:20 when I gave a presentation at the
00:22 EmacsConf 2020 I give this title to it:
00:25 "On why most of the best features in eev
00:30 look like 5-minute hacks",
00:34 and the last section of that
00:36 presentation was about one specific
00:38 feature that I really implemented in
00:40 just five minutes.
00:42 We can play the video here by
00:45 executing this link here...
00:51 oops, sorry, here: Part 4...
00:56 and I explained a certain notion of
00:59 user-friendliness, and then i explained
01:00 the function called
01:02 `find-emacs-tangents-links'
01:03 in this part here...
01:12 but let's see it in a more technical way.
01:15 if we execute (find-emacs-tangents-links)
01:19 we get a buffer like this, in which this
01:22 part here is generated by a template,
01:24 and if I change these things here
01:28 by something else, for example by YEAR
01:31 in uppercase letters, and I run this line
01:33 again, then the all the buffer is going
01:37 to be generated again with these values
01:39 for the the things in curly braces, so
01:43 if I execute this I get this...
01:45 taaa - this became YEAR.
01:50 The implementation of this is very
01:52 simple, it is just a function, here...
01:55 with the template here...
01:57 and the interesting thing is that...
02:00 the thing that allowed me to write this
02:02 thing in just five minutes is that
02:05 I have a function that generates
02:07 skeletons for functions like this.
02:08 If I run this hyperlink here -
02:13 and note that in the code of
02:16 `find-emacs-tangents-links',
02:18 in these comments here, I have a link
02:20 to this skeleton...
02:24 if I run this skeleton here
02:27 I get a buffer that has
02:31 this header, this `defun' here,
02:35 the optional arguments, and then this
02:39 field here, that is blank... in this field
02:42 is a list of of temporary variables that
02:45 I set in a `let*'.
02:47 For example, let me change this to FOO
02:50 and BAR in uppercase letters.
02:52 If I execute this again I get
02:56 this other skeleton here, in which now I
02:59 this `let*' here, that sets FOO and
03:02 BAR to default values,
03:04 and then the indentation changes a bit.
03:07 If I delete these things and I generate
03:11 the buffer again...
03:12 look at this part here, the `let*' is
03:15 going to disappear, and this thing is
03:16 going to to move a bit to the left,
03:18 and one of these parentheses
03:20 is going to disappear.
03:23 That's it.
03:25 So, to write this function
03:28 `find-emacs-tangents-links'
03:30 I essentially started with a skeleton
03:33 like this,
03:34 I had a draft of this thing that I put
03:38 in the template,
03:39 and I just moved this thing to the
03:41 template and
03:43 put backslashes in the right places, so
03:46 that this thing is
03:47 going to be just a big string, because...
03:51 no, let's look at the source code.
03:56 If I don't have a backslash here then
03:59 this thing becomes a big mess and
04:01 some things that should be strings
04:04 are not going to be strings, and, well,
04:06 whatever...
04:10 So, this is how I wrote this function and
04:13 most of my template-based
04:15 hyperlink functions.
04:20 This one is called
04:22 `find-find-links-links-new' because it is
04:24 a successor of a previous version that
04:27 was called just `find-find-links-links',
04:31 that was my function that produced the
04:34 buffer that would create a skeleton for a
04:38 function called `find-something-links'
04:46 but this one was a bit messy, and
04:48 the new one is quite clean.
04:50 So I like it very much and I hate the
04:52 old one, but I still have the code
04:54 of it somewhere, and I think that I
04:55 still have some
04:58 functions that depend on it.
05:01 Now let's see one function that uses a
05:06 template...
05:07 its code is quite short, but I
05:10 that that's a very interesting idea.
05:15 In one of the sections of one of the
05:18 tutorials of eev...
05:20 the one that has number eight here in
05:22 the index of the tutorials;
05:24 it is called find-psne-intro, and
05:28 psne is a contraction of something
05:32 that was already a contraction...
05:34 this is explained there, but it's not
05:36 important now...
05:39 and the thing is that psne
05:44 is a way to download local copies of
05:47 files from the internet...
05:49 and it has this example here, where
05:53 if we execute these...
05:56 let me change to a smaller font...
05:57 if we execute this thing here we create
05:59 a temporary buffer, here,
06:01 that runs a shell, and we set the
06:04 target of eepitch to
06:06 this shell here... and now in the
06:10 lines that do not start with a
06:12 red star...
06:14 if I type an f8 here then that line is
06:16 going to be sent to the target buffer
06:18 as if the user was typing that line...
06:22 and in this case, these four lines...
06:26 they create a directory corresponding to
06:30 to the remote location of this
06:33 URL here,
06:38 it changes - it "cd"s to that directory -
06:41 and it "wget"s that file...
06:45 and it also saves the URL
06:48 to a certain log file.
06:51 So this is the general idea
06:54 And then this tutorial explains how i
06:56 use something
06:58 similar to this, but much more
07:00 complicated to download local copies of
07:02 files from the internet.
07:06 Let me switch to a bigger font again...
07:10 and the new way is by just using
07:15 `M-x brep'... and the "br"
07:19 in the beginning is the prefix that
07:21 indicates that we're going to do a
07:23 variant of `browse-url', and this "ep"
07:27 means that we are going to run
07:31 a version in Emacs of something that
07:34 I used to call "psne" 20 years ago.
07:36 If we run this hyperlink here
07:40 we get a temporary
07:43 buffer like this...
07:45 so it has some variants of how to
07:48 download this,
07:50 in which this thing here is changed...
07:54 and we have code to download a
07:56 local copy of this URL here...
07:58 and we have these links here
08:01 that will let us check the local copy.
08:04 so we get this -
08:09 the contents don't matter to us now...
08:12 and my favorite way of running this
08:16 is by typing `M-x brep',
08:24 which calls `find-psne-links'
08:27 on this URL here.
08:31 So it's a variant of `browse-url'
08:35 in which instead of browsing the url we
08:38 are generating a temporary buffer with it,
08:41 and this temporary buffer
08:43 allows us to,
08:44 to change the URL if we need to...
08:48 let me confirm here - and then we get this
08:52 this buffer here, and usually I just go
08:56 to this block, and I execute this
08:58 without even thinking.
09:08 So, the rest of this tutorial explains
09:10 the details, but let me go back...
09:15 The third template-based function
09:19 that I want to show is the function that
09:21 defines this `brep', because...
09:25 well, let me show this in practice.
09:29 The `brep' is defined
09:32 by this sexp here,
09:36 that uses a template... and this is a
09:39 variant of `code-c-d' that defines
09:42 this function... it generates a
09:46 lot of elisp code as text, and then it
09:49 `read's and `eval's it,
09:51 and it generates in this case
09:54 just one function that is
09:56 based on this function here,
09:57 `find-psne-links', that operates on urls,
10:02 and it defines this function here, `brep'.
10:05 And the nice thing is that we can
10:06 just add this prefix here, "find-",
10:10 to the line above, to check the code
10:13 that this thing generates...
10:15 So instead of executing this
10:17 code we are going to just generate
10:18 the code and show it as Emacs Lisp,
10:22 which means: with nice colors...
10:26 So this is the definition of `brep', and
10:29 the docstring of it is just "Apply
10:33 `find-psne-links' on URL",
10:36 and it runs blah blah blah, the details
10:38 don't matter...
10:40 and the general idea behind this
10:43 `code-something' functions and their
10:46 variants that start with `find-'
10:48 is explained in my presentation in
10:51 the EmacsConf 2020, in this position
10:55 here... let me just show it...
10:59 ...that we saw in the
11:02 previous section...
11:04 we can see the the code that it produces
11:07 by making a copy of this line and
11:10 prepending this string here to the name
11:13 of the function, so instead of running
11:15 `code-c-d' we run `find-code-c-d',
11:17 and it creates a new temporary buffer
11:20 with the code that `code-c-d' would
11:23 execute...
11:25 ok, let me go back.
11:28 This is explained in the... even in the
11:31 main tutorial, because `code-c-d'
11:33 is very important and the variants of
11:35 `code-c-d' are very are, so there's a
11:37 section called "Shorter hyperlinks"
11:41 here, a subsection that is just about
11:46 `code-c-d'...
11:49 and this explanation here -
11:53 very brief but it sort of works -
11:57 of how `code-c-d' works... it produces
11:59 a big string using a template...
12:01 and an explanation of this idea of
12:04 prepending a "find-" to the `code-c-d'
12:08 to understand the code that the thing
12:10 generates...
12:12 And several of my functions that
12:16 are related to `code-c-d' accept extra
12:19 arguments,
12:20 and this tutorial has even a section
12:22 about these extra arguments,
12:24 using `code-c-d', that is the main
12:26 function that users are going to
12:28 to use... and it has some examples.
12:33 If we run just this
12:36 we generate this code here,
12:40 that starts with comments, and then it
12:43 has several definitions here: it defines
12:45 a variable,
12:46 and it defines several functions...
12:49 one of the reasons for using text
12:51 instead of using macros,
12:53 by the way, is that by generating
12:55 text I can add comments,
12:57 and these comments here have even
12:59 elisp hyperlinks to the documentation.
13:04 Ok, so this is the code generated by
13:07 just `find-code-c-d' without extra
13:10 arguments...
13:12 and we if we add an extra argument here
13:18 the output becomes a little bigger...
13:22 this section appears, and this section
13:24 defines a function that opens a node
13:30 in a certain info manual...
13:34 and then this thing explains a bit of
13:36 the innards, and a bit of the other
13:38 extra arguments that we can use...
13:43 So this was a very quick
13:46 introduction to this `code-c-d'
13:48 and its related functions...
13:53 and again: when I defined `brep'
13:56 I used one of these `code-something'
13:59 functions, `code-brurl', and we can
14:01 inspect its code by running
14:04 this `find-code-brurl'.
14:06 So: (code-brurl 'find-psne-links ...)
14:13 executes this thing here.
14:21 Ok, next section:
14:23 4. `find-esetkey-links'.
14:26 Sometimes... one of the things that
14:28 beginners often want to do
14:30 is to define new key bindings,
14:35 and I realized that I could use
14:39 the ideas of eev to provide a
14:43 different way of doing that.
14:46 If we just run (find-esetkey-links) -
14:50 or with `M-x' or with this sexp here, -
14:57 sorry, if we run with `M-x' we get
15:01 a prompt here that tells us to to give a
15:05 key and then a command... let me try
15:09 M-f5
15:12 and then the command is going to be
15:16 `next-line'. We get a buffer here that
15:21 has a big header with lots of help...
15:27 for example, this line here
15:30 shows the section of Emacs manual
15:34 that explains how to change key bindings
15:37 interactively...
15:39 it's not trivial to to save these key
15:42 bindings to your .emacs after defining
15:46 them interactively...
15:50 and these links go to the documentation
15:52 of these functions here...
15:55 and this has some calls to these
15:56 functions that
15:59 it seems that the Emacs suggests
16:02 people to use interactively...
16:05 but here we generate sexps
16:09 for them, both for setting the key
16:13 and for unsetting the key, and we can
16:15 save these the settings in our notes,
16:20 or even in our ~/.emacs file.
16:23 For example, I have these keybindings
16:29 here. I use the super key for several
16:33 toggles... here in my keyboard the
16:36 super key is the Windows key.
16:39 So if i use super-t I toggle the
16:43 `tool-bar-mode', which is this thing here...
16:46 so let's do that several times...
16:50 if I use super-m I toggle the
16:56 `menu-bar-mode'... I can have both at the
16:59 same time, I can toggle them
17:00 very quickly, whatever... but I usually
17:04 don't like them.
17:06 and I realized that one thing that
17:08 I do very often especially when I'm
17:11 recording videos with a big font is
17:13 that I toggle line wrap...
17:16 and I have a function, that i've defined
17:18 ages ago, that is called just `wrap'...
17:20 I used to call it with just `M-x wrap'.
17:27 Its definition is here. It's in my
17:30 ~/.emacs, that is a total mess...
17:35 and I realized that I could use
17:39 this `define-key' here to define
17:44 super-w to wrap, and in this case here,
17:49 for reasons that I'm not going to
17:51 explain now, instead of setting this in
17:53 the global keymap I'm setting this
17:55 in the eev keymap... and if I go
17:59 here there's even a link to describe
18:02 what are the current
18:04 bindings in the eev keymap...
18:07 so we get them here,
18:11 and we get the `wrap' here.
18:18 So... in the emacs-devel mailing list
18:21 people are always discussing how to
18:23 make these things more user-friendly
18:25 without ever using Lisp, because
18:29 "USERS SHOULD NOT BE FORCED
18:31 TO SEE LISP", and I'm taking
18:33 exactly the opposite - I'm
18:35 doing everything with the Lisp
18:38 very evident, with no hidden text,
18:40 and whatevers...
18:42 and this is an experiment to see
18:46 if users like this thing... this is
18:49 very recent, I haven't
18:51 tested this in
18:54 guinea pig users yet, so I didn't get
18:58 any feedback yet...
18:59 but i think that this can be a good way
19:01 to teach users how to
19:03 to bind keys, especially because
19:06 if they type something wrong they can
19:08 see what they have
19:10 typed wrong, and they can see the sexps
19:13 that corresponds to doing that, they can
19:15 change the sexps, and so on...
19:19 Ok, this was was the fourth thing that
19:21 I wanted to show.
19:23 And the fifth thing that I want to show
19:25 now is how I download
19:30 videos from Youtube.
19:33 And this is really far from
19:36 a 5-minute hack, because this
19:38 one does a lot of magic.
19:40 And the idea, as always,
19:44 is that if we twist the notion of
19:47 "user" in exactly the right way
19:49 then user-friendly and hacker-friendly
19:51 become very similar to one another.
19:54 So this is _my_ user-friendly way to
19:58 download videos from Youtube that is
20:00 user-friendly to _me_, and maybe
20:02 to other people... but whatever.
20:05 The documentation about this
20:08 `find-youtubedl-links' is in this
20:11 section here
20:13 of the tutorial about how to use
20:15 audio and video files in eev...
20:18 in this section here...
20:20 and the idea is that
20:22 links to Youtube can have
20:27 several formats. The long format is this
20:30 one, but there's also a couple of
20:32 shorthands to this... and
20:34 they always contain an id
20:39 that is always 11 characters long.
20:42 It only uses certain characters,
20:45 and I don't remember exactly why, but
20:49 I decided to call it the "hash" instead
20:51 of the "id", so in the code i refer to
20:54 this thing as the "hash" of the
20:56 video everywhere.
20:59 And so... here the documentation says
21:02 how to download the video if you have
21:07 youtube-dl installed, and due to this
21:09 option here the video is going to be
21:13 downloaded with both its title and its
21:19 identifier in the local file name.
21:25 And my favorite way of downloading a
21:30 local copy is... with this function,
21:33 `find-youtubedl-links'...
21:37 it's code is here, it's not
21:39 very ugly, but the thing is that
21:42 it uses lots of internal functions
21:46 and variables to discover what
21:48 is the local file
21:51 corresponding to the video.
21:55 Let me show a demo - here. I'm going to
21:57 use a temporary directory for the
22:00 video just to not have so much clutter
22:03 in the screen...
22:07 let me switch to a smaller font again...
22:10 ok, let me recreate this directory.
22:15 By the way, i never type
22:17 these things by hand
22:19 what I do is that I just put
22:22 the name of the directory in a line
22:24 by itself,
22:26 and I type meta-uppercase-r.
22:29 And I get this.
22:35 But let's go back to the demo. I'm going
22:37 to set my favorite directories for videos
22:39 to this directory here, that is
22:42 a temporary directory that is not
22:45 the one that i tend to use... and
22:48 let me show how to download a certain
22:50 video.
22:53 So: the hash of the video is here...
22:56 I just have to place the coursor on the
22:59 hash and type `M-x find-youtubedl-links'...
23:03 and this function discovers
23:07 what is the hash around point,
23:11 let me type an Enter here...
23:15 and it produces this temporary
23:18 buffer here...
23:21 oops, sorry...
23:26 here we have two different functions
23:30 that regenerate this buffer in
23:33 slightly different ways...
23:36 and I'm going to run this script here.
23:41 Note that it has several variants that
23:44 run youtube-dl with slightly different
23:49 arguments... I'm going to to use the
23:51 default one.
23:53 It takes a while...
23:58 it downloads the video - it's quite short,
24:00 it's just 10 megabytes -
24:02 and now I have a video with that name -
24:05 I mean, with this hash in its name.
24:07 If I visit the directory where I'm
24:10 downloading the videos I'm going to see
24:13 that there's a video with this
24:14 string in its name, so if execute this
24:18 this sexp opens that directory and
24:22 uh searches for the first occurrence of
24:25 this string, which is exactly in the line
24:28 where my video is. It is here -
24:33 so my magic functions have to discover
24:37 the rest of this file name just
24:40 by this string here...
24:50 and if I run this sexp here,
24:54 that has nil in the place of the title,
24:59 then `find-youtubedl-links' is going to
25:02 try to guess the title of the video
25:04 from just this thing and the directory.
25:07 Let me try... TA-DA! It found
25:09 the right title, here we have a sexp
25:16 that concatenates the directory, the
25:20 title, and the hash, and the extension...
25:23 the magic functions also discover the
25:25 extension...
25:27 and if I change this {stem} here
25:35 I get short links to this video.
25:38 So if I execute this I get a short
25:44 link to this video... let's use the usual
25:47 trick...
25:48 if I run this `find-code-video'
25:52 here I will get the code that
25:58 `code-video' is going to run...
26:01 let me copy this to my notes...
26:08 these hashes look ugly. So, if I execute
26:12 this... note that now I have very long
26:16 lines, so I can type super-w, and ta-da,
26:18 it toggles line wrapping...
26:25 ok, so if I run this thing here...
26:29 I get a buffer that shows the
26:31 code that defines this function here -
26:34 `find-preadingvideo' - "The problem
26:38 with reading (something)".
26:42 If I just execute this line here it
26:45 defines `find-preadingvideo',
26:49 and if I execute this I open this...
26:52 "In the rest of the significant portion
26:54 of the play..."
26:55 in the beginning
26:57 but suppose that i've downloaded this
27:00 video because I discovered that it has a
27:02 sentence... a part that is very
27:05 important... so i took down notes of
27:07 where it starts and what is the sentence,
27:11 so I can just make a copy of this
27:18 that points to the right position...
27:20 "...of the play where Jocasta
27:22 the queen has no lines, and because we're
27:25 reading the play - most of us now read
27:27 the play very few of us will have the
27:29 opportunity - although i urge you to take
27:31 it if it comes - to see the play
27:32 enacted... there are some movie versions,
27:35 and occasionally..."
27:37 well, whatever.
27:42 These are things that I have just put
27:45 here because initially I thought
27:48 about presenting this in a
27:50 in a different order... so: this is how
27:54 I download videos from youtube,
27:56 in a way that is only user-friendly
27:59 if I define "users"
28:01 in exactly the right way, in which
28:04 the main user in the universe is me.
28:11 And the last template-based function
28:14 that I wanted to present is
28:18 `find-here-links'. This is one that
28:21 deserves another presentation, I'm
28:23 to record a video about it, but let me
28:27 present it very quickly. This is one
28:30 of the main functions of eev -
28:32 I use it hundreds of times a day
28:34 because the central idea of eev is that
28:36 we can keep executable logs of what
28:42 we do, and these executable logs
28:44 usually are made
28:47 half of hyperlinks to interesting things
28:50 and half of executable code, like
28:54 shell command, or things like that...
29:00 so this tutorial explained these ideas,
29:03 and then the technical details...
29:08 for example, if i run `find-here-links'
29:15 here... note that it is bound to
29:20 `M-h M-h', and...
29:23 when I type `M-h M-h'
29:27 it generates a a temporary buffer
29:31 with links to "here"...
29:33 here is a header with help, and here
29:36 is the link that I want: a link to
29:40 the tutorial in which i was...
29:45 And I want to show something that is
29:48 not very well documented yet,
29:51 that is a different way to create
29:56 links to video files, audio files, PDF
29:59 files, and so on...
30:05 it is explained in this section of
30:08 the tutorial but
30:09 i don't think that i've revised it
30:13 enough times yet, so it may not be
30:16 very readable...
30:19 and the idea is that if you type
30:24 `M-h M-e' then this runs
30:31 `find-extra-file-links', and
30:34 this is an experimental feature whose
30:36 behavior may change soon...
30:38 but here is how it works now.
30:42 Here is an example in Lisp. If we
30:44 execute this we get a temporary buffer
30:46 with several kinds of hyperlinks,
30:50 including `code-c-d', `code-video',
30:53 etc, pointing to this file here...
30:54 so: this block here supposes that
31:01 this file is a PDF file, this one
31:03 supposes that it is a video file,
31:06 and I can use this {stem} here
31:12 to generate functions that have this
31:15 string, "MYFOO", in their names...
31:21 and let me show a more realistic
31:23 example of how to use this,
31:26 which is... let's go to the directory
31:30 where I've downloaded this video file:
31:32 here. If I type `M-h M-e' here I get
31:38 a buffer that lets me define several
31:45 kinds of links to this file...
31:50 this file is a video file,
31:53 and let me use this string to identify
31:56 it...
31:58 uh =(
32:23 sorry, I played this as an audio,
32:27 and there's no very easy way to to stop
32:34 it...
32:38 so, if I run this... now I've defined
32:42 these short links here...
32:47 `find-preadvideo'... and if i
32:50 execute this...
33:02 ok, sorry for the mess! And
33:05 these were the things that I wanted to
33:07 show in this presentation, and that's it.
33:10 Bye! =P
|