;;; Commentary:
-;; Library search.el provides advanced text searching commands, inspired
-;; by Icicles search (https://www.emacswiki.org/emacs/Icicles).
+;; This library provides advanced text searching commands, inspired by
+;; Icicles search (https://www.emacswiki.org/emacs/Icicles).
;;; Todo:
'((t :inherit highlight :foreground "black"))
"Face for highlighting matches for current input during \\[search].")
-(defun search-read-target (&optional beg end re-or-fn)
- "Prompt for \\[search] target between BEG and END matching RE-OR-FN."
- (let* ((buffer (current-buffer))
- (beg (or beg (point-min)))
- (end (or end (point-max)))
- (reg nil)
- (sfn (if (functionp re-or-fn)
- (prog1 re-or-fn (setq reg "match"))
- (setq reg (or re-or-fn (read-regexp "Search regular expression")))
- (lambda () (re-search-forward reg end t))))
- (ovs nil)
- (ovz nil)
- (cur nil)
- (trs nil)
- (tab (make-hash-table))
- (ind 0)
- (rep nil))
- (deactivate-mark)
+(defun search-change ()
+ "Change the current `search' context."
+ (interactive)
+ (throw 'search-change (minibuffer-contents)))
+
+(defun search-read-target-mode-p (_symbol buffer)
+ "Check whether `search-read-target-mode' is enabled in BUFFER."
+ (buffer-local-value 'search-read-target-mode buffer))
+
+(put 'search-change 'completion-predicate #'search-read-target-mode-p)
+
+(defvar-keymap search-read-target-mode-map
+ :doc "Keymap for `search-read-target-mode'."
+ "M-s M-s" #'search-change)
+
+(define-minor-mode search-read-target-mode
+ "Minor mode for `search-read-target' minibuffer.")
+
+(defun search--read-target (buffer beg end reg sfn init)
+ "Prompt for search target in BUFFER between BEG and END matching REG.
+
+SFN is the search function to use for finding matches. INIT is the
+initial minibuffer input."
+ (let ((tab (make-hash-table)) (ind 0) ovs ovz cur trs rep)
(save-excursion
(goto-char beg)
(let ((pos beg) done)
(unwind-protect
(minibuffer-with-setup-hook
(lambda ()
+ (search-read-target-mode)
(setq minibuffer-action
(cons
(lambda (c)
. ,(lambda (string &optional transform)
(when transform
(substring string (1+ (string-search ":" string))))))))
- nil t nil t))
+ nil t init t))
tab))
(mapc #'delete-overlay ovs)
(mapc #'delete-overlay ovz))))
+(defun search-read-target (&optional beg end re-or-fn)
+ "Prompt for \\[search] target between BEG and END matching RE-OR-FN."
+ (let* ((buf (current-buffer))
+ (beg (or beg (point-min)))
+ (end (or end (point-max)))
+ reg res
+ (sfn (if (functionp re-or-fn)
+ (prog1 re-or-fn (setq reg "match"))
+ (setq reg (or re-or-fn (read-regexp "Search regular expression")))
+ (lambda () (re-search-forward reg end t)))))
+ (deactivate-mark)
+ (while (stringp (setq res (catch 'search-change
+ (search--read-target buf beg end reg sfn res))))
+ (setq reg (read-regexp "Search regular expression")
+ sfn (lambda () (re-search-forward reg end t))))
+ res))
+
;;;###autoload
(defun search (beg end)
"Go to and pulse region starting at BEG and ending at END."
(interactive
- (save-excursion (search-read-target (use-region-beginning) (use-region-end))))
+ (save-excursion
+ (search-read-target (use-region-beginning) (use-region-end))))
(push-mark)
(goto-char beg)
(pulse-momentary-highlight-region beg end 'isearch))
;;;###autoload
(defun search-from-isearch (beg end)
+ "Pivot to `search' between BEG and END from `isearch'."
(interactive
(if isearch-mode
(save-excursion
(defun search-lines (beg end)
"Go to and pulse line starting at BEG and ending at END."
(interactive
- (save-excursion (search-read-target (use-region-beginning) (use-region-end) ".*")))
+ (save-excursion
+ (search-read-target (use-region-beginning) (use-region-end) ".*")))
(search beg end))
(provide 'search)
-;;; refactor.el ends here
+;;; search.el ends here