]> git.eshelyaron.com Git - emacs.git/commitdiff
Let `dired-omit-mode' match lines, as well as file names
authorDrew Adams <drew.adams@oracle.com>
Sun, 19 Jun 2022 23:49:24 +0000 (01:49 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Sun, 19 Jun 2022 23:49:24 +0000 (01:49 +0200)
* lisp/dired-aux.el (dired-do-kill-lines): Adjust to use it.

* lisp/dired-x.el (dired-omit-line-regexp): New user option
(bug#46882).
(dired-omit-mode, dired-omit-expunge): Use the new user option.

etc/NEWS
lisp/dired-aux.el
lisp/dired-x.el

index 8103ac0d67f2c458771ba19db4e62ba4ca739dd6..1a90cf15c096d183ffa0a05894c46db994e23672 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1618,6 +1618,11 @@ the thumbnail file.
 
 ** Dired
 
+---
+*** New user option 'dired-omit-line-regexp'.
+This is used by 'dired-omit-mode', and now allows you to hide based on
+other things than just the file names.
+
 +++
 *** New user option 'dired-mouse-drag-files'.
 If non-nil, dragging file names with the mouse in a Dired buffer will
index 1b7088104d74e240ba4c7ff0c5432c63bb5f75c5..91106e0704819a7b68362a812ef2dc3eb6140056 100644 (file)
@@ -1095,45 +1095,46 @@ With a prefix argument, kill that many lines starting with the current line.
     (dired-move-to-filename)))
 
 ;;;###autoload
-(defun dired-do-kill-lines (&optional arg fmt)
-  "Kill all marked lines (not the files).
-With a prefix argument, kill that many lines starting with the current line.
-\(A negative argument kills backward.)
+(defun dired-do-kill-lines (&optional arg fmt init-count)
+  "Remove all marked lines, or the next ARG lines.
+The files or directories on those lines are _not_ deleted.  Only the
+Dired listing is affected.  To restore the removals, use `\\[revert-buffer]'.
 
-If you use this command with a prefix argument to kill the line
-for a file that is a directory, which you have inserted in the
-Dired buffer as a subdirectory, then it deletes that subdirectory
-from the buffer as well.
+With a numeric prefix arg, remove that many lines going forward,
+starting with the current line.  (A negative prefix arg removes lines
+going backward.)
 
-To kill an entire subdirectory \(without killing its line in the
-parent directory), go to its directory header line and use this
-command with a prefix argument (the value does not matter).
+If you use a prefix arg to remove the line for a subdir whose listing
+you have inserted into the Dired buffer, then that subdir listing is
+also removed.
 
-To undo the killing, the undo command can be used as normally.
+To remove a subdir listing _without_ removing the subdir's line in its
+parent listing, go to the header line of the subdir listing and use
+this command with any prefix arg.
 
-This function returns the number of killed lines.
+When called from Lisp, non-nil INIT-COUNT is added to the number of
+lines removed by this invocation, for the reporting message.
 
-FMT is a format string used for messaging the user about the
-killed lines, and defaults to \"Killed %d line%s.\" if not
-present.  A FMT of \"\" will suppress the messaging."
+A FMT of \"\" will suppress the messaging."
+  ;; Returns count of killed lines.
   (interactive "P")
   (if arg
       (if (dired-get-subdir)
-         (dired-kill-subdir)
-       (dired-kill-line arg))
+          (dired-kill-subdir)
+        (dired-kill-line arg))
     (save-excursion
       (goto-char (point-min))
-      (let (buffer-read-only
-           (count 0)
-           (regexp (dired-marker-regexp)))
-       (while (and (not (eobp))
-                   (re-search-forward regexp nil t))
-         (setq count (1+ count))
-         (delete-region (line-beginning-position)
-                        (progn (forward-line 1) (point))))
-       (or (equal "" fmt)
-           (message (or fmt "Killed %d line%s.") count (dired-plural-s count)))
-       count))))
+      (let ((count (or init-count  0))
+            (regexp (dired-marker-regexp))
+            (inhibit-read-only t))
+        (while (and (not (eobp))
+                    (re-search-forward regexp nil t))
+          (setq count (1+ count))
+          (delete-region (line-beginning-position)
+                         (progn (forward-line 1) (point))))
+        (unless (equal "" fmt)
+          (message (or fmt "Killed %d line%s.") count (dired-plural-s count)))
+        count))))
 
 \f
 ;;; Compression
index 56036b6c16670a28165081886005e9ef069510b2..6eb0f63ee5208f5ee36934a9a42f357b2d3ced00 100644 (file)
@@ -125,14 +125,49 @@ folding to be used on case-insensitive filesystems only."
       (file-name-case-insensitive-p dir)
     dired-omit-case-fold))
 
