Use 'regexp-opt' in 'dired-omit-regexp'

In my benchmarking, for large dired buffers, using 'regexp-opt'
provides around a 3x speedup in omitting.

'regexp-opt' takes around 5 milliseconds, so to avoid slowing
down omitting in small dired buffers we cache the return value.

Since omitting is now 3x faster, increase 'dired-omit-size-limit'
by 3x.  Also, document 'dired-omit-size-limit' better.

* doc/misc/dired-x.texi (Omitting Variables): Document
'dired-omit-size-limit'.
* etc/NEWS: Announce increase of 'dired-omit-size-limit'.
* lisp/dired-x.el (dired-omit--extension-regexp-cache): Add.
(dired-omit-regexp): Use 'regexp-opt'.  (Bug#69775)
(dired-omit-size-limit): Increase and improve docs.
This commit is contained in:
Spencer Baugh 2024-03-16 17:11:24 +00:00 committed by Eli Zaretskii
parent 8d7a3ed349
commit abc2d39e01
3 changed files with 35 additions and 6 deletions

View file

@ -346,6 +346,15 @@ only match against the non-directory part of the file name. Set it to
match the file name relative to the buffer's top-level directory.
@end defvar
@defvar dired-omit-size-limit
If non-@code{nil}, @code{dired-omit-mode} will be effectively disabled
in directories whose listing has size (in bytes) larger than the value
of this option. Since omitting can be slow for very large directories,
this avoids having to wait before seeing the directory. This variable
is ignored when @code{dired-omit-mode} is called interactively, such as
by @code{C-x M-o}, so you can still enable omitting in the directory
after the initial display.
@cindex omitting additional files
@defvar dired-omit-marker-char
Temporary marker used by Dired to implement omitting. Should never be used

View file

@ -705,6 +705,12 @@ marked or clicked on files according to the OS conventions. For
example, on systems supporting XDG, this runs 'xdg-open' on the
files.
*** The default value of 'dired-omit-size-limit' was increased.
After performance improvements to omitting in large directories, the new
default value is 300k, up from 100k. This means 'dired-omit-mode' will
omit files in directories whose directory listing is up to 300 kilobytes
in size.
+++
*** 'dired-listing-switches' handles connection-local values if exist.
This allows to customize different switches for different remote machines.

View file

@ -77,12 +77,17 @@ files not writable by you are visited read-only."
(other :tag "non-writable only" if-file-read-only))
:group 'dired-x)
(defcustom dired-omit-size-limit 100000
"Maximum size for the \"omitting\" feature.
(defcustom dired-omit-size-limit 300000
"Maximum buffer size for `dired-omit-mode'.
Omitting will be disabled if the directory listing exceeds this size in
bytes. This variable is ignored when `dired-omit-mode' is called
interactively.
If nil, there is no maximum size."
:type '(choice (const :tag "no maximum" nil) integer)
:group 'dired-x
:version "29.1")
:version "30.1")
(defcustom dired-omit-case-fold 'filesystem
"Determine whether \"omitting\" patterns are case-sensitive.
@ -506,14 +511,23 @@ status message."
(re-search-forward dired-re-mark nil t))))
count)))
(defvar dired-omit--extension-regexp-cache
nil
"A cache of `regexp-opt' applied to `dired-omit-extensions'.
This is a cons whose car is a list of strings and whose cdr is a
regexp produced by `regexp-opt'.")
(defun dired-omit-regexp ()
(unless (equal dired-omit-extensions (car dired-omit--extension-regexp-cache))
(setq dired-omit--extension-regexp-cache
(cons dired-omit-extensions (regexp-opt dired-omit-extensions))))
(concat (if dired-omit-files (concat "\\(" dired-omit-files "\\)") "")
(if (and dired-omit-files dired-omit-extensions) "\\|" "")
(if dired-omit-extensions
(concat ".";; a non-extension part should exist
"\\("
(mapconcat 'regexp-quote dired-omit-extensions "\\|")
"\\)$")
(cdr dired-omit--extension-regexp-cache)
"$")
"")))
;; Returns t if any work was done, nil otherwise.