在Dired缓冲区中,将点放置在该目录中最重要的文件上


14

90%的时间我访问Emacs中的目录时,我要做的第一件事是将鼠标指向一个特定的文件并打开它。很多时候,我需要打开的文件非常可预测。例如:

  • 如果.tex此目录中有文件,我通常会直接转到master.tex
  • 在Android项目的根源,通常是AndroidManifest.xml
  • 在我开发emacs软件包的目录中,它几乎始终是软件包的主要源文件。这通常是(但并非总是).el此目录中的唯一文件。

当我打开这些目录时,有什么方法可以自动将点放置在这些文件上吗?

这将提供很多便利(因为我可以通过单击来打开它们RET),但是仍然可以灵活地访问其他文件。

Answers:


16

为编写自定义函数dired-initial-position-hook。在此函数中,您可以使用各种Dired函数来搜索文件,并最终调用dired-goto-file将点移动到“最佳”文件:

(defun my-dired-goto-important-file ()
  "Go to an important file in the current dired buffer."
  (unless (bound-and-true-p save-place)
    (let ((candidates '("master.tex" "AndroidManifest.xml"))
          candidate)
      (while (and candidates
                  (not (dired-goto-file (expand-file-name (pop candidates)))))
        nil))))

(add-hook 'dired-initial-position-hook #'my-dired-goto-important-file)

在下文中,我将解释此功能的特定方面,并重点介绍潜在的扩展。

跳至档案

dired-goto-filenil如果该文件在当前Dired缓冲区中不存在,则返回,因此无需事先检查就可以安全地调用。但是dired-goto-file需要一个绝对文件名(相对名称时出错)expand-file-name

搜索文件

Dired不提供直接的API搜索文件。通常,您可以遍历所有文件,就像遍历缓冲区中的所有行一样:

(let (files)
  (goto-char (point-min))
  (while (not (eobp))
    (let ((filename (dired-get-filename nil 'no-error)))
      (when filename
        (push filename files)))
    (forward-line 1))
  ;; Now `files' is a list of files, which you can search for patterns
  ;; …
  )

但是,使用标记功能更为方便。只要小心使用“不寻常”的标记字符,就不要丢失现有的交互式标记:

(unwind-protect
    (when (dired-mark-files-regexp (rx ".tex" string-end) ?t)
      (dired-goto-file (expand-file-name "master.tex")))
  (dired-unmark-all-files ?t))

保存位置模式

如果启用了“保存位置模式”,则还需要注意。在Dired缓冲区中,“保存位置模式”不像其他模式那样记住点值,而是打开了最后一个文件名。就像我们一样,它恢复了该文件名:它挂接dired-initial-position-hook并调用dired-goto-file(实际上,这就是我从:)中偷走的代码的位置)。

如果我们的钩子位于保存位置之前,则保存位置模式将无条件覆盖我们的位置。但是,如果它在钩子之前出现(例如在设置此钩子后启用“保存位置”的情况),我们的功能实际上将覆盖“保存位置”,这是不希望的。但是,就像在任何缓冲区中一样,“保存位置” save-place会将局部变量设置为非nil值,因此我们可以简单地进行检查并仅执行操作,“保存位置”不会恢复文件名。

如果你宁愿保存的地方“宽松”,删除了检查save-place,并确保我们的钩子运行保存地点,通过使保存就位模式第一,然后调用add-hook与它是一个非空值APPEND的论点。


好答案。您可能需要定义bound-and-true-p。:-)
马拉巴巴2014年

@Malabarba bound-and-true-p是的内置宏bindings.el
lunaryorn 2014年

亲爱的上帝,我没有让我感到更糟的事实,我不知道的事实或者我什至没有检查的事实。
马拉巴巴2014年

@Malabarba没关系,我花了一年时间(从字面上看)才发现此功能的存在。
lunaryorn 2014年

是的,这是我以前从未听说过的一个很棒的功能!
sanityinc 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.