[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