branch: elpa/projectile
commit 9d6b20b81cce3a827fb01c98cd1359b3ae6a697e
Author: Bozhidar Batsov <[email protected]>
Commit: Bozhidar Batsov <[email protected]>
Drive the reviewable search/replace from the dispatch switches
The two reviewable-search entries (sR literal, sX regexp) collapse into a
single sR that reads the --regexp switch, the same way --regexp already
drives the ag/ripgrep search. A new --case-sensitive switch seeds the
reviewable search/replace case-sensitive by binding case-fold-search
around the call; both can still be flipped with x/c in the results buffer.
Classic external-tool backends (grep/ag/rg) keep their own case handling
and aren't touched here; whole-word matching is a separate follow-up.
---
CHANGELOG.md | 1 +
projectile.el | 46 ++++++++++++++++++++++++++++++++--------
test/projectile-dispatch-test.el | 44 ++++++++++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6f0a14968a..4598f2d1a5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,6 +43,7 @@
* Add `projectile-frecency-max-projects` (default 100), which caps how many
projects' frecency history is kept so the store can't grow without bound.
* `projectile-replace-scan-chunk-size` is now a user-facing `defcustom` (was
an internal variable).
+* Wire the reviewable search/replace into the `projectile-dispatch` Modifiers:
the two literal/regexp search entries are folded into one `sR` driven by
`--regexp` (matching how `--regexp` already drives the ag/ripgrep search), and
a new `--case-sensitive` switch seeds the reviewable search/replace
case-sensitive. Both can still be flipped with `x`/`c` in the results buffer.
* Highlight the search tool and the default value in the search prompts, and
give them one consistent `Search [tool] for (default: X)` format across
`projectile-search`, `projectile-grep`/`-ag`/`-ripgrep` and the reviewable
search. The tool that will run (`grep`/`ag`/`ripgrep`, or `ripgrep`/`elisp` for
the reviewable search's literal fast-path) is faced with
`projectile-search-prompt-tool` and the symbol-at-point default with
`projectile-search-prompt-default`. The reviewable search now [...]
### Bugs fixed
diff --git a/projectile.el b/projectile.el
index 9b2ca2e05b..523727fe61 100644
--- a/projectile.el
+++ b/projectile.el
@@ -11767,6 +11767,30 @@ PROPS is a plist of:
:prefix-arg "--regexp")
(projectile-dispatch--define projectile-dispatch-ripgrep projectile-ripgrep
:prefix-arg "--regexp")
+
+(defun projectile-dispatch-search-review ()
+ "Reviewable search honouring the `--regexp' and `--case-sensitive' switches.
+`--regexp' runs the Emacs-regexp reviewer, `--case-sensitive' seeds the
+search case-sensitive; both can still be flipped (`x'/`c') in the results
+buffer."
+ (interactive)
+ (let ((switches (projectile-dispatch--args)))
+ (let ((case-fold-search (if (member "--case-sensitive" switches)
+ nil case-fold-search)))
+ (call-interactively (if (member "--regexp" switches)
+ #'projectile-search-regexp-review
+ #'projectile-search-review)))))
+
+(defun projectile-dispatch-replace-review ()
+ "Reviewable replace honouring the `--regexp' and `--case-sensitive' switches.
+Like `projectile-dispatch-search-review', but for the replace reviewer."
+ (interactive)
+ (let ((switches (projectile-dispatch--args)))
+ (let ((case-fold-search (if (member "--case-sensitive" switches)
+ nil case-fold-search)))
+ (call-interactively (if (member "--regexp" switches)
+ #'projectile-replace-regexp-review
+ #'projectile-replace-review)))))
;; New process
(projectile-dispatch--define projectile-dispatch-run projectile-run
:prefix-arg "--new-process")
@@ -11800,12 +11824,15 @@ PROPS is a plist of:
The switches in the Modifiers group tweak how the commands below run:
`--invalidate-cache' rebuilds the file cache first (file/dir commands),
-`--regexp' searches for a regexp (ag/ripgrep), `--new-process' starts a
-fresh process (shells), and `--display' opens the result in another
-window or frame (file/buffer/project commands)."
+`--regexp' searches for a regexp (the ag/ripgrep search and the
+reviewable search/replace), `--case-sensitive' seeds the reviewable
+search/replace case-sensitive, `--new-process' starts a fresh process
+(shells), and `--display' opens the result in another window or frame
+(file/buffer/project commands)."
["Modifiers"
("-i" "invalidate cache" "--invalidate-cache")
("-r" "regexp search" "--regexp")
+ ("-c" "case-sensitive search" "--case-sensitive")
("-n" "new process" "--new-process")
("-d" "display in" "--display="
:class transient-switches
@@ -11838,11 +11865,10 @@ window or frame (file/buffer/project commands)."
("sr" "ripgrep" projectile-dispatch-ripgrep)
("sa" "ag" projectile-dispatch-ag)
("sx" "references" projectile-find-references)
- ("sR" "search (review)" projectile-search-review)
- ("sX" "search regexp (review)" projectile-search-regexp-review)
+ ("sR" "search (review)" projectile-dispatch-search-review)
("o" "multi-occur" projectile-multi-occur)
("r" "replace" projectile-replace)
- ("R" "replace (review)" projectile-replace-review)]]
+ ("R" "replace (review)" projectile-dispatch-replace-review)]]
[["Project"
("p" "switch project" projectile-dispatch-switch-project)
("q" "switch open project" projectile-switch-open-project)
@@ -11886,9 +11912,11 @@ window or frame (file/buffer/project commands)."
The switches in the Modifiers group tweak how the commands below run:
`--invalidate-cache' rebuilds the file cache first (file/dir commands),
-`--regexp' searches for a regexp (ag/ripgrep), `--new-process' starts a
-fresh process (shells), and `--display' opens the result in another
-window or frame (file/buffer/project commands)."
+`--regexp' searches for a regexp (the ag/ripgrep search and the
+reviewable search/replace), `--case-sensitive' seeds the reviewable
+search/replace case-sensitive, `--new-process' starts a fresh process
+(shells), and `--display' opens the result in another window or frame
+(file/buffer/project commands)."
(interactive)
;; Loading `transient' is deferred until the menu is first used; this
;; stub is replaced by the real transient prefix on that first call.
diff --git a/test/projectile-dispatch-test.el b/test/projectile-dispatch-test.el
index f4c5f59ab2..846e02f4fa 100644
--- a/test/projectile-dispatch-test.el
+++ b/test/projectile-dispatch-test.el
@@ -74,6 +74,50 @@
(projectile-dispatch-switch-project)
(expect captured :to-equal (cons 'projectile-switch-project nil))))
+(describe "projectile-dispatch reviewable search/replace wrappers"
+ ;; These wrappers pick the literal vs regexp reviewer from `--regexp' and
+ ;; seed case sensitivity from `--case-sensitive' (by binding
+ ;; `case-fold-search' around the call). Capture both the command run and
+ ;; the `case-fold-search' in effect at that moment.
+ :var (captured cfs)
+ (before-each
+ (setq captured nil cfs 'unset)
+ (spy-on 'projectile-dispatch--args :and-return-value nil)
+ (spy-on 'call-interactively :and-call-fake
+ (lambda (command) (setq captured command cfs case-fold-search))))
+
+ (it "runs the literal search reviewer and leaves case as-is with no
modifiers"
+ (let ((case-fold-search t))
+ (projectile-dispatch-search-review))
+ (expect captured :to-be 'projectile-search-review)
+ (expect cfs :to-be t))
+
+ (it "runs the regexp search reviewer when --regexp is active"
+ (spy-on 'projectile-dispatch--args :and-return-value '("--regexp"))
+ (projectile-dispatch-search-review)
+ (expect captured :to-be 'projectile-search-regexp-review))
+
+ (it "seeds a case-sensitive search when --case-sensitive is active"
+ (spy-on 'projectile-dispatch--args :and-return-value '("--case-sensitive"))
+ (let ((case-fold-search t))
+ (projectile-dispatch-search-review))
+ (expect captured :to-be 'projectile-search-review)
+ (expect cfs :to-be nil))
+
+ (it "combines --regexp and --case-sensitive"
+ (spy-on 'projectile-dispatch--args :and-return-value '("--regexp"
"--case-sensitive"))
+ (let ((case-fold-search t))
+ (projectile-dispatch-search-review))
+ (expect captured :to-be 'projectile-search-regexp-review)
+ (expect cfs :to-be nil))
+
+ (it "applies the same switches to the replace reviewer"
+ (spy-on 'projectile-dispatch--args :and-return-value '("--regexp"
"--case-sensitive"))
+ (let ((case-fold-search t))
+ (projectile-dispatch-replace-review))
+ (expect captured :to-be 'projectile-replace-regexp-review)
+ (expect cfs :to-be nil)))
+
(describe "projectile-dispatch prefix"
(it "is defined as a transient prefix"
;; transient is bundled with Emacs 28.1+ (Projectile's minimum), so the