EINVAL: Valid solutions for invalid problems

Emacs as a Shell

When I log into a new server, one of the first things I do is install a minimal Emacs package1. Of course assuming nobody minds if the server is not strictly mine, I’m not a monster.

Emacs serves me as a de facto shell when setting up whatever there is to set up. By “shell” I mean a broader meaning of this word than just a command prompt: it’s the central program I use to interact with the system. Regardless of the system and its current configuration, I can expect Emacs to be predictably the same program suitable for both configuration file editing and advanced file management thanks to the built-in dired module. One could say I use it like many people use Midnight Commander (mc) though I consider it much more powerful for various reasons. Let me show you what it looks like:

Emacs example

Let’s walk through this screenshot slowly as it’s pretty packed. First of all, Emacs can be split freely, both horizontally and vertically. In this case I have 3 splits2. The first one contains a config file being edited while the other two show the mentioned file manager called dired. Text editing is pretty self-explanatory while dired is the central piece of my “Emacs as a shell” workflow, so let’s focus on it for now.

As you may want to follow along, to open dired press C-x d (i.e. ctrl+x followed by d; not ctrl+d!) and enter a path to open.

Viewing files with dired

dired

This dired window shows two files; to be specific, symlinks along with their targets. The rest of it look very similar to the familiar ls(1) output and for a good reason: dired uses it as the source of this data. We can leverage this fact and customize the ls(1) --switches used by pressing C-u s:

dired switches editing

By default dired uses -al. Let’s add -L to make it show the symlink targets in place of symlinks (though admittedly it already shows after an arrow).

dired switches applied

The symlinks are now resolved completely, we can now see the metadata of files themselves and so on. We could also instead add some switch affecting the file sorting order like -t. I’ll leave it as an exercise for the reader.

This is one of the things about Emacs I appreciate the most: it often doesn’t try to hide the complexity behind its workings. It embraces it, enriches it and exposes it to the user in an accessible manner. If I said dired is like ls(1) on some wild Emacs-flavored steroids, I wouldn’t be far from the truth.

Managing files with dired

Okay, listing files is easy but I mentioned managing files, not just listing. Let’s start with renaming: the best way to rename a file in dired is to press C-x C-q (which toggles the read-only mode in most contexts in Emacs) which enables us to… edit the file listing like a text file. Considering Emacs is a text editor after all, we can use all its text editing goodness here.

There it is, I’ve changed “blog” into “blargh”. To save the changes, C-x C-s can be used which is once again a general Emacs keybinding for saving whatever we’re editing. There are more nice details about this editable mode but it’s a topic for another whole blog post.

For more complex file operations dired uses various, usually capital, letters:

  • C for copying
  • R for an alternate way of moving/renaming
  • S for creating symlinks (and Y for relative symlinks)
  • D for deleting
  • x for secondary deleting of specially marked files (“flagged” in the dired lingo)

We can either operate on the currently focused file or mark more of them with m:

There are two types of marks in here: the “regular marks” and “flags”. They are differentiated by the letter on the left3: “*” or “D”. The “*” marks are used for most of the operations I listed before while “D” are used by the mentioned x deletion operation.

Okay, so we’ve marked some files we want to move elsewhere, what now? Let’s press R:

Now we need to enter the target path. But we already have a second dired window open just beside this one, why won’t it guess we want to move the files there? The answer is surprisingly simple: because we didn’t ask it to guess. Let’s press the down arrow. A little of context: up arrow would navigate the history of previous inputs, Bash-style. Using the down arrow can be seen as guessing the future input.

It’s essentially an on-demand version of mc-style dual-pane file management with some added flexibility.

The same trick may also be used to summon the current permissions when using the equivalent of chmod, chown and chgrp (M, O and G respectively).

Shelling out

File management aside, sometimes I need to perform a file operation not provided by dired and need to run an external command instead. Luckily dired has a very robust facility run with the ! key. The manual describes it really well but to summarize, let’s assume we’ve got three files marked, “foo”, “bar” and “baz”.

  • Entering echo or echo ? would run echo foo; echo bar; echo baz.
  • Entering echo * would run echo foo bar baz.
  • There are also various additional modifiers controlling how the commands will be run, for example & or ;, but I use them rarely.

So one can use * or ? to control how and where the marked files will be placed in the command. It’s a very terse but expressive way to run commands on files and one of my first “wow moments” with dired.

For commands not run with files as arguments I either use a non-dired variant of this command (it’s bound to M-!) or eshell which is a simple shell command prompt built into Emacs.

For long running commands I still use a regular shell, possibly in tmux. Mostly because Emacs is still a single-threaded program and while it has some async capabilities, I still prefer to keep such commands separate.

Summary

So that would be it. My workflow and reasons for using Emacs as my home away from home. What I’ve shown works out of the box, without any Emacs configuration and only with minimal Emacs knowledge. I highly recommend to give it a try as it saved me a lot of time over the years.

PS: A note for Emacs veterans: Yes, I am aware of TRAMP and use it extensively but there are times when I prefer to work directly on a remote host, for instance when I’d need multiple hops to reach the intended machine as the intended user as they tend to slow things down (2 hops is the most I’m usually willing to do). It’s also much harder to recommend using it to a beginner.


  1. In the Debian family called emacs-nox for “no X11”. ↩︎

  2. Technically speaking in Emacs lingo they are called “windows” while the GUI windows are called “frames” but that’s not relevant here. ↩︎

  3. Technically one can mark a file with any character but it’s uncommon. ↩︎