diff --git a/TODO.org b/TODO.org index 416cd2fd0..f1d826459 100644 --- a/TODO.org +++ b/TODO.org @@ -5,7 +5,7 @@ + [-] Work-in-progress + [X] Complete -** Unreleased [48/124] +** Unreleased [49/124] + [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/emacs-lsp/lsp-mode][lsp-mode]]: client for MS Language Server Protocol, keep an eye on this @@ -98,7 +98,7 @@ + [ ] Update screenshots + [ ] 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) -+ [-] 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] 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 diff --git a/modules/completion/ivy/autoload/evil.el b/modules/completion/ivy/autoload/evil.el index f41d996f1..2ce329c5d 100644 --- a/modules/completion/ivy/autoload/evil.el +++ b/modules/completion/ivy/autoload/evil.el @@ -1,11 +1,11 @@ ;;; 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) -(evil-define-operator +ivy:ag-search (beg end search regex-p &optional dir) - "Preform a counsel search with SEARCH. If SEARCH is nil and in visual mode, -use the selection, otherwise activate live ag searching in helm. +;;;###autoload (autoload '+ivy:file-search "completion/ivy/autoload/evil" nil t) +(evil-define-operator +ivy:file-search (beg end search regex-p &optional dir) + "Preform a `counsel-rg' search with SEARCH. If SEARCH is nil and in visual +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. 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 "") (let ((search (or search (and (evil-visual-state-p) - (and beg end - (let ((str (buffer-substring-no-properties beg end))) - (if regex-p (rxt-quote-pcre str) str)))) - +ivy--ag-last-search))) - (setq +ivy--ag-last-search search) - (counsel-ag (if regex-p search (regexp-quote search)) + (and beg end (buffer-substring-no-properties beg end))) + +ivy--file-last-search))) + (setq +ivy--file-last-search search) + (counsel-rg search (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) -(evil-define-operator +ivy:ag-search-cwd (beg end search regex-p) +;;;###autoload (autoload '+ivy:file-search-cwd "completion/ivy/autoload/evil" nil t) +(evil-define-operator +ivy:file-search-cwd (beg end search regex-p) :type inclusive :repeat nil (interactive "") - (+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) (evil-define-command +ivy:swiper (&optional search) diff --git a/modules/completion/ivy/autoload/ivy.el b/modules/completion/ivy/autoload/ivy.el index 118d41ecd..8c5f0fd0b 100644 --- a/modules/completion/ivy/autoload/ivy.el +++ b/modules/completion/ivy/autoload/ivy.el @@ -77,37 +77,67 @@ limit to buffers in the current workspace." ;;;###autoload (defun +ivy/tasks () + "Search through all TODO/FIXME tags in the current project using +`counsel-rg'." (interactive) - ;; TODO Make nicer - (counsel-ag " (TODO|FIXME|NOTE) " (doom-project-root))) + (counsel-rg "\\(TODO|FIXME\\)\\s" (doom-project-root) "--case-sensitive -w")) ;;;###autoload (defun +ivy*counsel-ag-function (string base-cmd extra-ag-args) - "Advice to get rid of the character limit from `counsel-ag-function', which -interferes with my custom :ag ex command `+ivy:ag-search'." + "Advice to 1) get rid of the character limit from `counsel-ag-function' and 2) +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) (setq extra-ag-args "")) - (if (< (length string) 1) + (if (< (length string) 1) ;; #1 (counsel-more-chars 1) (let ((default-directory counsel--git-grep-dir) (regex (counsel-unquote-regex-parens (setq ivy--old-re - (ivy--regex string))))) - (let ((ag-cmd (format base-cmd - (concat extra-ag-args - " -- " - (shell-quote-argument regex))))) + (ivy--regex + (counsel-unquote-regex-parens string)))))) ;; #2 + (let* ((args-end (string-match " -- " extra-ag-args)) + (file (if args-end + (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) (split-string (shell-command-to-string ag-cmd) "\n" t) (counsel--async-command ag-cmd) nil))))) ;;;###autoload -(defun +ivy/counsel-ag-occur () - "Invoke the search+replace wgrep buffer on the current ag search results." +(defun +ivy/wgrep-occur () + "Invoke the search+replace wgrep buffer on the current ag/rg search results." (interactive) - (require 'wgrep) - (call-interactively 'ivy-occur)) + (if (not (window-minibuffer-p)) + (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 (defun +ivy-yas-prompt (prompt choices &optional display-fn) diff --git a/modules/completion/ivy/config.el b/modules/completion/ivy/config.el index 03bb95e24..88bd599fa 100644 --- a/modules/completion/ivy/config.el +++ b/modules/completion/ivy/config.el @@ -2,7 +2,7 @@ ;; 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 in the ag occur buffer. ;; + An Atom/Sublime-Text Command-T implementation with `counsel-find-file' and ;; `counsel-projectile-find-file'. @@ -82,7 +82,7 @@ :config (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) @@ -107,15 +107,16 @@ (when dest-win (select-window dest-win)))))) - (add-hook! 'doom-popup-mode-hook - (when (eq major-mode 'ivy-occur-grep-mode) - (ivy-wgrep-change-to-wgrep-mode))) + (map! :map counsel-ag-map ; applies to counsel-rg too + [backtab] #'+ivy/wgrep-occur ; search/replace on results + "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) - (map! :map counsel-ag-map - [backtab] #'+ivy/counsel-ag-occur ; search/replace on results - "C-SPC" #'counsel-git-grep-recenter ; preview - "M-RET" #'+ivy/counsel-ag-open-in-other-window)) + ;; 1) Gets rid of the character limit from `counsel-ag-function' and + ;; 2) Disables ivy's over-zealous parentheses quoting behavior + ;; + ;; These both interfere with my custom :[ar]g ex command `+ivy:file-search'. + (advice-add #'counsel-ag-function :override #'+ivy*counsel-ag-function)) ;; Used by `counsel-M-x' diff --git a/modules/private/hlissner/+commands.el b/modules/private/hlissner/+commands.el index 85a2e684a..7c372fa79 100644 --- a/modules/private/hlissner/+commands.el +++ b/modules/private/hlissner/+commands.el @@ -51,8 +51,10 @@ ;; Project navigation (ex! "a" 'projectile-find-other-file) -(ex! "ag" '+ivy:ag-search) -(ex! "ag[cw]d" '+ivy:ag-search-cwd) +(ex! "ag" '+ivy:file-search) +(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! "sw[iper]" '+ivy:swiper) ; in-file search