unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Some further ideas for Isearch
@ 2021-04-25  8:20 Augusto Stoffel
  2021-04-25 17:36 ` Juri Linkov
  0 siblings, 1 reply; 5+ messages in thread
From: Augusto Stoffel @ 2021-04-25  8:20 UTC (permalink / raw)
  To: emacs-devel

Here are some further ideas for Isearch, partially inspired by the
alternative buffer search packages out there:

Future history
--------------

Pressing `C-s M-n M-n ...' could present a few useful search
candidates, controlled for instance by the
`isearch-forward-thing-at-point' variable.  This would be more
flexible and more mnemonic than the recently introduced
`isearch-forward-thing-at-point' command.

Resume canceled searches
------------------------

`C-s C-s' recovers the last history element, so it's more or less
equivalent to `C-s M-p'.  It would be nice to have the ability to
resume a canceled search, i.e., make `C-s C-s' look into
`isearch-cmds' instead.

Fuzzy search
------------

By this I mean a search mode where `search-whitespace-regexp' is set
to ".*?".

Implementing this wouldn't be completely trivial because, unlike case
sensitivity, the whitespace laxness settings are not local to each
Isearch session.  (As a quick check, note that `M-s c' changes
case-sensitivity for the current search only, but `M-s SPC' changes
whitespace laxness for future searches as well.)

The whitespace regexp should also be saved as a property in the
search-ring elements.

Whole words vs lax whitespace
-----------------------------

The word search mode (M-s w) does two things at once: it wraps the
search string around "\\< ... \\>" and treats whitespace as "\\W+".  It
would be nice to make these two aspects orthogonal.

Sometimes, one might want to search whole words with literal spaces.
Much more often, however, one might want "\\W+" whitespace but not the
whole-word restriction.

I'm not sure what a good UI would be, but one idea is to make `M-s SPC'
cycle between a few useful whitespace regexps (e.g., nil, "\\s-+",
"\\W+" and ".*?").



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Some further ideas for Isearch
  2021-04-25  8:20 Some further ideas for Isearch Augusto Stoffel
@ 2021-04-25 17:36 ` Juri Linkov
  2021-04-26  5:32   ` Augusto Stoffel
  0 siblings, 1 reply; 5+ messages in thread
From: Juri Linkov @ 2021-04-25 17:36 UTC (permalink / raw)
  To: Augusto Stoffel; +Cc: emacs-devel

> Here are some further ideas for Isearch, partially inspired by the
> alternative buffer search packages out there:

Thanks for more ideas that hopefully will find a path to isearch.

> Future history
> --------------
>
> Pressing `C-s M-n M-n ...' could present a few useful search
> candidates, controlled for instance by the
> `isearch-forward-thing-at-point' variable.  This would be more
> flexible and more mnemonic than the recently introduced
> `isearch-forward-thing-at-point' command.

The problem is that the isearch history is a ring,
so maybe the users already expect that typing 'C-s M-n'
should get the top element of the isearch ring.

This is what 'M-n' bound to 'isearch-ring-advance' currently does
to search for the next item in the search ring.

> Resume canceled searches
> ------------------------
>
> `C-s C-s' recovers the last history element, so it's more or less
> equivalent to `C-s M-p'.  It would be nice to have the ability to
> resume a canceled search, i.e., make `C-s C-s' look into
> `isearch-cmds' instead.

This feature was proposed in https://debbugs.gnu.org/11378#71

> Fuzzy search
> ------------
>
> By this I mean a search mode where `search-whitespace-regexp' is set
> to ".*?".
>
> Implementing this wouldn't be completely trivial because, unlike case
> sensitivity, the whitespace laxness settings are not local to each
> Isearch session.  (As a quick check, note that `M-s c' changes
> case-sensitivity for the current search only, but `M-s SPC' changes
> whitespace laxness for future searches as well.)
>
> The whitespace regexp should also be saved as a property in the
> search-ring elements.

As the first step, this regexp could be added as a new option to
the search-whitespace-regexp defcustom.  Then later `M-s SPC'
could cycle between different options.

> Whole words vs lax whitespace
> -----------------------------
>
> The word search mode (M-s w) does two things at once: it wraps the
> search string around "\\< ... \\>" and treats whitespace as "\\W+".  It
> would be nice to make these two aspects orthogonal.
>
> Sometimes, one might want to search whole words with literal spaces.
> Much more often, however, one might want "\\W+" whitespace but not the
> whole-word restriction.
>
> I'm not sure what a good UI would be, but one idea is to make `M-s SPC'
> cycle between a few useful whitespace regexps (e.g., nil, "\\s-+",
> "\\W+" and ".*?").

