Re: [PATCH] git.el: Add "git grep" functionality in a grep-style compilation buffer
From: David Kågedal <hidden>
Date: 2016-06-15 22:45:20
vanicat@debian.org (Rémi Vanicat) writes:
From: David Kågedal <redacted> Subject: [PATCH] [PATCH] git.el: Add a git-grep command This allows easy access to git grep from Emacs. Signed-off-by: David Kågedal <redacted> Tested-by: Rémi Vanicat <redacted> --- David Kågedal [off-list ref] writes:quoted
David Christensen [off-list ref] writes:quoted
Signed-off-by: David Christensen <redacted>I posted a longer version of git-grep that built on the grep commands in Emacs 22 a while ago. It gives you a better was to navigate to the hits etc. I'll dig it up again.Was it this one ?
Kindof. This seems to be an improved version that doesn't fail on older emacsen and that adds a menu. I'm not sure who contributed that, but it's probably also in some mail somewhere. I use this every day (but without the improvements) and I think it is really useful.
quoted hunk
-- Rémi Vanicat contrib/emacs/git.el | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 52 insertions(+), 0 deletions(-)diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el index c1cf1cb..57351a5 100644 --- a/contrib/emacs/git.el +++ b/contrib/emacs/git.el@@ -49,6 +49,7 @@ (require 'ewoc) (require 'log-edit) (require 'easymenu) +(require 'grep () t) ;;;; Customizations@@ -1496,6 +1497,7 @@ amended version of it." ["Diff File" git-diff-file t] ["Interactive Diff File" git-diff-file-idiff t] ["Log" git-log-file t] + ,@(if (featurep 'grep) (list ["Grep" git-grep t]) ()) "--------" ["Mark" git-mark-file t] ["Mark All" git-mark-all t]@@ -1584,5 +1586,55 @@ Meant to be used in `after-save-hook'." (interactive) (describe-function 'git-status-mode)) +(when (featurep 'grep) + (defvar git-grep-history nil) + + (defun git-grep (regexp &optional files dir) + "Recursively grep for REGEXP in FILES in directory tree rooted at DIR. +The search is limited to file names matching shell pattern FILES. +FILES may use abbreviations defined in `grep-files-aliases', e.g. +entering `ch' is equivalent to `*.[ch]'. + +With \\[universal-argument] prefix, you can edit the constructed shell command line +before it is executed. +With two \\[universal-argument] prefixes, directly edit and run `git-grep-find-command'. + +Collect output in a buffer. While find runs asynchronously, you +can use \\[next-error] (M-x next-error), or \\<grep-mode-map>\\[compile-goto-error] +in the grep output buffer, to go to the lines where grep found matches." + (interactive + (cond + ((equal current-prefix-arg '(16)) + (list (read-from-minibuffer "Run: " "git grep " + nil nil 'git-grep-history) + nil)) + (t (let* ((regexp (grep-read-regexp)) + (files (grep-read-files regexp)) + (dir (read-directory-name "Base directory: " + nil default-directory t))) + (list regexp files dir))))) + (when (and (stringp regexp) (> (length regexp) 0)) + (if (null files) + (if (not (string= regexp grep-find-command)) + (compilation-start regexp 'grep-mode)) + (setq dir (file-name-as-directory (expand-file-name dir))) + (let ((command (concat + "git grep -n " + "-e " (shell-quote-argument regexp) + (if (string= files "*") + "" + (concat " -- " (shell-quote-argument files)))))) + (when command + (if current-prefix-arg + (setq command + (read-from-minibuffer "Confirm: " + command nil nil 'git-grep-history)) + (add-to-history 'git-grep-history command)) + (let ((default-directory dir)) + (compilation-start (concat "PAGER= " command) 'grep-mode)) + ;; Set default-directory if we started rgrep in the *grep* buffer. + (if (eq next-error-last-buffer (current-buffer)) + (setq default-directory dir)))))))) + (provide 'git) ;;; git.el ends here
-- David Kågedal