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

Reply via email to