Function: xref-matches-in-directory

xref-matches-in-directory is an autoloaded and byte-compiled function defined in xref.el.gz.

Signature

(xref-matches-in-directory REGEXP FILES DIR IGNORES)

Documentation

Find all matches for REGEXP in directory DIR.

Return a list of xref values. Only files matching some of FILES and none of IGNORES are searched. FILES is a string with glob patterns separated by spaces. IGNORES is a list of glob patterns for files to ignore.

Probably introduced at or before Emacs version 28.1.

Aliases

xref-collect-matches (obsolete since 27.1)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/xref.el.gz
;;;###autoload
(defun xref-matches-in-directory (regexp files dir ignores)
  "Find all matches for REGEXP in directory DIR.
Return a list of xref values.
Only files matching some of FILES and none of IGNORES are searched.
FILES is a string with glob patterns separated by spaces.
IGNORES is a list of glob patterns for files to ignore."
  ;; DIR can also be a regular file for now; let's not advertise that.
  (grep-compute-defaults)
  (defvar grep-find-template)
  (defvar grep-highlight-matches)
  (pcase-let*
      ((grep-find-template (replace-regexp-in-string "<C>" "<C> -E"
                                                     grep-find-template t t))
       (grep-highlight-matches nil)
       ;; TODO: Sanitize the regexp to remove Emacs-specific terms,
       ;; so that Grep can search for the "relaxed" version.  Can we
       ;; do that reliably enough, without creating false negatives?
       (command (xref--rgrep-command (xref--regexp-to-extended regexp)
                                     files
                                     "."
                                     ignores))
       (local-dir (directory-file-name
                   (file-name-unquote
                    (file-local-name (expand-file-name dir)))))
       (buf (get-buffer-create " *xref-grep*"))
       (`(,grep-re ,file-group ,line-group . ,_) (car grep-regexp-alist))
       (status nil)
       (hits nil))
    (with-current-buffer buf
      (erase-buffer)
      (setq default-directory dir)
      (setq status
            (process-file-shell-command command nil t))
      (goto-char (point-min))
      ;; Can't use the exit status: Grep exits with 1 to mean "no
      ;; matches found".  Find exits with 1 if any of the invocations
      ;; exit with non-zero. "No matches" and "Grep program not found"
      ;; are all the same to it.
      (when (and (/= (point-min) (point-max))
                 (not (looking-at grep-re)))
        (user-error "Search failed with status %d: %s" status (buffer-string)))
      (while (re-search-forward grep-re nil t)
        (push (list (string-to-number (match-string line-group))
                    (concat local-dir (substring (match-string file-group) 1))
                    (buffer-substring-no-properties (point) (line-end-position)))
              hits)))
    (xref--convert-hits (nreverse hits) regexp)))