Since there doesn't seem to be a built-in way, I implemented this with the same approach I used to add a face and hide some columns.
The following is the code stripped to only that part which is relevant to the question. (The rest, hiding some columns, needs more tuning.) It's barely tested, but this should hide only that part of a subdirectory's path that corresponds to default-directory
, replacing it with ./
(defconst egoge-dired-path-regex
(rx line-start
(* blank)
(group ?/
(* graphic))
?:
line-end
))
(defsubst egoge-dired-dir-path ()
"Hide 'default-directory' part of directory paths."
(let ((ddir (expand-file-name default-directory)))
(when (and (looking-at egoge-dired-path-regex)
(let ((match (match-string-no-properties 1)))
;; Check if this is a sub directory of default-directory,
;; but not default-directory itself.
(and (save-match-data
(string-match (concat "^" ddir)
match))
;; Note: the above should already fail even if it
;; _is_ the default-directory, because of the
;; trailing slash. But I'd rather not rely on
;; that. Better to have an explicit check:
(not (string= (concat match "/")
ddir))
;; The file system root is a special case:
(not (string= match "/")))))
(let ((start (match-beginning 1)))
(put-text-property start
(+ start (length ddir))
'display "./")))))
(defun egoge-dired-hide+dim ()
"Process dired buffer and add text properties to specific parts."
(let ((inhibit-read-only t)
(inhibit-point-motion-hooks t))
(save-excursion
(remove-text-properties (point-min) (point-max) '(display))
(goto-char (point-min))
(while (not (eobp))
(let ((s (point)))
(or (search-forward "\n\n" nil t)
(goto-char (point-max)))
(save-restriction
(narrow-to-region s (point))
(goto-char (point-min))
(egoge-dired-dir-path)
;; (egoge-dired-hide+dim-dir)
(goto-char (point-max))))))))
(add-hook 'dired-after-readin-hook #'egoge-dired-hide+dim)
