completion/ivy: switch from ag to ripgrep

This commit is contained in:
Henrik Lissner 2017-05-06 16:41:17 +02:00
parent 8600d2e8d2
commit 434a5efeda
5 changed files with 75 additions and 43 deletions

View file

@ -5,7 +5,7 @@
+ [-] Work-in-progress + [-] Work-in-progress
+ [X] Complete + [X] Complete
** Unreleased [48/124] ** Unreleased [49/124]
+ [1/13] Potential plugins + [1/13] Potential plugins
+ [ ] [[https://github.com/etu/webpaste.el][webpaste.el]]: sending text to bin servies (like gist, ix.io, sprunge, etc.) + [ ] [[https://github.com/etu/webpaste.el][webpaste.el]]: sending text to bin servies (like gist, ix.io, sprunge, etc.)
+ [ ] [[https://github.com/emacs-lsp/lsp-mode][lsp-mode]]: client for MS Language Server Protocol, keep an eye on this + [ ] [[https://github.com/emacs-lsp/lsp-mode][lsp-mode]]: client for MS Language Server Protocol, keep an eye on this
@ -98,7 +98,7 @@
+ [ ] Update screenshots + [ ] Update screenshots
+ [ ] tools/upload: add ~+upload/open-remote-file~ command to open current file on the remote (with TRAMP) + [ ] tools/upload: add ~+upload/open-remote-file~ command to open current file on the remote (with TRAMP)
+ [ ] Fix ~0/0~ displaying in modeline (caused by leftover anzu state) + [ ] Fix ~0/0~ displaying in modeline (caused by leftover anzu state)
+ [-] lang/org: fix flickering line indentation while typing (caused by ~show-paren-mode~ in insert mode) + [X] completion/ivy: replace Ag with RipGrep
+ [X] Detect & load \~/.emacs.local.el, if available + [X] Detect & load \~/.emacs.local.el, if available
+ [X] lang/org: fontify items with all subitems done, e.g. ~+ [0/0] headline~ + [X] lang/org: fontify items with all subitems done, e.g. ~+ [0/0] headline~
+ [X] lang/org: fontify checked-checkbox items the same way DONE headlines are + [X] lang/org: fontify checked-checkbox items the same way DONE headlines are

View file

@ -1,11 +1,11 @@
;;; completion/ivy/autoload/evil.el ;;; completion/ivy/autoload/evil.el
(defvar +ivy--ag-last-search nil) (defvar +ivy--file-last-search nil)
;;;###autoload (autoload '+ivy:ag-search "completion/ivy/autoload/evil" nil t) ;;;###autoload (autoload '+ivy:file-search "completion/ivy/autoload/evil" nil t)
(evil-define-operator +ivy:ag-search (beg end search regex-p &optional dir) (evil-define-operator +ivy:file-search (beg end search regex-p &optional dir)
"Preform a counsel search with SEARCH. If SEARCH is nil and in visual mode, "Preform a `counsel-rg' search with SEARCH. If SEARCH is nil and in visual
use the selection, otherwise activate live ag searching in helm. mode, use the selection, otherwise activate live ag searching in helm.
If REGEX-P is non-nil, SEARCH will be treated as a regular expression. If REGEX-P is non-nil, SEARCH will be treated as a regular expression.
DIR specifies the default-directory from which ag is run." DIR specifies the default-directory from which ag is run."
@ -13,20 +13,19 @@ DIR specifies the default-directory from which ag is run."
(interactive "<r><a><!>") (interactive "<r><a><!>")
(let ((search (or search (let ((search (or search
(and (evil-visual-state-p) (and (evil-visual-state-p)
(and beg end (and beg end (buffer-substring-no-properties beg end)))
(let ((str (buffer-substring-no-properties beg end))) +ivy--file-last-search)))
(if regex-p (rxt-quote-pcre str) str)))) (setq +ivy--file-last-search search)
+ivy--ag-last-search))) (counsel-rg search
(setq +ivy--ag-last-search search)
(counsel-ag (if regex-p search (regexp-quote search))
(or dir (doom-project-root)) (or dir (doom-project-root))
(concat "--nocolor --nogroup" (if regex-p " -Q"))))) (unless regex-p " -F")
(format "File search (%s)" (if regex-p "regex" "literal")))))
;;;###autoload (autoload '+ivy:ag-search-cwd "completion/ivy/autoload/evil" nil t) ;;;###autoload (autoload '+ivy:file-search-cwd "completion/ivy/autoload/evil" nil t)
(evil-define-operator +ivy:ag-search-cwd (beg end search regex-p) (evil-define-operator +ivy:file-search-cwd (beg end search regex-p)
:type inclusive :repeat nil :type inclusive :repeat nil
(interactive "<r><a><!>") (interactive "<r><a><!>")
(+ivy:ag-search beg end search regex-p default-directory)) (+ivy:file-search beg end search regex-p default-directory))
;;;###autoload (autoload '+ivy:swiper "completion/ivy/autoload/evil" nil t) ;;;###autoload (autoload '+ivy:swiper "completion/ivy/autoload/evil" nil t)
(evil-define-command +ivy:swiper (&optional search) (evil-define-command +ivy:swiper (&optional search)

View file

@ -77,37 +77,67 @@ limit to buffers in the current workspace."
;;;###autoload ;;;###autoload
(defun +ivy/tasks () (defun +ivy/tasks ()
"Search through all TODO/FIXME tags in the current project using
`counsel-rg'."
(interactive) (interactive)
;; TODO Make nicer (counsel-rg "\\(TODO|FIXME\\)\\s" (doom-project-root) "--case-sensitive -w"))
(counsel-ag " (TODO|FIXME|NOTE) " (doom-project-root)))
;;;###autoload ;;;###autoload
(defun +ivy*counsel-ag-function (string base-cmd extra-ag-args) (defun +ivy*counsel-ag-function (string base-cmd extra-ag-args)
"Advice to get rid of the character limit from `counsel-ag-function', which "Advice to 1) get rid of the character limit from `counsel-ag-function' and 2)
interferes with my custom :ag ex command `+ivy:ag-search'." disable ivy's over-zealous parentheses quoting behavior, both of which
interferes with my custom :[ar]g ex command `+ivy:file-search'."
(when (null extra-ag-args) (when (null extra-ag-args)
(setq extra-ag-args "")) (setq extra-ag-args ""))
(if (< (length string) 1) (if (< (length string) 1) ;; #1
(counsel-more-chars 1) (counsel-more-chars 1)
(let ((default-directory counsel--git-grep-dir) (let ((default-directory counsel--git-grep-dir)
(regex (counsel-unquote-regex-parens (regex (counsel-unquote-regex-parens
(setq ivy--old-re (setq ivy--old-re
(ivy--regex string))))) (ivy--regex
(let ((ag-cmd (format base-cmd (counsel-unquote-regex-parens string)))))) ;; #2
(concat extra-ag-args (let* ((args-end (string-match " -- " extra-ag-args))
" -- " (file (if args-end
(shell-quote-argument regex))))) (substring-no-properties extra-ag-args (+ args-end 3))
""))
(extra-ag-args (if args-end
(substring-no-properties extra-ag-args 0 args-end)
extra-ag-args))
(ag-cmd (format base-cmd
(concat extra-ag-args
" -- "
(shell-quote-argument regex)
file))))
(if (file-remote-p default-directory) (if (file-remote-p default-directory)
(split-string (shell-command-to-string ag-cmd) "\n" t) (split-string (shell-command-to-string ag-cmd) "\n" t)
(counsel--async-command ag-cmd) (counsel--async-command ag-cmd)
nil))))) nil)))))
;;;###autoload ;;;###autoload
(defun +ivy/counsel-ag-occur () (defun +ivy/wgrep-occur ()
"Invoke the search+replace wgrep buffer on the current ag search results." "Invoke the search+replace wgrep buffer on the current ag/rg search results."
(interactive) (interactive)
(require 'wgrep) (if (not (window-minibuffer-p))
(call-interactively 'ivy-occur)) (user-error "No completion session is active")
(require 'wgrep)
(let* ((caller (ivy-state-caller ivy-last))
(occur-fn (plist-get ivy--occurs-list caller))
(buffer
(generate-new-buffer
(format "*ivy-occur%s \"%s\"*"
(if caller (concat " " (prin1-to-string caller)) "")
ivy-text))))
(with-current-buffer buffer
(let ((inhibit-read-only t))
(erase-buffer)
(funcall occur-fn))
(setf (ivy-state-text ivy-last) ivy-text)
(setq ivy-occur-last ivy-last)
(setq-local ivy--directory ivy--directory))
(ivy-exit-with-action
`(lambda (_)
(pop-to-buffer ,buffer)
(ivy-wgrep-change-to-wgrep-mode))))))
;;;###autoload ;;;###autoload
(defun +ivy-yas-prompt (prompt choices &optional display-fn) (defun +ivy-yas-prompt (prompt choices &optional display-fn)

View file

@ -2,7 +2,7 @@
;; Ivy is my completion backend of choice. With counsel's help, I get: ;; Ivy is my completion backend of choice. With counsel's help, I get:
;; ;;
;; + Project-wide search with `counsel-ag' (or `+ivy:ag-search') ;; + Project-wide search with `counsel-rg' (and `+ivy:file-search')
;; + Project-wide replace if you press <backtab> in the ag occur buffer. ;; + Project-wide replace if you press <backtab> in the ag occur buffer.
;; + An Atom/Sublime-Text Command-T implementation with `counsel-find-file' and ;; + An Atom/Sublime-Text Command-T implementation with `counsel-find-file' and
;; `counsel-projectile-find-file'. ;; `counsel-projectile-find-file'.
@ -82,7 +82,7 @@
:config :config
(setq counsel-find-file-ignore-regexp "\\(?:^[#.]\\)\\|\\(?:[#~]$\\)\\|\\(?:^Icon?\\)") (setq counsel-find-file-ignore-regexp "\\(?:^[#.]\\)\\|\\(?:[#~]$\\)\\|\\(?:^Icon?\\)")
(set! :popup "^\\*ivy-occur counsel-ag" :size 25 :regexp t :autokill t) (set! :popup "^\\*ivy-occur counsel-[ar]g" :size 25 :regexp t :autokill t)
(require 'counsel-projectile) (require 'counsel-projectile)
@ -107,15 +107,16 @@
(when dest-win (when dest-win
(select-window dest-win)))))) (select-window dest-win))))))
(add-hook! 'doom-popup-mode-hook (map! :map counsel-ag-map ; applies to counsel-rg too
(when (eq major-mode 'ivy-occur-grep-mode) [backtab] #'+ivy/wgrep-occur ; search/replace on results
(ivy-wgrep-change-to-wgrep-mode))) "C-SPC" #'counsel-git-grep-recenter ; preview
"M-RET" #'+ivy/counsel-ag-open-in-other-window)
(advice-add #'counsel-ag-function :override #'+ivy*counsel-ag-function) ;; 1) Gets rid of the character limit from `counsel-ag-function' and
(map! :map counsel-ag-map ;; 2) Disables ivy's over-zealous parentheses quoting behavior
[backtab] #'+ivy/counsel-ag-occur ; search/replace on results ;;
"C-SPC" #'counsel-git-grep-recenter ; preview ;; These both interfere with my custom :[ar]g ex command `+ivy:file-search'.
"M-RET" #'+ivy/counsel-ag-open-in-other-window)) (advice-add #'counsel-ag-function :override #'+ivy*counsel-ag-function))
;; Used by `counsel-M-x' ;; Used by `counsel-M-x'

View file

@ -51,8 +51,10 @@
;; Project navigation ;; Project navigation
(ex! "a" 'projectile-find-other-file) (ex! "a" 'projectile-find-other-file)
(ex! "ag" '+ivy:ag-search) (ex! "ag" '+ivy:file-search)
(ex! "ag[cw]d" '+ivy:ag-search-cwd) (ex! "ag[cw]d" '+ivy:file-search-cwd)
(ex! "rg" '+ivy:file-search)
(ex! "rg[cw]d" '+ivy:file-search-cwd)
(ex! "cd" '+hlissner:cd) (ex! "cd" '+hlissner:cd)
(ex! "sw[iper]" '+ivy:swiper) ; in-file search (ex! "sw[iper]" '+ivy:swiper) ; in-file search