4

I would like to customize the amount of detail displayed in Dired. Basically I would like to cherry-pick the "columns" to display. More precisely, I would like to hide the "owner group" information. So instead of this:

drwxrwxrwx  1 fgeorges Utilisa. du domaine  40960 01-28 20:16 bar
-rw-rw-rw-  1 fgeorges Utilisa. du domaine  10574 01-29 08:31 file.txt
-rw-rw-rw-  1 fgeorges Utilisa. du domaine 198331 01-29 08:31 file.xml
drwxrwxrwx  1 fgeorges Utilisa. du domaine  40960 01-29 08:31 foo
-rw-rw-rw-  1 fgeorges Utilisa. du domaine  10499 01-28 20:17 file.json

I would rather see this:

drwxrwxrwx  1 fgeorges  40960 01-28 20:16 bar
-rw-rw-rw-  1 fgeorges  10574 01-29 08:31 file.txt
-rw-rw-rw-  1 fgeorges 198331 01-29 08:31 file.xml
drwxrwxrwx  1 fgeorges  40960 01-29 08:31 foo
-rw-rw-rw-  1 fgeorges  10499 01-28 20:17 file.json

It would be OK to never generate it in the first place, or to be able to hide it, by configuration or using a command.

I am aware of dired-hide-details-mode, but this is different. It presents everything or nothing. I would still like to have details, but just not some of them.

I searched quite a lot, and found nothing, but I cannot believe it is not possible to configure which columns to display in Dired.

BTW - I take solutions using Dired+ as well (I can consider any other extension, but would like to keep it to Dired or Dired+)

Florent Georges
  • 203
  • 1
  • 7

2 Answers2

2

(Got to this question, because it was a suggestion by stackexchange when I asked my own question related to this.)

Weeeeell, just today I hacked something together to achieve that. It needs refactoring, it's barely tested, it's not complete (for instance, I plan to update the regex at the core whenever I run into something that breaks it, like Dired marks.)

But if you're daring or willing to hack Elisp, this might be a starting point:

;; In file: egoge-dired.el

(defconst egoge-dired-regex
  (rx line-start
      ;; Dired mark
      (? (or ?C ?*))
      ;; leading whitespace
      (* blank)
      ;; 1. directory, file, or link.
      (group (or ?d ?- ?l))
      ;; 2. user permissions
      (group (or ?r ?-) (or ?w ?-) (or ?x ?- ?s))
      ;; 3. group permission
      (group (or ?r ?-) (or ?w ?-) (or ?x ?- ?s))
      ;; 4. other permissions
      (group (or ?r ?-) (or ?w ?-) (or ?x ?- ?s))
      ;; whitespace
      ;; (+ blank)
      (+ blank)
      ;; 5. links
      (group (+ digit))
      ;; whitespace
      blank
      ;; 6. owner
      (group (+ graphic))
      ;; whitespace
      (+ blank)
      ;; 7. group
      (group (+ graphic))
      ;; whitespace
      (+ blank)
      ;; 8. size
      (group (+ digit)
             (? (and (or ?\, ?\.)
                     (+ digit)))
             (? (or ?K ?M ?G))
             )
      ;; whitespace
      (+ blank)
      ;; 9. date (default or long-iso
      (group (or (and (+ alpha)
                      blank
                      (+ digit))
                 (and (repeat 4 digit)
                      ?- (repeat 2 digit)
                      ?- (repeat 2 digit))))
      ;; whitespace
      (+ blank)
      ;; 10. time
      (group (repeat 2 digit)
             ?:
             (repeat 2 digit))
      ))

(defface egoge-dired-face
  '((((class color) (background dark))
     (:foreground "grey40" :height .8))
    (((class color) (background light))
     (:foreground "grey50")))
  "Dim dired information")

