emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 80d40e4 046/399: Dynamically handle grep tool look-arounds


From: Oleh Krehel
Subject: [elpa] master 80d40e4 046/399: Dynamically handle grep tool look-arounds
Date: Sat, 20 Jul 2019 14:56:46 -0400 (EDT)

branch: master
commit 80d40e4fb5e7da0f20bac05333ae068597a76863
Author: CeleritasCelery <address@hidden>
Commit: Oleh Krehel <address@hidden>

    Dynamically handle grep tool look-arounds
    
    Fixes #1935
---
 counsel.el | 51 ++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 38 insertions(+), 13 deletions(-)

diff --git a/counsel.el b/counsel.el
index 81b0402..a1e43f6 100644
--- a/counsel.el
+++ b/counsel.el
@@ -54,7 +54,7 @@
 
 (define-obsolete-function-alias 'counsel-more-chars 'ivy-more-chars "0.10.0")
 
-(defun counsel--elisp-to-pcre (regex)
+(defun counsel--elisp-to-pcre (regex &optional look-around)
   "Convert REGEX from Elisp format to PCRE format, on best-effort basis.
 REGEX may be of any format returned by an Ivy regex function,
 namely a string or a list.  The return value is always a string.
@@ -62,14 +62,23 @@ namely a string or a list.  The return value is always a 
string.
 Note that incorrect results may be returned for sufficiently
 complex regexes."
   (if (consp regex)
-      (mapconcat
-       (lambda (pair)
-         (let ((subexp (counsel--elisp-to-pcre (car pair))))
-           (if (string-match-p "|" subexp)
-               (format "(?:%s)" subexp)
-             subexp)))
-       (cl-remove-if-not #'cdr regex)
-       ".*")
+      (if look-around
+          (mapconcat
+           (lambda (pair)
+             (let ((subexp (counsel--elisp-to-pcre (car pair))))
+               (format "(?%c.*%s)"
+                       (if (cdr pair) ?= ?!)
+                       subexp)))
+           regex
+           "")
+        (mapconcat
+         (lambda (pair)
+           (let ((subexp (counsel--elisp-to-pcre (car pair))))
+             (if (string-match-p "|" subexp)
+                 (format "(?:%s)" subexp)
+               subexp)))
+         (cl-remove-if-not #'cdr regex)
+         ".*"))
     (replace-regexp-in-string
      "\\\\[(){}|]\\|[()]"
      (lambda (s)
@@ -2534,6 +2543,10 @@ regex string."
 
 (defvar counsel-ag-command nil)
 
+(defvar counsel--grep-tool-look-around t)
+
+(defvar counsel--regex-look-around nil)
+
 (counsel-set-async-exit-code 'counsel-ag 1 "No matches found")
 (ivy-set-occur 'counsel-ag 'counsel-ag-occur)
 (ivy-set-display-transformer 'counsel-ag 'counsel-git-grep-transformer)
@@ -2565,7 +2578,8 @@ NEEDLE is the search string."
 (defun counsel--grep-regex (str)
   (counsel--elisp-to-pcre
    (setq ivy--old-re
-         (funcall ivy--regex-function str))))
+         (funcall ivy--regex-function str))
+   counsel--regex-look-around))
 
 (defun counsel-ag-function (string)
   "Grep in the current directory for STRING."
@@ -2577,6 +2591,9 @@ NEEDLE is the search string."
          (ivy-more-chars))
        (let ((default-directory (ivy-state-directory ivy-last))
              (regex (counsel--grep-regex search-term)))
+         (if (and (stringp counsel--regex-look-around)
+                  (string-match-p "\\`(\\?[=!]" regex)) ;; using look-arounds
+             (setq switches (concat switches " " counsel--regex-look-around)))
          (counsel--async-command (counsel--format-ag-command
                                   switches
                                   (shell-quote-argument regex)))
@@ -2591,6 +2608,7 @@ EXTRA-AG-ARGS string, if non-nil, is appended to 
`counsel-ag-base-command'.
 AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument."
   (interactive)
   (setq counsel-ag-command counsel-ag-base-command)
+  (setq counsel--regex-look-around counsel--grep-tool-look-around)
   (counsel-require-program counsel-ag-command)
   (when current-prefix-arg
     (setq initial-directory
@@ -2663,7 +2681,8 @@ INITIAL-INPUT can be given as the initial minibuffer 
input.
 This uses `counsel-ag' with `counsel-pt-base-command' instead of
 `counsel-ag-base-command'."
   (interactive)
-  (let ((counsel-ag-base-command counsel-pt-base-command))
+  (let ((counsel-ag-base-command counsel-pt-base-command)
+        (counsel--grep-tool-look-around nil))
     (counsel-ag initial-input)))
 (cl-pushnew 'counsel-pt ivy-highlight-grep-commands)
 
@@ -2683,7 +2702,8 @@ INITIAL-INPUT can be given as the initial minibuffer 
input.
 This uses `counsel-ag' with `counsel-ack-base-command' replacing
 `counsel-ag-base-command'."
   (interactive)
-  (let ((counsel-ag-base-command counsel-ack-base-command))
+  (let ((counsel-ag-base-command counsel-ack-base-command)
+        (counsel--grep-tool-look-around t))
     (counsel-ag initial-input)))
 
 
@@ -2706,7 +2726,12 @@ INITIAL-DIRECTORY, if non-nil, is used as the root 
directory for search.
 EXTRA-RG-ARGS string, if non-nil, is appended to `counsel-rg-base-command'.
 RG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument."
   (interactive)
-  (let ((counsel-ag-base-command counsel-rg-base-command))
+  (let ((counsel-ag-base-command counsel-rg-base-command)
+        (counsel--grep-tool-look-around
+         (let ((rg (car (split-string counsel-rg-base-command)))
+               (switch "--pcre2"))
+           (and (eq 0 (call-process rg nil nil nil switch "--version"))
+                switch))))
     (counsel-ag initial-input initial-directory extra-rg-args rg-prompt)))
 (cl-pushnew 'counsel-rg ivy-highlight-grep-commands)
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]