[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] scratch/project-files-pipe-grep b40d951 1/3: Add project-f
From: |
Dmitry Gutov |
Subject: |
[Emacs-diffs] scratch/project-files-pipe-grep b40d951 1/3: Add project-files-pipe-grep |
Date: |
Thu, 27 Dec 2018 19:30:52 -0500 (EST) |
branch: scratch/project-files-pipe-grep
commit b40d95133653f93c7e2f710a96b237529b84cdb4
Author: Dmitry Gutov <address@hidden>
Commit: Dmitry Gutov <address@hidden>
Add project-files-pipe-grep
---
lisp/progmodes/project.el | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index f3f29cb..c8ac0a9 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -362,6 +362,48 @@ pattern to search for."
(user-error "No matches for: %s" regexp))
(xref--show-xrefs xrefs nil)))
+(defun project-files-pipe-grep (project regexp)
+ (pcase-let*
+ ((files (project-files project))
+ (infile (make-temp-file "pftg"))
+ (output (get-buffer-create " *project grep output*"))
+ (`(,grep-re ,file-group ,line-group . ,_) (car grep-regexp-alist))
+ (status nil)
+ (hits nil)
+ (xrefs nil))
+ (with-temp-buffer
+ (insert (mapconcat #'identity files "\0"))
+ ;; FIXME: Try without a temporary file.
+ (write-region (point-min) (point-max) infile))
+ (with-current-buffer output
+ (erase-buffer)
+ (setq status
+ (process-file-shell-command
+ (format "xargs -0 -P 1 grep %s -nHe %s"
+ (if (and case-fold-search
+ (isearch-no-upper-case-p regexp t))
+ "-i"
+ "")
+ (shell-quote-argument (xref--regexp-to-extended regexp)))
+ infile
+ t))
+ (goto-char (point-min))
+ (when (and (/= (point-min) (point-max))
+ (not (looking-at grep-re))
+ ;; TODO: Show these matches as well somehow?
+ (not (looking-at "Binary file .* matches")))
+ (user-error "Search failed with status %d: %s" status
+ (buffer-substring (point-min) (line-end-position))))
+ (while (re-search-forward grep-re nil t)
+ (push (list (string-to-number (match-string line-group))
+ (match-string file-group)
+ (buffer-substring-no-properties (point)
(line-end-position)))
+ hits)))
+ (setq xrefs (xref--convert-hits (nreverse hits) regexp))
+ (unless xrefs
+ (user-error "No matches for: %s" regexp))
+ (xref--show-xrefs xrefs nil)))
+
;;;###autoload
(defun project-find-file ()
"Visit a file (with completion) in the current project's roots.