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

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

[elpa] master f5508e5 390/399: swiper.el (swiper-isearch-backward): Add


From: Oleh Krehel
Subject: [elpa] master f5508e5 390/399: swiper.el (swiper-isearch-backward): Add backward search
Date: Sat, 20 Jul 2019 14:58:06 -0400 (EDT)

branch: master
commit f5508e598147e7e33ca44612435245c875cd6286
Author: Andrew Schwartzmeyer <address@hidden>
Commit: Oleh Krehel <address@hidden>

    swiper.el (swiper-isearch-backward): Add backward search
    
    - Sets the first candidate before the point instead of after the point
    - Meant to be used on `C-r` like `swiper-isearch` on `C-s`
    - This searches in reverse in comparison to `swiper-isearch` in order to
      handle the placement of the point properly.
    
    ivy-test.el (swiper-isearch-backward): Add new tests
    
    - Note explains the discrepancy in behaviors.
    
    Fixes #2125
---
 ivy-test.el | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 swiper.el   | 36 +++++++++++++++++++++++++++---------
 2 files changed, 76 insertions(+), 9 deletions(-)

diff --git a/ivy-test.el b/ivy-test.el
index 6566279..a83e728 100644
--- a/ivy-test.el
+++ b/ivy-test.el
@@ -1089,6 +1089,13 @@ a buffer visiting a file."
    (string=
     (ivy-with-text
      "|(defun foo)\nasdf\n(defvar bar)"
+     (global-set-key (kbd "C-s") #'isearch-forward-regexp)
+     ("C-s" "defun\\|defvar" "RET"))
+    "(defun| foo)\nasdf\n(defvar bar)"))
+  (should
+   (string=
+    (ivy-with-text
+     "|(defun foo)\nasdf\n(defvar bar)"
      (global-set-key (kbd "C-s") #'swiper-isearch)
      ("C-s" "defun\\|defvar" "RET"))
     "(defun| foo)\nasdf\n(defvar bar)"))
@@ -1100,6 +1107,48 @@ a buffer visiting a file."
      ("C-s" "defun\\|defvar" "C-n RET"))
     "(defun foo)\nasdf\n(defvar| bar)")))
 
+(ert-deftest swiper-isearch-backward ()
+  (should
+   (string=
+    (ivy-with-text
+     "abc\nasdf123 def\ndem|"
+     (global-set-key (kbd "C-r") #'isearch-backward-regexp)
+     ("C-r" "de" "" "RET"))
+    "abc\nasdf123 def\n|dem"))
+  (should
+   (string=
+    (ivy-with-text
+     "abc\nasdf123 def\ndem|"
+     (global-set-key (kbd "C-r") #'swiper-isearch-backward)
+     ("C-r" "de" "" "RET"))
+    "abc\nasdf123 def\n|dem"))
+  (should
+   (string=
+    (ivy-with-text
+     "(defun foo)\nasdf\n(defvar bar)|"
+     (global-set-key (kbd "C-r") #'isearch-backward-regexp)
+     ("C-r" "defun\\|defvar" "RET"))
+    "(defun foo)\nasdf\n(|defvar bar)"))
+  ;; NOTE: The following two behaviors do not match
+  ;; `isearch-backward-regexp', but they match that of
+  ;; `swiper-isearch-forward', as `swiper-isearch' does not reset the
+  ;; point when the regexp becomes invalid, meaning the point is left
+  ;; at the initial match of the first part of the regexp.
+  (should
+   (string=
+    (ivy-with-text
+     "(defun foo)\nasdf\n(defvar bar)|"
+     (global-set-key (kbd "C-r") #'swiper-isearch-backward)
+     ("C-r" "defun\\|defvar" "RET"))
+    "(|defun foo)\nasdf\n(defvar bar)"))
+  (should
+   (string=
+    (ivy-with-text
+     "(defun foo)\nasdf\n(defvar bar)|"
+     (global-set-key (kbd "C-r") #'swiper-isearch-backward)
+     ("C-r" "defun\\|defvar" "C-n RET"))
+    "(defun foo)\nasdf\n(|defvar bar)")))
+
 (ert-deftest swiper-isearch-case-fold ()
   (should
    (string=
diff --git a/swiper.el b/swiper.el
index 6524fd0..4c201a1 100644
--- a/swiper.el
+++ b/swiper.el
@@ -129,7 +129,8 @@
   :group 'swiper)
 
 (defcustom swiper-goto-start-of-match nil
-  "When non-nil, go to the start of the match, not its end."
+  "When non-nil, go to the start of the match, not its end.
+Treated as non-nil when searching backwards."
   :type 'boolean
   :group 'swiper)
 
@@ -1303,6 +1304,8 @@ come back to the same place as when \"a\" was initially 
entered.")
               (invisible-p (overlay-get ov 'invisible)))
             (overlays-at (point))))))
 
+(defvar swiper--isearch-backward nil)
+
 (defun swiper--isearch-function (str)
   (let* ((case-fold-search (ivy--case-fold-p str))
          (re-full (funcall ivy--regex-function str))
@@ -1316,24 +1319,32 @@ come back to the same place as when \"a\" was initially 
entered.")
             idx-found
             (idx 0))
         (save-excursion
-          (goto-char (point-min))
-          (while (re-search-forward re nil t)
+          (goto-char (if swiper--isearch-backward (point-max) (point-min)))
+          (while (funcall (if swiper--isearch-backward #'re-search-backward 
#'re-search-forward) re nil t)
             (when (swiper-match-usable-p)
               (unless idx-found
-                (when (or
-                       (eq (match-beginning 0) pt-hist)
-                       (>= (match-beginning 0) (cdar 
swiper--isearch-point-history)))
+                (when (if swiper--isearch-backward
+                          ;; test if match is before point
+                          (<= (match-beginning 0) (cdar 
swiper--isearch-point-history))
+                        (or
+                         ;; test if match is at or after point
+                         (eq (match-beginning 0) pt-hist)
+                         (>= (match-beginning 0) (cdar 
swiper--isearch-point-history))))
                   (push (cons str (match-beginning 0)) 
swiper--isearch-point-history)
                   (setq idx-found idx)))
               (cl-incf idx)
-              (let ((pos (if swiper-goto-start-of-match
+              (let ((pos (if (or swiper--isearch-backward 
swiper-goto-start-of-match)
                              (match-beginning 0)
                            (point))))
                 (push pos cands)))))
         (setq ivy--old-re re)
         (when idx-found
-          (ivy-set-index idx-found))
-        (setq ivy--old-cands (nreverse cands))))))
+          (ivy-set-index (if swiper--isearch-backward
+                             (- (length cands) idx-found 1)
+                           idx-found)))
+        (setq ivy--old-cands (if swiper--isearch-backward
+                                 cands
+                               (nreverse cands)))))))
 
 (defcustom swiper-isearch-highlight-delay '(2 0.2)
   "When `ivy-text' is too short, delay showing the overlay.
@@ -1537,6 +1548,13 @@ When not running `swiper-isearch' already, start it."
       (unless (or res (string= ivy-text ""))
         (cl-pushnew ivy-text swiper-history)))))
 
+;;;###autoload
+(defun swiper-isearch-backward (&optional initial-input)
+  "Like `swiper-isearch' but the first result is before the point."
+  (interactive)
+  (let ((swiper--isearch-backward t))
+    (swiper-isearch initial-input)))
+
 (add-to-list 'ivy-format-functions-alist '(swiper-isearch . 
swiper-isearch-format-function))
 (ivy-set-occur 'swiper-isearch 'swiper-occur)
 



reply via email to

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