Subject: bug#48071: closed (Re: bug#48071: 28.0.50: dired-guess-default: comply with docstring options [PATCH])

From: [email-masked] (GNU bug Tracking System)
Date: Wed, 21 Jul 2021 23:29:02 +0000

Your bug report

#48071: 28.0.50: dired-guess-default: comply with docstring options [PATCH]

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
48071: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=48071
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#48071: 28.0.50: dired-guess-default: comply with docstring options [PATCH]
From: Michael Heerdegen <[email-masked]>
To: Lars Ingebrigtsen <[email-masked]>
Cc: [email-masked], Boruch Baum <[email-masked]>
Date: Thu, 22 Jul 2021 01:28:36 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Lars Ingebrigtsen <[email-masked]> writes:

> Michael Heerdegen <[email-masked]> writes:
>
> > Other things changed, too: AFAIU now only one file has to match,
> > originally all had to - correct?
>
> Fixed now.

Yes - thanks.

So the (only) remaining user visible change is that now all matching
entries are considered instead of only the first one, which is actually
a fix: the docstring of `dired-guess-shell-alist-user' describes it
should work like that.

Ok, I hope we are done then ;-) and: closing again.

Thanks,

Michael.

Subject: 28.0.50: dired-guess-default: comply with docstring options [PATCH]
From: Boruch Baum <[email-masked]>
To: Emacs Bug Reporting <[email-masked]>
Date: Tue, 27 Apr 2021 14:53:40 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

The docstring for dired-guess-default claims it should handle multiple
instances of COMMAND each of which could be a STRING or a FUNCTION which
evaluates to a STRING ...

The attached patch does that. It also weeds out strings that don't represent
valid programs on the host machine.

It turned out that function dired-guess-shell-command wasn't ready for
the multiple responses, so the patch corrects that as well.

My package diredc has an additional feature of an option for a universal
fall-back. My memory is that the emacs developers rejected the idea when
I originally proposed it, so it's not in this patch.

--
hkp://keys.gnupg.net
CA45 09B5 5351 7C11 A9D1  7286 0036 9E45 1595 8BC0
diff --git a/dired-x.el b/dired-x.el
index 80a266f..d122027 100644
--- a/dired-x.el
+++ b/dired-x.el
@@ -1039,64 +1039,50 @@ REGEXP is matched case-sensitively."
 (defun dired-guess-default (files)
   "Return a shell command, or a list of commands, appropriate for FILES.
 See `dired-guess-shell-alist-user'."
-
   (let* ((case-fold-search dired-guess-shell-case-fold-search)
          ;; Prepend the user's alist to the default alist.
          (alist (append dired-guess-shell-alist-user
                         dired-guess-shell-alist-default))
-         (file (car files))
-         (flist (cdr files))
          elt regexp cmds)
-
-    ;; Find the first match in the alist for first file in FILES.
-    (while alist
-      (setq elt (car alist)
-            regexp (car elt)
-            alist (cdr alist))
-      (if (string-match-p regexp file)
-          (setq cmds (cdr elt)
-                alist nil)))
-
-    ;; If more than one file, see if all of FILES match regular expression.
-    (while (and flist
-                (string-match-p regexp (car flist)))
-      (setq flist (cdr flist)))
-
-    ;; If flist is still non-nil, then do not guess since this means that not
-    ;; all the files in FILES were matched by the regexp.
-    (setq cmds (and (not flist) cmds))
-
-    ;; Return commands or nil if flist is still non-nil.
-    ;; Evaluate the commands in order that any logical testing will be done.
-    (if (cdr cmds)
-	(delete-dups (mapcar (lambda (cmd) (eval cmd `((file . ,file)))) cmds))
-      (eval (car cmds) `((file . ,file))))))		; single command
+    (cl-loop
+      for elt in alist
+      do (setq regexp (car elt))
+         (cl-loop
+           for file in files
+           always (string-match-p regexp file)
+           finally
+             (cl-loop
+               for cmd in (cdr elt) do
+               (unless (stringp cmd)
+                 (setq cmd (condition-case nil
+                             (funcall cmd `((file . ,file)))
+                             (error nil))))
+               (and (stringp cmd)
+                    (executable-find cmd)
+                    (push cmd cmds)))))
+    (nreverse (delete-dups cmds))))

 (defun dired-guess-shell-command (prompt files)
   "Ask user with PROMPT for a shell command, guessing a default from FILES."
   (let ((default (dired-guess-default files))
-        default-list val)
+        val)
     (if (null default)
         ;; Nothing to guess
         (read-shell-command prompt nil 'dired-shell-command-history)
       (setq prompt (replace-regexp-in-string ": $" " " prompt))
-      (if (listp default)
+      (if (cdr default)
           ;; More than one guess
-          (setq default-list default
-                default (car default)
-                prompt (concat
+          (setq prompt (concat
                         prompt
-                        (format "{%d guesses} " (length default-list))))
-        ;; Just one guess
-        (setq default-list (list default)))
+                        (format "{%d guesses} " (length default-list)))))
       ;; Put the first guess in the prompt but not in the initial value.
-      (setq prompt (concat prompt (format "[%s]: " default)))
+      (setq prompt (concat prompt (format "[%s]: " (car default))))
       ;; All guesses can be retrieved with M-n
       (setq val (read-shell-command prompt nil
                                     'dired-shell-command-history
-                                    default-list))
+                                    default))
       ;; If we got a return, then return default.
-      (if (equal val "") default val))))
+      (if (equal val "") (car default) val))))

 
 ;;; RELATIVE SYMBOLIC LINKS.