1

On Linux/macOS, using omit-mode in Dired is there a way to omit executables? Executables are files which have the Unix executable flag set and are then listed via ls -lF with an * after the filename.

Note:

I do know how to colorise executables in Dired: Via the diredful package (install from melpa) it is easy to setup a rule for this. Diredful can colorioser dried entries according to the full ls line (including the * character for executables). - I am wondering whether something like this is possible for omitting as well.

8
  • You might be able to hack something together by using a hook to locally modify the omit variables in each buffer, so as to match specific files, but unless I'm missing something it sounds like this is a feature request you could submit upstream with M-x report-emacs-bug RET. – Basil Mar 1 at 8:20
  • Please consider specifying what you mean by "special file mode flags", and how executables are specified using that feature, as opposed to being specified with a file-name extension. For example, how, from Elisp, is such a file detected? – Drew Mar 1 at 16:30
  • @Drew File mode flags are also known as permission bits. Some of these bits, when set, determine whether the file is executable and by whom. See file-modes, file-executable-p, (info "(elisp) Testing Accessibility"), etc. – Basil Mar 1 at 18:00
  • @Basil: Hadn't heard permission bits called "file mode bits" before. Anyway, it wouldn't hurt to make this clearer in the question. – Drew Mar 1 at 18:22
  • @drew See updated question. – halloleo Mar 2 at 1:47
1

dired-omit-mode, as currently defined, looks only at the (relative) file name. It does not look at the permission bits.

You would need to define a mode that (1) does first what dired-omit-mode does - match file names and omit them, and (2) then matches the x permission bits at the beginning of the file line.

The second is a separate operation because dired-omit-expunge, which does the work of dired-omit-mode, matches a regexp against only the file names.

The regexp to use, to match the x permission bits, is the value of variable dired-re-exe. But again, you need to match that against the full line, not just the file name.


This should do the trick: M-x my-dired-omit-mode. These are just dired-omit-mode and dired-omit-expunge, but tweaked to also omit executables.

(defcustom diredp-omit-line-regexp dired-re-exe
  "Regexp matching lines to be omitted.
This has effect only when `dired-omit-mode' is non-nil
See command `my-dired-omit-mode' (\\[my-dired-omit-mode]).
The default regexp matches lines for executable files."
  :type 'regexp :group 'dired-x)

(define-minor-mode my-dired-omit-mode
  "Toggle omission of uninteresting files in Dired (Dired-Omit mode).
With a prefix argument ARG, enable Dired-Omit mode if ARG is
positive, and disable it otherwise.  If called from Lisp, enable
the mode if ARG is omitted or nil.

My-Dired-Omit mode is a buffer-local minor mode.

When enabled in a Dired buffer, Dired does not list files whose
filenames match regexp `dired-omit-files', files ending with
extensions in `dired-omit-extensions', or files on lines matching
`diredp-omit-line-regexp'.

To enable omitting in every Dired buffer, you can put this in
your init file:

  (add-hook \\='dired-mode-hook (lambda () (dired-omit-mode)))

See Info node `(dired-x) Omitting Variables' for more information."
  nil nil nil
  (if (not my-dired-omit-mode)
      (revert-buffer)
    (let ((dired-omit-size-limit nil))
      (my-dired-omit-expunge)
      ;; THIS omits lines with an executable file. 
      (my-dired-omit-expunge diredp-omit-line-regexp t))))

;; Added optional arg LINEP.
;;
(defun my-dired-omit-expunge (&optional regexp linep)
  "Erases all unmarked files whose names match REGEXP.
Does nothing if global variable `my-dired-omit-mode' is nil, or if called
  non-interactively and buffer is bigger than `dired-omit-size-limit'.
If REGEXP is nil or not specified, use `dired-omit-files', and also omit
  filenames ending in `dired-omit-extensions'.
If REGEXP is the empty string, this function is a no-op.

With a prefix arg (non-nil LINEP when called from Lisp), match REGEXP
against the whole line, not just the file name.

This temporarily binds `dired-marker-char' to `dired-omit-marker-char'
and calls `dired-do-kill-lines'."
  (interactive "sOmit files (regexp): \nP")
  (if (and my-dired-omit-mode
           (or (called-interactively-p 'interactive)
               (not dired-omit-size-limit)
               (< (buffer-size) dired-omit-size-limit)
               (progn
                 (when dired-omit-verbose
                   (message "Not omitting: directory larger than %d characters."
                            dired-omit-size-limit))
                 (setq my-dired-omit-mode  nil)
                 nil)))
      (let ((omit-re         (or regexp  (dired-omit-regexp)))
            (old-modified-p  (buffer-modified-p))
            count)
        (unless (string= omit-re "")
          (let ((dired-marker-char  dired-omit-marker-char))
            (when dired-omit-verbose (message "Omitting..."))
            (if (if linep
                    (not (dired-mark-if
                          (and (= (following-char) ?\s) ; not already marked
                               (string-match-p
                                omit-re
                                (buffer-substring
                                  (line-beginning-position)
                                  (line-end-position))))
                          nil))
                  (not (dired-mark-unmarked-files
                          omit-re nil nil dired-omit-localp
                          (dired-omit-case-fold-p (if (stringp dired-directory)
                                                      dired-directory
                                                    (car dired-directory))))))
                (when dired-omit-verbose (message "(Nothing to omit)"))
              (setq count (dired-do-kill-lines
                           nil
                           (if dired-omit-verbose "Omitted %d line%s" "")))
              (force-mode-line-update))))
        ;; Try to preserve modified state of buffer.  So `%*' doesn't appear
        ;; in mode-line of omitted buffers.
        (set-buffer-modified-p (and old-modified-p
                                    (save-excursion
                                      (goto-char (point-min))
                                      (re-search-forward dired-re-mark nil t))))
        count)))

UPDATE

I've added this feature of omitting lines that match a regexp (not just lines with a file name that matches a regexp) to Dired+. The behavior is governed by a new user option, diredp-omit-line-regexp.

1
  • So cool, @Drew! Thanks a lot. Using the whole ls output line is the way to go! – halloleo Mar 5 at 0:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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