我的 Emacs 配置 (Dired)
My Emacs Configuration (Dired)

原始链接: https://eugene-andrienko.com/2026-07-05-my-emacs-configuration-dired.html

Emacs Dired 提供了强大的功能,可调用外部程序来打开和处理文件。 若要实现打开文件的自动化(例如使用 `sxiv` 查看图片或使用 `mplayer` 播放视频),您可以配置 `dired-open-extensions` 变量,将文件扩展名映射到特定的应用程序。 对于更复杂的任务,Dired 提供了 `!`(同步)和 `&`(异步)快捷键,用于在选定的文件上运行 Shell 命令。您可以使用 `dired-guess-shell-alist-user` 预先定义针对特定文件类型的建议命令列表。当在迷你缓冲区(minibuffer)中提示输入时,使用 `M-n` 可以循环切换这些建议,使用 `M-p` 则可以调用之前的命令。 该系统还支持使用特殊占位符构建动态命令: * `*`:将命令一次性应用于所有选定文件。 * `?`:为每个文件单独执行命令。 * `?`:允许进行字符串操作,例如在不丢失基本文件名的情况下为原始文件名附加扩展名。 这些工具使您可以直接在文件管理器中实现灵活、高效的批处理操作。

Hacker News 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 我的 Emacs 配置(Dired)(eugene-andrienko.com) 8 分,由 meysamazad 于 2 小时前发布 | 隐藏 | 过往 | 收藏 | 讨论 帮助 考虑申请 YC 2026 年秋季批次!申请截止日期为 7 月 27 日。 准则 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

Now it's time to speak about external programs, which could be called from inside Dired.

By default, the Emacs tries to open any file inside itself, if user presses RET on the file in the Dired buffer. But, it may be convenient to open some files with external programs, for example open videos with MPlayer or open an image with nSxiv. And the variable dired-open-extensions could help with that!

It is just a list of conses, where the car is the file extension and the cdr is the program (from $PATH in my case) which should open all the files with such extension:

(setopt dired-open-extensions '(("png"  . "sxiv")
                                ("PNG"  . "sxiv")
                                ("jpeg" . "sxiv")
                                ("jpg"  . "sxiv")
                                ("JPEG" . "sxiv")
                                ("JPG"  . "sxiv")
                                ("gif"  . "sxiv")
                                ("GIF"  . "sxiv")
                                ("webp" . "sxiv")
                                ("WEBP" . "sxiv")
                                ("avi"  . "mplayer")
                                ("m4a"  . "mplayer")
                                ("mkv"  . "mplayer")
                                ("mp3"  . "mplayer")
                                ("flac" . "mplayer")
                                ("mp4"  . "mplayer")
                                ("webm" . "mplayer")
                                ("eps"  . "gv")))

I think, this part of configuration is self-explanatory — it instructs Dired to open all images with sxiv command, and all videos with mplayer command.

Let's look to another way to launch specific programs for specific files in the Dired. I'm speaking about dired-guess-shell-alist-user variable and the ! or & hotkeys in the Dired buffer.

First thing, you (as a reader) should know, The ! hotkey in the Dired buffer will run entered command synchronously — so Emacs will lock itself, while the command is running. Sometimes, when the command (like gm convert) will exit very fast, it is OK and I could wait some small time while my files are transforming. But, some commands take a lot of time, so there the & is to the rescue. It will run the entered command asynchronously, so the Emacs will not be locked while the command is running. It is useful for e.g. converting some video files from WEBM to MP4, etc.

Of course, the entered command will be applied to the file under the cursor or to the marked files in the Dired buffer.

Second thing: after your press one of the before-mentioned keybindings, then the Dired will show you the prompt in the minibuffer, like this:

Emacs Dired prompting for command to launch on the 2026-01-24-emacs-dired-C-x-C-d.png file.

And there are two important keybindings:

  • M-p shows you the commands which you entered before in this prompt.
  • M-n shows the predefined commands.

Emacs Dired allows to define a lot of commands, depending on the filename extension, so for the images the M-n will show one set of predefined commands and for videos it will show another set of commands. The variable dired-guess-shell-alist-user allows to define these commands, like this:

dired-guess-shell-alist-user
'(("\\.\\([Jj][Pp][Ee]?[Gg]\\|[Pp][Nn][Gg]\\|[Tt][Ii][Ff]\\{2\\}\\|[Ww][Ee][Bb][Pp]\\)$"
   "sxiv -t * "
   "sxiv -o * | xargs rm -f"
   "sxiv -o * | xargs dragon"
   "sxiv -o * | xargs gimp"
   "gm convert ? -resize 1080x1080^ resized_`?`"
   "gm convert ? -resize 2560x2560^ resized_`?`"
   "pngquant --speed 1 --strip --skip-if-larger --force * "
   "jpegoptim -m 80 --auto-mode -s * ")
  ("\\.ORF$"
   "rawtherapee * ")
  ("\\.[Gg][Pp][Xx]$"
   "qmapshack * "))

This variable is just a list of lists, where the each inner list should contain two things:

  1. Regular expression which selects the file extension. For this extension (or these extensions) the next written command(s) will be displayed after pressing M-n.
  2. The next items of inner list is just a strings with commands, which should be launched for the files with extensions from item #1.

So, in the example, provided above, there are:

  • Some commands: sxiv, gm, pngquant and jpegoptim — were assigned to the common extensions for images, like: JPG, PNG, TIFF and WEBP images.
  • Command to launch RawTherapee for *.orf files.
  • Command to launch QMapShack for *.gpx files.

Note, that where a various wildcard symbols in these command: *, ? and `?`. For example (and for my further explanation), lets assume what we have the next files in the catalog, opened in Dired:

The command like this: rm * — issued from Dired with the help of ! or & keys will be landed to the shell in the next form:

rm 01.jpg 02.jpg 03.jpg

But, if you type the rm ? instead — then the Dired will issue three commands:

rm 01.jpg
rm 02.jpg
rm 03.jpg

And for the mv ? `?`.test the next three commands will be issued:

mv 01.jpg 01.jpg.test
mv 02.jpg 02.jpg.test
mv 03.jpg 03.jpg.test

How these tricks with *, ? and `?` could be used? The first one is self-explanatory — just use it, if need to apply some command to the all selected files.

The ? and `?` are more tricky. E.g., they could be used for image conversion via GraphicsMagick — when you don't want to lost the original filename. Here the `?` comes to the rescue — with back-quotes it is possible to add some text before or after the original filename, because both * and ? should be surrounded by spaces or Dired will not understand it. So with e.g. gm convert ? `?`.png the next three commands will be executed by the Emacs:

gm convert 01.jpg 01.jpg.png
gm convert 02.jpg 02.jpg.png
gm convert 03.jpg 03.jpg.png

And the next command won't do anything meaningful:

gm convert ? ?.png

First, it will ask user about:

1 occurrence of ‘?’ will not be substituted.  Proceed? (y, n, ?)

And if user answers y, then the next non-desired commands will be executed:

gm convert 01.jpg ?.png
gm convert 02.jpg ?.png
gm convert 03.jpg ?.png
联系我们 contact @ memedata.com