bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#27631: dired a/*/b


From: Tino Calancha
Subject: bug#27631: dired a/*/b
Date: Fri, 14 Jul 2017 00:13:28 +0900
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.50 (gnu/linux)

積丹尼 Dan Jacobson <address@hidden> writes:

> Maybe make dired and list-directory deal with wildcards in positions like
> ~/.config/chromium/Default/*/menkifleemblimdogmoihpfopnplikde/

Hi Michael,

i'd like to provide Tramp support for this new Dired feature.
The implementation is fairly straight: just adds a function
'insert-directory-wildcard-in-dir-p' in files.el, and use it in
'insert-directory' and Dired.

To get Tramp support i've added a handler
'tramp-sh-handle-insert-directory-wildcard-in-dir-p'.
Is this procedure OK or i am doing something weird?

Best regards,
Tino

--8<-----------------------------cut here---------------start------------->8---
commit e5d5bd9822c1c562a7feb16f035062fda603d4d9
Author: Tino Calancha <address@hidden>
Date:   Thu Jul 13 23:56:43 2017 +0900

    Dired: Handle wildards in directory part
    
    Allow to Dired to handle calls like
    \(dired \"~/foo/*/*.el\"), that is, with wildcards withing
    the directory part of the file argument.
    * lisp/files.el (insert-directory-wildcard-in-dir-p): New predicate.
    (insert-directory)
    * lisp/dired.el(dired-internal-noselect)
    (dired-insert-directory): Use it.
    * /etc/NEWS: Announce it.
    * doc/emacs/dired.texi (Dired Enter): Update manual.

diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 28cb51d88b..2113381e3a 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -64,10 +64,23 @@ Dired Enter
 directory name using the minibuffer, and opens a @dfn{Dired buffer}
 listing the files in that directory.  You can also supply a wildcard
 file name pattern as the minibuffer argument, in which case the Dired
-buffer lists all files matching that pattern.  The usual history and
-completion commands can be used in the minibuffer; in particular,
address@hidden puts the name of the visited file (if any) in the minibuffer
-(@pxref{Minibuffer History}).
+buffer lists all files matching that pattern.  A wildcard may appear
+in the directory part as well.
+For instance,
+
address@hidden
+C-x d  ~/foo/*.el  @key{RET}
+C-x d  ~/foo/*/*.el  @key{RET}
address@hidden example
+
+The former lists all the files with extension @samp{.el} in directory
address@hidden  The latter lists the files with extension @samp{.el}
+in @samp{foo} subdirectories; the sudirectories are 1 level of depth
+below @samp{foo}.
+
+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}).
 
   You can also invoke Dired by giving @kbd{C-x C-f} (@code{find-file})
 a directory name.
diff --git a/etc/NEWS b/etc/NEWS
index 71a2da1b63..e16c4a7b76 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -559,9 +559,13 @@ properties as intact as possible.
 * Changes in Specialized Modes and Packages in Emacs 26.1
 
 ** Dired
-You can now use '`?`' in 'dired-do-shell-command'; as ' ? ', it gets replaced
++++
+*** You can now use '`?`' in 'dired-do-shell-command'; as ' ? ', it gets 
replaced
 by the current file name.
 
++++
+*** Now Dired support wildcards in the directory part of file names.
+
 *** html2text is now marked obsolete.
 
 *** smerge-refine-regions can refine regions in separate buffers
diff --git a/lisp/dired.el b/lisp/dired.el
index 0c1f3e4af6..50dd81dfdd 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -913,11 +913,12 @@ dired-internal-noselect
                           "Directory has changed on disk; type 
\\[revert-buffer] to update Dired")))))
       ;; Else a new buffer
       (setq default-directory
-           ;; We can do this unconditionally
-           ;; because dired-noselect ensures that the name
-           ;; is passed in directory name syntax
-           ;; if it was the name of a directory at all.
-           (file-name-directory dirname))
+            (or (car (insert-directory-wildcard-in-dir-p dirname))
+               ;; We can do this unconditionally
+               ;; because dired-noselect ensures that the name
+               ;; is passed in directory name syntax
+               ;; if it was the name of a directory at all.
+               (file-name-directory dirname)))
       (or switches (setq switches dired-listing-switches))
       (if mode (funcall mode)
         (dired-mode dir-or-list switches))
