14 comments

[ 2.0 ms ] story [ 49.8 ms ] thread
I wish someone could write a "The Good Parts" book for Emacs. Even after reading the manual twice, I'm still overwhelmed with the API and forget even the most basic configuration options after a month of inactivity.
> forget even the most basic configuration options after a month of inactivity

So do I. ChatGPT4o and the like of course do not forget, and they've read more documentation, library code, and message forum postings than any human could. They know all the five or so ways to initialize per-buffer variables and will write you little snippets of Elisp to add to your .emacs or .dir-locals.el or per-file headers/trailers.

So, if Org-mode or multi-occur aren't doing what I want, and `M-x info-emacs-manual` doesn't make it obvious, ChatGPT4o is my next recourse.

I've been using Emacs daily for well over a decade now, but I just can't get myself to use any of its shells, or features that replace standard shell workflows.

I think the main reason—besides muscle memory and the scripts, aliases, and commands I'm already used to—is because a POSIX-compliant shell exposes a generic interface for both programs and users. Programs can receive and output data over standard file descriptors. They have a CLI with common design conventions regarding flag and argument parsing. Some programs choose not to follow these conventions, and some have a very complex CLI, but for the most part users can expect a specific interface to exist. Man pages have a standard format, and way of accessing them for all programs. And so on. All compliant shells on Unix-like systems work in a similar way, which means that the workflows I'm already used to are easily transferrable to any other system.

Contrast this with the workflow table in TFA. It's a mishmash of different Emacs modes, each with their own quirks, UI, and ways of interacting with other modes. One could say that Elisp ties it all together, but it's a general purpose programming language which obviously doesn't enforce a cohesive user interface for packages to follow. Eshell even complicates this because it resembles a POSIX shell, but doesn't follow any Emacs interface guidelines, so it breaks conventions of both sides. Sure, I could force myself to learn the intricacies of each package over a long time, and create a cohesive Emacs configuration that works for me, but I would need to lug around that configuration and depend on Emacs for everything. Which I'm sure Emacs purists would claim is the way to go, but I don't like that. The beauty of Unix systems is the ability to easily replace any tool in your workflow without impacting everything else. For example, I've mostly replaced `ls` with `eza`, `grep` with `rg`, `find` with `fd`, `top` with `btop`, etc. These were essentially drop-in replacements with minimal impact to me. Consider what it would take to replace dired or Magit, as perfect as they might be.

The Unix "small programs that do one thing well" philosophy is often ignored, unfortunately. Emacs might be the single biggest offender of it, though I suppose it's to be expected since "GNU's Not Unix"... The benefit of it is precisely the flexibility it gives to users. As much as I love Emacs, I'm not married to it, so relying on one special program that does many things would be harmful for me in the long run if a better alternative appears in the future.

Every few years I put time into learning eshell and it's seriously impressive.

But what I really want is eshell outside of emacs. In fact I want all the bits of emacs outside of emacs.

The problem with eshell is the problem with emacs. It's a monolith. I know I know that's also its strength, but what I really want is for all the bits of emacs to be exploded out into components that make up an overall environment (yes, yes, Genera/Lisp Machines).

Unlike emacs purists, I am too much in and out of that environment to really ever feel fully comfortable adopting all its tools as my mainstay tools.

The writer is incredibly knowledgable. But all of this is completely unapealing. To me this isn't power, it is just learning a lot more things.
I feel like most folks misunderstand Eshell when going into it. It's not really their fault, as they _expect_ something bash-like, and in many ways it is. However, Eshell is _not_ bash. It's not zsh. It's not fish. It's Eshell. When you use Eshell, you get a marriage of command-line tools and Emacs. This isn't always the best case, and some tools are awful to try and use in Eshell.

Eshell shines when you're looking to use Emacs to do stuff in the shell, but not really deal with the shell itself. It will dutifully run whatever program you feed it, but the real magic is when you want to deal with the output. You can redirect outputs to buffers, which you can then manipulate with Emacs familiarity. You can even handle remote sessions just as easily as you would open a remote file in TRAMP. I've used this on many occasions to edit a remote config file, then trigger Eshell, which puts me in that directory, to then restart the service without having to launch a separate SSH session or terminal.

While there are a lot of clunky bits of Emacs, I feel like Eshell gets an especially bad rap. Some of it's justified: It presents itself as a bash-like interface, while actually having vastly different ways of handling things. I feel like folks don't really get the idea that it's an interactive Emacs session, a worksheet for the command-line that lets you ingest data from external tools in a more ergonomic way than doing `shell-command` or similar.

> For file management these days, Dired is my interface of choice. It is simply the more elegant tool for the job. Case in point: renaming a bunch of files in a directory to arbitrary names. With a shell, my standard approach would have been to run some variant of `ls -1 > foo.sh`, edit `foo.sh` to insert `mv` on each line to a renamed target file, `chmod u+x foo.sh` to be executable, run `foo.sh`, delete `foo.sh` and call it a day.

I used to do this before I discovered vidir. [1] vidir is not actually tied to vi; it lets you rename and delete files through your `$EDITOR`. You edit a temporary file that looks like this:

  ...
  0093<tab>./fstab
  0094<tab>./fuse.conf
  0095<tab>./fwupd
  ...
There is also https://github.com/bulletmark/edir designed to improve on vidir. I haven't used it yet.

I'll give Emacs another try some day, I swear, and Dired is one of the reasons.

Edit: [1] I linked to https://github.com/trapd00r/vidir here at first. That is a fork; vidir comes from https://joeyh.name/code/moreutils/. You probably want the original. It is packaged for Debian, FreeBSD, Homebrew, etc. as part of the package `moreutils`.

I like the point raised by the author here about the power of elisp in the shell. For context, I've used emacs for well over a decade and write a good bit of elisp most weeks. However, I ended up finding elisp to be the wrong language for replacing a shell: it removes a lot of simplicity/convention for not enough reward, imo: it's just the wrong abstraction because elisp's most natural transformations are very stateful and buffer based, and, additionally, it really doesn't provide that much expanded capability in the end (and this is despite the fact that I'm one of those people who would absolutely never leave my emacs environment even for web browsing if I could feasibly make it work consistently for the kinds of things I need).

However, despite disliking python, I found https://xon.sh/ to be really excellent and provides a lot of the benefits of eshell, but better, in my humble opinion: it has a well-enough structured base language that is essentially already built to be a library glue-code language, which works really well with the unix philosophy that traditional shells utilize (a good library is just a tool that does a thing really well). It's really nice to just do things like this example

    from somelib import process_image #returns a file name that it saved to
    for f in $(some_executable_that_prints_a_file_list).strip().split("\n"):
      img = cv2.imread(f)
      cp @(process_image(img)) publish_dir
      make publish
It feels a lot like an extension of old shells to me rather than a complete replacement.
I've been using Dired for years and I've not heard of Wdired mode until now. This looks awesome.
One of the reasons why I kept driving into Emacs land was the dopamine effect of "Oh, shit, I didn't even know it could do this..." Over the years my attitude has changed. Now it's purely "task oriented" — whenever I need to get something done, I'd raise a question "can I do that in a more efficient, delightful way?"

Sometimes that manifests into adding a TODO item into my notes. Often I simply start experimenting with basic Elisp in my scratch buffer. These days I may ask an LLM.

When non-emacs muggles mock emacsians for wasting their lives to "maintain" editor config, they don't even realize — for an experienced Lisper their emacs is not like a self-made car that constantly requires attention, it's more like a garden — if you want to eat apples — you'd have to get your hands dirty, but that knowledge and time aren't wasted — you can then use the primitives you built to grow many other things later.