Maybe not `M-s SPC', but `M-s w' could cycle between different versions
of 'word-search-regexp' assigned to 'isearch-regexp-function'?



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Some further ideas for Isearch
  2021-04-25 17:36 ` Juri Linkov
@ 2021-04-26  5:32   ` Augusto Stoffel
  2021-04-28 21:11     ` Juri Linkov
  0 siblings, 1 reply; 5+ messages in thread
From: Augusto Stoffel @ 2021-04-26  5:32 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

On Sun, 25 Apr 2021 at 20:36, Juri Linkov <juri@linkov.net> wrote:

>> Here are some further ideas for Isearch, partially inspired by the
>> alternative buffer search packages out there:
>
> Thanks for more ideas that hopefully will find a path to isearch.
>
>> Future history
>> --------------
>>
>> Pressing `C-s M-n M-n ...' could present a few useful search
>> candidates, controlled for instance by the
>> `isearch-forward-thing-at-point' variable.  This would be more
>> flexible and more mnemonic than the recently introduced
>> `isearch-forward-thing-at-point' command.
>
> The problem is that the isearch history is a ring,
> so maybe the users already expect that typing 'C-s M-n'
> should get the top element of the isearch ring.
>
> This is what 'M-n' bound to 'isearch-ring-advance' currently does
> to search for the next item in the search ring.

But the top element is the oldest, the next one to be forgotten, right?
Why would this be remotely as interesting than first seeing the region,
word, symbol, sexp at point?

Speaking of the search ring(s):  Now that the search mode is saved as
properties in the history elements, can we get rid of separate histories
for regexp and regular searches?  I see at least two reasons for this:

- If you use regexp search by default, it's very annoying to resume a
  previous symbol-at-point search.
- Given one regexp and one literal history item, you can't know which is
  oldest.

Now, of course you are going to say this needs to be a defcustom, so
I'm already going to ask: can it be on by default?

>
>> Resume canceled searches
>> ------------------------
>>
>> `C-s C-s' recovers the last history element, so it's more or less
>> equivalent to `C-s M-p'.  It would be nice to have the ability to
>> resume a canceled search, i.e., make `C-s C-s' look into
>> `isearch-cmds' instead.
>
> This feature was proposed in https://debbugs.gnu.org/11378#71

Should be easy to do.  But please, let's let `C-s C-s' resume the last
search, period, not the last search of the same mode as `C-s' normally
does.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Some further ideas for Isearch
  2021-04-26  5:32   ` Augusto Stoffel
@ 2021-04-28 21:11     ` Juri Linkov
  2021-04-28 21:55       ` Augusto Stoffel
  0 siblings, 1 reply; 5+ messages in thread
From: Juri Linkov @ 2021-04-28 21:11 UTC (permalink / raw)
  To: Augusto Stoffel; +Cc: emacs-devel

>> This is what 'M-n' bound to 'isearch-ring-advance' currently does
>> to search for the next item in the search ring.
>
> But the top element is the oldest, the next one to be forgotten, right?
> Why would this be remotely as interesting than first seeing the region,
> word, symbol, sexp at point?

Indeed, it would be nice to have 'C-s M-n' to get the next thing at point.

> Speaking of the search ring(s):  Now that the search mode is saved as
> properties in the history elements, can we get rid of separate histories
> for regexp and regular searches?

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

> I see at least two reasons for this:
>
> - If you use regexp search by default, it's very annoying to resume a
>   previous symbol-at-point search.

Please elaborate.  Do you rebind C-s to isearch-forward-regexp,
then after using isearch-forward-symbol, can't repeat it with C-s?
Does something like this do the right thing for you?

  (defvaralias 'regexp-search-ring 'search-ring)

> - Given one regexp and one literal history item, you can't know which is
>   oldest.
>
> Now, of course you are going to say this needs to be a defcustom, so
> I'm already going to ask: can it be on by default?

Changing the default is a very sensitive topic.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Some further ideas for Isearch
  2021-04-28 21:11     ` Juri Linkov
@ 2021-04-28 21:55       ` Augusto Stoffel
  0 siblings, 0 replies; 5+ messages in thread
From: Augusto Stoffel @ 2021-04-28 21:55 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 864 bytes --]

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?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Allow-resuming-a-canceled-isearch.patch --]
[-- Type: text/x-patch, Size: 5832 bytes --]

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 "")))
 
 \f
 ;; 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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-04-28 21:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-25  8:20 Some further ideas for Isearch Augusto Stoffel
2021-04-25 17:36 ` Juri Linkov
2021-04-26  5:32   ` Augusto Stoffel
2021-04-28 21:11     ` Juri Linkov
2021-04-28 21:55       ` Augusto Stoffel

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).