From 29bb72f0432c7b89d2f7dec5022c582f8e10ada9 Mon Sep 17 00:00:00 2001 From: Tino Calancha Date: Sat, 22 Aug 2020 17:39:16 +0200 Subject: [PATCH] Handle globstar in dired Allow user to enable globstar when the shell support it and disable it by default (e.g. bash). * lisp/dired.el (dired-maybe-use-globstar): New user option. (dired-enable-globstar-in-shell): New variable. (dired-insert-directory): if `dired-maybe-use-globstar' is non-nil and the shell supports globstar, then enable it. * doc/emacs/dired.texi: Document feature. ; * etc/NEWS: Add entry. --- doc/emacs/dired.texi | 18 ++++++++++++++++++ etc/NEWS | 6 ++++++ lisp/dired.el | 27 +++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index de449e31c37..39caab086c2 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -79,6 +79,24 @@ The former lists all the files with extension @samp{.el} in directory @samp{foo}. The latter lists the files with extension @samp{.el} in all the subdirectories of @samp{foo}. +When the system shell supports globstar and it's enabled, then you +can use recursive globbing: + +@example +C-x d ~/foo/**/*.el @key{RET} +@end example + +This command lists all the files with extension @samp{.el} descending +recursively in all the subdirectories of @samp{foo}. Note that there +are small differences in the implementation of globstar between shells. +Check your shell manual to know the expected behavior. + +@vindex dired-maybe-use-globstar +@vindex dired-enable-globstar-in-shell +If the shell supports globstar and disables it by default, you +can still enable this feature with @code{dired-maybe-use-globstar} if +the shell is included in @code{dired-enable-globstar-in-shell}. + The usual history and completion commands can be used in the minibuffer; in particular, @kbd{M-n} puts the name of the visited file (if any) in the minibuffer (@pxref{Minibuffer History}). diff --git a/etc/NEWS b/etc/NEWS index b4833473ec6..a47b6e10b16 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -228,6 +228,12 @@ time zones will use a form like "+0100" instead of "CET". ** Dired ++++ +*** New user option 'dired-maybe-use-globstar'. +If set, enables globstar in shells that support this feature. The new +variable 'dired-enable-globstar-in-shell' lists which shells can have +globstar enabled. + +++ *** New user option 'dired-copy-dereference'. If set to non-nil, Dired will dereference symbolic links when copying. diff --git a/lisp/dired.el b/lisp/dired.el index 77bb6cfa9ca..d22d52ce627 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -77,6 +77,26 @@ If nil, `dired-listing-switches' is used." :type '(choice (const :tag "Use dired-listing-switches" nil) (string :tag "Switches"))) +(defcustom dired-maybe-use-globstar nil + "If non-nil, enable globstar if the shell supports it. +Some shells enable this feature by default (e.g. zsh or fish). + +See `dired-enable-globstar-in-shell' for a list of shells +that support globstar and disable it by default. + +Note that the implementations of globstar have small differences +between shells. You must check your shell documentation to see +what to expect." + :type 'boolean + :group 'dired) + +(defconst dired-enable-globstar-in-shell + '(("ksh" . "set -G") + ("bash" . "shopt -s globstar")) + "Alist of (SHELL . COMMAND), where COMMAND enables globstar in SHELL. +If `dired-maybe-use-globstar' is non-nil, then `dired-insert-directory' +checks this alist to enable globstar in the shell subprocess.") + (defcustom dired-chown-program (purecopy (cond ((executable-find "chown") "chown") ((file-executable-p "/usr/sbin/chown") "/usr/sbin/chown") @@ -1470,6 +1490,13 @@ see `dired-use-ls-dired' for more details.") (executable-find explicit-shell-file-name)) (executable-find "sh"))) (switch (if remotep "-c" shell-command-switch))) + ;; Enable globstar + (when-let ((globstar dired-maybe-use-globstar) + (enable-it + (assoc-default + (file-truename sh) dired-enable-globstar-in-shell + (lambda (reg shell) (string-match reg shell))))) + (setq script (format "%s; %s" enable-it script))) (unless (zerop (process-file sh nil (current-buffer) nil switch script)) -- 2.39.2