(defsubst egoge-dired-hide+dim-dir ()
  (goto-char (point-min))
  (let ((max-group-length 0)
        (max-size-length 0)
        group-pos-lst
        size-pos-lst)
    (while (not (eobp))
      (when (looking-at egoge-dired-regex)
        (let ((s (match-beginning 1))
              (e (match-end 10)))
          (put-text-property s e 'font-lock-face 'egoge-dired-face)
          (put-text-property s e 'help-echo (buffer-substring-no-properties s e)))
        ;; type + permissions
        (put-text-property (match-beginning 1)
                           (1+ (match-end 4))
                           'invisible 'egoge-dired-hide-permissions)
        ;; links
        (let ((type (match-string-no-properties 1))
              (s (match-beginning 5))
              (e (match-end 5)))
          (unless (string= type "d") 
            (put-text-property s e 'display " "))
          (put-text-property s (1+ e) 'invisible 'egoge-dired-hide-links))
        ;; owner + group
        (put-text-property (match-beginning 6)
                           (match-end 6)
                           'invisible 'egoge-dired-hide-owner+group)
        (push (match-beginning 7) group-pos-lst)
        (let ((len (- (match-end 7)
                      (match-beginning 7))))
          (and (> len max-group-length)
               (setq max-group-length len)))
        ;; (message "str: %s, len: %S" (match-string-no-properties 7) max-group-length)
        ;; size
        (let ((type (match-string-no-properties 1)))
          (unless (string= type "-")
            (let* ((s (match-beginning 8))
                   (e (match-end 8))
                   (len (- e s)))
              (push e size-pos-lst)
              (and (> len max-size-length)
                   (setq max-size-length len))
              ;; (put-text-property s e 'display (make-string (- e s) ?-))
              )))

        ;; time
        (put-text-property (match-beginning 10)
                           (1+ (match-end 10))
                           'invisible 'egoge-dired-hide-time))
      (forward-line 1))

    (dolist (p group-pos-lst)
      (put-text-property (1- p) (+ p max-group-length 1)
                         'invisible 'egoge-dired-hide-owner+group))
    (dolist (p size-pos-lst)
      (put-text-property (- p max-size-length)
                         p
                         'display (make-string max-size-length ?-)))))


(defun egoge-dired-hide+dim ()
  (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))
            (egoge-dired-hide+dim-dir)
            (goto-char (point-max))))))))            


(defun egoge-dired-toggle-property (prop)
  (if (not (eq major-mode 'dired-mode))
      (message "Not in Dired buffer")
    (if (memq prop buffer-invisibility-spec)
        (remove-from-invisibility-spec prop)
      (add-to-invisibility-spec prop))))

(defun egoge-dired-toggle-permissions ()
  (interactive)
  (egoge-dired-toggle-property 'egoge-dired-hide-permissions))

(defun egoge-dired-toggle-owner+group ()
  (interactive)
  (egoge-dired-toggle-property 'egoge-dired-hide-owner+group))

(defun egoge-dired-toggle-time ()
  (interactive)
  (egoge-dired-toggle-property 'egoge-dired-hide-time))

(defun egoge-dired-toggle-links ()
  (interactive)
  (egoge-dired-toggle-property 'egoge-dired-hide-links))


(defvar egoge-dired-visibility-properties
  '(egoge-dired-hide-permissions
    egoge-dired-hide-owner+group
    egoge-dired-hide-time
    egoge-dired-hide-links
    ))


(defun egoge-dired-show-all ()
  (interactive)
  (let ((inhibit-read-only t))
    (remove-text-properties (point-min) (point-max) '(display)))
  (if (not (eq major-mode 'dired-mode))
      (message "Not in Dired buffer")
    (dolist (p egoge-dired-visibility-properties)
      (remove-from-invisibility-spec p))))

(defun egoge-dired-hide-all ()
  (interactive)
  (if (not (eq major-mode 'dired-mode))
      (message "Not in Dired buffer")
    (dolist (p egoge-dired-visibility-properties)
      (add-to-invisibility-spec p))))

(provide 'egoge-dired)

;; In .emacs:

(when (require 'egoge-dired nil t)
  (add-hook 'dired-after-readin-hook #'egoge-dired-hide+dim)
  (add-hook 'dired-mode-hook #'egoge-dired-hide-all))

Or, if there's interest in this, I would be willing to update it whenever I fix something. Btw., is there still something like gnu.emacs.sources of the old days?

Oliver Scholz
  • 846
  • 7
  • 12
0

You can configure the columns with dired-listing-switches. For GNU ls, the relevant switch is:

-G, --no-group
       in a long listing, don't print group names

Here is a snippet from my .emacs (macOS, with GNU coreutils installed):

;; Show human-readable sizes, and group directories first.
(when (eq system-type 'darwin)
  (setq dired-use-ls-dired t
        insert-directory-program "/usr/local/bin/gls"
        dired-listing-switches "-l --all --group-directories-first --human-readable --no-group"))

The result:

enter image description here