Sometimes curiosity leads me to use alternative packages for built-in solutions
which I should have explored better. For instance, it took me moving through
helm-ag and helm-rg1 before realising Helm already comes with a functionality
suitable for my needs:
By now I expect you to be familiar with the wonders of ripgrep. I was heavily
counsel-rg back in my Ivy days, and I needed a similar command in
Helm. Truth be told,
helm-do-grep-ag is not the replacement I was looking for,
but understanding its code helped me devise my own utilities for super fast
First of all, let’s use
ripgrep instead of
(setq helm-grep-ag-command (concat "rg" " --color=never" " --smart-case" " --no-heading" " --line-number %s %s %s") helm-grep-file-path-style 'relative)
Note that the string for
helm-grep-ag-command comes from its documentation.
helm-grep-file-path-style because I find relative file
paths in the search result buffer more useful than their base name.
helm-do-grep-ag defers to
helm-grep-ag, which in turns defers to
helm-grep-ag-1, and this is the Helm facility I can leverage for my own
(defun mu-helm-rg (directory &optional with-types) "Search in DIRECTORY with RG. With WITH-TYPES, ask for file types to search in." (interactive "P") (require 'helm-adaptive) (helm-grep-ag-1 (expand-file-name directory) (helm-aif (and with-types (helm-grep-ag-get-types)) (helm-comp-read "RG type: " it :must-match t :marked-candidates t :fc-transformer 'helm-adaptive-sort :buffer "*helm rg types*"))))
helm-grep-ag with minor aesthetic changes, but you know me. Note
with-types parameter. If I use this command with
C-u I get to pick one or
more file types to narrow the search down to. I don’t remember if this is
counsel-rg, but in large projects it is an absolute must have.
Furthermore, the symbol at point, if any, is the default search parameter. Why
is this awesome? Keep reading.
mu-helm-rg in place, I can build a couple of commands to make my life
(defun mu-helm-project-search (&optional with-types) "Search in current project with RG. With WITH-TYPES, ask for file types to search in." (interactive "P") (mu-helm-rg (mu--project-root) with-types)) (defun mu-helm-file-search (&optional with-types) "Search in `default-directory' with RG. With WITH-TYPES, ask for file types to search in." (interactive "P") (mu-helm-rg default-directory with-types))
In case you are wondering,
mu–-project-root is a trivial function to figure out
the current project’s root directory.
(defun mu--project-root () "Return the project root directory or `helm-current-directory'." (require 'helm-ls-git) (if-let (dir (helm-ls-git-root-dir)) dir (helm-current-directory)))
I don’t need
mu-helm-file-search as often as
mu-helm-project-search, which is
why I’ve bound the latter to M-?. I use this key binding so much it must be a
quick one. And this is why having the symbol at point automatically picked up by
mu-helm-rg is so important: it just makes the whole search operation as simple
Oh wait, the symbol at point is not what you are after? No problem, you can start typing whatever you want and have Helm ripgrepping your files.
Both packages seem hardly maintained these days. ↩