@@ -1049,13 +1050,14 @@ dired-readin-insert
             (not file-list))
        ;; If we are reading a whole single directory...
        (dired-insert-directory dir dired-actual-switches nil nil t)
-      (if (not (file-readable-p
-               (directory-file-name (file-name-directory dir))))
-         (error "Directory %s inaccessible or nonexistent" dir)
-       ;; Else treat it as a wildcard spec
-       ;; unless we have an explicit list of files.
-       (dired-insert-directory dir dired-actual-switches
-                               file-list (not file-list) t)))))
+      (if (and (not (insert-directory-wildcard-in-dir-p dir))
+               (not (file-readable-p
+                    (directory-file-name (file-name-directory dir)))))
+         (error "Directory %s inaccessible or nonexistent" dir))
+      ;; Else treat it as a wildcard spec
+      ;; unless we have an explicit list of files.
+      (dired-insert-directory dir dired-actual-switches
+                             file-list (not file-list) t))))
 
 (defun dired-align-file (beg end)
   "Align the fields of a file to the ones of surrounding lines.
@@ -1272,11 +1274,14 @@ dired-insert-directory
          ;; Note that dired-build-subdir-alist will replace the name
          ;; by its expansion, so it does not matter whether what we insert
          ;; here is fully expanded, but it should be absolute.
-         (insert "  " (directory-file-name (file-name-directory dir)) ":\n")
+         (insert "  " (or (car (insert-directory-wildcard-in-dir-p dir))
+                           (directory-file-name (file-name-directory dir))) 
":\n")
          (setq content-point (point)))
        (when wildcard
          ;; Insert "wildcard" line where "total" line would be for a full dir.
-         (insert "  wildcard " (file-name-nondirectory dir) "\n")))
+         (insert "  wildcard " (or (cdr (insert-directory-wildcard-in-dir-p 
dir))
+                                    (file-name-nondirectory dir))
+                  "\n")))
       (dired-insert-set-properties content-point (point)))))
 
 (defun dired-insert-set-properties (beg end)
diff --git a/lisp/files.el b/lisp/files.el
index 2f3efa33c2..96c6357d92 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -6552,6 +6552,12 @@ directory-listing-before-filename-regexp
 
 (defvar insert-directory-ls-version 'unknown)
 
+(defun insert-directory-wildcard-in-dir-p (dir)
+  (when (string-match "[*]" (file-name-directory dir))
+    (let ((regexp "\\`\\([^*]+/\\)\\([^*]*[*].*\\)"))
+      (string-match regexp dir)
+      (cons (match-string 1 dir) (match-string 2 dir)))))
+
 ;; insert-directory
 ;; - must insert _exactly_one_line_ describing FILE if WILDCARD and
 ;;   FULL-DIRECTORY-P is nil.
@@ -6611,13 +6617,19 @@ insert-directory
                           default-file-name-coding-system))))
            (setq result
                  (if wildcard
-                     ;; Run ls in the directory part of the file pattern
-                     ;; using the last component as argument.
-                     (let ((default-directory
-                             (if (file-name-absolute-p file)
-                                 (file-name-directory file)
-                               (file-name-directory (expand-file-name file))))
-                           (pattern (file-name-nondirectory file)))
+                     ;; If the wildcard is just in the file part, then run ls 
in
+                      ;; the directory part of the file pattern using the last
+                      ;; component as argument.  Otherwise, run ls in the 
longest
+                      ;; subdirectory of the directory part free of wildcars; 
use
+                      ;; the remaining of the file pattern as argument.
+                     (let* ((dir-wildcard (insert-directory-wildcard-in-dir-p 
file))
+                             (default-directory
+                               (cond (dir-wildcard (car dir-wildcard))
+                                     (t
+                                     (if (file-name-absolute-p file)
+                                         (file-name-directory file)
+                                       (file-name-directory (expand-file-name 
file))))))
+                            (pattern (if dir-wildcard (cdr dir-wildcard) 
(file-name-nondirectory file))))
                        ;; NB since switches is passed to the shell, be
                        ;; careful of malicious values, eg "-l;reboot".
                        ;; See eg dired-safe-switches-p.


commit 15eef43279e2d92ef1e20e66bb2a4ff23c22ead3
Author: Tino Calancha <address@hidden>
Date:   Thu Jul 13 23:56:43 2017 +0900

    Dired: Tramp support for wildcards in directory part
    
    * lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory-wildcard-in-dir-p):
    New handler for 'insert-directory-wildcard-in-dir-p'.
    (tramp-sh-file-name-handler-alist):
    Add it t the list.
    (tramp-sh-handle-insert-directory): Use it.

diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 4beb6fe521..3a0094d8f7 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -1030,6 +1030,7 @@ tramp-sh-file-name-handler-alist
     ;; `find-file-noselect' performed by default handler.
     ;; `get-file-buffer' performed by default handler.
     (insert-directory . tramp-sh-handle-insert-directory)
+    (insert-directory-wildcard-in-dir-p . 
tramp-sh-handle-insert-directory-wildcard-in-dir-p)
     (insert-file-contents . tramp-handle-insert-file-contents)
     (load . tramp-handle-load)
     (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
@@ -2632,8 +2633,12 @@ tramp-sh-handle-insert-directory
                 (not (tramp-get-ls-command-with-dired v)))
        (setq switches (delete "--dired" switches)))
       (when wildcard
-        (setq wildcard (tramp-run-real-handler
-                       'file-name-nondirectory (list localname)))
+        (setq wildcard  (or (cdr (tramp-run-real-handler
+                                  'insert-directory-wildcard-in-dir-p
+                                  (list localname)))
+                            (tramp-run-real-handler
+                            'file-name-nondirectory
+                             (list localname))))
         (setq localname (tramp-run-real-handler
                         'file-name-directory (list localname))))
       (unless (or full-directory-p (member "-d" switches))
@@ -2654,13 +2659,19 @@ tramp-sh-handle-insert-directory
                   (tramp-get-ls-command v)
                   switches
                   (if wildcard
-                      localname
+                      (or (car (tramp-run-real-handler
+                                 'insert-directory-wildcard-in-dir-p
+                                 (list localname))) localname)
                     (tramp-shell-quote-argument (concat localname ".")))))
        (tramp-barf-unless-okay
         v
         (format "cd %s" (tramp-shell-quote-argument
-                         (tramp-run-real-handler
-                          'file-name-directory (list localname))))
+                          (or (car (tramp-run-real-handler
+                               'insert-directory-wildcard-in-dir-p
+                               (list localname)))
+                             (tramp-run-real-handler
+                              'file-name-directory
+                               (list localname)))))
         "Couldn't `cd %s'"
         (tramp-shell-quote-argument
          (tramp-run-real-handler 'file-name-directory (list localname))))
@@ -2736,6 +2747,11 @@ tramp-sh-handle-insert-directory
 
          (goto-char (point-max)))))))
 
+(defun tramp-sh-handle-insert-directory-wildcard-in-dir-p (dir)
+  "Like `insert-directory-wildcard-in-dir-p' for Tramp files."
+  (with-parsed-tramp-file-name dir nil
+    (insert-directory-wildcard-in-dir-p localname)))
+
 ;; Canonicalization of file names.
 
 (defun tramp-sh-handle-expand-file-name (name &optional dir)

--8<-----------------------------cut here---------------end--------------->8---
In GNU Emacs 26.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
 of 2017-07-13
Repository revision: 1f08279e1b20bd1e07132b6ee0a25a154811615a





reply via email to

[Prev in Thread] Current Thread [Next in Thread]