Fix usage of cons cells in grep-find-ignored-files
authorSpencer Baugh <sbaugh@janestreet.com>
Wed, 22 May 2024 12:28:07 +0000 (08:28 -0400)
committerDmitry Gutov <dmitry@gutov.dev>
Fri, 24 May 2024 20:04:32 +0000 (23:04 +0300)
grep-find-ignored-files is documented to also include cons
cells, not just globs, but there were two places outside grep.el
where we were using it as if it was only a string list.

To fix this, add a helper function named grep-find-ignored-files
which handles grep-find-ignored-files properly and returns the
list of globs, and use it everywhere.

* lisp/progmodes/grep.el (grep--filter-list-by-dir)
(grep-find-ignored-files): New functions.
(rgrep-find-ignored-directories): Use grep--filter-list-by-dir.
(lgrep, rgrep-default-command):
Use grep-find-ignored-files function.
* lisp/dired-aux.el (dired-do-find-regexp):
Use grep-find-ignored-files function.
* lisp/progmodes/project.el (project-ignores):
Use grep-find-ignored-files function, if bound. (bug#71115)

lisp/dired-aux.el
lisp/progmodes/grep.el
lisp/progmodes/project.el

index bb9115133212a8683f7afbd13aaa93a48aae7d7a..ddacd2600d06927f4b0cd4ea81fa7b12523c3533 100644 (file)
@@ -3851,13 +3851,13 @@ REGEXP should use constructs supported by your local `grep' command."
   (interactive "sSearch marked files (regexp): " dired-mode)
   (require 'grep)
   (require 'xref)
-  (defvar grep-find-ignored-files)
   (declare-function rgrep-find-ignored-directories "grep" (dir))
+  (declare-function grep-find-ignored-files "grep" (dir))
   (let* ((marks (dired-get-marked-files nil nil nil nil t))
          (ignores (nconc (mapcar
                           #'file-name-as-directory
                           (rgrep-find-ignored-directories default-directory))
-                         grep-find-ignored-files))
+                         (grep-find-ignored-files default-directory)))
          (fetcher
           (lambda ()
             (let (files xrefs)
index 657349cbdff1845f2c1f9989ba8f166be20cad69..0a9de04fce1d207d75ce2b2d149c3584fe596f33 100644 (file)
@@ -1176,6 +1176,19 @@ REGEXP is used as a string in the prompt."
 
 (defvar grep-use-directories-skip 'auto-detect)
 
+(defun grep--filter-list-by-dir (list dir)
+  "Include elements of LIST which are applicable to DIR."
+  (delq nil (mapcar
+             (lambda (ignore)
+               (cond ((stringp ignore) ignore)
+                     ((consp ignore)
+                      (and (funcall (car ignore) dir) (cdr ignore)))))
+             list)))
+
+(defun grep-find-ignored-files (dir)
+  "Return the list of ignored files applicable to DIR."
+  (grep--filter-list-by-dir grep-find-ignored-files dir))
+
 ;;;###autoload
 (defun lgrep (regexp &optional files dir confirm)
   "Run grep, searching for REGEXP in FILES in directory DIR.
@@ -1236,20 +1249,13 @@ command before it's run."
                       regexp
                       files
                       nil
-                      (and grep-find-ignored-files
-                           (concat " --exclude="
-                                   (mapconcat
-                                     (lambda (ignore)
-                                       (cond ((stringp ignore)
-                                              (shell-quote-argument
-                                               ignore grep-quoting-style))
-                                             ((consp ignore)
-                                              (and (funcall (car ignore) dir)
-                                                   (shell-quote-argument
-                                                    (cdr ignore)
-                                                    grep-quoting-style)))))
-                                    grep-find-ignored-files
-                                    " --exclude=")))
+                       (when-let ((ignores (grep-find-ignored-files dir)))
+                        (concat " --exclude="
+                                (mapconcat
+                                  (lambda (ignore)
+                                    (shell-quote-argument ignore grep-quoting-style))
+                                  ignores
+                                  " --exclude=")))
                       (and (eq grep-use-directories-skip t)
                            '("--directories=skip"))))
        (when command
@@ -1353,13 +1359,8 @@ to indicate whether the grep should be case sensitive or not."
              (setq default-directory dir)))))))
 
 (defun rgrep-find-ignored-directories (dir)
-  "Return the list of ignored directories applicable to `dir'."
-  (delq nil (mapcar
-             (lambda (ignore)
-               (cond ((stringp ignore) ignore)
-                     ((consp ignore)
-                      (and (funcall (car ignore) dir) (cdr ignore)))))
-             grep-find-ignored-directories)))
+  "Return the list of ignored directories applicable to DIR."
+  (grep--filter-list-by-dir grep-find-ignored-directories dir))
 
 (defun rgrep-default-command (regexp files dir)
   "Compute the command for \\[rgrep] to use by default."
@@ -1377,37 +1378,31 @@ to indicate whether the grep should be case sensitive or not."
            (shell-quote-argument ")" grep-quoting-style))
    dir
    (concat
-    (and grep-find-ignored-directories
-         (concat "-type d "
-                 (shell-quote-argument "(" grep-quoting-style)
-                 ;; we should use shell-quote-argument here
-                 " -path "
-                 (mapconcat
-                  (lambda (d)
-                    (shell-quote-argument (concat "*/" d) grep-quoting-style))
-                  (rgrep-find-ignored-directories dir)
-                  " -o -path ")
-                 " "
-                 (shell-quote-argument ")" grep-quoting-style)
-                 " -prune -o "))
-    (and grep-find-ignored-files
-         (concat (shell-quote-argument "!" grep-quoting-style) " -type d "
-                 (shell-quote-argument "(" grep-quoting-style)
-                 ;; we should use shell-quote-argument here
-                 " -name "
-                 (mapconcat
-                  (lambda (ignore)
-                    (cond ((stringp ignore)
-                           (shell-quote-argument ignore grep-quoting-style))
-                          ((consp ignore)
-                           (and (funcall (car ignore) dir)
-                                (shell-quote-argument
-                                 (cdr ignore) grep-quoting-style)))))
-                  grep-find-ignored-files
-                  " -o -name ")
-                 " "
-                 (shell-quote-argument ")" grep-quoting-style)
-                 " -prune -o ")))))
+    (when-let ((ignored-dirs (rgrep-find-ignored-directories dir)))
+      (concat "-type d "
+              (shell-quote-argument "(" grep-quoting-style)
+              ;; we should use shell-quote-argument here
+              " -path "
+              (mapconcat
+               (lambda (d)
+                 (shell-quote-argument (concat "*/" d) grep-quoting-style))
+               ignored-dirs
+               " -o -path ")
+              " "
+              (shell-quote-argument ")" grep-quoting-style)
+              " -prune -o "))
+    (when-let ((ignored-files (grep-find-ignored-files dir)))
+      (concat (shell-quote-argument "!" grep-quoting-style) " -type d "
+              (shell-quote-argument "(" grep-quoting-style)
+              ;; we should use shell-quote-argument here
+              " -name "
+              (mapconcat
+               (lambda (ignore) (shell-quote-argument ignore grep-quoting-style))
+               ignored-files
+               " -o -name ")
+              " "
+              (shell-quote-argument ")" grep-quoting-style)
+              " -prune -o ")))))
 
 (defun grep-find-toggle-abbreviation ()
   "Toggle showing the hidden part of rgrep/lgrep/zrgrep command line."
index a95d1267dd22c0847fcd7761592a5c292f041603..c57c16073b9358dfabe2aed525cacd990bde3458 100644 (file)
@@ -295,7 +295,7 @@ headers search path, load path, class path, and so on."
 Nominally unique, but not enforced."
   (file-name-nondirectory (directory-file-name (project-root project))))
 
-(cl-defgeneric project-ignores (_project _dir)
+(cl-defgeneric project-ignores (_project dir)
   "Return the list of glob patterns to ignore inside DIR.
 Patterns can match both regular files and directories.
 To root an entry, start it with `./'.  To match directories only,
@@ -305,12 +305,15 @@ end it with `/'.  DIR must be either `project-root' or one of
   ;; TODO: Support whitelist entries.
   (require 'grep)
   (defvar grep-find-ignored-files)
+  (declare-function grep-find-ignored-files "grep" (dir))
   (nconc
    (mapcar
     (lambda (dir)
       (concat dir "/"))
     vc-directory-exclusion-list)
-   grep-find-ignored-files))
+   (if (fboundp 'grep-find-ignored-files)
+       (grep-find-ignored-files dir)
+     grep-find-ignored-files)))
 
 (defun project--file-completion-table (all-files)
   (lambda (string pred action)