emacs-devel
[Top][All Lists]
Advanced

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

Re: Simple isearch concerns


From: Juri Linkov
Subject: Re: Simple isearch concerns
Date: Fri, 30 Apr 2021 19:41:25 +0300
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (x86_64-pc-linux-gnu)

>> What would be good customization options for that?  I imagine
>> a new boolean option 'isearch-buffer-local'.  Maybe later
>> it would require a new value to support even multiple isearch
>> sessions in different buffers.  In this case, all state variables
>> like isearch-cmds, isearch-lazy-highlight-overlays etc. could be made
>> buffer-local.
>
> I don't understand why `isearch-buffer-local' should be a user
> customization, since it doesn't change the external behavior of Isearch,
> but simply improves the implementation.  It might break third-party code
> that hacks into isearch.el, though.

Indeed, we need to care about third-party code as well.
So we could add a new option, then ask the users to enable it
to see what effect it has on user customizations, then after
the next release its default could be changed to t:

diff --git a/lisp/isearch.el b/lisp/isearch.el
index 9f3cfd70fb..5c71519054 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -195,6 +195,11 @@ isearch-repeat-on-direction-change
                  (const :tag "Move to another match" t))
   :version "28.1")
 
+(defcustom isearch-buffer-local nil
+  "Whether isearch should be buffer-local."
+  :type 'boolean
+  :version "28.1")
+
 (defvar isearch-mode-hook nil
   "Function(s) to call after starting up an incremental search.")
 
@@ -1295,11 +1300,14 @@ isearch-mode
   (setq        isearch-mode " Isearch")  ;; forward? regexp?
   (force-mode-line-update)
 
