From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.devel Subject: Re: Simple isearch concerns Date: Fri, 30 Apr 2021 19:41:25 +0300 Organization: LINKOV.NET Message-ID: <87tunnzqci.fsf@mail.linkov.net> References: <20210403001539.x4rb55dvh46rmhb3.ref@Ergus> <20210403001539.x4rb55dvh46rmhb3@Ergus> <2599ffef-4f70-025c-5f9c-61b9ac94faf8@inventati.org> <87eefrbo9k.fsf@posteo.net> <7473b27b2b479f5686af@heytings.org> <87tuon9vf1.fsf@posteo.net> <20210403174508.xwr5uc36dzityitn@Ergus> <87wnsurdr7.fsf@gmail.com> <87fszij6to.fsf@mail.linkov.net> <87v98asulc.fsf@gmail.com> <87pmyimiwd.fsf@mail.linkov.net> <87bla11u5q.fsf@gmail.com> <87lf937hgk.fsf@mail.linkov.net> <87y2d1ksga.fsf@mail.linkov.net> <87r1it7zfw.fsf@gmail.com> <87v98466it.fsf@mail.linkov.net> <87bl9wcksv.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="11129"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (x86_64-pc-linux-gnu) Cc: Philip Kaludercic , emacs-devel@gnu.org, Manuel Uberti , Gregory Heytings , Ergus To: Augusto Stoffel Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Apr 30 19:38:23 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lcX5r-0002md-BZ for ged-emacs-devel@m.gmane-mx.org; Fri, 30 Apr 2021 19:38:23 +0200 Original-Received: from localhost ([::1]:49736 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lcX5q-0001Oo-FB for ged-emacs-devel@m.gmane-mx.org; Fri, 30 Apr 2021 13:38:22 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:39850) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lcWiH-0003Og-U4 for emacs-devel@gnu.org; Fri, 30 Apr 2021 13:14:03 -0400 Original-Received: from relay5-d.mail.gandi.net ([217.70.183.197]:40935) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lcWiE-0006Gq-Ci for emacs-devel@gnu.org; Fri, 30 Apr 2021 13:14:01 -0400 X-Originating-IP: 91.129.102.166 Original-Received: from mail.gandi.net (m91-129-102-166.cust.tele2.ee [91.129.102.166]) (Authenticated sender: juri@linkov.net) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 873DF1C0008; Fri, 30 Apr 2021 17:13:51 +0000 (UTC) In-Reply-To: <87bl9wcksv.fsf@gmail.com> (Augusto Stoffel's message of "Fri, 30 Apr 2021 09:07:28 +0200") Received-SPF: pass client-ip=217.70.183.197; envelope-from=juri@linkov.net; helo=relay5-d.mail.gandi.net X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:268675 Archived-At: --=-=-= Content-Type: text/plain >> 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: --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=isearch-buffer-local.patch 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 --=-=-= Content-Type: text/plain 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: --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=isearch-edit-string-after-change.patch 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." --=-=-=--