+(defcustom dired-omit-line-regexp nil
+  "Regexp matching lines to be omitted by `dired-omit-mode'.
+The value can also be a variable whose value is such a regexp.
+The value can also be nil, which means do no line matching.
+
+Some predefined regexp variables for Dired, which you can use as the
+option value:
+
+* `dired-re-inode-size'
+* `dired-re-mark'
+* `dired-re-maybe-mark'
+* `dired-re-dir'
+* `dired-re-sym'
+* `dired-re-exe'
+* `dired-re-perms'
+* `dired-re-dot'
+* `dired-re-no-dot'"
+  :type `(choice
+          (const :tag "Do not match lines to omit" nil)
+          (regexp
+           :tag "Regexp to match lines to omit (default omits executables)"
+           :value ,dired-re-exe)
+          (restricted-sexp
+           :tag "Variable with regexp value (default: `dired-re-exe')"
+           :match-alternatives
+           ((lambda (obj) (and (symbolp obj) (boundp obj))))
+           :value dired-re-exe))
+  :group 'dired-x)
+
 ;;;###autoload
 (define-minor-mode dired-omit-mode
   "Toggle omission of uninteresting files in Dired (Dired-Omit mode).
+With 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.
+
+Dired-Omit mode is a buffer-local minor mode.
 
-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', nor files ending with extensions in
-`dired-omit-extensions'.
+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 listed on lines
+matching `dired-omit-line-regexp'.
 
 To enable omitting in every Dired buffer, you can put this in
 your init file:
@@ -141,10 +176,16 @@ your init file:
 
 See Info node `(dired-x) Omitting Variables' for more information."
   :group 'dired-x
-  (if dired-omit-mode
-      ;; This will mention how many lines were omitted:
-      (let ((dired-omit-size-limit nil)) (dired-omit-expunge))
-    (revert-buffer)))
+  (if (not dired-omit-mode)
+      (revert-buffer)
+    (let ((dired-omit-size-limit  nil)
+          (file-count 0))
+      ;; Omit by file-name match, then omit by line match.
+      ;; Use count of file-name match as INIT-COUNT for line match.
+      ;; Return total count.  (Return value is not used anywhere, so far).
+      (setq file-count (dired-omit-expunge))
+      (when dired-omit-line-regexp
+        (dired-omit-expunge dired-omit-line-regexp 'LINEP file-count)))))
 
 (put 'dired-omit-mode 'safe-local-variable 'booleanp)
 
@@ -486,45 +527,61 @@ variables `dired-omit-mode' and `dired-omit-files'."
   :type '(repeat string)
   :group 'dired-x)
 
-(defun dired-omit-expunge (&optional regexp)
-  "Erases all unmarked files matching REGEXP.
-Does nothing if global variable `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, uses `dired-omit-files', and also omits
-  filenames ending in `dired-omit-extensions'.
-If REGEXP is the empty string, this function is a no-op.
-
-This functions works by temporarily binding `dired-marker-char' to
-`dired-omit-marker-char' and calling `dired-do-kill-lines'."
-  (interactive "sOmit files (regexp): ")
+(defun dired-omit-expunge (&optional regexp linep init-count)
+  "Erase all unmarked files whose names match REGEXP.
+With a prefix arg (non-nil LINEP when called from Lisp), match REGEXP
+against the whole line.  Otherwise, match it against the file name.
+
+If REGEXP is nil, use `dired-omit-files', and also omit file names
+ending in `dired-omit-extensions'.
+
+Do nothing if REGEXP is the empty string, `dired-omit-mode' is nil, or
+if called from Lisp and buffer is bigger than `dired-omit-size-limit'.
+
+Optional arg INIT-COUNT is an initial count tha'is added to the number
+of lines omitted by this invocation of `dired-omit-expunge', in the
+status message."
+  (interactive "sOmit files (regexp): \nP")
+  ;; Bind `dired-marker-char' to `dired-omit-marker-char',
+  ;; then call `dired-do-kill-lines'.
   (if (and 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 dired-omit-mode nil)
-                nil)))
+               (progn
+                 (when dired-omit-verbose
+                   (message "Not omitting: directory larger than %d characters."
+                            dired-omit-size-limit))
+                 (setq dired-omit-mode nil)
+                 nil)))
       (let ((omit-re (or regexp (dired-omit-regexp)))
             (old-modified-p (buffer-modified-p))
-            count)
-        (or (string= omit-re "")
-            (let ((dired-marker-char dired-omit-marker-char))
-              (when dired-omit-verbose (message "Omitting..."))
-              (if (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))))
-                  (progn
-                    (setq count (dired-do-kill-lines
-                                nil
-                                (if dired-omit-verbose "Omitted %d line%s." "")))
-                    (force-mode-line-update))
-                (when dired-omit-verbose (message "(Nothing to omit)")))))
-        ;; Try to preserve modified state of buffer.  So `%*' doesn't appear
-        ;; in mode-line of omitted buffers.
+            (count (or init-count 0)))
+        (unless (string= omit-re "")
+          (let ((dired-marker-char dired-omit-marker-char))
+            (when dired-omit-verbose (message "Omitting..."))
+            (if (not (if linep
+                         (dired-mark-if
+                          (and (= (following-char) ?\s) ; Not already marked
+                               (string-match-p
+                                omit-re (buffer-substring
+                                         (line-beginning-position)
+                                         (line-end-position))))
+                          nil)
+                       (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  (+ count
+                              (dired-do-kill-lines
+                               nil
+                               (if dired-omit-verbose "Omitted %d line%s" "")
+                               init-count)))
+              (force-mode-line-update))))
+        ;; Try to preserve modified state, so `%*' doesn't appear in
+        ;; `mode-line'.
         (set-buffer-modified-p (and old-modified-p
                                     (save-excursion
                                       (goto-char (point-min))