-  (setq overriding-terminal-local-map isearch-mode-map)
+  (if isearch-buffer-local
+      (add-to-list 'emulation-mode-map-alists `((isearch-mode . 
,isearch-mode-map)))
+    (setq overriding-terminal-local-map isearch-mode-map))
   (run-hooks 'isearch-mode-hook)
-  ;; Remember the initial map possibly modified
-  ;; by external packages in isearch-mode-hook.  (Bug#16035)
-  (setq isearch--saved-overriding-local-map overriding-terminal-local-map)
+  (unless isearch-buffer-local
+    ;; Remember the initial map possibly modified
+    ;; by external packages in isearch-mode-hook.  (Bug#16035)
+    (setq isearch--saved-overriding-local-map overriding-terminal-local-map))
 
   ;; Pushing the initial state used to be before running isearch-mode-hook,
   ;; but a hook might set `isearch-push-state-function' used in
@@ -1308,10 +1316,10 @@ isearch-mode
 
   (isearch-update)
 
-  (add-hook 'pre-command-hook 'isearch-pre-command-hook)
-  (add-hook 'post-command-hook 'isearch-post-command-hook)
-  (add-hook 'mouse-leave-buffer-hook 'isearch-mouse-leave-buffer)
-  (add-hook 'kbd-macro-termination-hook 'isearch-done)
+  (add-hook 'pre-command-hook 'isearch-pre-command-hook nil 
isearch-buffer-local)
+  (add-hook 'post-command-hook 'isearch-post-command-hook nil 
isearch-buffer-local)
+  (add-hook 'mouse-leave-buffer-hook 'isearch-mouse-leave-buffer nil 
isearch-buffer-local)
+  (add-hook 'kbd-macro-termination-hook 'isearch-done nil isearch-buffer-local)
 
   ;; isearch-mode can be made modal (in the sense of not returning to
   ;; the calling function until searching is completed) by entering
@@ -1406,10 +1414,11 @@ isearch-done
                                      ,isearch-message
                                      ',isearch-case-fold-search)))
 
-  (remove-hook 'pre-command-hook 'isearch-pre-command-hook)
-  (remove-hook 'post-command-hook 'isearch-post-command-hook)
-  (remove-hook 'mouse-leave-buffer-hook 'isearch-mouse-leave-buffer)
-  (remove-hook 'kbd-macro-termination-hook 'isearch-done)
+  (remove-hook 'pre-command-hook 'isearch-pre-command-hook 
isearch-buffer-local)
+  (remove-hook 'post-command-hook 'isearch-post-command-hook 
isearch-buffer-local)
+  (remove-hook 'mouse-leave-buffer-hook 'isearch-mouse-leave-buffer 
isearch-buffer-local)
+  (remove-hook 'kbd-macro-termination-hook 'isearch-done isearch-buffer-local)
+
   (when (buffer-live-p isearch--current-buffer)
     (with-current-buffer isearch--current-buffer
       (setq isearch--current-buffer nil)
@@ -1630,12 +1639,19 @@ with-isearch-suspended
 `isearch-new-string', `isearch-new-message', `isearch-new-forward',
 `isearch-new-regexp-function', `isearch-new-case-fold',
 `isearch-new-nonincremental'."
+  `(if isearch-buffer-local
+       (let ((isearch-new-string isearch-string)
+             (isearch-new-message isearch-message))
+         (progn ,@body)
+         (setq isearch-string isearch-new-string
+               isearch-message isearch-new-message)
+         (let ((isearch-yank-flag t)) (isearch-search-and-update)))
   ;; This code is very hairy for several reasons, explained in the code.
   ;; Mainly, isearch-mode must be terminated while editing and then restarted.
   ;; If there were a way to catch any change of buffer from the minibuffer,
   ;; this could be simplified greatly.
   ;; Editing doesn't back up the search point.  Should it?
-  `(condition-case nil
+   (condition-case nil
       (progn
        (let ((isearch-new-nonincremental isearch-nonincremental)
 
@@ -1779,7 +1795,7 @@ with-isearch-suspended
     (quit  ; handle abort-recursive-edit
      (setq isearch-suspended nil)
      (isearch-abort)  ;; outside of let to restore outside global values
-     )))
+     ))))
 
 (defvar minibuffer-history-symbol) ;; from external package gmhist.el
 
@@ -3018,7 +3060,8 @@ isearch-pre-command-hook
     (cond
      ;; Don't exit Isearch if we're in the middle of some
      ;; `set-transient-map' thingy like `universal-argument--mode'.
-     ((not (eq overriding-terminal-local-map 
isearch--saved-overriding-local-map)))
+     ((unless isearch-buffer-local
+        (not (eq overriding-terminal-local-map 
isearch--saved-overriding-local-map))))
      ;; Don't exit Isearch for isearch key bindings.
      ((or (commandp (lookup-key isearch-mode-map key nil))
           (commandp
And here is a patch for updating the search from the minibuffer. This allows
to implement 
https://lists.gnu.org/archive/html/emacs-devel/2020-01/msg00447.html
to control the search from the minibuffer.  But I'm not sure if the same option
isearch-buffer-local should enable this mode:

diff --git a/lisp/isearch.el b/lisp/isearch.el
index 9f3cfd70fb..5c71519054 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -1803,21 +1819,33 @@ isearch-edit-string
          (minibuffer-history-symbol)
          ;; Search string might have meta information on text properties.
          (minibuffer-allow-text-properties t))
-     (setq isearch-new-string
-          (read-from-minibuffer
-           (isearch-message-prefix nil isearch-nonincremental)
-           (cons isearch-string (1+ (or (isearch-fail-pos)
-                                        (length isearch-string))))
-           minibuffer-local-isearch-map nil
-           (if isearch-regexp
-               (cons 'regexp-search-ring
-                     (1+ (or regexp-search-ring-yank-pointer -1)))
-             (cons 'search-ring
-                   (1+ (or search-ring-yank-pointer -1))))
-           nil t)
-          isearch-new-message
-          (mapconcat 'isearch-text-char-description
-                     isearch-new-string "")))))
+     (minibuffer-with-setup-hook
+         (lambda ()
+           (when isearch-buffer-local
+             (add-hook 'after-change-functions
+                       (lambda (_ _ _)
+                         (let ((new-string (minibuffer-contents)))
+                           (with-minibuffer-selected-window
+                             (setq isearch-string new-string
+                                   isearch-message (mapconcat 
'isearch-text-char-description
+                                                             isearch-string 
""))
+                             (let ((isearch-yank-flag t)) 
(isearch-search-and-update)))))
+                       nil t)))
+       (setq isearch-new-string
+            (read-from-minibuffer
+             (isearch-message-prefix nil isearch-nonincremental)
+             (cons isearch-string (1+ (or (isearch-fail-pos)
+                                          (length isearch-string))))
+             minibuffer-local-isearch-map nil
+             (if isearch-regexp
+                 (cons 'regexp-search-ring
+                       (1+ (or regexp-search-ring-yank-pointer -1)))
+               (cons 'search-ring
+                     (1+ (or search-ring-yank-pointer -1))))
+             nil t)
+            isearch-new-message
+            (mapconcat 'isearch-text-char-description
+                       isearch-new-string ""))))))
 
 (defun isearch-nonincremental-exit-minibuffer ()
   (interactive)
@@ -1830,14 +1858,28 @@ isearch-nonincremental-exit-minibuffer
 (defun isearch-forward-exit-minibuffer ()
   "Resume isearching forward from the minibuffer that edits the search string."
   (interactive)
-  (setq isearch-new-forward t isearch-new-nonincremental nil)
-  (exit-minibuffer))
+  (if isearch-buffer-local
+      (let ((new-string (minibuffer-contents)))
+        (with-minibuffer-selected-window
+          (setq isearch-string new-string
+                isearch-message (mapconcat 'isearch-text-char-description
+                                          isearch-string ""))
+          (isearch-repeat-forward)))
+    (setq isearch-new-forward t isearch-new-nonincremental nil)
+    (exit-minibuffer)))
 
 (defun isearch-reverse-exit-minibuffer ()
   "Resume isearching backward from the minibuffer that edits the search 
string."
   (interactive)
-  (setq isearch-new-forward nil isearch-new-nonincremental nil)
-  (exit-minibuffer))
+  (if isearch-buffer-local
+      (let ((new-string (minibuffer-contents)))
+        (with-minibuffer-selected-window
+          (setq isearch-string new-string
+                isearch-message (mapconcat 'isearch-text-char-description
+                                          isearch-string ""))
+          (isearch-repeat-backward)))
+    (setq isearch-new-forward nil isearch-new-nonincremental nil)
+    (exit-minibuffer)))
 
 (defun isearch-cancel ()
   "Terminate the search and go back to the starting point."

reply via email to

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