summaryrefslogtreecommitdiffstats
path: root/2022
diff options
context:
space:
mode:
Diffstat (limited to '2022')
-rw-r--r--2022/captions/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main--chapters.vtt38
-rw-r--r--2022/captions/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main.vtt739
-rw-r--r--2022/info/eshell-after.md245
-rw-r--r--2022/info/eshell-before.md26
4 files changed, 1046 insertions, 2 deletions
diff --git a/2022/captions/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main--chapters.vtt b/2022/captions/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main--chapters.vtt
new file mode 100644
index 00000000..e2ead1cc
--- /dev/null
+++ b/2022/captions/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main--chapters.vtt
@@ -0,0 +1,38 @@
+WEBVTT
+
+
+00:00:00.000 --> 00:00:28.999
+Introduction
+
+00:00:29.000 --> 00:00:48.599
+1. It’s an Emacs REPL
+
+00:00:48.600 --> 00:01:10.119
+2. It’s also a shell
+
+00:01:10.120 --> 00:03:27.559
+3. You can mix these two modes
+
+00:03:27.560 --> 00:04:36.079
+4. Emacs is better than shell
+
+00:04:36.080 --> 00:06:13.479
+5. Better regular expressions
+
+00:06:13.480 --> 00:07:39.639
+6. Loops are better with predicates
+
+00:07:39.640 --> 00:09:08.519
+7. Output of last command
+
+00:09:08.520 --> 00:10:26.879
+8. Redirection back to Emacs
+
+00:10:26.880 --> 00:12:28.399
+9. Using Emacs buffers
+
+00:12:28.400 --> 00:12:59.359
+10. cd to remote systems
+
+00:12:59.360 --> 00:14:01.920
+Summary
diff --git a/2022/captions/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main.vtt b/2022/captions/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main.vtt
new file mode 100644
index 00000000..80b3afb8
--- /dev/null
+++ b/2022/captions/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main.vtt
@@ -0,0 +1,739 @@
+WEBVTT captioned by howard
+
+NOTE Introduction
+
+00:00:00.000 --> 00:00:04.999
+I have 10 minutes to talk you into
+
+00:00:05.000 --> 00:00:07.879
+giving Eshell a second chance.
+
+00:00:07.880 --> 00:00:10.119
+Have the right perspective and expectation,
+
+00:00:10.120 --> 00:00:12.919
+and I think you’ll really enjoy it.
+
+00:00:12.920 --> 00:00:15.679
+Just remember eshell is a shell,
+
+00:00:15.680 --> 00:00:17.839
+not a terminal emulator.
+
+00:00:17.840 --> 00:00:20.279
+I use both Eshell and vterm.
+
+00:00:20.280 --> 00:00:23.479
+I’m going to talk and type fast,
+
+00:00:23.480 --> 00:00:28.999
+as I have 10 reasons for you to try Eshell again.
+
+NOTE 1. It’s an Emacs REPL
+
+00:00:29.000 --> 00:00:32.599
+1. It’s an Emacs REPL.
+
+00:00:32.600 --> 00:00:33.999
+I mean, check this out.
+
+00:00:34.000 --> 00:00:36.999
+Let’s start up Eshell here.
+
+00:00:37.000 --> 00:00:41.399
+Let’s just type a Lisp expression.
+
+00:00:41.400 --> 00:00:43.919
+It works.
+
+00:00:43.920 --> 00:00:48.599
+As a shell, the parens are kinda optional.
+
+NOTE 2. It’s also a shell
+
+00:00:48.600 --> 00:00:52.519
+2. It’s also a shell.
+
+00:00:52.520 --> 00:00:56.479
+While eshell may look like a shell, like Bash
+
+00:00:56.480 --> 00:00:58.559
+you should view it as a REPL
+
+00:00:58.560 --> 00:01:02.399
+with parenthesis-less s-expressions.
+
+00:01:02.400 --> 00:01:05.559
+This makes sense, because a shell command with options,
+
+00:01:05.560 --> 00:01:07.999
+like this ls command,
+
+00:01:08.000 --> 00:01:10.119
+looks like an s-expression.
+
+NOTE 3. You can mix these two modes
+
+00:01:10.120 --> 00:01:12.879
+3. You can mix these two modes.
+
+00:01:12.880 --> 00:01:14.959
+Shells can call subshells
+
+00:01:14.960 --> 00:01:17.919
+which return their output like a function call,
+
+00:01:17.920 --> 00:01:20.799
+like this Bash command.
+
+00:01:20.800 --> 00:01:22.759
+In this Eshell example,
+
+00:01:22.760 --> 00:01:24.639
+I use the output of a text file
+
+00:01:24.640 --> 00:01:27.959
+as command line arguments to ripgrep.
+
+00:01:27.960 --> 00:01:29.639
+Notice how I use braces
+
+00:01:29.640 --> 00:01:34.759
+to state that it is a call to an eshell expression.
+
+00:01:34.760 --> 00:01:40.039
+We can mix Lisp-expressions and Shell-expressions.
+
+00:01:40.040 --> 00:01:45.599
+Allow me a contrived example.
+
+00:01:45.600 --> 00:01:50.079
+Notice I use good ol' setq to create a variable.
+
+00:01:50.080 --> 00:01:54.919
+Yes, those are global Emacs variables available everywhere.
+
+00:01:54.920 --> 00:01:59.599
+In Eshell, the wildcard actually creates a list.
+
+00:01:59.600 --> 00:02:04.479
+This variable assignment doesn’t work as you might expect,
+
+00:02:04.480 --> 00:02:07.559
+as setq in Eshell is still setq,
+
+00:02:07.560 --> 00:02:10.319
+and it assigns variables in pairs.
+
+00:02:10.320 --> 00:02:17.119
+To make a list in Eshell, we use listify:
+
+00:02:17.120 --> 00:02:21.239
+Without parens, Eshell is in “shell mode”,
+
+00:02:21.240 --> 00:02:23.799
+which means that words are strings,
+
+00:02:23.800 --> 00:02:26.879
+and variables need to be prefixed with dollar signs.
+
+00:02:26.880 --> 00:02:32.399
+A command can have both Eshell and Lisp expressions.
+
+00:02:32.400 --> 00:02:34.559
+As you can see here,
+
+00:02:34.560 --> 00:02:37.119
+I have a call to ripgrep,
+
+00:02:37.120 --> 00:02:40.319
+but part of it is an s-expression.
+
+00:02:40.320 --> 00:02:42.239
+Remember the differences:
+
+00:02:42.240 --> 00:02:46.159
+With parens, eshell treats it as Lisp,
+
+00:02:46.160 --> 00:02:49.199
+like the last line in my example.
+
+00:02:49.200 --> 00:02:53.919
+With braces, eshell follows these shell-like rules:
+
+00:02:53.920 --> 00:02:57.159
+First, if it looks like a number, it's a number.
+
+00:02:57.160 --> 00:02:59.439
+Otherwise, eshell converts it to a string
+
+00:02:59.440 --> 00:03:03.679
+(quotes, like a shell, groups words).
+
+00:03:03.680 --> 00:03:07.519
+What about this mix between functions and executables
+
+00:03:07.520 --> 00:03:10.839
+for the first word?
+
+00:03:10.840 --> 00:03:15.439
+Functions that begin with eshell are called first.
+
+00:03:15.440 --> 00:03:19.079
+Next in priority are executables on your $PATH,
+
+00:03:19.080 --> 00:03:22.159
+then matching Lisp functions.
+
+00:03:22.160 --> 00:03:23.940
+You can actually switch this order
+
+00:03:23.941 --> 00:03:27.559
+with the `eshell-prefer-lisp-functions' variable.
+
+NOTE 4. Emacs is better than shell
+
+00:03:27.560 --> 00:03:31.759
+4. Emacs is actually better than shell.
+
+00:03:31.760 --> 00:03:35.199
+If the following works, why would you call
+
+00:03:35.200 --> 00:03:40.039
+expr or bc or dc, or any of those other calculators?
+
+00:03:40.040 --> 00:03:43.639
+You can just call a Lisp expression.
+
+00:03:43.640 --> 00:03:47.999
+Why call less or more when you could call view-file?
+
+00:03:48.000 --> 00:03:52.839
+Here, I’ve aliased less to view-file.
+
+00:03:52.840 --> 00:03:57.559
+Load it up, and it shows up in an Emacs mode.
+
+00:03:57.560 --> 00:04:01.519
+Just like with less, if you hit q,
+
+00:04:01.520 --> 00:04:05.759
+you go back to your Eshell terminal.
+
+00:04:05.760 --> 00:04:08.439
+I do have an improvement, though.
+
+00:04:08.440 --> 00:04:10.479
+The problem with view-file is
+
+00:04:10.480 --> 00:04:13.399
+it takes a single file as an argument.
+
+00:04:13.400 --> 00:04:15.719
+In a shell, we might want to view more than one.
+
+00:04:15.720 --> 00:04:18.719
+So let’s make a solution to that.
+
+00:04:18.720 --> 00:04:20.999
+This function will call the first function
+
+00:04:21.000 --> 00:04:22.159
+with the first argument,
+
+00:04:22.160 --> 00:04:26.679
+and the second function with each of the rest.
+
+00:04:26.680 --> 00:04:29.559
+This allows me to make a version of less
+
+00:04:29.560 --> 00:04:33.159
+that calls view-file on the first [argument] given,
+
+00:04:33.160 --> 00:04:36.079
+but open in another window for each additional file.
+
+NOTE 5. Better regular expressions
+
+00:04:36.080 --> 00:04:41.239
+5. Better regular expressions.
+
+00:04:41.240 --> 00:04:44.799
+Can’t remember regular expressions when calling
+
+00:04:44.800 --> 00:04:48.639
+grep or some other search function? Use the rx macro.
+
+00:04:48.640 --> 00:04:55.919
+Here I call ripgrep again, but this time,
+
+00:04:55.920 --> 00:05:00.679
+I’m using a Lisp expression calling the rx macro
+
+00:05:00.680 --> 00:05:04.719
+to look for UUIDs in the files in my current directory.
+
+00:05:04.720 --> 00:05:08.159
+But I have another improvement for this.
+
+00:05:08.160 --> 00:05:13.479
+While the rx macro is freaking cool for Emacs Lisp,
+
+00:05:13.480 --> 00:05:15.919
+it doesn’t always translate to regular expressions
+
+00:05:15.920 --> 00:05:20.079
+accepted by most commands.
+
+00:05:20.080 --> 00:05:25.199
+The (I have no idea how to pronounce this) pcre2el project
+
+00:05:25.200 --> 00:05:28.519
+can convert from a Lisp regular expression
+
+00:05:28.520 --> 00:05:31.359
+to Perl-compatible regular expressions (PCRE)
+
+00:05:31.360 --> 00:05:33.519
+acceptable by most search commands.
+
+00:05:33.520 --> 00:05:37.879
+I’ve created a new macro here, prx,
+
+00:05:37.880 --> 00:05:41.319
+that translates the output of the rx macro.
+
+00:05:41.320 --> 00:05:46.519
+This allows me to type something much more readable,
+
+00:05:46.520 --> 00:05:48.519
+and probably easier to remember.
+
+00:05:48.520 --> 00:05:54.679
+Certainly easier than this freaking regular expression.
+
+00:05:54.680 --> 00:05:59.439
+I’ve got an even better improvement.
+
+00:05:59.440 --> 00:06:03.559
+The rx macro with regular expression snippets
+
+00:06:03.560 --> 00:06:05.759
+can be assigned to key words
+
+00:06:05.760 --> 00:06:08.679
+that I can then take advantage of.
+
+00:06:08.680 --> 00:06:13.479
+Now our command would be much simpler to type.
+
+NOTE 6. Loops are better with predicates
+
+00:06:13.480 --> 00:06:16.159
+6. Loops are better with predicates.
+
+00:06:16.160 --> 00:06:18.759
+Let’s say you want to remove the execute bit
+
+00:06:18.760 --> 00:06:20.479
+from files that have it.
+
+00:06:20.480 --> 00:06:24.399
+In a shell like bash, you need both a for loop and an if,
+
+00:06:24.400 --> 00:06:26.599
+as you can see in this example.
+
+00:06:26.600 --> 00:06:31.559
+With eshell, use a predicate to combine into a simple loop.
+
+00:06:31.560 --> 00:06:34.359
+The paren x after a file glob
+
+00:06:34.360 --> 00:06:36.879
+filters for only files marked as executable.
+
+00:06:36.880 --> 00:06:43.559
+Now here is another improvement.
+
+00:06:43.560 --> 00:06:47.959
+Since we often type loops to execute on one command,
+
+00:06:47.960 --> 00:06:49.519
+what about creating a function
+
+00:06:49.520 --> 00:06:50.999
+that can do this all in one go?
+
+00:06:51.000 --> 00:06:57.599
+This do function splits the arguments on that double colon,
+
+00:06:57.600 --> 00:07:00.079
+where the left side is a single statement to run,
+
+00:07:00.080 --> 00:07:02.599
+and the right side is a list of files.
+
+00:07:02.600 --> 00:07:05.839
+I have to append and flatten it
+
+00:07:05.840 --> 00:07:07.639
+in order for it to work.
+
+00:07:07.640 --> 00:07:09.399
+It loops through each file,
+
+00:07:09.400 --> 00:07:12.079
+creating an eshell command with the file appended.
+
+00:07:12.080 --> 00:07:15.759
+With this, I can remove the execute bit
+
+00:07:15.760 --> 00:07:20.759
+on all CSV files that have it.
+
+00:07:20.760 --> 00:07:24.319
+I see that my example wasn’t too good, as most commands
+
+00:07:24.320 --> 00:07:29.039
+like chmod accept multiple files, but you get the idea.
+
+00:07:29.040 --> 00:07:33.159
+In my final, larger form on my website,
+
+00:07:33.160 --> 00:07:35.279
+I don’t assume the command expression accepts
+
+00:07:35.280 --> 00:07:36.719
+a file as a final argument,
+
+00:07:36.720 --> 00:07:39.639
+as I can also replace underscores with the filename.
+
+NOTE 7. Output of last command
+
+00:07:39.640 --> 00:07:45.399
+7. Output of last command.
+
+00:07:45.400 --> 00:07:48.799
+Most shells have a special variable
+
+00:07:48.800 --> 00:07:52.839
+like $? for the exit code of the last command.
+
+00:07:52.840 --> 00:07:55.919
+While reading through the source code,
+
+00:07:55.920 --> 00:07:58.799
+I noticed that the $$ refers to
+
+00:07:58.800 --> 00:08:00.599
+the output of the last command.
+
+00:08:00.600 --> 00:08:05.799
+This seems pretty cool.
+
+00:08:05.800 --> 00:08:10.759
+However, Eshell returns true or nil
+
+00:08:10.760 --> 00:08:12.719
+when running external commands,
+
+00:08:12.720 --> 00:08:15.879
+so accessing the output from a call to ls
+
+00:08:15.880 --> 00:08:19.479
+doesn’t work as expected.
+
+00:08:19.480 --> 00:08:21.119
+But this is Emacs.
+
+00:08:21.120 --> 00:08:23.159
+We can fix that.
+
+00:08:23.160 --> 00:08:28.119
+After running any command, eshell sets these four variables.
+
+00:08:28.120 --> 00:08:33.519
+I can hook a function call after every Eshell command.
+
+00:08:33.520 --> 00:08:36.759
+Using buffer-substring,
+
+00:08:36.760 --> 00:08:39.279
+I store the output into a global variable,
+
+00:08:39.280 --> 00:08:43.599
+and extend Eshell’s special variables list.
+
+00:08:43.600 --> 00:08:46.519
+In my Emacs configuration,
+
+00:08:46.520 --> 00:08:48.479
+I turned this variable into a ring,
+
+00:08:48.480 --> 00:08:51.439
+so while $$ works,
+
+00:08:51.440 --> 00:08:54.399
+so does array sub-scripting on that variable.
+
+00:08:54.400 --> 00:08:58.399
+This allows me to run a command
+
+00:08:58.400 --> 00:09:02.279
+and use the output from that command more than once.
+
+00:09:02.280 --> 00:09:05.279
+The code for this is a bit longer,
+
+00:09:05.280 --> 00:09:08.519
+so you’ll need to see my Emacs configuration for details.
+
+NOTE 8. Redirection back to Emacs
+
+00:09:08.520 --> 00:09:13.439
+8. Redirection back to Emacs.
+
+00:09:13.440 --> 00:09:14.879
+Output of any command
+
+00:09:14.880 --> 00:09:18.519
+can go to kill-ring (or the clipboard).
+
+00:09:18.520 --> 00:09:21.079
+Think of the implications.
+
+00:09:21.080 --> 00:09:23.839
+You don’t have to go into text selection mode.
+
+00:09:23.840 --> 00:09:26.239
+Just grab the output.
+
+00:09:26.240 --> 00:09:30.279
+In fact, with our $$ improvement,
+
+00:09:30.280 --> 00:09:33.239
+we can always copy the output from the last command
+
+00:09:33.240 --> 00:09:34.079
+to the clipboard.
+
+00:09:34.080 --> 00:09:37.999
+Better yet, let’s write the output
+
+00:09:38.000 --> 00:09:39.399
+to our engineering notebook.
+
+00:09:39.400 --> 00:09:41.679
+Here’s my idea.
+
+00:09:41.680 --> 00:09:46.079
+First, create a capture template that takes a string,
+
+00:09:46.080 --> 00:09:48.199
+or if called interactively, the region,
+
+00:09:48.200 --> 00:09:51.879
+and that does an immediate-finish after inserting
+
+00:09:51.880 --> 00:09:53.879
+that string to the default notes file.
+
+00:09:53.880 --> 00:09:57.679
+Next, create a wrapper function
+
+00:09:57.680 --> 00:10:01.559
+to call org-capture-string to run that template.
+
+00:10:01.560 --> 00:10:07.639
+Finally, we add our new function to eshell-virtual-targets.
+
+00:10:07.640 --> 00:10:08.759
+Let’s see this in action.
+
+00:10:08.760 --> 00:10:15.707
+I have a CSV file of user information.
+
+00:10:15.708 --> 00:10:19.719
+I can use grep and cut to extract some of that
+
+00:10:19.720 --> 00:10:26.879
+and write it out to this month’s engineering notebook.
+
+NOTE 9. Using Emacs buffers
+
+00:10:26.880 --> 00:10:35.279
+9. Using Emacs buffers.
+
+00:10:35.280 --> 00:10:39.159
+Why leave the results of eshell commands
+
+00:10:39.160 --> 00:10:40.279
+in the *eshell* buffer?
+
+00:10:40.280 --> 00:10:44.119
+Send the output into a buffer where you can use it.
+
+00:10:44.120 --> 00:10:47.999
+Here’s a call to ripgrep
+
+00:10:48.000 --> 00:10:50.759
+that searches for lines with email addresses
+
+00:10:50.760 --> 00:10:53.519
+using a complicated regular expression
+
+00:10:53.520 --> 00:10:56.079
+that I added to my prx macro.
+
+00:10:56.080 --> 00:11:01.079
+When I switch to this almost-grep buffer,
+
+00:11:01.080 --> 00:11:03.319
+I can turn on grep-mode.
+
+00:11:03.320 --> 00:11:09.039
+Now I can jump around as if I just called grep directly.
+
+00:11:09.040 --> 00:11:14.759
+Perhaps I’m proficient with my prx macro
+
+00:11:14.760 --> 00:11:16.639
+to filter out entries,
+
+00:11:16.640 --> 00:11:19.279
+but not good with shell commands
+
+00:11:19.280 --> 00:11:23.999
+that I can use in pipes to extract just one…
+
+00:11:24.000 --> 00:11:26.039
+the address column, for instance?
+
+00:11:26.040 --> 00:11:28.959
+Let’s just extract it,
+
+00:11:28.960 --> 00:11:33.279
+send it to a buffer called email-list,
+
+00:11:33.280 --> 00:11:38.479
+and now I can use Emacs commands that I know and love
+
+00:11:38.480 --> 00:11:39.799
+to edit the data directly.
+
+00:11:39.800 --> 00:11:55.799
+We currently have an over-sight
+
+00:11:55.800 --> 00:11:58.839
+that the Eshell’s built-in cat command
+
+00:11:58.840 --> 00:12:02.719
+doesn’t pipe buffer contents as standard in.
+
+00:12:02.720 --> 00:12:07.919
+So I created a bcat, a buffer cat, function to do this.
+
+00:12:07.920 --> 00:12:09.879
+So this command works
+
+00:12:09.880 --> 00:12:14.599
+to grab my email addresses I just extracted
+
+00:12:14.600 --> 00:12:16.319
+and send them to another program.
+
+00:12:16.320 --> 00:12:20.959
+If you’re interested, I have a more elaborate
+
+00:12:20.960 --> 00:12:25.759
+and yet simpler workflow surrounding sending data
+
+00:12:25.760 --> 00:12:28.399
+back and forth from Eshell to Emacs buffers.
+
+NOTE 10. cd to remote systems
+
+00:12:28.400 --> 00:12:35.679
+10. Did I mention that you can cd to remote systems?
+
+00:12:35.680 --> 00:12:39.879
+This command uses SSH to jump to my host, goblin,
+
+00:12:39.880 --> 00:12:44.039
+start a root session, and jump to the etc directory.
+
+00:12:44.040 --> 00:12:47.719
+Remember that Tramp can be finicky
+
+00:12:47.720 --> 00:12:52.839
+if you start blinging your remote hosts with oh-my-zshell,
+
+00:12:52.840 --> 00:12:57.790
+and funky prompts and things like that,
+
+00:12:57.791 --> 00:12:59.359
+so your mileage may vary.
+
+NOTE Summary
+
+00:12:59.360 --> 00:13:03.959
+In summary: Use eshell if you want
+
+00:13:03.960 --> 00:13:07.319
+a quick way to run commands and Emacs functions as a REPL,
+
+00:13:07.320 --> 00:13:11.479
+or to run an OS program but process the output with Emacs.
+
+00:13:11.480 --> 00:13:15.919
+Keep in mind that Eshell has two types of subshells,
+
+00:13:15.920 --> 00:13:19.599
+and you can mix and match during a command call.
+
+00:13:19.600 --> 00:13:22.639
+The rx macro is really cool.
+
+00:13:22.640 --> 00:13:26.599
+Eshell loops are better with filters and predicates …
+
+00:13:26.600 --> 00:13:28.239
+if you can remember them.
+
+00:13:28.240 --> 00:13:30.959
+Take advantage of Emacs buffers
+
+00:13:30.960 --> 00:13:32.879
+to really enhance your shell experience.
+
+00:13:32.880 --> 00:13:36.039
+You’ve now seen that just like Emacs,
+
+00:13:36.040 --> 00:13:39.519
+I’ve crafted Eshell to be my own shell creation,
+
+00:13:39.520 --> 00:13:41.039
+tailored to my workflow.
+
+00:13:41.040 --> 00:13:44.799
+So, steal my spells, cast your own magic,
+
+00:13:44.800 --> 00:13:48.759
+but feel free to share your incantations back to me.
+
+00:13:48.760 --> 00:13:51.359
+I’ve gone over my time allotment, so we’ll have to
+
+00:13:51.360 --> 00:13:53.679
+continue this discussion on the intertubes.
+
+00:13:53.680 --> 00:13:57.159
+Why yes, I have joined the birdless diaspora,
+
+00:13:57.160 --> 00:13:59.199
+so toot me over there.
+
+00:13:59.200 --> 00:14:01.920
+Thanks.
diff --git a/2022/info/eshell-after.md b/2022/info/eshell-after.md
index d805b442..b346fc15 100644
--- a/2022/info/eshell-after.md
+++ b/2022/info/eshell-after.md
@@ -1,6 +1,251 @@
<!-- Automatically generated by emacsconf-publish-after-page -->
+<a name="eshell-mainVideo-transcript"></a>
+# Transcript
+
+[[!template new="1" text="""I have 10 minutes to talk you into""" start="00:00:00.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""giving Eshell a second chance.""" start="00:00:05.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Have the right perspective and expectation,""" start="00:00:07.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and I think you’ll really enjoy it.""" start="00:00:10.120" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Just remember eshell is a shell,""" start="00:00:12.920" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""not a terminal emulator.""" start="00:00:15.680" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I use both Eshell and vterm.""" start="00:00:17.840" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I’m going to talk and type fast,""" start="00:00:20.280" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""as I have 10 reasons for you to try Eshell again.""" start="00:00:23.480" video="mainVideo-eshell" id="subtitle"]]
+[[!template new="1" text="""1. It’s an Emacs REPL.""" start="00:00:29.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I mean, check this out.""" start="00:00:32.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Let’s start up Eshell here.""" start="00:00:34.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Let’s just type a Lisp expression.""" start="00:00:37.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""It works.""" start="00:00:41.400" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""As a shell, the parens are kinda optional.""" start="00:00:43.920" video="mainVideo-eshell" id="subtitle"]]
+[[!template new="1" text="""2. It’s also a shell.""" start="00:00:48.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""While eshell may look like a shell, like Bash""" start="00:00:52.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""you should view it as a REPL""" start="00:00:56.480" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""with parenthesis-less s-expressions.""" start="00:00:58.560" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""This makes sense, because a shell command with options,""" start="00:01:02.400" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""like this ls command,""" start="00:01:05.560" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""looks like an s-expression.""" start="00:01:08.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template new="1" text="""3. You can mix these two modes.""" start="00:01:10.120" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Shells can call subshells""" start="00:01:12.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""which return their output like a function call,""" start="00:01:14.960" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""like this Bash command.""" start="00:01:17.920" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""In this Eshell example,""" start="00:01:20.800" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I use the output of a text file""" start="00:01:22.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""as command line arguments to ripgrep.""" start="00:01:24.640" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Notice how I use braces""" start="00:01:27.960" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""to state that it is a call to an eshell expression.""" start="00:01:29.640" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""We can mix Lisp-expressions and Shell-expressions.""" start="00:01:34.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Allow me a contrived example.""" start="00:01:40.040" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Notice I use good ol' setq to create a variable.""" start="00:01:45.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Yes, those are global Emacs variables available everywhere.""" start="00:01:50.080" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""In Eshell, the wildcard actually creates a list.""" start="00:01:54.920" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""This variable assignment doesn’t work as you might expect,""" start="00:01:59.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""as setq in Eshell is still setq,""" start="00:02:04.480" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and it assigns variables in pairs.""" start="00:02:07.560" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""To make a list in Eshell, we use listify:""" start="00:02:10.320" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Without parens, Eshell is in “shell mode”,""" start="00:02:17.120" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""which means that words are strings,""" start="00:02:21.240" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and variables need to be prefixed with dollar signs.""" start="00:02:23.800" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""A command can have both Eshell and Lisp expressions.""" start="00:02:26.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""As you can see here,""" start="00:02:32.400" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I have a call to ripgrep,""" start="00:02:34.560" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""but part of it is an s-expression.""" start="00:02:37.120" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Remember the differences:""" start="00:02:40.320" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""With parens, eshell treats it as Lisp,""" start="00:02:42.240" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""like the last line in my example.""" start="00:02:46.160" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""With braces, eshell follows these shell-like rules:""" start="00:02:49.200" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""First, if it looks like a number, it's a number.""" start="00:02:53.920" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Otherwise, eshell converts it to a string""" start="00:02:57.160" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""(quotes, like a shell, groups words).""" start="00:02:59.440" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""What about this mix between functions and executables""" start="00:03:03.680" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""for the first word?""" start="00:03:07.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Functions that begin with eshell are called first.""" start="00:03:10.840" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Next in priority are executables on your $PATH,""" start="00:03:15.440" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""then matching Lisp functions.""" start="00:03:19.080" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""You can actually switch this order""" start="00:03:22.160" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""with the `eshell-prefer-lisp-functions' variable.""" start="00:03:23.941" video="mainVideo-eshell" id="subtitle"]]
+[[!template new="1" text="""4. Emacs is actually better than shell.""" start="00:03:27.560" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""If the following works, why would you call""" start="00:03:31.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""expr or bc or dc, or any of those other calculators?""" start="00:03:35.200" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""You can just call a Lisp expression.""" start="00:03:40.040" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Why call less or more when you could call view-file?""" start="00:03:43.640" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Here, I’ve aliased less to view-file.""" start="00:03:48.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Load it up, and it shows up in an Emacs mode.""" start="00:03:52.840" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Just like with less, if you hit q,""" start="00:03:57.560" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""you go back to your Eshell terminal.""" start="00:04:01.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I do have an improvement, though.""" start="00:04:05.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""The problem with view-file is""" start="00:04:08.440" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""it takes a single file as an argument.""" start="00:04:10.480" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""In a shell, we might want to view more than one.""" start="00:04:13.400" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""So let’s make a solution to that.""" start="00:04:15.720" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""This function will call the first function""" start="00:04:18.720" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""with the first argument,""" start="00:04:21.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and the second function with each of the rest.""" start="00:04:22.160" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""This allows me to make a version of less""" start="00:04:26.680" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""that calls view-file on the first [argument] given,""" start="00:04:29.560" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""but open in another window for each additional file.""" start="00:04:33.160" video="mainVideo-eshell" id="subtitle"]]
+[[!template new="1" text="""5. Better regular expressions.""" start="00:04:36.080" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Can’t remember regular expressions when calling""" start="00:04:41.240" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""grep or some other search function? Use the rx macro.""" start="00:04:44.800" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Here I call ripgrep again, but this time,""" start="00:04:48.640" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I’m using a Lisp expression calling the rx macro""" start="00:04:55.920" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""to look for UUIDs in the files in my current directory.""" start="00:05:00.680" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""But I have another improvement for this.""" start="00:05:04.720" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""While the rx macro is freaking cool for Emacs Lisp,""" start="00:05:08.160" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""it doesn’t always translate to regular expressions""" start="00:05:13.480" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""accepted by most commands.""" start="00:05:15.920" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""The (I have no idea how to pronounce this) pcre2el project""" start="00:05:20.080" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""can convert from a Lisp regular expression""" start="00:05:25.200" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""to Perl-compatible regular expressions (PCRE)""" start="00:05:28.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""acceptable by most search commands.""" start="00:05:31.360" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I’ve created a new macro here, prx,""" start="00:05:33.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""that translates the output of the rx macro.""" start="00:05:37.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""This allows me to type something much more readable,""" start="00:05:41.320" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and probably easier to remember.""" start="00:05:46.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Certainly easier than this freaking regular expression.""" start="00:05:48.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I’ve got an even better improvement.""" start="00:05:54.680" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""The rx macro with regular expression snippets""" start="00:05:59.440" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""can be assigned to key words""" start="00:06:03.560" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""that I can then take advantage of.""" start="00:06:05.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Now our command would be much simpler to type.""" start="00:06:08.680" video="mainVideo-eshell" id="subtitle"]]
+[[!template new="1" text="""6. Loops are better with predicates.""" start="00:06:13.480" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Let’s say you want to remove the execute bit""" start="00:06:16.160" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""from files that have it.""" start="00:06:18.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""In a shell like bash, you need both a for loop and an if,""" start="00:06:20.480" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""as you can see in this example.""" start="00:06:24.400" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""With eshell, use a predicate to combine into a simple loop.""" start="00:06:26.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""The paren x after a file glob""" start="00:06:31.560" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""filters for only files marked as executable.""" start="00:06:34.360" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Now here is another improvement.""" start="00:06:36.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Since we often type loops to execute on one command,""" start="00:06:43.560" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""what about creating a function""" start="00:06:47.960" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""that can do this all in one go?""" start="00:06:49.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""This do function splits the arguments on that double colon,""" start="00:06:51.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""where the left side is a single statement to run,""" start="00:06:57.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and the right side is a list of files.""" start="00:07:00.080" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I have to append and flatten it""" start="00:07:02.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""in order for it to work.""" start="00:07:05.840" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""It loops through each file,""" start="00:07:07.640" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""creating an eshell command with the file appended.""" start="00:07:09.400" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""With this, I can remove the execute bit""" start="00:07:12.080" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""on all CSV files that have it.""" start="00:07:15.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I see that my example wasn’t too good, as most commands""" start="00:07:20.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""like chmod accept multiple files, but you get the idea.""" start="00:07:24.320" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""In my final, larger form on my website,""" start="00:07:29.040" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I don’t assume the command expression accepts""" start="00:07:33.160" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""a file as a final argument,""" start="00:07:35.280" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""as I can also replace underscores with the filename.""" start="00:07:36.720" video="mainVideo-eshell" id="subtitle"]]
+[[!template new="1" text="""7. Output of last command.""" start="00:07:39.640" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Most shells have a special variable""" start="00:07:45.400" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""like $? for the exit code of the last command.""" start="00:07:48.800" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""While reading through the source code,""" start="00:07:52.840" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I noticed that the $$ refers to""" start="00:07:55.920" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""the output of the last command.""" start="00:07:58.800" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""This seems pretty cool.""" start="00:08:00.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""However, Eshell returns true or nil""" start="00:08:05.800" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""when running external commands,""" start="00:08:10.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""so accessing the output from a call to ls""" start="00:08:12.720" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""doesn’t work as expected.""" start="00:08:15.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""But this is Emacs.""" start="00:08:19.480" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""We can fix that.""" start="00:08:21.120" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""After running any command, eshell sets these four variables.""" start="00:08:23.160" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I can hook a function call after every Eshell command.""" start="00:08:28.120" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Using buffer-substring,""" start="00:08:33.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I store the output into a global variable,""" start="00:08:36.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and extend Eshell’s special variables list.""" start="00:08:39.280" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""In my Emacs configuration,""" start="00:08:43.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I turned this variable into a ring,""" start="00:08:46.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""so while $$ works,""" start="00:08:48.480" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""so does array sub-scripting on that variable.""" start="00:08:51.440" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""This allows me to run a command""" start="00:08:54.400" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and use the output from that command more than once.""" start="00:08:58.400" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""The code for this is a bit longer,""" start="00:09:02.280" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""so you’ll need to see my Emacs configuration for details.""" start="00:09:05.280" video="mainVideo-eshell" id="subtitle"]]
+[[!template new="1" text="""8. Redirection back to Emacs.""" start="00:09:08.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Output of any command""" start="00:09:13.440" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""can go to kill-ring (or the clipboard).""" start="00:09:14.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Think of the implications.""" start="00:09:18.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""You don’t have to go into text selection mode.""" start="00:09:21.080" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Just grab the output.""" start="00:09:23.840" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""In fact, with our $$ improvement,""" start="00:09:26.240" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""we can always copy the output from the last command""" start="00:09:30.280" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""to the clipboard.""" start="00:09:33.240" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Better yet, let’s write the output""" start="00:09:34.080" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""to our engineering notebook.""" start="00:09:38.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Here’s my idea.""" start="00:09:39.400" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""First, create a capture template that takes a string,""" start="00:09:41.680" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""or if called interactively, the region,""" start="00:09:46.080" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and that does an immediate-finish after inserting""" start="00:09:48.200" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""that string to the default notes file.""" start="00:09:51.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Next, create a wrapper function""" start="00:09:53.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""to call org-capture-string to run that template.""" start="00:09:57.680" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Finally, we add our new function to eshell-virtual-targets.""" start="00:10:01.560" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Let’s see this in action.""" start="00:10:07.640" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I have a CSV file of user information.""" start="00:10:08.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I can use grep and cut to extract some of that""" start="00:10:15.708" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and write it out to this month’s engineering notebook.""" start="00:10:19.720" video="mainVideo-eshell" id="subtitle"]]
+[[!template new="1" text="""9. Using Emacs buffers.""" start="00:10:26.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Why leave the results of eshell commands""" start="00:10:35.280" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""in the *eshell* buffer?""" start="00:10:39.160" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Send the output into a buffer where you can use it.""" start="00:10:40.280" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Here’s a call to ripgrep""" start="00:10:44.120" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""that searches for lines with email addresses""" start="00:10:48.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""using a complicated regular expression""" start="00:10:50.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""that I added to my prx macro.""" start="00:10:53.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""When I switch to this almost-grep buffer,""" start="00:10:56.080" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I can turn on grep-mode.""" start="00:11:01.080" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Now I can jump around as if I just called grep directly.""" start="00:11:03.320" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Perhaps I’m proficient with my prx macro""" start="00:11:09.040" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""to filter out entries,""" start="00:11:14.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""but not good with shell commands""" start="00:11:16.640" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""that I can use in pipes to extract just one…""" start="00:11:19.280" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""the address column, for instance?""" start="00:11:24.000" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Let’s just extract it,""" start="00:11:26.040" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""send it to a buffer called email-list,""" start="00:11:28.960" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and now I can use Emacs commands that I know and love""" start="00:11:33.280" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""to edit the data directly.""" start="00:11:38.480" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""We currently have an over-sight""" start="00:11:39.800" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""that the Eshell’s built-in cat command""" start="00:11:55.800" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""doesn’t pipe buffer contents as standard in.""" start="00:11:58.840" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""So I created a bcat, a buffer cat, function to do this.""" start="00:12:02.720" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""So this command works""" start="00:12:07.920" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""to grab my email addresses I just extracted""" start="00:12:09.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and send them to another program.""" start="00:12:14.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""If you’re interested, I have a more elaborate""" start="00:12:16.320" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and yet simpler workflow surrounding sending data""" start="00:12:20.960" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""back and forth from Eshell to Emacs buffers.""" start="00:12:25.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template new="1" text="""10. Did I mention that you can cd to remote systems?""" start="00:12:28.400" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""This command uses SSH to jump to my host, goblin,""" start="00:12:35.680" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""start a root session, and jump to the etc directory.""" start="00:12:39.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Remember that Tramp can be finicky""" start="00:12:44.040" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""if you start blinging your remote hosts with oh-my-zshell,""" start="00:12:47.720" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and funky prompts and things like that,""" start="00:12:52.840" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""so your mileage may vary.""" start="00:12:57.791" video="mainVideo-eshell" id="subtitle"]]
+[[!template new="1" text="""In summary: Use eshell if you want""" start="00:12:59.360" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""a quick way to run commands and Emacs functions as a REPL,""" start="00:13:03.960" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""or to run an OS program but process the output with Emacs.""" start="00:13:07.320" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Keep in mind that Eshell has two types of subshells,""" start="00:13:11.480" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""and you can mix and match during a command call.""" start="00:13:15.920" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""The rx macro is really cool.""" start="00:13:19.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Eshell loops are better with filters and predicates …""" start="00:13:22.640" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""if you can remember them.""" start="00:13:26.600" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Take advantage of Emacs buffers""" start="00:13:28.240" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""to really enhance your shell experience.""" start="00:13:30.960" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""You’ve now seen that just like Emacs,""" start="00:13:32.880" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I’ve crafted Eshell to be my own shell creation,""" start="00:13:36.040" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""tailored to my workflow.""" start="00:13:39.520" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""So, steal my spells, cast your own magic,""" start="00:13:41.040" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""but feel free to share your incantations back to me.""" start="00:13:44.800" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""I’ve gone over my time allotment, so we’ll have to""" start="00:13:48.760" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""continue this discussion on the intertubes.""" start="00:13:51.360" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Why yes, I have joined the birdless diaspora,""" start="00:13:53.680" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""so toot me over there.""" start="00:13:57.160" video="mainVideo-eshell" id="subtitle"]]
+[[!template text="""Thanks.""" start="00:13:59.200" video="mainVideo-eshell" id="subtitle"]]
+
+
+
+Captioner: howard
Questions or comments? Please e-mail [emacsconf-org-private@gnu.org](mailto:emacsconf-org-private@gnu.org?subject=Comment%20for%20EmacsConf%202022%20eshell%3A%20Top%2010%20reasons%20why%20you%20should%20be%20using%20Eshell)
diff --git a/2022/info/eshell-before.md b/2022/info/eshell-before.md
index 2a0a08fd..2b5206fd 100644
--- a/2022/info/eshell-before.md
+++ b/2022/info/eshell-before.md
@@ -3,16 +3,38 @@ In this talk, Howard Abrams shows how eshell combines the best of Emacs Lisp and
The following image shows where the talk is in the schedule for Sun 2022-12-04. Solid lines show talks with Q&A via BigBlueButton. Dashed lines show talks with Q&A via IRC or Etherpad.<div class="schedule-in-context schedule-svg-container" data-slug="eshell">
-<svg width="800" height="150" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title> Schedule for Sunday</title> <rect width="800" height="150" x="0" y="0" fill="white"></rect> <text font-size="10" fill="black" y="12" x="3"> Sunday</text> <a href="/2022/talks/sun-open" title="Sunday opening remarks" data-slug="sun-open"> <title> 9:00- 9:05 Sunday opening remarks</title> <rect x="0" y="15" opacity="0.5" width="7" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(5,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> sun-open</text></g></a> <a href="/2022/talks/survey" title="Results of the 2022 Emacs Survey" data-slug="survey"> <title> 9:05- 9:25 Results of the 2022 Emacs Survey</title> <rect x="7" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(36,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> survey</text></g></a> <a href="/2022/talks/orgyear" title="This Year in Org" data-slug="orgyear"> <title> 9:35- 9:45 This Year in Org</title> <rect x="54" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(67,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> orgyear</text></g></a> <a href="/2022/talks/rolodex" title="Build a Zettelkasten with the Hyperbole Rolodex" data-slug="rolodex"> <title> 9:55-10:20 Build a Zettelkasten with the Hyperbole Rolodex</title> <rect x="86" y="15" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(123,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> rolodex</text></g></a> <a href="/2022/talks/orgsuperlinks" title="Linking headings with org-super-links (poor-man's Zettelkasten)" data-slug="orgsuperlinks"> <title> 10:40-10:50 Linking headings with org-super-links (poor-man's Zettelkasten)</title> <rect x="156" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(169,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> orgsuperlinks</text></g></a> <a href="/2022/talks/orgvm" title="orgvm: a simple HTTP server for org" data-slug="orgvm"> <title> 11:10-11:20 orgvm: a simple HTTP server for org</title> <rect x="203" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(216,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> orgvm</text></g></a> <a href="/2022/talks/hyperorg" title="Powerful productivity with Hyperbole and Org Mode" data-slug="hyperorg"> <title> 1:00- 1:30 Powerful productivity with Hyperbole and Org Mode</title> <rect x="376" y="15" opacity="0.5" width="47" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(421,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> hyperorg</text></g></a> <a href="/2022/talks/workflows" title="Org workflows for developers" data-slug="workflows"> <title> 1:50- 2:15 Org workflows for developers</title> <rect x="454" y="15" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(491,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> workflows</text></g></a> <a href="/2022/talks/grail" title="GRAIL---A Generalized Representation and Aggregation of Information Layers" data-slug="grail"> <title> 2:35- 2:55 GRAIL---A Generalized Representation and Aggregation of Information Layers</title> <rect x="525" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(554,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> grail</text></g></a> <a href="/2022/talks/indieweb" title="Putting Org Mode on the Indieweb" data-slug="indieweb"> <title> 3:25- 3:45 Putting Org Mode on the Indieweb</title> <rect x="603" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(632,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> indieweb</text></g></a> <a href="/2022/talks/devel" title="Emacs development updates" data-slug="devel"> <title> 4:05- 4:15 Emacs development updates</title> <rect x="666" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(679,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> devel</text></g></a> <a href="/2022/talks/fanfare" title="Fanfare for the Common Emacs User" data-slug="fanfare"> <title> 4:25- 4:35 Fanfare for the Common Emacs User</title> <rect x="698" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(711,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> fanfare</text></g></a> <a href="/2022/talks/sun-close" title="Sunday closing remarks" data-slug="sun-close"> <title> 4:50- 5:00 Sunday closing remarks</title> <rect x="737" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(750,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> sun-close</text></g></a> <a href="/2022/talks/rde" title="rde Emacs introduction" data-slug="rde"> <title> 10:00-10:25 rde Emacs introduction</title> <rect x="94" y="75" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(131,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> rde</text></g></a> <a href="/2022/talks/justl" title="justl: Driving recipes within Emacs" data-slug="justl"> <title> 10:50-11:05 justl: Driving recipes within Emacs</title> <rect x="172" y="75" opacity="0.5" width="23" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(193,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> justl</text></g></a> <a href="/2022/talks/rms" title="What I'd like to see in Emacs" data-slug="rms"> <title> 11:15-11:35 What I'd like to see in Emacs</title> <rect x="211" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(240,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> rms</text></g></a> <a href="/2022/talks/detached" title="Getting detached from Emacs" data-slug="detached"> <title> 1:00- 1:15 Getting detached from Emacs</title> <rect x="376" y="75" opacity="0.5" width="23" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(397,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> detached</text></g></a> <a href="/2022/talks/eshell" title="Top 10 reasons why you should be using Eshell" data-slug="eshell"> <title> 1:40- 1:55 Top 10 reasons why you should be using Eshell</title> <rect stroke-width="3" x="439" y="75" opacity="0.8" width="23" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(460,133)"> <text font-weight="bold" fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> eshell</text></g></a> <a href="/2022/talks/async" title="Emacs was async before async was cool" data-slug="async"> <title> 2:20- 2:40 Emacs was async before async was cool</title> <rect x="501" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(530,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> async</text></g></a> <a href="/2022/talks/dbus" title="The Wheels on D-Bus" data-slug="dbus"> <title> 3:15- 3:35 The Wheels on D-Bus</title> <rect x="588" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(617,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> dbus</text></g></a> <a href="/2022/talks/localizing" title="Pre-localizing Emacs" data-slug="localizing"> <title> 4:00- 4:10 Pre-localizing Emacs</title> <rect x="658" y="75" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(671,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> localizing</text></g></a> <a href="/2022/talks/python" title="Short hyperlinks to Python docs" data-slug="python"> <title> 4:30- 4:35 Short hyperlinks to Python docs</title> <rect x="705" y="75" opacity="0.5" width="7" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(710,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> python</text></g></a> <g transform="translate(0,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 9 AM</text></g> <g transform="translate(94,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 10 AM</text></g> <g transform="translate(188,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 11 AM</text></g> <g transform="translate(282,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 12 PM</text></g> <g transform="translate(376,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 1 PM</text></g> <g transform="translate(470,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 2 PM</text></g> <g transform="translate(564,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 3 PM</text></g> <g transform="translate(658,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 4 PM</text></g> <g transform="translate(752,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 5 PM</text></g></svg>
+<svg width="800" height="150" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title> Schedule for Sunday</title> <rect width="800" height="150" x="0" y="0" fill="white"></rect> <text font-size="10" fill="black" y="12" x="3"> Sunday</text> <a href="/2022/talks/sun-open" title="Sunday opening remarks" data-slug="sun-open"> <title> 9:00- 9:05 Sunday opening remarks</title> <rect x="0" y="15" opacity="0.5" width="7" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(5,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> sun-open</text></g></a> <a href="/2022/talks/survey" title="Results of the 2022 Emacs Survey" data-slug="survey"> <title> 9:06- 9:26 Results of the 2022 Emacs Survey</title> <rect x="9" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(38,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> survey</text></g></a> <a href="/2022/talks/orgyear" title="This Year in Org" data-slug="orgyear"> <title> 9:35- 9:45 This Year in Org</title> <rect x="54" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(67,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> orgyear</text></g></a> <a href="/2022/talks/rolodex" title="Build a Zettelkasten with the Hyperbole Rolodex" data-slug="rolodex"> <title> 9:57-10:22 Build a Zettelkasten with the Hyperbole Rolodex</title> <rect x="89" y="15" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(126,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> rolodex</text></g></a> <a href="/2022/talks/orgsuperlinks" title="Linking headings with org-super-links (poor-man's Zettelkasten)" data-slug="orgsuperlinks"> <title> 10:40-10:50 Linking headings with org-super-links (poor-man's Zettelkasten)</title> <rect x="156" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(169,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> orgsuperlinks</text></g></a> <a href="/2022/talks/orgvm" title="orgvm: a simple HTTP server for org" data-slug="orgvm"> <title> 11:10-11:20 orgvm: a simple HTTP server for org</title> <rect x="203" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(216,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> orgvm</text></g></a> <a href="/2022/talks/hyperorg" title="Powerful productivity with Hyperbole and Org Mode" data-slug="hyperorg"> <title> 1:00- 1:30 Powerful productivity with Hyperbole and Org Mode</title> <rect x="376" y="15" opacity="0.5" width="47" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(421,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> hyperorg</text></g></a> <a href="/2022/talks/workflows" title="Org workflows for developers" data-slug="workflows"> <title> 1:50- 2:15 Org workflows for developers</title> <rect x="454" y="15" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(491,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> workflows</text></g></a> <a href="/2022/talks/grail" title="GRAIL---A Generalized Representation and Aggregation of Information Layers" data-slug="grail"> <title> 2:35- 2:55 GRAIL---A Generalized Representation and Aggregation of Information Layers</title> <rect x="525" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(554,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> grail</text></g></a> <a href="/2022/talks/indieweb" title="Putting Org Mode on the Indieweb" data-slug="indieweb"> <title> 3:25- 3:45 Putting Org Mode on the Indieweb</title> <rect x="603" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(632,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> indieweb</text></g></a> <a href="/2022/talks/devel" title="Emacs development updates" data-slug="devel"> <title> 4:05- 4:15 Emacs development updates</title> <rect x="666" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(679,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> devel</text></g></a> <a href="/2022/talks/fanfare" title="Fanfare for the Common Emacs User" data-slug="fanfare"> <title> 4:25- 4:35 Fanfare for the Common Emacs User</title> <rect x="698" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(711,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> fanfare</text></g></a> <a href="/2022/talks/sun-close" title="Sunday closing remarks" data-slug="sun-close"> <title> 4:50- 5:00 Sunday closing remarks</title> <rect x="737" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(750,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> sun-close</text></g></a> <a href="/2022/talks/rde" title="rde Emacs introduction" data-slug="rde"> <title> 10:00-10:25 rde Emacs introduction</title> <rect x="94" y="75" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(131,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> rde</text></g></a> <a href="/2022/talks/justl" title="justl: Driving recipes within Emacs" data-slug="justl"> <title> 10:50-11:05 justl: Driving recipes within Emacs</title> <rect x="172" y="75" opacity="0.5" width="23" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(193,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> justl</text></g></a> <a href="/2022/talks/rms" title="What I'd like to see in Emacs" data-slug="rms"> <title> 11:15-11:35 What I'd like to see in Emacs</title> <rect x="211" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(240,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> rms</text></g></a> <a href="/2022/talks/detached" title="Getting detached from Emacs" data-slug="detached"> <title> 1:01- 1:16 Getting detached from Emacs</title> <rect x="378" y="75" opacity="0.5" width="23" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(399,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> detached</text></g></a> <a href="/2022/talks/eshell" title="Top 10 reasons why you should be using Eshell" data-slug="eshell"> <title> 1:40- 1:55 Top 10 reasons why you should be using Eshell</title> <rect stroke-width="3" x="439" y="75" opacity="0.8" width="23" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(460,133)"> <text font-weight="bold" fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> eshell</text></g></a> <a href="/2022/talks/async" title="Emacs was async before async was cool" data-slug="async"> <title> 2:20- 2:40 Emacs was async before async was cool</title> <rect x="501" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(530,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> async</text></g></a> <a href="/2022/talks/dbus" title="The Wheels on D-Bus" data-slug="dbus"> <title> 3:15- 3:35 The Wheels on D-Bus</title> <rect x="588" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(617,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> dbus</text></g></a> <a href="/2022/talks/localizing" title="Pre-localizing Emacs" data-slug="localizing"> <title> 4:00- 4:10 Pre-localizing Emacs</title> <rect x="658" y="75" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(671,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> localizing</text></g></a> <a href="/2022/talks/python" title="Short hyperlinks to Python docs" data-slug="python"> <title> 4:30- 4:35 Short hyperlinks to Python docs</title> <rect x="705" y="75" opacity="0.5" width="7" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(710,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> python</text></g></a> <g transform="translate(0,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 9 AM</text></g> <g transform="translate(94,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 10 AM</text></g> <g transform="translate(188,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 11 AM</text></g> <g transform="translate(282,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 12 PM</text></g> <g transform="translate(376,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 1 PM</text></g> <g transform="translate(470,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 2 PM</text></g> <g transform="translate(564,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 3 PM</text></g> <g transform="translate(658,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 4 PM</text></g> <g transform="translate(752,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 5 PM</text></g></svg>
</div>
[[!toc ]]
Format: 15-min talk followed by live Q&A (<https://emacsconf.org/current/eshell/room>)
Etherpad: <https://pad.emacsconf.org/2022-eshell>
Discuss on IRC: [#emacsconf-dev](https://chat.emacsconf.org/?join=emacsconf,emacsconf-dev)
-Status: Talk captioned
+Status: Now playing on the conference livestream
<div>Times in different timezones:</div><div class="times" start="2022-12-04T18:40:00Z" end="2022-12-04T18:55:00Z"><div class="conf-time">Sunday, Dec 4 2022, ~1:40 PM - 1:55 PM EST (US/Eastern)</div><div class="others"><div>which is the same as:</div>Sunday, Dec 4 2022, ~12:40 PM - 12:55 PM CST (US/Central)<br />Sunday, Dec 4 2022, ~11:40 AM - 11:55 AM MST (US/Mountain)<br />Sunday, Dec 4 2022, ~10:40 AM - 10:55 AM PST (US/Pacific)<br />Sunday, Dec 4 2022, ~6:40 PM - 6:55 PM UTC <br />Sunday, Dec 4 2022, ~7:40 PM - 7:55 PM CET (Europe/Paris)<br />Sunday, Dec 4 2022, ~8:40 PM - 8:55 PM EET (Europe/Athens)<br />Monday, Dec 5 2022, ~12:10 AM - 12:25 AM IST (Asia/Kolkata)<br />Monday, Dec 5 2022, ~2:40 AM - 2:55 AM +08 (Asia/Singapore)<br />Monday, Dec 5 2022, ~3:40 AM - 3:55 AM JST (Asia/Tokyo)</div></div><div><a href="/2022/watch/dev/">Find out how to watch and participate</a></div>
+[[!template id="vid" vidid="eshell-mainVideo" src="https://media.emacsconf.org/2022/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main.webm" poster="https://media.emacsconf.org/2022/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main.png" captions="""<track label="English" kind="captions" srclang="en" src="/2022/captions/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main.vtt" default />"""
+size="46M" duration="14:02" other_resources="""[Download --main.webm (45MB)](https://media.emacsconf.org/2022/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main.webm)
+[Download --main.vtt](https://media.emacsconf.org/2022/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main.vtt)
+[Download --main--chapters.vtt](https://media.emacsconf.org/2022/emacsconf-2022-eshell--top-10-reasons-why-you-should-be-using-eshell--howard-abrams--main--chapters.vtt)
+[View transcript](https://emacsconf.org/2022/talks/eshell#eshell-mainVideo-transcript)
+[View on Toobnix](https://toobnix.org/w/ndrA731VbY2U6SP8onw3yw)
+"""]]
+[[!template id="chapters" vidid="eshell-mainVideo" data="""
+00:00:00.000 Introduction
+00:29.000 1. It’s an Emacs REPL
+00:48.600 2. It’s also a shell
+01:10.120 3. You can mix these two modes
+03:27.560 4. Emacs is better than shell
+04:36.080 5. Better regular expressions
+06:13.480 6. Loops are better with predicates
+07:39.640 7. Output of last command
+09:08.520 8. Redirection back to Emacs
+10:26.880 9. Using Emacs buffers
+12:28.400 10. cd to remote systems
+12:59.360 Summary
+
+"""]]
# Description