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

    Add support for various regexp syntaxes, defaulting to BRE
---
 urgrep-tests.el |  41 +++++++++++++++++-----
 urgrep.el       | 104 ++++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 102 insertions(+), 43 deletions(-)

diff --git a/urgrep-tests.el b/urgrep-tests.el
index fd79b04b7b..55472139df 100644
--- a/urgrep-tests.el
+++ b/urgrep-tests.el
@@ -33,8 +33,12 @@
                    (concat common-args "-F --heading -- foo")))
     (should (equal (urgrep-command "foo" :tool tool :group nil)
                    (concat common-args "-F --no-heading -- foo")))
-    (should (equal (urgrep-command "foo" :tool tool :regexp t)
-                   (concat common-args "--heading -- foo")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'bre)
+                   (concat common-args "--heading -- \\\\\\(foo\\\\\\)")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'ere)
+                   (concat common-args "--heading -- \\(foo\\)")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'pcre)
+                   (concat common-args "--heading -- \\(foo\\)")))
     (should (equal (urgrep-command "foo" :tool tool :context 3)
                    (concat common-args "-C3 -F --heading -- foo")))))
 
@@ -45,8 +49,12 @@
                    (concat common-args "-Q --group -- foo")))
     (should (equal (urgrep-command "foo" :tool tool :group nil)
                    (concat common-args "-Q --nogroup -- foo")))
-    (should (equal (urgrep-command "foo" :tool tool :regexp t)
-                   (concat common-args "--group -- foo")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'bre)
+                   (concat common-args "--group -- \\\\\\(foo\\\\\\)")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'ere)
+                   (concat common-args "--group -- \\(foo\\)")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'pcre)
+                   (concat common-args "--group -- \\(foo\\)")))
     (should (equal (urgrep-command "foo" :tool tool :context 3)
                    (concat common-args "-C3 -Q --group -- foo")))))
 
@@ -57,8 +65,12 @@
                    (concat common-args "-Q --group -- foo")))
     (should (equal (urgrep-command "foo" :tool tool :group nil)
                    (concat common-args "-Q --nogroup -- foo")))
-    (should (equal (urgrep-command "foo" :tool tool :regexp t)
-                   (concat common-args "--group -- foo")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'bre)
+                   (concat common-args "--group -- \\\\\\(foo\\\\\\)")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'ere)
+                   (concat common-args "--group -- \\(foo\\)")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'pcre)
+                   (concat common-args "--group -- \\(foo\\)")))
     (should (equal (urgrep-command "foo" :tool tool :context 3)
                    (concat common-args "-C3 -Q --group -- foo")))))
 
@@ -69,8 +81,12 @@
                    (concat common-args "-F --heading --break -e foo")))
     (should (equal (urgrep-command "foo" :tool tool :group nil)
                    (concat common-args "-F -e foo")))
-    (should (equal (urgrep-command "foo" :tool tool :regexp t)
-                   (concat common-args "--heading --break -e foo")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'bre)
+                   (concat common-args "-G --heading --break -e \\(foo\\)")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'ere)
+                   (concat common-args "-E --heading --break -e \\(foo\\)")))
+    (should (equal (urgrep-command "(foo)" :tool tool :regexp-syntax 'pcre)
+                   (concat common-args "-P --heading --break -e \\(foo\\)")))
     (should (equal (urgrep-command "foo" :tool tool :context 3)
                    (concat common-args "-C3 -F --heading --break -e foo")))))
 
