emacs-elpa-diffs
[Top][All Lists]
Advanced

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

[elpa] externals/isearch-mb 9f11fda 05/20: Several improvements, reorgan


From: Stefan Monnier
Subject: [elpa] externals/isearch-mb 9f11fda 05/20: Several improvements, reorganization
Date: Sun, 16 May 2021 17:21:12 -0400 (EDT)

branch: externals/isearch-mb
commit 9f11fda34f46afe95192ed280f21245f280c947d
Author: Augusto Stoffel <arstoffel@gmail.com>
Commit: Augusto Stoffel <arstoffel@gmail.com>

    Several improvements, reorganization
---
 isearch-mb.el | 237 ++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 140 insertions(+), 97 deletions(-)

diff --git a/isearch-mb.el b/isearch-mb.el
index fd64795..43b74d9 100644
--- a/isearch-mb.el
+++ b/isearch-mb.el
@@ -26,30 +26,53 @@
 
 (eval-when-compile (require 'subr-x))
 
-(put 'next-history-element 'isearch-mb-no-search t)
-(put 'previous-history-element 'isearch-mb-no-search t)
-
 (defvar isearch-mb--prompt-overlay nil
   "Overlay for minibuffer prompt updates.")
 
+(defvar isearch-mb-minibuffer-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map minibuffer-local-map)
+    (define-key map (kbd "C-s") 'isearch-repeat-forward)
+    (define-key map (kbd "<down>") 'isearch-repeat-forward)
+    (define-key map (kbd "C-r") 'isearch-repeat-backward)
+    (define-key map (kbd "<up>") 'isearch-repeat-backward)
+    (define-key map (kbd "M-%") 'isearch-query-replace)
+    (define-key map (kbd "C-M-%") 'isearch-query-replace-regexp)
+    (define-key map (kbd "M-<") 'isearch-beginning-of-buffer)
+    (define-key map (kbd "M->") 'isearch-end-of-buffer)
+    (define-key map (kbd "M-s '") 'isearch-toggle-char-fold)
+    (define-key map (kbd "M-s SPC") 'isearch-toggle-lax-whitespace)
+    (define-key map (kbd "M-s _") 'isearch-toggle-symbol)
+    (define-key map (kbd "M-s c") 'isearch-toggle-case-fold)
+    (define-key map (kbd "M-s h r") 'isearch-highlight-regexp)
+    (define-key map (kbd "M-s h l") 'isearch-highlight-lines-matching-regexp)
+    (define-key map (kbd "M-s i") 'isearch-toggle-invisible)
+    (define-key map (kbd "M-s o") 'isearch-occur)
+    (define-key map (kbd "M-s r") 'isearch-toggle-regexp)
+    (define-key map (kbd "M-s w") 'isearch-toggle-word)
+    map)
+  "Minibuffer keymap used by Isearch-Mb.")
+
 (defun isearch-mb--post-command-hook ()
-  (let ((inhibit-redisplay t)
-        (new-string (minibuffer-contents)))
+  "Hook to run from the minibuffer to update the Isearch state."
+  (let ((text (minibuffer-contents)))
     ;; We never update isearch-message.  If it's not empty, then
     ;; Isearch itself changed the search string, and we update it.
     (unless (string-empty-p isearch-message)
-      (setq isearch-message "" new-string isearch-string)
+      (setq isearch-message ""
+            text isearch-string)
       (delete-minibuffer-contents)
       (insert isearch-string))
-    (unless (string= new-string isearch-string)
-      (with-minibuffer-selected-window
-        (setq isearch-string new-string)
-        (isearch-update-from-string-properties new-string)
-        (if (get this-command 'isearch-mb-no-search)
-            (isearch-update)
-          (goto-char isearch-barrier)
-          (setq isearch-adjusted t isearch-yank-flag t)
-        (isearch-search-and-update)))))
+    (unless (string-equal text isearch-string)
+      (let ((inhibit-redisplay t))
+        (with-minibuffer-selected-window
+          (setq isearch-string (substring-no-properties text))
+          (isearch-update-from-string-properties text)
+          (if (get this-command 'isearch-mb--no-search)
+              (isearch-update)
+            (goto-char isearch-barrier)
+            (setq isearch-adjusted t isearch-yank-flag t)
+            (isearch-search-and-update))))))
   (set-text-properties (minibuffer-prompt-end) (point-max) nil)
   (when-let ((fail-pos (isearch-fail-pos)))
     (add-text-properties (+ (minibuffer-prompt-end) fail-pos)
@@ -58,94 +81,115 @@
   (when isearch-error
     (isearch-mb--message isearch-error)))
 
-(defun isearch-mb--minibuffer-setup ()
-  (setq isearch-mb--prompt-overlay (make-overlay (point-min) (point-min)
-                                                         (current-buffer) t t))
-  (isearch-mb--prompt)
-  (add-hook 'post-command-hook 'isearch-mb--post-command-hook nil 'local))
-
-(defun isearch-mb--message (message &rest _)
-  (message (propertize (concat " [" message "]")
-                       'face 'minibuffer-prompt)))
+(defun isearch-mb--message (message)
+  "Display a momentary MESSAGE."
+  (when isearch-mb-mode
+    (message (propertize (concat " [" message "]")
+                         'face 'minibuffer-prompt))))
 
 (defun isearch-mb--prompt (&rest _)
-  (when isearch-mb--prompt-overlay
-    (overlay-put isearch-mb--prompt-overlay
-                 'before-string
-                 (concat
-                  (isearch-lazy-count-format)
-                  (capitalize
-                   (isearch--describe-regexp-mode isearch-regexp-function))))))
-
-(defvar isearch-mb-minibuffer-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map minibuffer-local-map)
-    (define-key map (kbd "C-s") 'isearch-repeat-forward)
-    (define-key map (kbd "C-r") 'isearch-repeat-backward)
-    (define-key map (kbd "<down>") 'isearch-repeat-forward)
-    (define-key map (kbd "<up>") 'isearch-repeat-backward)
-    (define-key map (kbd "M-s r") 'isearch-toggle-regexp)
-    (define-key map (kbd "M-s c") 'isearch-toggle-case-fold)
-    (define-key map (kbd "M-s w") 'isearch-toggle-word)
-    (define-key map (kbd "M-<") 'isearch-beginning-of-buffer)
-    (define-key map (kbd "M->") 'isearch-end-of-buffer)
-    map))
-
-(defun isearch-mb--command-advice (fn &rest args)
-  (if (eq (current-buffer) isearch--current-buffer)
-      (apply fn args)
-    (let ((inhibit-redisplay t))
-      (with-minibuffer-selected-window
-        (apply fn args)))))
-
-(defun isearch-mb--activate (&rest _)
-  "Activate `isearch-mode' read from the minibuffer."
+  "Update the minibuffer prompt according to search status."
+  (prog1 isearch-mb-mode
+    (when isearch-mb--prompt-overlay
+      (overlay-put isearch-mb--prompt-overlay
+                   'before-string
+                   (concat
+                    (when isearch-lazy-count
+                      (format "%-6s" (isearch-lazy-count-format)))
+                    (capitalize
+                     (isearch--describe-regexp-mode
+                      isearch-regexp-function)))))))
+
+(defun isearch-mb--with-buffer (fn &rest args)
+  "Call FN with ARGS in the search buffer.
+Intended as an advice for Isearch commands."
+  (if (and (minibufferp)
+           (not (eq (current-buffer) isearch--current-buffer)))
+      (let ((enable-recursive-minibuffers t)
+            (inhibit-redisplay t))
+        (with-minibuffer-selected-window
+          (apply fn args)
+          (unless isearch-mode
+            (throw 'isearch-mb--after-exit '(ignore)))))
+    (apply fn args)))
+
+(defun isearch-mb--after-exit (fn &rest args)
+  "Call FN with ARGS, after quitting Isearch-Mb.
+Intended as an advice for commands that quit Isearch."
+  (if (and (minibufferp)
+             (not (eq (current-buffer) isearch--current-buffer)))
+      (throw 'isearch-mb--after-exit (cons fn args))
+    (apply fn args)))
+
+(defun isearch-mb--session ()
+  "Read search string from the minibuffer."
+  (when isearch-mode
+    (condition-case nil
+        (apply
+         (catch 'isearch-mb--after-exit
+           (let (;; Hack to render `isearch-pre-command-hook' without effect.
+                 (isearch--saved-overriding-local-map t)
+                 ;; We need to set `inhibit-redisplay' at certain points to
+                 ;; avoid flicker.  As a side effect, window-start/end in
+                 ;; `isearch-lazy-highlight-update' will have incorrect values,
+                 ;; so we need to lazy-highlight the whole buffer.
+                 (lazy-highlight-buffer (not (null isearch-lazy-highlight))))
+             (minibuffer-with-setup-hook
+                 (lambda ()
+                   (add-hook 'post-command-hook 'isearch-mb--post-command-hook 
nil 'local)
+                   (setq isearch-mb--prompt-overlay (make-overlay (point-min) 
(point-min)
+                                                                  
(current-buffer) t t))
+                   (isearch-mb--prompt))
+               (read-from-minibuffer
+                "I-search: "
+                isearch-string
+                isearch-mb-minibuffer-map
+                nil
+                (if isearch-regexp 'regexp-search-ring 'search-ring)
+                (when-let (thing (thing-at-point 'symbol))
+                  (if isearch-regexp (regexp-quote thing) thing))
+                t))
+             (if isearch-mode '(isearch-done) '(ignore)))))
+      (quit (if isearch-mode (isearch-cancel) (signal 'quit nil))))))
+
+(defun isearch-mb--setup ()
+  "Arrange to start Isearch-Mb after this command, if applicable."
   (when isearch-mb-mode
     (setq overriding-terminal-local-map nil)
-    (advice-add 'isearch-message :override 'isearch-mb--prompt)
-    (advice-add 'isearch--momentary-message :override 'isearch-mb--message)
-    (let ((history-add-new-input nil)
-          ;; We need to set `inhibit-redisplay' at certain points to
-          ;; avoid flicker.  As a side effect, window-start/end in
-          ;; `isearch-lazy-highlight-update' will have incorrect values,
-          ;; so we need to lazy-highlight the whole buffer.
-          (lazy-highlight-buffer (not (null isearch-lazy-highlight))))
-      (unwind-protect
-          (progn
-            (minibuffer-with-setup-hook 'isearch-mb--minibuffer-setup
-              (read-from-minibuffer
-               "I-search: "
-               isearch-string
-               isearch-mb-minibuffer-map
-               nil
-               (if isearch-regexp 'regexp-search-ring 'search-ring)
-               (when-let (thing (thing-at-point 'symbol))
-                 (if isearch-regexp (regexp-quote thing) thing))
-               t))
-            (isearch-done))
-        (when isearch-mode (ignore-error quit (isearch-cancel)))
-        (advice-remove 'isearch-message 'isearch-mb--prompt)
-        (advice-remove 'isearch--momentary-message 'isearch-mb--message)))))
-
-(advice-add 'isearch-forward                 :after 'isearch-mb--activate)
-(advice-add 'isearch-backward                :after 'isearch-mb--activate)
-(advice-add 'isearch-forward-regexp          :after 'isearch-mb--activate)
-(advice-add 'isearch-backward-regexp         :after 'isearch-mb--activate)
-(advice-add 'isearch-forward-word            :after 'isearch-mb--activate)
-;(advice-add 'isearch-forward-symbol          :after 'isearch-mb--activate)
-(advice-add 'isearch-forward-symbol-at-point :after 'isearch-mb--activate)
-
-(advice-add 'isearch-toggle-regexp       :around 'isearch-mb--command-advice)
-(advice-add 'isearch-toggle-case-fold    :around 'isearch-mb--command-advice)
-(advice-add 'isearch-toggle-word         :around 'isearch-mb--command-advice)
-(advice-add 'isearch-repeat-forward      :around 'isearch-mb--command-advice)
-(advice-add 'isearch-repeat-backward     :around 'isearch-mb--command-advice)
-(advice-add 'isearch-beginning-of-buffer :around 'isearch-mb--command-advice)
-(advice-add 'isearch-end-of-buffer       :around 'isearch-mb--command-advice)
+    (run-with-idle-timer 0 nil 'isearch-mb--session)))
+
+(add-hook 'isearch-mode-hook 'isearch-mb--setup)
+
+(put 'next-history-element 'isearch-mb--no-search t)
+(put 'previous-history-element 'isearch-mb--no-search t)
+
+(advice-add 'isearch-message            :before-until 'isearch-mb--prompt)
+(advice-add 'isearch--momentary-message :before-until 'isearch-mb--message)
+
+(advice-add 'isearch-beginning-of-buffer   :around 'isearch-mb--with-buffer)
+(advice-add 'isearch-end-of-buffer         :around 'isearch-mb--with-buffer)
+(advice-add 'isearch-occur                 :around 'isearch-mb--with-buffer)
+(advice-add 'isearch-repeat-backward       :around 'isearch-mb--with-buffer)
+(advice-add 'isearch-repeat-forward        :around 'isearch-mb--with-buffer)
+(advice-add 'isearch-toggle-case-fold      :around 'isearch-mb--with-buffer)
+(advice-add 'isearch-toggle-char-fold      :around 'isearch-mb--with-buffer)
+(advice-add 'isearch-toggle-invisible      :around 'isearch-mb--with-buffer)
+(advice-add 'isearch-toggle-lax-whitespace :around 'isearch-mb--with-buffer)
+(advice-add 'isearch-toggle-regexp         :around 'isearch-mb--with-buffer)
+(advice-add 'isearch-toggle-symbol         :around 'isearch-mb--with-buffer)
+(advice-add 'isearch-toggle-word           :around 'isearch-mb--with-buffer)
+
+(advice-add 'isearch-query-replace                   :around 
'isearch-mb--after-exit)
+(advice-add 'isearch-query-replace-regexp            :around 
'isearch-mb--after-exit)
+(advice-add 'isearch-highlight-regexp                :around 
'isearch-mb--after-exit)
+(advice-add 'isearch-highlight-lines-matching-regexp :around 
'isearch-mb--after-exit)
 
 ;;;###autoload
 (define-minor-mode isearch-mb-mode
-  "Control Isearch from minibuffer.")
+  "Control Isearch from the minibuffer.
+
+During an Isearch-Mb session, the following keys are available:
+\\{isearch-mb-minibuffer-map}")
 
 ;;;###autoload
 (define-globalized-minor-mode isearch-mb-global-mode
@@ -153,5 +197,4 @@
   (lambda () (unless (minibufferp) (isearch-mb-mode))))
 
 (provide 'isearch-mb)
-
 ;;; isearch-mb.el ends here



reply via email to

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