branch: externals/urgrep
commit 3370860a1b50a01c5f7f37cbeb60732f6ec62b93
Author: Jim Porter <jporterb...@gmail.com>
Commit: Jim Porter <jporterb...@gmail.com>

    Add support for toggling color output
---
 urgrep-tests.el | 78 ++++++++++++++++++++++++++++++++++++++-------------------
 urgrep.el       | 75 ++++++++++++++++++++++++++++++++++--------------------
 2 files changed, 100 insertions(+), 53 deletions(-)

diff --git a/urgrep-tests.el b/urgrep-tests.el
index b58391a0a1..f61ddd6e2f 100644
--- a/urgrep-tests.el
+++ b/urgrep-tests.el
@@ -109,7 +109,11 @@
     (urgrep-test--check-command
      (urgrep-command "foo" :tool tool :files '("*.c" "*.h"))
      (append common-args '("-g" "*.c" "-g" "*.h" "--heading" "-i" "-F" "--"
-                           "foo")))))
+                           "foo")))
+    ;; Color
+    (urgrep-test--check-command
+     (urgrep-command "foo" :tool tool :color nil)
+     (append '("rg" "--color" "never" "--heading" "-i" "-F" "--" "foo")))))
 
 (ert-deftest urgrep-tests-command-ag ()
   (let ((tool (assoc "ag" urgrep-tools))
@@ -172,7 +176,11 @@
     (urgrep-test--check-command
      (urgrep-command "foo" :tool tool :files '("*.c" "*.h"))
      (append common-args '("-G" "^[^\\000]*\\.(c|h)$" "--group" "-i" "-Q" "--"
-                           "foo")))))
+                           "foo")))
+    ;; Color
+    (urgrep-test--check-command
+     (urgrep-command "foo" :tool tool :color nil)
+     (append '("ag" "--nocolor" "--group" "-i" "-Q" "--" "foo")))))
 
 (ert-deftest urgrep-tests-command-ack ()
   (let ((tool (assoc "ack" urgrep-tools))
@@ -236,7 +244,11 @@
     (urgrep-test--check-command
      (urgrep-command "foo" :tool tool :files '("*.c" "*.h"))
      (append common-args '("-G" "^[^\\000]*\\.(c|h)$" "--group" "-i" "-Q" "--"
-                           "foo")))))
+                           "foo")))
+    ;; Color
+    (urgrep-test--check-command
+     (urgrep-command "foo" :tool tool :color nil)
+     (append '("ack" "--nocolor" "--group" "-i" "-Q" "--" "foo")))))
 
 (ert-deftest urgrep-tests-command-git-grep ()
   (let ((tool (assoc "git-grep" urgrep-tools))
@@ -300,57 +312,71 @@
      (append common-args group-args '("-i" "-F" "-e" "foo" "--" "*.el")))
     (urgrep-test--check-command
      (urgrep-command "foo" :tool tool :files '("*.c" "*.h"))
-     (append common-args group-args '("-i" "-F" "-e" "foo" "--" "*.c" 
"*.h")))))
+     (append common-args group-args '("-i" "-F" "-e" "foo" "--" "*.c" "*.h")))
+    ;; Color
+    (urgrep-test--check-command
+     (urgrep-command "foo" :tool tool :color nil)
+     (append
+      '("git" "--no-pager" "grep" "--no-color" "-n" "--recurse-submodules")
+      group-args
+      '("-i" "-F" "-e" "foo" "--")))))
 
 (ert-deftest urgrep-tests-command-grep ()
   (let ((tool (assoc "grep" urgrep-tools)))
     ;; String/case
-    (should (string-match "^find \\. .*grep -F .*-i .*foo"
+    (should (string-match "^find \\. .*grep --color=always -i -F .*foo"
                           (urgrep-command "foo" :tool tool)))
-    (should (string-match "^find \\. .*grep -F .*Foo"
+    (should (string-match "^find \\. .*grep --color=always -F .*Foo"
                           (urgrep-command "Foo" :tool tool)))
     (let ((case-fold-search nil))
-      (should (string-match "^find \\. .*grep -F .*foo"
+      (should (string-match "^find \\. .*grep --color=always -F .*foo"
                             (urgrep-command "foo" :tool tool))))
-    (should (string-match "^find \\. .*grep -F .*-i .*foo"
+    (should (string-match "^find \\. .*grep --color=always -i -F .*foo"
                           (urgrep-command "foo" :tool tool :case-fold t)))
-    (should (string-match "^find \\. .*grep -F .*foo"
+    (should (string-match "^find \\. .*grep --color=always -F .*foo"
                           (urgrep-command "foo" :tool tool :case-fold nil)))
-    (should (string-match "^find \\. .*grep -F .*-i .*foo"
+    (should (string-match "^find \\. .*grep --color=always -i -F .*foo"
                           (urgrep-command "foo" :tool tool :case-fold 'smart)))
-    (should (string-match "^find \\. .*grep -F .*Foo"
+    (should (string-match "^find \\. .*grep --color=always -F .*Foo"
                           (urgrep-command "Foo" :tool tool :case-fold 'smart)))
     ;; Group
-    (should (string-match "^find \\. .*grep -F .*-i .*foo"
+    (should (string-match "^find \\. .*grep --color=always -i -F .*foo"
                           (urgrep-command "foo" :tool tool :group nil)))
     ;; Regexp
     (let ((query (shell-quote-argument "(foo)")))
-      (should (string-match (concat "^find \\. .*grep -G .*-i .*" query)
-                            (urgrep-command "(foo)" :tool tool :regexp t)))
-      (should (string-match (concat "^find \\. .*grep -G .*-i .*" query)
-                            (urgrep-command "(foo)" :tool tool :regexp 'bre)))
-      (should (string-match (concat "^find \\. .*grep -E .*-i .*" query)
-                            (urgrep-command "(foo)" :tool tool :regexp 'ere)))
-      (should (string-match (concat "^find \\. .*grep -P .*-i .*" query)
-                            (urgrep-command "(foo)" :tool tool :regexp 
'pcre))))
+      (should (string-match
+               (concat "^find \\. .*grep --color=always -i -G .*" query)
+               (urgrep-command "(foo)" :tool tool :regexp t)))
+      (should (string-match
+               (concat "^find \\. .*grep --color=always -i -G .*" query)
+               (urgrep-command "(foo)" :tool tool :regexp 'bre)))
+      (should (string-match
+               (concat "^find \\. .*grep --color=always -i -E .*" query)
+               (urgrep-command "(foo)" :tool tool :regexp 'ere)))
+      (should (string-match
+               (concat "^find \\. .*grep --color=always -i -P .*" query)
+               (urgrep-command "(foo)" :tool tool :regexp 'pcre))))
     ;; Context
-    (should (string-match "^find \\. .*grep -F -C3 .*-i .*foo"
+    (should (string-match "^find \\. .*grep --color=always -C3 -i -F .*foo"
                           (urgrep-command "foo" :tool tool :context 3)))
-    (should (string-match "^find \\. .*grep -F -C3 .*-i .*foo"
+    (should (string-match "^find \\. .*grep --color=always -C3 -i -F .*foo"
                           (urgrep-command "foo" :tool tool :context '(3 . 3))))
-    (should (string-match "^find \\. .*grep -F -B2 -A4 .*-i .*foo"
+    (should (string-match "^find \\. .*grep --color=always -B2 -A4 -i -F .*foo"
                           (urgrep-command "foo" :tool tool :context '(2 . 4))))
     ;; File wildcard
     (let ((escape (lambda (i) (regexp-quote (shell-quote-argument i)))))
       (should (string-match
                (concat "^find \\. .*-i?name " (funcall escape "*.el")
-                       " .*grep -F .*-i .*foo")
+                       " .*grep --color=always -i -F .*foo")
                (urgrep-command "foo" :tool tool :files "*.el")))
       (should (string-match
                (concat "^find \\. .*-i?name " (funcall escape "*.c")
                        " -o -i?name " (funcall escape "*.h")
-                       " .*grep -F .*-i .*foo")
-               (urgrep-command "foo" :tool tool :files '("*.c" "*.h")))))))
+                       " .*grep --color=always -i -F .*foo")
+               (urgrep-command "foo" :tool tool :files '("*.c" "*.h")))))
+    ;; Color
+    (should (string-match "^find \\. .*grep +-i -F .*foo"
+                          (urgrep-command "foo" :tool tool :color nil)))))
 
 (ert-deftest urgrep-tests-get-tool-default ()
   (cl-letf (((symbol-function #'executable-find) #'always))
diff --git a/urgrep.el b/urgrep.el
index a553204af8..ef6f1f64bf 100644
--- a/urgrep.el
+++ b/urgrep.el
@@ -158,23 +158,27 @@ and escapes null characters."
     ((or `(,c . ,c) (and c (pred numberp))) (list (format "-C%d" c)))
     (`(,b . ,a) (list (format "-B%d" b) (format "-A%d" a)))))
 
-(cl-defun urgrep--rgrep-command (query &key tool regexp context files
-                                       &allow-other-keys)
+(cl-defun urgrep--rgrep-command (query &key tool regexp case-fold context files
+                                       color &allow-other-keys)
   "Get the command to run for QUERY when using rgrep.
-Optional keys TOOL, REGEXP, CONTEXT, and FILES are as in `urgrep-command'."
+Optional keys TOOL, REGEXP, CASE-FOLD, CONTEXT, FILES, and COLOR are
+as in `urgrep-command'."
   (grep-compute-defaults)
   ;; Locally add options to `grep-find-template' that grep.el isn't aware of.
   (let ((grep-find-template grep-find-template)
+        (grep-highlight-matches (if color 'always nil))
         (files (if files (mapconcat #'identity files " ") "*")))
-    (dolist (i `((regexp-arguments  . ,regexp)
-                 (context-arguments . ,context)))
-      (when-let ((args (urgrep-get-property-pcase tool (car i) (cdr i)))
+    (pcase-dolist (`(,k . ,v) `((regexp-arguments    . ,regexp)
+                                (case-fold-arguments . ,case-fold)
+                                (context-arguments   . ,context)))
+      (when-let ((args (urgrep-get-property-pcase tool k v))
                  (args (mapconcat #'urgrep--maybe-shell-quote-argument args
                                   " "))
                  ((string-match "<C>" grep-find-template)))
         (setq grep-find-template
-              (replace-match (concat args " <C>") t t grep-find-template))))
-    (rgrep-default-command query files nil)))
+              (replace-match (concat "<C> " args) t t grep-find-template))))
+    (let ((case-fold-search nil))
+      (rgrep-default-command query files nil))))
 
 (defun urgrep--rgrep-process-setup ()
   "Set up environment variables for rgrep.
@@ -191,9 +195,12 @@ See also `grep-process-setup'."
   `(("ripgrep"
      (executable-name "rg")
      (regexp-syntax (pcre))
-     (arguments (executable "--color" "always" "--colors" "path:fg:magenta"
-                 "--colors" "match:fg:red" "--colors" "match:style:bold"
-                 file-wildcards group context case-fold regexp "--" query))
+     (arguments (executable color file-wildcards group context case-fold regexp
+                            "--" query))
+     (color-arguments (('nil '("--color" "never"))
+                       (_    '("--color" "always" "--colors" "path:fg:magenta"
+                               "--colors" "match:fg:red" "--colors"
+                               "match:style:bold"))))
      (group-arguments (('nil '("--no-heading"))
                        (_    '("--heading"))))
      (context-arguments ,urgrep--context-arguments)
@@ -205,8 +212,10 @@ See also `grep-process-setup'."
     ("ag"
      (executable-name "ag")
      (regexp-syntax (pcre))
-     (arguments (executable "--color-path" "35" "--color-match" "1;31"
-                 file-wildcards group context case-fold regexp "--" query))
+     (arguments (executable color file-wildcards group context case-fold regexp
+                            "--" query))
+     (color-arguments (('nil '("--nocolor"))
+                       (_    '("--color-path" "35" "--color-match" "1;31"))))
      (group-arguments (('nil '("--nogroup"))
                        (_    '("--group"))))
      (context-arguments ,urgrep--context-arguments)
@@ -219,9 +228,11 @@ See also `grep-process-setup'."
     ("ack"
      (executable-name "ack")
      (regexp-syntax (pcre))
-     (arguments (executable "--color-filename" "magenta" "--color-match"
-                 "bold red" file-wildcards group context case-fold regexp "--"
-                 query))
+     (arguments (executable color file-wildcards group context case-fold regexp
+                            "--" query))
+     (color-arguments (('nil '("--nocolor"))
+                       (_    '("--color-filename" "magenta" "--color-match"
+                               "bold red"))))
      (group-arguments (('nil '("--nogroup"))
                        (_    '("--group"))))
      (context-arguments ,urgrep--context-arguments)
@@ -234,10 +245,15 @@ See also `grep-process-setup'."
      (executable-name "git")
      (vc-backend "Git")
      (regexp-syntax (bre ere pcre))
-     (arguments (executable "--no-pager" "-c" "color.grep.filename=magenta"
-                 "-c" "color.grep.match=bold red" "grep" "--color" "-n"
-                 "--recurse-submodules" group context case-fold regexp "-e"
-                 query "--" file-wildcards))
+     (arguments (executable "--no-pager" color "-n" "--recurse-submodules" 
group
+                            context case-fold regexp "-e" query "--"
+                            file-wildcards))
+     ;; git is a bit odd in that color specification happens *before* the
+     ;; subcommand and turning colors on/off happens *after*, so
+     ;; `color-arguments' needs to include the subcommand "grep".
+     (color-arguments (('nil '("grep" "--no-color"))
+                       (_    '("-c" "color.grep.filename=magenta" "-c"
+                               "color.grep.match=bold red" "grep" "--color"))))
      (group-arguments (((pred identity) '("--heading" "--break"))))
      (context-arguments ,urgrep--context-arguments)
      (regexp-arguments (('bre  '("-G"))
@@ -258,7 +274,8 @@ See also `grep-process-setup'."
      (regexp-arguments (('bre  '("-G"))
                         ('ere  '("-E"))
                         ('pcre '("-P"))
-                        (_     '("-F"))))))
+                        (_     '("-F"))))
+     (case-fold-arguments (((pred identity) '("-i"))))))
   "An alist of known tools to try when running urgrep.")
 
 (defcustom urgrep-preferred-tools nil
@@ -347,8 +364,8 @@ for MS shells."
           (t (car tool-syntaxes)))))
 
 ;;;###autoload
-(cl-defun urgrep-command (query &rest rest &key tool (group t) regexp
-                                (case-fold 'inherit) (context 0) files)
+(cl-defun urgrep-command (query &key tool (group t) regexp (case-fold 'inherit)
+                                (context 0) files (color t))
   "Return a command to use to search for QUERY.
 Several keyword arguments can be supplied to adjust the resulting
 command:
@@ -371,7 +388,9 @@ CONTEXT: the number of lines of context to show around 
results; either
 an integer (to show the same number of lines before and after) or a
 cons (to show CAR and CDR lines before and after, respectively).
 
-FILES: a wildcard (or list of wildcards) to limit the files searched."
+FILES: a wildcard (or list of wildcards) to limit the files searched.
+
+COLOR: non-nil (the default) if the output should use color."
   (let* ((regexp-syntax (if (eq regexp t) urgrep-regexp-syntax regexp))
          (files (if (listp files) files (list files)))
          (tool (urgrep-get-tool tool))
@@ -385,8 +404,9 @@ FILES: a wildcard (or list of wildcards) to limit the files 
searched."
       (setq case-fold (isearch-no-upper-case-p query regexp-syntax)))
     ;; Build the command arguments.
     (if cmd-fun
-        (apply cmd-fun query :tool tool :regexp regexp-syntax
-               :case-fold case-fold :files files rest)
+        (funcall cmd-fun query :tool tool :regexp regexp-syntax
+                 :case-fold case-fold :context context :files files
+                 :color color)
       (let* ((executable (urgrep-get-property tool 'executable-name))
              (arguments (urgrep-get-property tool 'arguments)))
         (setq arguments (cl-substitute executable 'executable arguments))
@@ -396,7 +416,8 @@ FILES: a wildcard (or list of wildcards) to limit the files 
searched."
                                     (case-fold      . ,case-fold)
                                     (context        . ,context)
                                     (group          . ,group)
-                                    (file-wildcards . ,files)))
+                                    (file-wildcards . ,files)
+                                    (color          . ,color)))
           (let* ((prop (intern (concat (symbol-name k) "-arguments")))
                  (args (urgrep-get-property-pcase tool prop v)))
             (setq arguments (cl-substitute args k arguments))))

Reply via email to