@@ -81,7 +97,14 @@
     (should (string-match "^find \\."
                           (urgrep-command "foo" :tool tool :group nil)))
     (should (string-match "^find \\."
-                          (urgrep-command "foo" :tool tool :regexp t)))
+                          (urgrep-command "(foo)" :tool tool
+                                          :regexp-syntax 'bre)))
+    (should (string-match "^find \\."
+                          (urgrep-command "(foo)" :tool tool
+                                          :regexp-syntax 'ere)))
+    (should (string-match "^find \\."
+                          (urgrep-command "(foo)" :tool tool
+                                          :regexp-syntax 'pcre)))
     (should (string-match "^find \\."
                           (urgrep-command "foo" :tool tool :context 3)))))
 
diff --git a/urgrep.el b/urgrep.el
index 418429589e..3072e8960e 100644
--- a/urgrep.el
+++ b/urgrep.el
@@ -49,6 +49,13 @@
   :type 'boolean
   :group 'urgrep)
 
+(defcustom urgrep-regexp-syntax 'bre
+  "Default syntax to use for regexp searches."
+  :type '(choice (const :tag "Basic regexp" bre)
+                 (const :tag "Extended regexp" ere)
+                 (const :tag "Perl-compatible regexp" pcre))
+  :group 'urgrep)
+
 (defcustom urgrep-context-lines 0
   "Number of lines of context to show."
   :type 'integer
@@ -81,6 +88,7 @@
 (defvar urgrep-tools
   `(("ripgrep"
      (executable-name "rg")
+     (regexp-syntax (pcre))
      (pre-arguments ("--color" "always" "--colors" "path:fg:magenta"
                      "--colors" "match:fg:red" "--colors" "match:style:bold"))
      (post-arguments ("--"))
@@ -90,6 +98,7 @@
      (context-arguments "-C%d"))
     ("ag"
      (executable-name "ag")
+     (regexp-syntax (pcre))
      (pre-arguments ("--color-path" "35" "--color-match" "1;31"))
      (post-arguments ("--"))
      (group-arguments ((t   ("--group"))
@@ -98,6 +107,7 @@
      (context-arguments "-C%d"))
     ("ack"
      (executable-name "ack")
+     (regexp-syntax (pcre))
      (pre-arguments ("--color-filename" "magenta" "--color-match" "bold red"))
      (post-arguments ("--"))
      (group-arguments ((t   ("--group"))
@@ -107,12 +117,16 @@
     ("git-grep"
      (executable-name "git")
      (vc-backend "Git")
+     (regexp-syntax (bre ere pcre))
      (pre-arguments ("--no-pager" "-c" "color.grep.filename=magenta"
                      "-c" "color.grep.match=bold red" "grep" "--color" "-n"
                      "--recurse-submodules"))
      (post-arguments ("-e"))
      (group-arguments ((t ("--heading" "--break"))))
-     (regexp-arguments ((nil ("-F"))))
+     (regexp-arguments ((bre ("-G"))
+                        (ere ("-E"))
+                        (pcre ("-P"))
+                        (nil ("-F"))))
      (context-arguments "-C%d"))
     ("grep"
      (executable-name "grep")
@@ -156,33 +170,54 @@ for MS shells."
       argument
     (shell-quote-argument argument)))
 
-(cl-defun urgrep-command (query &rest rest &key tool (group t) regexp
+(defun urgrep--get-best-syntax (syntax tool)
+  "Return the regexp syntax closest to SYNTAX that TOOL supports."
+  (let ((tool-syntaxes (urgrep-get-property tool 'regexp-syntax)))
+    (cond ((not syntax) nil)
+          ((memq syntax tool-syntaxes) syntax)
+          ((and (eq syntax 'ere) (memq 'pcre tool-syntaxes)) 'pcre)
+          ((and (eq syntax 'pcre) (memq 'extended tool-syntaxes)) 'ere)
+          (t (car tool-syntaxes)))))
+
+(defun urgrep--convert-regexp (expr from-syntax to-syntax)
+  "Convert the regexp EXP from FROM-SYNTAX to TO-SYNTAX."
+  (cond ((and (not (eq from-syntax to-syntax))
+              (or (eq from-syntax 'bre) (eq to-syntax 'bre)))
+         ;; XXX: This is a bit of a hack, but xref.el contains an internal
+         ;; function for converting between basic and extended regexps. It 
might
+         ;; be wise to use our own implementation, but this should work for 
now.
+         (require 'xref)
+         (xref--regexp-to-extended expr))
+        (t expr)))
+
+(cl-defun urgrep-command (query &rest rest &key tool (group t) regexp-syntax
                                 (context 0))
-  (let* ((tool (or tool (urgrep-get-tool)))
-         (cmd-fun (urgrep-get-property tool 'command-function)))
-    (if cmd-fun
-        (apply cmd-fun query rest)
-      (let ((executable (urgrep-get-property tool 'executable-name))
-            (pre-args (or (urgrep-get-property tool 'pre-arguments) '()))
-            (arguments (or (urgrep-get-property tool 'post-arguments) '())))
-        ;; Fill in group arguments. XXX: Maybe figure out a more flexible way 
to
-        ;; do this?
-        (when-let ((x (urgrep-get-property-assoc tool 'group-arguments group)))
-          (setq arguments (append x arguments)))
-        ;; Fill in regexp/literal arguments.
-        (when-let ((x (urgrep-get-property-assoc tool 'regexp-arguments
-                                                 regexp)))
-          (setq arguments (append x arguments)))
-        ;; Fill in context arguments.
-        (when-let (((> context 0))
-                   (prop (urgrep-get-property tool 'context-arguments))
-                   (context-arg (format prop context)))
-          (setq arguments (append (list context-arg) arguments)))
-        ;; FIXME: Inside compile and dired buffers, `shell-quote-argument'
-        ;; doesn't handle TRAMP right...
-        (mapconcat #'urgrep--maybe-shell-quote-argument
-                   (append `(,executable) pre-args arguments `(,query))
-                   " ")))))
+  (if-let ((tool (or tool (urgrep-get-tool)))
+           (cmd-fun (urgrep-get-property tool 'command-function)))
+      (apply cmd-fun query rest)
+    (let* ((tool-re-syntax (urgrep--get-best-syntax regexp-syntax tool))
+           (query (urgrep--convert-regexp query regexp-syntax tool-re-syntax))
+           (executable (urgrep-get-property tool 'executable-name))
+           (pre-args (or (urgrep-get-property tool 'pre-arguments) '()))
+           (arguments (or (urgrep-get-property tool 'post-arguments) '())))
+      ;; Fill in group arguments. XXX: Maybe figure out a more flexible way to
+      ;; do this?
+      (when-let ((x (urgrep-get-property-assoc tool 'group-arguments group)))
+        (setq arguments (append x arguments)))
+      ;; Fill in regexp/literal arguments.
+      (when-let ((x (urgrep-get-property-assoc tool 'regexp-arguments
+                                               tool-re-syntax)))
+        (setq arguments (append x arguments)))
+      ;; Fill in context arguments.
+      (when-let (((> context 0))
+                 (prop (urgrep-get-property tool 'context-arguments))
+                 (context-arg (format prop context)))
+        (setq arguments (append (list context-arg) arguments)))
+      ;; FIXME: Inside compile and dired buffers, `shell-quote-argument'
+      ;; doesn't handle TRAMP right...
+      (mapconcat #'urgrep--maybe-shell-quote-argument
+                 (append `(,executable) pre-args arguments `(,query))
+                 " "))))
 
 
 ;; urgrep-mode
@@ -255,7 +290,7 @@ for MS shells."
       (tool-bar-local-item
        "cancel" 'kill-compilation 'kill-compilation map
        :enable '(let ((buffer (compilation-find-buffer)))
-                 (get-buffer-process buffer))
+                  (get-buffer-process buffer))
        :help "Stop search")
       (tool-bar-local-item
        "refresh" 'recompile 'recompile map
@@ -357,17 +392,17 @@ See `compilation-error-regexp-alist' for format details.")
       ;; sets buffer-modified to nil before running the command,
       ;; so the buffer is still unmodified if there is no output.
       (cond ((and (zerop code) (buffer-modified-p))
-            (if (> urgrep-num-matches-found 0)
+             (if (> urgrep-num-matches-found 0)
                  (cons (format (ngettext "finished with %d match found\n"
                                          "finished with %d matches found\n"
                                          urgrep-num-matches-found)
                                urgrep-num-matches-found)
                        "matched")
                '("finished with matches found\n" . "matched")))
-           ((not (buffer-modified-p))
-            '("finished with no matches found\n" . "no match"))
-           (t
-            (cons msg code)))
+            ((not (buffer-modified-p))
+             '("finished with no matches found\n" . "no match"))
+            (t
+             (cons msg code)))
     (cons msg code)))
 
 (defun urgrep-filter ()
@@ -504,7 +539,8 @@ command."
                   (read-from-minibuffer prompt nil urgrep-minibuffer-map nil
                                         'urgrep-search-history default)))
          (query (if (equal query "") default query)))
-    (list query :group urgrep-group-matches :regexp urgrep-search-regexp
+    (list query :group urgrep-group-matches
+          :regexp-syntax (and urgrep-search-regexp urgrep-regexp-syntax)
           :context urgrep-context-lines)))
 
 

Reply via email to