Write a custom function for dired-initial-position-hook
. In this function you can use various dired functions to search for files, and eventually call dired-goto-file
to move point to the “best” 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)
In the following I'll explain specific aspects of this function, and highlight potential extensions.
Jumping to files
dired-goto-file
returns nil
if the file does not exist in the current dired buffer, so it's safe to call without prior checking. However dired-goto-file
requires an absolute file name (it errors on relative names), hence expand-file-name
.
Searching for files
Dired does not provide a straight-forward API to search for files. Generally, you can iterate over all files just like you'd iterate over all lines in a buffer:
(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
;; …
)
However, it's more convenient to use the marking functions. Just take care to use an “unusual” marker characters, to not loose existing interactive marks:
(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))
Save Place Mode
You also need to be careful with regards to Save Place Mode, in case you enabled it.
In Dired buffers, Save Place Mode does not remember the point value as in other modes, but rather the last file name point was on. It restores this file name just like we do: It hooks into dired-initial-position-hook
and calls dired-goto-file
(in fact, that's where I stole that code from :) ).
If our hook comes before save place, Save Place Mode will unconditionally overwrite our position. However, if it comes before our hook (as is the case when Save Place is enabled after you setup this hook) our function would actually overwrite Save Place which is not desirable. However, as in any buffer, Save Place sets the local variable save-place
to a non-nil value, so we can simply check that and only act it Save Place did not restore a file name.
If you'd rather have Save Place “loose”, remove the check for save-place
, and make sure that our hook is run after Save Place, by enabling Save Place Mode first, and then calling add-hook
with a non-nil value for its APPEND
argument.