4

I've hacked something together for myself to hide/toggle columns of my choice in Dired and display what's left with a less obtrusive face. As a side effect this makes the width of Dired buffer small enough to use it as a speedbar replacement.

I use subdirectories, inserted with i a lot. I now want Dired to show only relative paths; and only for subdirectories. I.e.:

enter image description here

Since I'm manipulating Dired's output anyways, I certainly could use the same regex based approach to achieve that. But before I go into another circle of introducing bugs and typos, I thought I'd rather check whether this already exists. Does it? I couldn't find anything in the Docs or via Google.

1

You can do it. But:

  1. It's not really advisable in the general case, because the directories listed in a Dired buffer are not necessarily descendants of the top-level directory - they are not necessarily related at all.

  2. You can do it by substituting this sexp: (file-relative-name dir) for this sexp: (directory-file-name (file-name-directory dir)), in the definition of function dired-insert-directory (in file dired.el).

    (You might need to make some other tweaks, as there are multiple condition branches, and this just affects one of the main ones. But this will at least get you much of the way there, so you can see the effect etc. and check for other problems that it might introduce.)

  3. You might also need to fiddle with a few other functions, which expect the displayed directory name to be absolute.

In sum, I wouldn't do it, but you're welcome to try.

  • Heh! Nah, in that case I'd rather use the same approach and put a text property like invisble: my-hide-subdir-path on the part I want to hide. I can check against the path of their parent dir and leave out directories that are not subdirs. Anyways, thanks for the answer! – Oliver Scholz Apr 20 '18 at 17:51
1

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)

Screenshot of result

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.