unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#46882: 26.3; Let `dired-omit-mode' match lines, as well as file names
@ 2021-03-03  0:39 Drew Adams
  2021-03-03 18:10 ` Drew Adams
  2022-06-19 23:49 ` Lars Ingebrigtsen
  0 siblings, 2 replies; 7+ messages in thread
From: Drew Adams @ 2021-03-03  0:39 UTC (permalink / raw)
  To: 46882

[-- Attachment #1: Type: text/plain, Size: 1680 bytes --]

`dired-omit-mode' matches file names against regexps, and removes their
lines from the Dired listing.

It can also be useful to match other things on a file's line, besides
its name.  For example, match the `x' permission to omit executable files.

The attached code implements this.  It adds a new option,
`dired-omit-line-regexp', which is a regexp to match lines.

It redefines `dired-omit-mode', `dired-omit-expunge', and
`dired-do-kill-lines'.  It adds optional args LINEP and INIT-COUNT to
`dired-omit-expunge', and optional arg INIT-COUNT to
`dired-do-kill-lines'.

When the new option is non-nil, `dired-omit-mode' calls
`dired-omit-expunge' a second time, to omit matching lines.

The updated doc of `dired-do-kill-lines' speaks only of removing lines
from the listing, not of "killing" lines, to avoid confusion with kills
(the `kill-ring' is unaffected by this command).  We should consider
renaming the command altogether, but then the key binding of `k' would
no longer be mnemonic'.  At the very least, if the doc continues to
speak of "killing" lines then it should explicitly say that the
`kill-ring' is unaffected.

If this improvement is OK (try it) then I can send a patch.  Otherwise,
I won't bother.

The improvement was inspired by this user question:

https://emacs.stackexchange.com/q/63659/105


In GNU Emacs 26.3 (build 1, x86_64-w64-mingw32)
 of 2019-08-29
Repository revision: 96dd0196c28bc36779584e47fffcca433c9309cd
Windowing system distributor `Microsoft Corp.', version 10.0.19041
Configured using:
 `configure --without-dbus --host=x86_64-w64-mingw32
 --without-compress-install 'CFLAGS=-O2 -static -g3''


[-- Attachment #2: throw-dir-omit.el --]
[-- Type: application/octet-stream, Size: 6851 bytes --]

(defcustom dired-omit-line-regexp nil
  "Regexp matching lines to be omitted by `dired-omit-mode'.
The value can also be nil, which means do no line matching.

See command `dired-omit-mode' (\\[dired-omit-mode]).

Some predefined regexp variables for Dired, whose values 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 "Don't match lines" nil)
                 (regexp :tag "Match lines with regexp (default: executables)"
                         :value ,dired-re-exe))
  :group 'dired-x)


;; REPLACE ORIGINAL in `dired-x.el'.
;;
;; When `dired-omit-line-regexp' is non-nil, call `dired-omit-expunge'
;; again to omit matching lines.
;;
(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.

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:

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

See Info node `(dired-x) Omitting Variables' for more information."
  nil nil nil :group 'dired-x
  (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)))))


;; REPLACE ORIGINAL in `dired-x.el'.
;;
;; Added optional args LINEP and INIT-COUNT.
;;
(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)))
      (let ((omit-re         (or regexp  (dired-omit-regexp)))
            (old-modified-p  (buffer-modified-p))
            (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))
                                      (re-search-forward dired-re-mark nil t))))
        count)))


;; REPLACE ORIGINAL in `dired-aux.el'.
;;
;; 1. Added optional arg INIT-COUNT.
;; 2. Changed doc to speak of removing, not killing.
;;
(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]'.

With a numeric prefix arg, remove that many lines going forward,
starting with the current line.  (A negative prefix arg removes lines
going backward.)

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 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.

When called from Lisp, non-nil INIT-COUNT is added to the number of
lines removed by this invocation, for the reporting message."
  ;; Returns count of killed lines.  FMT="" suppresses message.
  (interactive "P")
  (if arg
      (if (dired-get-subdir) (dired-kill-subdir) (dired-kill-line arg))
    (save-excursion
      (goto-char (point-min))
      (let ((count   (or init-count  0))
            (regexp  (dired-marker-regexp))
            buffer-read-only)
        (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))))

^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#46882: 26.3; Let `dired-omit-mode' match lines, as well as file names
  2021-03-03  0:39 bug#46882: 26.3; Let `dired-omit-mode' match lines, as well as file names Drew Adams
@ 2021-03-03 18:10 ` Drew Adams
  2022-06-19 23:49 ` Lars Ingebrigtsen
  1 sibling, 0 replies; 7+ messages in thread
From: Drew Adams @ 2021-03-03 18:10 UTC (permalink / raw)
  To: Drew Adams, 46882

I changed the option so its value can also be a var
whose value is such a regexp.

