Package: emacs;
Reported by: Tom Tromey <tom <at> tromey.com>
Date: Fri, 18 May 2018 15:34:02 UTC
Severity: minor
Tags: fixed
Found in version 26.1
Fixed in version 28.1
Done: Lars Ingebrigtsen <larsi <at> gnus.org>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Tino Calancha <tino.calancha <at> gmail.com> To: Tom Tromey <tom <at> tromey.com> Cc: Eli Zaretskii <eliz <at> gnu.org>, Michael Albinus <michael.albinus <at> gmx.de>, 31495 <at> debbugs.gnu.org Subject: bug#31495: 26.1; filename completion -vs- "*" Date: Sat, 19 May 2018 22:32:03 +0900
Tom Tromey <tom <at> tromey.com> writes: > I found a situation where using "*" globbing in filename completion acts > strangely. > > Here is how to set up to see the bug: > > $ cd /tmp > $ mkdir -p a/b/c a/d/c > $ touch a/b/c/q > > Now in Emacs, C-x C-f /tmp/a/*/c TAB > > On the first TAB, a "/" is appended, and then point moves to the "/" > before "c". Yeah, it's broken. In this example adding a '/' makes the completion works C-x C-f /tmp/a/*/c/ TAB > Now type TAB again. > At this point, the "/tmp/a" is greyed out and the minibuffer shows: > > Find file: /tmp/a//c/ > > ... so now only completions for "/c" are available. > > I think instead the "*" should be preserved. Often I'm using this > feature to try to find a specific file where I don't know the exact > subdirectory it is in. Since Emacs 26.1 dired supports wildcards in the directory part. You can use C-x d /tmp/a/*/c/q RET If you shell in '/bin/sh' supports globstar (and have it enabled by default) then you can do just: C-x d /tmp/**/q RET We could even let the user enable globstar in those shells supporting it but having it disable by default (e.g. bash). For instance, following patch: --8<-----------------------------cut here---------------start------------->8--- commit 1c1116e6a6ed369db63ddf00865f04f687579e71 Author: Tino Calancha <tino.calancha <at> gmail.com> Date: Sat May 19 21:57:42 2018 +0900 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. diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index fbb3030c2a..ad63c2f6a5 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -79,6 +79,24 @@ Dired Enter @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 c7ffb17ad3..931289f0af 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -266,6 +266,12 @@ unescaping text. ** Dired +++ +*** The new user option 'dired-maybe-use-globstar' enables globstar +in shells that support this feature. The new variable +'dired-enable-globstar-in-shell' lists which shells can have enabled +globstar. + ++++ *** The new user option 'dired-create-destination-dirs' controls whether 'dired-do-copy' and 'dired-rename-file' should create non-existent directories in the destination. diff --git a/lisp/dired.el b/lisp/dired.el index 1348df6934..0adffdbd3f 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -77,6 +77,26 @@ dired-subdir-switches :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 support 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 implementation 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") @@ -1297,6 +1317,13 @@ dired-insert-directory (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)) --8<-----------------------------cut here---------------end--------------->8--- In GNU Emacs 27.0.50 (build 12, x86_64-pc-linux-gnu, GTK+ Version 3.22.11) of 2018-05-17 built on calancha-pc Repository revision: 593c367b0727affc739832ab4f4bdb9d7dd1ddd7
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.