Focus on ripgrep; remove ag, git-grep & grep support

We're focusing on ripgrep so we can iterate on search functionality in
Doom quicker. There is nothing the other search backends can do that
ripgrep can't. It is now a hard dependency for Doom.
This commit is contained in:
Henrik Lissner 2019-11-17 01:19:59 -05:00
parent 7a7b89ded1
commit a66872fe25
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
4 changed files with 78 additions and 292 deletions

View file

@ -610,18 +610,12 @@ Uses the symbol at point or the current selection, if available."
(list (read-string (list (read-string
(format "Search load-path (default: %s): " query) (format "Search load-path (default: %s): " query)
nil 'git-grep query)))) nil 'git-grep query))))
;; REVIEW Replace with deadgrep or ivy/helm interface when we drop ag/git-grep ;; REVIEW Replace with deadgrep
;; support later
(grep-find (grep-find
(mapconcat (mapconcat
#'shell-quote-argument #'shell-quote-argument
(cond ((executable-find "rg") (append (list "rg" "-L" "--search-zip" "--no-heading" "--color=never" query)
`("rg" "-L" "--search-zip" "--no-heading" "--color=never" (cl-remove-if-not #'file-directory-p load-path))
,query ,@(cl-remove-if-not #'file-directory-p load-path)))
((executable-find "ag")
`("ag" "--search-zip" "--nogroup" "--nocolor"
,query ,@(cl-remove-if-not #'file-directory-p load-path)))
((user-error "This command requires ripgrep or the_silver_searcher to be installed on your system")))
" "))) " ")))
;; TODO factor our the duplicate code between this and the above ;; TODO factor our the duplicate code between this and the above
@ -639,18 +633,13 @@ Uses the symbol at point or the current selection, if available."
(list (read-string (list (read-string
(format "Search load-path (default: %s): " query) (format "Search load-path (default: %s): " query)
nil 'git-grep query)))) nil 'git-grep query))))
(unless (executable-find "rg")
(user-error "Can't find ripgrep on your system"))
(require 'elisp-refs) (require 'elisp-refs)
;; REVIEW Replace with deadgrep or ivy/helm interface when we drop ag/git-grep ;; REVIEW Replace with deadgrep
;; support later
(grep-find (grep-find
(mapconcat (mapconcat
#'shell-quote-argument #'shell-quote-argument
(let ((search (elisp-refs--loaded-paths))) (append (list "rg" "-L" "--search-zip" "--no-heading" "--color=never" query)
(cond ((executable-find "rg") (cl-remove-if-not #'file-directory-p (elisp-refs--loaded-paths)))
`("rg" "-L" "--search-zip" "--no-heading" "--color=never"
,query ,@(cl-remove-if-not #'file-directory-p search)))
((executable-find "ag")
`("ag" "--search-zip" "--nogroup" "--nocolor"
,query ,@(cl-remove-if-not #'file-directory-p search)))
((user-error "This command requires ripgrep or the_silver_searcher to be installed on your system"))))
" "))) " ")))

View file

@ -37,68 +37,9 @@ workspace."
;; ;;
;;; Project search ;;; Project search
(defun +helm-ag-search-args (all-files-p recursive-p)
(list (concat "ag " (if IS-WINDOWS "--vimgrep" "--nocolor --nogroup"))
"-S"
(if all-files-p "-z -a")
(unless recursive-p "--depth 1")))
(defun +helm-rg-search-args (all-files-p recursive-p)
(list "rg --no-heading --line-number --color never"
"-S"
(when all-files-p "-z -uu")
(unless recursive-p "--maxdepth 1")))
;;
(defun +helm--grep-source ()
(require 'helm-projectile)
(helm-build-async-source (capitalize (helm-grep-command t))
:header-name (lambda (_name) "Helm Projectile Grep (C-c ? Help)")
:candidates-process #'helm-grep-collect-candidates
:filter-one-by-one #'helm-grep-filter-one-by-one
:candidate-number-limit 9999
:nohighlight t
:keymap helm-grep-map
:history 'helm-grep-history
:action (apply #'helm-make-actions helm-projectile-grep-or-ack-actions)
:persistent-action 'helm-grep-persistent-action
:persistent-help "Jump to line (`C-u' Record in mark ring)"
:requires-pattern 2))
(defun +helm--grep-search (directory query prompt &optional all-files-p recursive-p)
(let* ((default-directory directory)
(helm-ff-default-directory directory)
(helm-grep-in-recurse recursive-p)
(helm-grep-ignored-files
(unless all-files-p
(cl-union (projectile-ignored-files-rel) grep-find-ignored-files)))
(helm-grep-ignored-directories
(unless all-files-p
(cl-union (mapcar 'directory-file-name (projectile-ignored-directories-rel))
grep-find-ignored-directories)))
(helm-grep-default-command
(if (and nil (eq (projectile-project-vcs) 'git))
(format "git --no-pager grep --no-color -n%%c -e %%p %s -- %%f"
(if recursive-p "" "--max-depth 1 "))
(format "grep -si -a%s %%e -n%%cH -e %%p %%f %s"
(if recursive-p " -R" "")
(if recursive-p "." "./*"))))
(helm-grep-default-recurse-command helm-grep-default-command))
(setq helm-source-grep (+helm--grep-source))
(helm :sources 'helm-source-grep
:input query
:prompt prompt
:buffer "*helm grep*"
:default-directory directory
:keymap helm-grep-map
:history 'helm-grep-history
:truncate-lines helm-grep-truncate-lines)))
;;;###autoload ;;;###autoload
(cl-defun +helm-file-search (engine &key query in all-files (recursive t)) (cl-defun +helm-file-search (&key query in all-files (recursive t))
"Conduct a file search using ENGINE, which can be any of: rg, ag, pt, and "Conduct a file search using ripgrep.
grep. If omitted, ENGINE will default to the first one it detects, in that
order.
:query STRING :query STRING
Determines the initial input to search for. Determines the initial input to search for.
@ -108,6 +49,8 @@ order.
:recursive BOOL :recursive BOOL
Whether or not to search files recursively from the base directory." Whether or not to search files recursively from the base directory."
(declare (indent defun)) (declare (indent defun))
(unless (executable-find "rg")
(user-error "Couldn't find ripgrep in your PATH"))
(require 'helm-ag) (require 'helm-ag)
(helm-ag--init-state) (helm-ag--init-state)
(let* ((project-root (or (doom-project-root) default-directory)) (let* ((project-root (or (doom-project-root) default-directory))
@ -115,13 +58,6 @@ order.
(default-directory directory) (default-directory directory)
(helm-ag--default-directory directory) (helm-ag--default-directory directory)
(helm-ag--default-target (list directory)) (helm-ag--default-target (list directory))
(engine (or engine
(cl-find-if #'executable-find +helm-project-search-engines
:key #'symbol-name)
(and (or (executable-find "grep")
(executable-find "git"))
'grep)
(user-error "No search engine specified (is ag, rg, or git installed?)")))
(query (or query (query (or query
(when (use-region-p) (when (use-region-p)
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning))) (let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
@ -129,23 +65,20 @@ order.
(when (> (abs (- end beg)) 1) (when (> (abs (- end beg)) 1)
(rxt-quote-pcre (buffer-substring-no-properties beg end))))) (rxt-quote-pcre (buffer-substring-no-properties beg end)))))
"")) ""))
(prompt (format "[%s %s] " (prompt (format "[rg %s] "
(symbol-name engine)
(cond ((file-equal-p directory project-root) (cond ((file-equal-p directory project-root)
(projectile-project-name)) (projectile-project-name))
((file-equal-p directory default-directory) ((file-equal-p directory default-directory)
"./") "./")
((file-relative-name directory project-root))))) ((file-relative-name directory project-root)))))
(command (command
(pcase engine (list "rg --no-heading --line-number --color never"
(`ag (+helm-ag-search-args all-files recursive)) "-S"
(`rg (+helm-rg-search-args all-files recursive)) (when all-files-p "-z -uu")
('grep (+helm--grep-search directory query prompt all-files recursive) (unless recursive-p "--maxdepth 1")))
(cl-return t))))
(helm-ag-base-command (string-join command " "))) (helm-ag-base-command (string-join command " ")))
;; TODO Define our own sources instead ;; TODO Define our own sources instead
(helm-attrset 'name (format "[%s %s] Searching %s" (helm-attrset 'name (format "[rg %s] Searching %s"
engine
(string-join (delq nil (cdr command)) " ") (string-join (delq nil (cdr command)) " ")
(abbreviate-file-name directory)) (abbreviate-file-name directory))
helm-source-do-ag) helm-source-do-ag)
@ -153,82 +86,39 @@ order.
(cl-letf (((symbol-function 'helm-do-ag--helm) (cl-letf (((symbol-function 'helm-do-ag--helm)
(lambda () (helm :sources '(helm-source-do-ag) (lambda () (helm :sources '(helm-source-do-ag)
:prompt prompt :prompt prompt
:buffer "*helm-ag*" :buffer "*helm-rg*"
:keymap helm-do-ag-map :keymap helm-do-ag-map
:input query :input query
:history 'helm-ag--helm-history)))) :history 'helm-ag--helm-history))))
(helm-do-ag directory)))) (helm-do-ag directory))))
(defun +helm--get-command (format)
(cl-loop for tool in (cl-remove-duplicates +helm-project-search-engines :from-end t)
if (executable-find (symbol-name tool))
return (intern (format format tool))))
;;;###autoload ;;;###autoload
(defun +helm/project-search (&optional arg initial-query directory) (defun +helm/project-search (&optional arg initial-query directory)
"Performs a project search from the project root. "Performs a project search from the project root with ripgrep.
Uses the first available search backend from `+helm-project-search-engines'. If
ARG (universal argument), include all files, even hidden or compressed ones, in ARG (universal argument), include all files, even hidden or compressed ones, in
the search." the search."
(interactive "P") (interactive "P")
(funcall (or (+helm--get-command "+helm/%s") (+helm-file-search
#'+helm/grep) :query initial-query
arg :in directory
initial-query :all-files (and (not (null arg))
directory)) (listp arg))))
;;;###autoload ;;;###autoload
(defun +helm/project-search-from-cwd (&optional arg initial-query) (defun +helm/project-search-from-cwd (&optional arg initial-query)
"Performs a project search recursively from the current directory. "Performs a project search recursively from the current directory.
Uses the first available search backend from `+helm-project-search-engines'. If If ARG (universal argument), include all files, even hidden or compressed ones."
ARG (universal argument), include all files, even hidden or compressed ones."
(interactive "P") (interactive "P")
(funcall (or (+helm--get-command "+helm/%s-from-cwd") (+helm-file-search
#'+helm/grep-from-cwd) :query initial-query
arg
initial-query))
;;;###autoload (autoload '+helm/rg "completion/helm/autoload/helm" nil t)
;;;###autoload (autoload '+helm/rg-from-cwd "completion/helm/autoload/helm" nil t)
;;;###autoload (autoload '+helm/ag "completion/helm/autoload/helm" nil t)
;;;###autoload (autoload '+helm/ag-from-cwd "completion/helm/autoload/helm" nil t)
;;;###autoload (autoload '+helm/grep "completion/helm/autoload/helm" nil t)
;;;###autoload (autoload '+helm/grep-from-cwd "completion/helm/autoload/helm" nil t)
(dolist (engine `(,@(cl-remove-duplicates +helm-project-search-engines :from-end t) grep))
(defalias (intern (format "+helm/%s" engine))
(lambda (arg &optional query directory)
(interactive "P")
(+helm-file-search engine
:query query
:in directory
:all-files (and (not (null arg))
(listp arg))))
(format "Perform a project file search using %s.
QUERY is a regexp. If omitted, the current selection is used. If no selection is
active, the last known search is used.
ARG is the universal argument. If a number is passed through it, e.g. C-u 3, then
If ALL-FILES-P, search compressed and hidden files as well."
engine))
(defalias (intern (format "+helm/%s-from-cwd" engine))
(lambda (arg &optional query)
(interactive "P")
(+helm-file-search engine
:query query
:in default-directory :in default-directory
:all-files (and (not (null arg)) :all-files (and (not (null arg))
(listp arg)))) (listp arg))))
(format "Perform a project file search from the current directory using %s.
QUERY is a regexp. If omitted, the current selection is used. If no selection is ;;;###autoload
active, the last known search is used. (defun +helm/jump-list ()
"TODO"
If ALL-FILES-P, search compressed and hidden files as well." (interactive)
engine))) (error "not implemented yet"))

View file

@ -236,25 +236,9 @@ The point of this is to avoid Emacs locking up indexing massive file trees."
(#'counsel-file-jump)))) (#'counsel-file-jump))))
(defvar +ivy-file-search-shell
(or (executable-find "dash")
(executable-find "sh")
shell-file-name)
"The SHELL to invoke ag/rg/pt/git-grep/grep searchs from.
This only affects `+ivy/*' search commands (e.g. `+ivy/rg' and
`+ivy/project-search').
By default, this the most basic, uncustomized shell, to prevent interference
caused by slow shell configs at the cost of isolating these programs from
envvars that may have been set in the user's shell config to change their
behavior. If this bothers you, change this to `shell-file-name'.")
;;;###autoload ;;;###autoload
(cl-defun +ivy-file-search (engine &key query in all-files (recursive t)) (cl-defun +ivy-file-search (&key query in all-files (recursive t))
"Conduct a file search using ENGINE, which can be any of: rg, ag, pt, and "Conduct a file search using ripgrep.
grep. If omitted, ENGINE will default to the first one it detects, in that
order.
:query STRING :query STRING
Determines the initial input to search for. Determines the initial input to search for.
@ -264,18 +248,16 @@ order.
:recursive BOOL :recursive BOOL
Whether or not to search files recursively from the base directory." Whether or not to search files recursively from the base directory."
(declare (indent defun)) (declare (indent defun))
(let* ((project-root (or (doom-project-root) default-directory)) (unless (executable-find "rg")
(user-error "Couldn't find ripgrep in your PATH"))
(require 'counsel)
(let* ((ivy-more-chars-alist '((t . 1)))
(project-root (or (doom-project-root) default-directory))
(directory (or in project-root)) (directory (or in project-root))
(default-directory directory) (default-directory directory)
(engine (or engine (args (concat (if all-files " -uu")
(cl-loop for tool in +ivy-project-search-engines (unless recursive " --maxdepth 1"))))
if (executable-find (symbol-name tool)) (counsel-rg
return tool)
(and (or (executable-find "grep")
(executable-find "git"))
'grep)
(error "No search engine specified (is ag, rg, pt or git installed?)")))
(query
(or (if query query) (or (if query query)
(when (use-region-p) (when (use-region-p)
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning))) (let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
@ -287,108 +269,35 @@ order.
(cond ((and (string= substr " ") (cond ((and (string= substr " ")
(not (featurep! +fuzzy))) (not (featurep! +fuzzy)))
" ") " ")
((and (string= substr "|") ((string= substr "|")
(eq engine 'rg))
"\\\\\\\\|") "\\\\\\\\|")
((concat "\\\\" substr)))) ((concat "\\\\" substr))))
(rxt-quote-pcre query)))))))) (rxt-quote-pcre query)))))))
(prompt directory args
(format "%s%%s %s" (format "rg%s %s"
(symbol-name engine) args
(cond ((equal directory default-directory) (cond ((equal directory default-directory)
"./") "./")
((equal directory project-root) ((equal directory project-root)
(projectile-project-name)) (projectile-project-name))
((file-relative-name directory project-root)))))) ((file-relative-name directory project-root)))))))
(require 'counsel)
(let ((ivy-more-chars-alist
(if query '((t . 1)) ivy-more-chars-alist))
(shell-file-name +ivy-file-search-shell))
(pcase engine
(`grep
(let ((counsel-projectile-grep-initial-input query))
(cl-letf (((symbol-function #'counsel-locate-git-root)
(lambda () directory)))
(if all-files
(cl-letf (((symbol-function #'projectile-ignored-directories-rel)
(symbol-function #'ignore))
((symbol-function #'projectile-ignored-files-rel)
(symbol-function #'ignore)))
(counsel-projectile-grep))
(counsel-projectile-grep)))))
(`ag
(let ((args (concat (if all-files " -a")
(unless recursive " --depth 1"))))
(counsel-ag query directory args (format prompt args))))
(`rg
(let ((args (concat (if all-files " -uu")
(unless recursive " --maxdepth 1"))))
(counsel-rg query directory args (format prompt args))))
(_ (error "No search engine specified"))))))
(defun +ivy--get-command (format)
(cl-loop for tool in (cl-remove-duplicates +ivy-project-search-engines :from-end t)
if (executable-find (symbol-name tool))
return (intern (format format tool))))
;;;###autoload ;;;###autoload
(defun +ivy/project-search (&optional arg initial-query directory) (defun +ivy/project-search (&optional arg initial-query directory)
"Performs a project search from the project root. "Performs a live project search from the project root using ripgrep.
Uses the first available search backend from `+ivy-project-search-engines'. If If ARG (universal argument), include all files, even hidden or compressed ones,
ARG (universal argument), include all files, even hidden or compressed ones, in in the search."
the search."
(interactive "P") (interactive "P")
(funcall (or (+ivy--get-command "+ivy/%s") (+ivy-file-search :query initial-query :in directory :all-files arg))
#'+ivy/grep)
arg
initial-query
directory))
;;;###autoload ;;;###autoload
(defun +ivy/project-search-from-cwd (&optional arg initial-query) (defun +ivy/project-search-from-cwd (&optional arg initial-query)
"Performs a project search recursively from the current directory. "Performs a project search recursively from the current directory.
Uses the first available search backend from `+ivy-project-search-engines'. If If ARG (universal argument), include all files, even hidden or compressed ones."
ARG (universal argument), include all files, even hidden or compressed ones."
(interactive "P") (interactive "P")
(funcall (or (+ivy--get-command "+ivy/%s-from-cwd") (+ivy/project-search arg initial-query default-directory))
#'+ivy/grep-from-cwd)
arg
initial-query))
;;;###autoload (autoload '+ivy/rg "completion/ivy/autoload/ivy" nil t)
;;;###autoload (autoload '+ivy/rg-from-cwd "completion/ivy/autoload/ivy" nil t)
;;;###autoload (autoload '+ivy/ag "completion/ivy/autoload/ivy" nil t)
;;;###autoload (autoload '+ivy/ag-from-cwd "completion/ivy/autoload/ivy" nil t)
;;;###autoload (autoload '+ivy/grep "completion/ivy/autoload/ivy" nil t)
;;;###autoload (autoload '+ivy/grep-from-cwd "completion/ivy/autoload/ivy" nil t)
(dolist (engine `(,@(cl-remove-duplicates +ivy-project-search-engines :from-end t) grep))
(defalias (intern (format "+ivy/%s" engine))
(lambda (all-files-p &optional query directory)
(interactive "P")
(+ivy-file-search engine :query query :in directory :all-files all-files-p))
(format "Perform a project file search using %s.
QUERY is a regexp. If omitted, the current selection is used. If no selection is
active, the last known search is used.
If ALL-FILES-P, search compressed and hidden files as well."
engine))
(defalias (intern (format "+ivy/%s-from-cwd" engine))
(lambda (all-files-p &optional query)
(interactive "P")
(+ivy-file-search engine :query query :in default-directory :all-files all-files-p))
(format "Perform a project file search from the current directory using %s.
QUERY is a regexp. If omitted, the current selection is used. If no selection is
active, the last known search is used.
If ALL-FILES-P, search compressed and hidden files as well."
engine)))
;; ;;

View file

@ -208,17 +208,15 @@ This backend prefers \"just working\" over accuracy."
"Conducts a simple project text search for IDENTIFIER. "Conducts a simple project text search for IDENTIFIER.
Uses and requires `+ivy-file-search' or `+helm-file-search'. Will return nil if Uses and requires `+ivy-file-search' or `+helm-file-search'. Will return nil if
neither is available. These search backends will use ag, rg, or pt (in an order neither is available. These require ripgrep to be installed."
dictated by `+ivy-project-search-engines' or `+helm-project-search-engines',
falling back to git-grep)."
(unless identifier (unless identifier
(let ((query (rxt-quote-pcre identifier))) (let ((query (rxt-quote-pcre identifier)))
(ignore-errors (ignore-errors
(cond ((featurep! :completion ivy) (cond ((featurep! :completion ivy)
(+ivy-file-search nil :query query) (+ivy-file-search :query query)
t) t)
((featurep! :completion helm) ((featurep! :completion helm)
(+helm-file-search nil :query query) (+helm-file-search :query query)
t)))))) t))))))
(defun +lookup-evil-goto-definition-backend-fn (_identifier) (defun +lookup-evil-goto-definition-backend-fn (_identifier)