(defcustom dired-omit-lines-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.

See command `dired-omit-mode' (\\[dired-omit-mode]).

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)





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#46882: 26.3; Let `dired-omit-mode' match lines, as well as file names
  2021-03-03  0:39 bug#46882: 26.3; Let `dired-omit-mode' match lines, as well as file names Drew Adams
  2021-03-03 18:10 ` Drew Adams
@ 2022-06-19 23:49 ` Lars Ingebrigtsen
  2022-06-20 16:49   ` Juri Linkov
  1 sibling, 1 reply; 7+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-19 23:49 UTC (permalink / raw)
  To: Drew Adams; +Cc: 46882

Drew Adams <drew.adams@oracle.com> writes:

> When the new option is non-nil, `dired-omit-mode' calls
> `dired-omit-expunge' a second time, to omit matching lines.

Seems to work well; I've now pushed to Emacs 29 (with some changes).

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#46882: 26.3; Let `dired-omit-mode' match lines, as well as file names
  2022-06-19 23:49 ` Lars Ingebrigtsen
@ 2022-06-20 16:49   ` Juri Linkov
  2022-06-20 19:36     ` Drew Adams
  2022-06-21 10:44     ` Lars Ingebrigtsen
  0 siblings, 2 replies; 7+ messages in thread
From: Juri Linkov @ 2022-06-20 16:49 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 46882, Drew Adams

>> When the new option is non-nil, `dired-omit-mode' calls
>> `dired-omit-expunge' a second time, to omit matching lines.
>
> Seems to work well; I've now pushed to Emacs 29 (with some changes).

Its counterpart variable is `dired-omit-files' that is a regexp.
Shouldn't the new variable be named with the same naming scheme
for consistency?  I.e. just `dired-omit-lines'.  Even so that
it's not just a regexp, but can be a symbol of a function name.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#46882: 26.3; Let `dired-omit-mode' match lines, as well as file names
  2022-06-20 16:49   ` Juri Linkov
@ 2022-06-20 19:36     ` Drew Adams
  2022-06-21 10:44     ` Lars Ingebrigtsen
  1 sibling, 0 replies; 7+ messages in thread
From: Drew Adams @ 2022-06-20 19:36 UTC (permalink / raw)
  To: Juri Linkov, Lars Ingebrigtsen; +Cc: 46882

> Its counterpart variable is `dired-omit-files' that is a regexp.
> Shouldn't the new variable be named with the same naming scheme
> for consistency?  I.e. just `dired-omit-lines'.  Even so that
> it's not just a regexp, but can be a symbol of a function name.

It's a valid question, but it opens a can of
worms.  There's no consistency already. ;-)

Consider option `dired-garbage-files-regexp',
for example.

Generally, an option whose value is a regexp
is better named with `regexp' in the name.

`dired-omit-files' would be better named
`dired-omit-files-regexp' or similar.

FWIW, Dired+ has these additional options:

diredp-visit-ignore-regexps
diredp-omit-files-font-lock-regexp

And of course diredp-omit-lines-regexp.

If you really want to aim for consistency
then consider renaming `dired-omit-files'
to `dired-omit-files-regexp'. ;-)





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#46882: 26.3; Let `dired-omit-mode' match lines, as well as file names
  2022-06-20 16:49   ` Juri Linkov
  2022-06-20 19:36     ` Drew Adams
@ 2022-06-21 10:44     ` Lars Ingebrigtsen
  2022-06-21 14:33       ` Drew Adams
  1 sibling, 1 reply; 7+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-21 10:44 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 46882, Drew Adams

Juri Linkov <juri@linkov.net> writes:

> Its counterpart variable is `dired-omit-files' that is a regexp.
> Shouldn't the new variable be named with the same naming scheme
> for consistency?  I.e. just `dired-omit-lines'.  Even so that
> it's not just a regexp, but can be a symbol of a function name.

Makes sense; now renamed.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#46882: 26.3; Let `dired-omit-mode' match lines, as well as file names
  2022-06-21 10:44     ` Lars Ingebrigtsen
@ 2022-06-21 14:33       ` Drew Adams
  0 siblings, 0 replies; 7+ messages in thread
From: Drew Adams @ 2022-06-21 14:33 UTC (permalink / raw)
  To: Lars Ingebrigtsen, Juri Linkov; +Cc: 46882

> > Its counterpart variable is `dired-omit-files' that is a regexp.
> > Shouldn't the new variable be named with the same naming scheme
> > for consistency?  I.e. just `dired-omit-lines'.  Even so that
> > it's not just a regexp, but can be a symbol of a function name.
                                                ^^^^^^^^^^^^^^^^^^
Ah, so you _didn't_ use the code I sent, which
supports a symbol as a _variable_, whose value
is a regexp.  Too bad.

And what kind of function are we talking about?
A function that returns a regexp?  A function
that does something else?

> Makes sense; now renamed.

Too bad.  Guess that changes this from "done"
to "won't fix".

Guess this is hidden behind your "I've now
pushed to Emacs 29 (with some changes)."
                    ^^^^^^^^^^^^^^^^^

Guess I'll have to keep the original option
`diredp-omit-lines-regexp' around.  I was
hoping Emacs would absorb it, so renaming
`diredp-' to `dired-' would suffice.

For your "consistency" maybe you'll now want
to change `dired-omit-files' to also support
a function symbol...  I mean, _consistency_,
right?

And while you're at it, for "consistency"
consider renaming `dired-garbage-files-regexp'.
Oh, and add support for it to be a function
symbol...  Consistency.

Consistency is a wonderful, hobgoblinny thing.





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-06-21 14:33 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-03  0:39 bug#46882: 26.3; Let `dired-omit-mode' match lines, as well as file names Drew Adams
2021-03-03 18:10 ` Drew Adams
2022-06-19 23:49 ` Lars Ingebrigtsen
2022-06-20 16:49   ` Juri Linkov
2022-06-20 19:36     ` Drew Adams
2022-06-21 10:44     ` Lars Ingebrigtsen
2022-06-21 14:33       ` Drew Adams

Code repositories for project(s) associated with this inbox:

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).