emacs-devel
[Top][All Lists]
Advanced

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

Re: Some further ideas for Isearch


From: Augusto Stoffel
Subject: Re: Some further ideas for Isearch
Date: Wed, 28 Apr 2021 23:55:35 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux)

On Thu, 29 Apr 2021 at 00:11, Juri Linkov <juri@linkov.net> wrote:

> The value of isearch-regexp is not saved as a property in the history.

But it should, right?

> Please elaborate.  Do you rebind C-s to isearch-forward-regexp,
> then after using isearch-forward-symbol, can't repeat it with C-s?

Exactly.

> Does something like this do the right thing for you?
>
>   (defvaralias 'regexp-search-ring 'search-ring)

Yes, I guess that would solve the problem I described, except that
isearch-regexp won't be set correctly.

Now, I'm not sure if a unified history is an interesting enough
feature to add.

But in the meanwhile something else occurred to me: `C-s C-s` is
equivalent to `C-s M-p'.  So how about making `C-s C-s' resume the
last search, event if it was canceled on in a different mode?

I have attached a patch sketching this.  What do you think?

>From 06a2afbe88a0456fb415bc082ff3150aba21656b Mon Sep 17 00:00:00 2001
From: Augusto Stoffel <arstoffel@gmail.com>
Date: Mon, 26 Apr 2021 18:09:47 +0200
Subject: [PATCH] Allow resuming a canceled isearch

* lisp/isearch.el (isearch-always-resume-previous,
isearch--previous-string): New variables

* lisp/isearch.el (isearch-set-string): New function for an often
repeated code snippet.

* lisp/isearch.el (isearch-string-propertize): Also record the value
of isearch-regexp

* lisp/isearch.el (isearch-repeat): When resuming a previous search
because the search string is empty, take
isearch-always-resume-previous and isearch--previous-string into
account
---
 lisp/isearch.el | 68 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 45 insertions(+), 23 deletions(-)

diff --git a/lisp/isearch.el b/lisp/isearch.el
index 9f3cfd70fb..488517b47d 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -172,6 +172,15 @@ isearch-resume-in-command-history
 command history."
   :type 'boolean)
 
+(defcustom isearch-resume-most-recent nil
+  "Whether to always resume the most recent search.
+When t, attempting to search for the empty string resumes the
+most recent search, even if it was canceled or in a different
+search mode.  When nil, use the appropriate history entry
+instead."
+  :type 'boolean
+  :version "28.1")
+
 (defcustom isearch-wrap-pause t
   "Define the behavior of wrapping when there are no more matches.
 When `t' (by default), signal an error when no more matches are found.
@@ -954,6 +963,9 @@ isearch-input-method-function
 
 (defvar isearch--saved-overriding-local-map nil)
 
+;; The previous non-empty search string, with properties
+(defvar isearch--previous-string nil)
+
 ;; Minor-mode-alist changes - kind of redundant with the
 ;; echo area, but if isearching in multiple windows, it can be useful.
 ;; Also, clicking the mode-line indicator pops up
@@ -1460,9 +1472,12 @@ isearch-done
            (next-single-property-change (point) 'intangible)
          (previous-single-property-change (point) 'intangible)))))
 
-  (if (and (> (length isearch-string) 0) (not nopush))
-      ;; Update the ring data.
-      (isearch-update-ring isearch-string isearch-regexp))
+  (unless (string-empty-p isearch-string)
+    (when isearch-resume-most-recent
+      (setq isearch--previous-string (isearch-string-propertize 
isearch-string)))
+    ;; Update the ring data.
+    (unless nopush
+      (isearch-update-ring isearch-string isearch-regexp)))
 
   (let ((isearch-mode-end-hook-quit (and nopush (not edit))))
     (run-hooks 'isearch-mode-end-hook))
@@ -1504,19 +1519,28 @@ isearch-update-ring
 (defun isearch-string-propertize (string &optional properties)
   "Add isearch properties to the isearch string."
   (unless properties
-    (setq properties `(isearch-case-fold-search ,isearch-case-fold-search))
-    (unless isearch-regexp
-      (setq properties (append properties `(isearch-regexp-function 
,isearch-regexp-function)))))
-  (apply 'propertize string properties))
+    (setq properties `(isearch-case-fold-search ,isearch-case-fold-search
+                       isearch-regexp-function ,isearch-regexp-function
+                       isearch-regexp ,isearch-regexp))
+  (apply 'propertize string properties)))
 
 (defun isearch-update-from-string-properties (string)
   "Update isearch properties from the isearch STRING."
-  (when (plist-member (text-properties-at 0 string) 'isearch-case-fold-search)
-    (setq isearch-case-fold-search
-         (get-text-property 0 'isearch-case-fold-search string)))
-  (when (plist-member (text-properties-at 0 string) 'isearch-regexp-function)
-    (setq isearch-regexp-function
-         (get-text-property 0 'isearch-regexp-function string))))
+  (let ((props (text-properties-at 0 string)))
+    (when-let (prop (plist-member props 'isearch-case-fold-search))
+      (setq isearch-case-fold-search (cadr prop)))
+    (when-let (prop (plist-member props 'isearch-regexp-function))
+      (setq isearch-regexp-function (cadr prop)))
+    (when-let (prop (plist-member props 'isearch-regexp))
+      (setq isearch-regexp (cadr prop)))))
+
+(defun isearch-set-string (string &optional properties)
+  "Set the current search string.
+If PROPERTIES is non-nil, also update the search mode from the
+text properties of STRING."
+  (when properties (isearch-update-from-string-properties string))
+  (setq isearch-string string
+       isearch-message (mapconcat 'isearch-text-char-description string "")))
 
 
 ;; The search status structure and stack.
@@ -1877,16 +1901,14 @@ isearch-repeat
       ;; C-s in forward or C-r in reverse.
       (if (equal isearch-string "")
          ;; If search string is empty, use last one.
-         (if (null (if isearch-regexp regexp-search-ring search-ring))
-             (setq isearch-error "No previous search string")
-           (setq isearch-string
-                 (car (if isearch-regexp regexp-search-ring search-ring))
-                 isearch-message
-                 (mapconcat 'isearch-text-char-description
-                            isearch-string "")
-                 isearch-case-fold-search isearch-last-case-fold-search)
-           ;; After taking the last element, adjust ring to previous one.
-           (isearch-ring-adjust1 nil))
+         (if (and isearch-resume-most-recent isearch--previous-string)
+              (isearch-set-string isearch--previous-string t)
+            (if-let ((ring (if isearch-regexp regexp-search-ring search-ring)))
+                (progn
+                  (isearch-set-string (car ring) t)
+                  ;; After taking the last element, adjust ring to previous 
one.
+                 (isearch-ring-adjust1 nil))
+              (setq isearch-error "No previous search string")))
        ;; If already have what to search for, repeat it.
        (unless (or isearch-success (null isearch-wrap-pause))
          ;; Set isearch-wrapped before calling isearch-wrap-function
-- 
2.30.2


reply via email to

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