new command: counsel-projectile-grep
This commit is contained in:
parent
293a8f2f6a
commit
332e4c9817
1 changed files with 136 additions and 0 deletions
|
|
@ -62,6 +62,21 @@ candidates list of `counsel-projectile-switch-project'."
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'counsel-projectile)
|
:group 'counsel-projectile)
|
||||||
|
|
||||||
|
(defcustom counsel-projectile-grep-initial-input nil
|
||||||
|
"Initial minibuffer input for `counsel-projectile-grep'. If
|
||||||
|
non-nil, it should be a Lisp expression whose evaluation yields
|
||||||
|
the initial input string.
|
||||||
|
|
||||||
|
Note that you can always insert the value
|
||||||
|
of `(ivy-thing-at-point)' by hitting \"M-n\" in the minibuffer."
|
||||||
|
:type '(choice
|
||||||
|
(const :tag "None" nil)
|
||||||
|
(const :tag "Symbol at point (generic)" '(thing-at-point 'symbol t))
|
||||||
|
(const :tag "Symbol or selection at point (projectile)" '(projectile-symbol-or-selection-at-point))
|
||||||
|
(const :tag "Thing at point (ivy)" '(ivy-thing-at-point))
|
||||||
|
(sexp :tag "Custom expression"))
|
||||||
|
:group 'counsel-projectile)
|
||||||
|
|
||||||
(defcustom counsel-projectile-ag-initial-input nil
|
(defcustom counsel-projectile-ag-initial-input nil
|
||||||
"Initial minibuffer input for `counsel-projectile-ag'. If
|
"Initial minibuffer input for `counsel-projectile-ag'. If
|
||||||
non-nil, it should be a Lisp expression whose evaluation yields
|
non-nil, it should be a Lisp expression whose evaluation yields
|
||||||
|
|
@ -203,6 +218,8 @@ afterwards to apply your changes."
|
||||||
"open in vc-dir / magit / monky")
|
"open in vc-dir / magit / monky")
|
||||||
("e" counsel-projectile-switch-project-action-run-eshell
|
("e" counsel-projectile-switch-project-action-run-eshell
|
||||||
"start eshell")
|
"start eshell")
|
||||||
|
("G" counsel-projectile-switch-project-action-grep
|
||||||
|
"search with grep")
|
||||||
("a" counsel-projectile-switch-project-action-ag
|
("a" counsel-projectile-switch-project-action-ag
|
||||||
"search with ag")
|
"search with ag")
|
||||||
("R" counsel-projectile-switch-project-action-rg
|
("R" counsel-projectile-switch-project-action-rg
|
||||||
|
|
@ -391,6 +408,114 @@ names as in `ivy--buffer-list'."
|
||||||
'counsel-projectile-switch-to-buffer
|
'counsel-projectile-switch-to-buffer
|
||||||
'ivy-switch-buffer-transformer)
|
'ivy-switch-buffer-transformer)
|
||||||
|
|
||||||
|
;;; counsel-projectile-grep
|
||||||
|
|
||||||
|
(defvar counsel-projectile-grep-base-command "grep -rnE %s -- %%s ."
|
||||||
|
"Format string to use in `cousel-projectile-grep-function' to
|
||||||
|
construct the command.")
|
||||||
|
|
||||||
|
(defvar counsel-projectile-grep-base-command nil)
|
||||||
|
|
||||||
|
(defun counsel-projectile-grep-function (string)
|
||||||
|
"Grep in the current project for STRING."
|
||||||
|
(if (< (length string) 3)
|
||||||
|
(counsel-more-chars 3)
|
||||||
|
(let ((default-directory counsel--git-dir)
|
||||||
|
(regex (counsel-unquote-regex-parens
|
||||||
|
(setq ivy--old-re
|
||||||
|
(ivy--regex string)))))
|
||||||
|
(counsel--async-command (format counsel-projectile-grep-command
|
||||||
|
(shell-quote-argument regex)))
|
||||||
|
nil)))
|
||||||
|
|
||||||
|
(defun counsel-projectile-grep-transformer (str)
|
||||||
|
"Higlight file and line number in STR, first removing the
|
||||||
|
\"./\" prefix from the filename."
|
||||||
|
;; This makes the display consistent with `counsel-git-grep' and
|
||||||
|
;; `counsel-ag'-like commands.
|
||||||
|
(counsel-git-grep-transformer (string-remove-prefix "./" str)))
|
||||||
|
|
||||||
|
(defun counsel-projectile-grep-occur ()
|
||||||
|
"Generate a custom occur buffer for `counsel-projectile-grep'."
|
||||||
|
;; Copied from `counsel-grep-like-occur', except that we don't
|
||||||
|
;; prepend "./" to the candidates since grep already does so.
|
||||||
|
(unless (eq major-mode 'ivy-occur-grep-mode)
|
||||||
|
(ivy-occur-grep-mode)
|
||||||
|
(setq default-directory counsel--git-dir))
|
||||||
|
(setq ivy-text
|
||||||
|
(and (string-match "\"\\(.*\\)\"" (buffer-name))
|
||||||
|
(match-string 1 (buffer-name))))
|
||||||
|
(let* ((cmd (format counsel-projectile-grep-command
|
||||||
|
(shell-quote-argument
|
||||||
|
(counsel-unquote-regex-parens
|
||||||
|
(ivy--regex ivy-text)))))
|
||||||
|
(cands (split-string (shell-command-to-string cmd) "\n" t)))
|
||||||
|
;; Need precise number of header lines for `wgrep' to work.
|
||||||
|
(insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n"
|
||||||
|
default-directory))
|
||||||
|
(insert (format "%d candidates:\n" (length cands)))
|
||||||
|
(ivy--occur-insert-lines cands)))
|
||||||
|
|
||||||
|
(defun counsel-projectile-grep (&optional options-or-cmd)
|
||||||
|
"Run a grep search in the project.
|
||||||
|
|
||||||
|
In a git project, use `counsel-git-grep'. In a non-git project,
|
||||||
|
use grep recursively.
|
||||||
|
|
||||||
|
OPTIONS-OR-CMD, if non-nil, is a string containing either
|
||||||
|
additional options to be passed to grep, or an alternative git
|
||||||
|
grep command. It is read from the minibuffer if the function is
|
||||||
|
called with a prefix argument."
|
||||||
|
(interactive)
|
||||||
|
(if (projectile-project-p)
|
||||||
|
(if (and (eq (projectile-project-vcs) 'git)
|
||||||
|
projectile-use-git-grep)
|
||||||
|
(let ((counsel-prompt-function
|
||||||
|
(lambda ()
|
||||||
|
(ivy-add-prompt-count
|
||||||
|
(format "%s: " (projectile-prepend-project-name (ivy-state-prompt ivy-last)))))))
|
||||||
|
(counsel-git-grep (or current-prefix-arg options-or-cmd)
|
||||||
|
counsel-projectile-grep-initial-input))
|
||||||
|
(counsel-require-program (car (split-string counsel-projectile-grep-base-command)))
|
||||||
|
(let* ((options (if current-prefix-arg
|
||||||
|
(read-string "options: ")
|
||||||
|
options-or-cmd))
|
||||||
|
(ignored-files
|
||||||
|
(cl-union (projectile-ignored-files-rel) grep-find-ignored-files))
|
||||||
|
(ignored-dirs
|
||||||
|
(cl-union (projectile-ignored-directories-rel) grep-find-ignored-directories))
|
||||||
|
(options
|
||||||
|
(concat options " "
|
||||||
|
(mapconcat (lambda (i)
|
||||||
|
(concat "--exclude=" (shell-quote-argument i)))
|
||||||
|
ignored-files
|
||||||
|
" ")
|
||||||
|
" "
|
||||||
|
(mapconcat (lambda (i)
|
||||||
|
(concat "--exclude-dir=" (shell-quote-argument i)))
|
||||||
|
ignored-dirs
|
||||||
|
" "))))
|
||||||
|
(setq counsel-projectile-grep-command
|
||||||
|
(format counsel-projectile-grep-base-command options))
|
||||||
|
(ivy-set-prompt 'counsel-projectile-grep counsel-prompt-function)
|
||||||
|
(setq counsel--git-dir (projectile-project-root))
|
||||||
|
(ivy-read (projectile-prepend-project-name "grep")
|
||||||
|
#'counsel-projectile-grep-function
|
||||||
|
:initial-input counsel-projectile-grep-initial-input
|
||||||
|
:dynamic-collection t
|
||||||
|
:keymap counsel-ag-map
|
||||||
|
:history 'counsel-git-grep-history
|
||||||
|
:action #'counsel-git-grep-action
|
||||||
|
:unwind (lambda ()
|
||||||
|
(counsel-delete-process)
|
||||||
|
(swiper--cleanup))
|
||||||
|
:caller 'counsel-projectile-grep)))
|
||||||
|
(user-error "You're not in a project")))
|
||||||
|
|
||||||
|
(counsel-set-async-exit-code 'counsel-projectile-grep 1 "No matches found")
|
||||||
|
(ivy-set-occur 'counsel-projectile-grep 'counsel-projectile-grep-occur)
|
||||||
|
(ivy-set-display-transformer 'counsel-projectile-grep 'counsel-projectile-grep-transformer)
|
||||||
|
|
||||||
;;; counsel-projectile-ag
|
;;; counsel-projectile-ag
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
|
|
@ -545,6 +670,12 @@ in vc-dir / magit / monky."
|
||||||
(let ((projectile-switch-project-action 'projectile-run-eshell))
|
(let ((projectile-switch-project-action 'projectile-run-eshell))
|
||||||
(counsel-projectile-switch-project-action project)))
|
(counsel-projectile-switch-project-action project)))
|
||||||
|
|
||||||
|
(defun counsel-projectile-switch-project-action-grep (project)
|
||||||
|
"Action for `counsel-projectile-switch-project' to search
|
||||||
|
PROJECT with `grep'."
|
||||||
|
(let ((projectile-switch-project-action 'counsel-projectile-ag))
|
||||||
|
(counsel-projectile-switch-project-action project)))
|
||||||
|
|
||||||
(defun counsel-projectile-switch-project-action-ag (project)
|
(defun counsel-projectile-switch-project-action-ag (project)
|
||||||
"Action for `counsel-projectile-switch-project' to search
|
"Action for `counsel-projectile-switch-project' to search
|
||||||
PROJECT with `ag'."
|
PROJECT with `ag'."
|
||||||
|
|
@ -659,6 +790,9 @@ With a prefix ARG invalidates the cache first."
|
||||||
(def-projectile-commander-method ?b
|
(def-projectile-commander-method ?b
|
||||||
"Switch to project buffer."
|
"Switch to project buffer."
|
||||||
(counsel-projectile-switch-to-buffer))
|
(counsel-projectile-switch-to-buffer))
|
||||||
|
(def-projectile-commander-method ?g
|
||||||
|
"Run grep on project."
|
||||||
|
(counsel-projectile-grep))
|
||||||
(def-projectile-commander-method ?A
|
(def-projectile-commander-method ?A
|
||||||
"Search project files with ag."
|
"Search project files with ag."
|
||||||
(counsel-projectile-ag))
|
(counsel-projectile-ag))
|
||||||
|
|
@ -675,6 +809,7 @@ With a prefix ARG invalidates the cache first."
|
||||||
(define-key projectile-mode-map [remap projectile-find-file] #'counsel-projectile-find-file)
|
(define-key projectile-mode-map [remap projectile-find-file] #'counsel-projectile-find-file)
|
||||||
(define-key projectile-mode-map [remap projectile-find-dir] #'counsel-projectile-find-dir)
|
(define-key projectile-mode-map [remap projectile-find-dir] #'counsel-projectile-find-dir)
|
||||||
(define-key projectile-mode-map [remap projectile-switch-project] #'counsel-projectile-switch-project)
|
(define-key projectile-mode-map [remap projectile-switch-project] #'counsel-projectile-switch-project)
|
||||||
|
(define-key projectile-mode-map [remap projectile-grep] #'counsel-projectile-grep)
|
||||||
(define-key projectile-mode-map [remap projectile-ag] #'counsel-projectile-ag)
|
(define-key projectile-mode-map [remap projectile-ag] #'counsel-projectile-ag)
|
||||||
(define-key projectile-mode-map [remap projectile-switch-to-buffer] #'counsel-projectile-switch-to-buffer)
|
(define-key projectile-mode-map [remap projectile-switch-to-buffer] #'counsel-projectile-switch-to-buffer)
|
||||||
(counsel-projectile-commander-bindings))
|
(counsel-projectile-commander-bindings))
|
||||||
|
|
@ -684,6 +819,7 @@ With a prefix ARG invalidates the cache first."
|
||||||
(define-key projectile-mode-map [remap projectile-find-file] nil)
|
(define-key projectile-mode-map [remap projectile-find-file] nil)
|
||||||
(define-key projectile-mode-map [remap projectile-find-dir] nil)
|
(define-key projectile-mode-map [remap projectile-find-dir] nil)
|
||||||
(define-key projectile-mode-map [remap projectile-switch-project] nil)
|
(define-key projectile-mode-map [remap projectile-switch-project] nil)
|
||||||
|
(define-key projectile-mode-map [remap projectile-grep] nil)
|
||||||
(define-key projectile-mode-map [remap projectile-ag] nil)
|
(define-key projectile-mode-map [remap projectile-ag] nil)
|
||||||
(define-key projectile-mode-map [remap projectile-switch-to-buffer] nil)
|
(define-key projectile-mode-map [remap projectile-switch-to-buffer] nil)
|
||||||
(projectile-commander-bindings))))
|
(projectile-commander-bindings))))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue