Skip to content

Commit

Permalink
rewrite search related code with isearch
Browse files Browse the repository at this point in the history
  • Loading branch information
jixiuf committed Feb 14, 2024
1 parent 54d4e93 commit 066c303
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 156 deletions.
29 changes: 16 additions & 13 deletions meow-beacon.el
Original file line number Diff line number Diff line change
Expand Up @@ -235,20 +235,23 @@ MATCH is the search regexp."
(meow--narrow-secondary-selection)
(let ((orig-end (region-end))
(orig-beg (region-beginning))
(back (meow--direction-backward-p)))
(back (meow--direction-backward-p))
(inhibit-redisplay t)
(isearch-state (isearch--get-state))
(isearch-wrap-pause nil)) ; never wrap, just stop at the last match.
(save-mark-and-excursion
(goto-char (point-min))
(let ((case-fold-search nil))
(while (re-search-forward match nil t)
(unless (or (= orig-end (point))
(= orig-beg (point)))
(let ((match (match-data)))
(meow--beacon-add-overlay-at-region
'(select . visit)
(car match)
(cadr match)
back)))))
(setq meow--beacon-overlays (reverse meow--beacon-overlays))))))
(while (meow--search back match nil t)
(unless (or (= orig-end (point))
(= orig-beg (point)))
(let ((match isearch-match-data))
(meow--beacon-add-overlay-at-region
'(select . visit)
(car match)
(cadr match)
back))))
(setq meow--beacon-overlays (reverse meow--beacon-overlays)))
(isearch--set-state isearch-state))))

(defun meow--beacon-count-lines (beg end)
"Count selected lines from BEG to END."
Expand Down Expand Up @@ -393,7 +396,7 @@ MATCH is the search regexp."
((word) (if (not (eq 'expand ex))
(meow--add-beacons-for-word)
(meow--add-beacons-for-match (meow--beacon-region-words-to-match))))
((visit) (meow--add-beacons-for-match (car regexp-search-ring)))
((visit) (meow--add-beacons-for-match nil))
((line) (meow--add-beacons-for-line))
((join) (meow--add-beacons-for-join))
((find) (meow--add-beacons-for-find))
Expand Down
128 changes: 46 additions & 82 deletions meow-command.el
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ This command supports `meow-selection-command-fallback'."
(meow--execute-kbd-macro meow--kbd-exchange-point-and-mark)
(if (member last-command
'(meow-visit meow-search meow-mark-symbol meow-mark-word))
(meow--highlight-regexp-in-buffer (car regexp-search-ring))
(save-mark-and-excursion
(meow-search nil)
(setq this-command last-command))
(meow--maybe-highlight-num-positions))))

;;; Buffer
Expand Down Expand Up @@ -755,8 +757,9 @@ Use negative argument to create a backward selection."
(meow--make-selection '(expand . word) beg end)
(meow--select (< n 0)))
(let ((search (format "\\<%s\\>" (regexp-quote (buffer-substring-no-properties beg end)))))
(meow--push-search search)
(meow--highlight-regexp-in-buffer search)))))
(save-mark-and-excursion
(goto-char (if (< n 0) end beg))
(meow--search (< n 0) search))))))

(defun meow-mark-symbol (n)
"Mark current symbol under cursor.
Expand All @@ -771,8 +774,9 @@ This command works similar to `meow-mark-word'."
(meow--make-selection '(expand . word) beg end)
(meow--select (< n 0)))
(let ((search (format "\\_<%s\\_>" (regexp-quote (buffer-substring-no-properties beg end)))))
(meow--push-search search)
(meow--highlight-regexp-in-buffer search)))))
(save-mark-and-excursion
(goto-char (if (< n 0) end beg))
(meow--search (< n 0) search))))))

(defun meow--forward-symbol-1 ()
(when (forward-symbol 1)
Expand Down Expand Up @@ -1315,49 +1319,36 @@ with UNIVERSAL ARGUMENT, search both side."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun meow-search (arg)
" Search and select with the car of current `regexp-search-ring'.
If the contents of selection doesn't match the regexp, will push it to `regexp-search-ring' before searching.
" Search and select with `isearch-string'.
To search backward, use \\[negative-argument]."
(interactive "P")
;; Test if we add current region as search target.
(when (and (region-active-p)
(let ((search (car regexp-search-ring)))
(or (not search)
(not (string-match-p
(format "^%s$" search)
(buffer-substring-no-properties (region-beginning) (region-end)))))))
(meow--push-search (regexp-quote (buffer-substring-no-properties (region-beginning) (region-end)))))
(when-let ((search (car regexp-search-ring)))
(let ((reverse (xor (meow--with-negative-argument-p arg) (meow--direction-backward-p)))
(case-fold-search nil))
(if (or (if reverse
(re-search-backward search nil t 1)
(re-search-forward search nil t 1))
;; Try research from buffer beginning/end
;; if we are already at the last/first matched
(save-mark-and-excursion
;; Recalculate search indicator
(meow--clean-search-indicator-state)
(goto-char (if reverse (point-max) (point-min)))
(if reverse
(re-search-backward search nil t 1)
(re-search-forward search nil t 1))))
(let* ((m (match-data))
(marker-beg (car m))
(marker-end (cadr m))
(beg (if reverse (marker-position marker-end) (marker-position marker-beg)))
(end (if reverse (marker-position marker-beg) (marker-position marker-end))))
(thread-first
(meow--make-selection '(select . visit) beg end)
(meow--select))
(if reverse
(message "Reverse search: %s" search)
(message "Search: %s" search))
(meow--ensure-visible))
(message "Searching %s failed" search))
(meow--highlight-regexp-in-buffer search))))
(let ((reverse (xor (meow--with-negative-argument-p arg)
(meow--direction-backward-p)))
match)
(when (region-active-p)
(setq match (buffer-substring-no-properties
(region-beginning)(region-end)))
;; (deactivate-mark)
(if (not (string-empty-p isearch-string))
;; Test if we add current region as search target.
(save-match-data
(save-mark-and-excursion
(let ((case-fold-search isearch-case-fold-search)
(search-invisible isearch-invisible))
(with-temp-buffer
(insert match)
(when isearch-forward
(goto-char (point-min)))
(when (and (isearch-search-string isearch-string nil t)
(string-equal (match-string 0) match))
;; when matched, should just call `isearch-repeat' later
(setq match nil))))))))
(when match (setq match (regexp-quote match)))
(when (and (not match) (string-empty-p isearch-string))
(user-error "Failed to Search: please make a selection to search for"))
(meow--search reverse match)
isearch-success))

(defun meow-pop-search ()
"Searching for the previous target."
Expand All @@ -1366,21 +1357,9 @@ To search backward, use \\[negative-argument]."
(message "current search is: %s" (car regexp-search-ring))
(meow--cancel-selection)))

(defun meow--visit-point (text reverse)
"Return the point of text for visit command.
Argument TEXT current search text.
Argument REVERSE if selection is reversed."
(let ((func (if reverse #'re-search-backward #'re-search-forward))
(func-2 (if reverse #'re-search-forward #'re-search-backward))
(case-fold-search nil))
(save-mark-and-excursion
(or (funcall func text nil t 1)
(funcall func-2 text nil t 1)))))

(defun meow-visit (arg)
"Read a string from minibuffer, then find and select it.
The input will be pushed into `regexp-search-ring'. So
\\[meow-search] can be used for further searching with the same condition.
A list of words and symbols in the current buffer will be provided for completion.
Expand All @@ -1391,25 +1370,10 @@ the words and symbols in the current buffer.
To search backward, use \\[negative-argument]."
(interactive "P")
(let* ((reverse arg)
(pos (point))
(text (meow--prompt-symbol-and-words
(if arg "Visit backward: " "Visit: ")
(point-min) (point-max)))
(visit-point (meow--visit-point text reverse)))
(if visit-point
(let* ((m (match-data))
(marker-beg (car m))
(marker-end (cadr m))
(beg (if (> pos visit-point) (marker-position marker-end) (marker-position marker-beg)))
(end (if (> pos visit-point) (marker-position marker-beg) (marker-position marker-end))))
(thread-first
(meow--make-selection '(select . visit) beg end)
(meow--select))
(meow--push-search text)
(meow--ensure-visible)
(meow--highlight-regexp-in-buffer text)
(setq meow--dont-remove-overlay t))
(message "Visit: %s failed" text))))
(point-min) (point-max))))
(meow--search reverse text)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; THING
Expand Down Expand Up @@ -1624,20 +1588,19 @@ Argument ARG if not nil, switching in a new window."
Use negative argument for backward application."
(interactive "P")
(let ((s (car regexp-search-ring))
(case-fold-search nil)
;;do not wrap when there are no more matches
(let ((isearch-wrap-pause nil)
(isearch-state (isearch--get-state))
(back (meow--with-negative-argument-p arg)))
(meow--wrap-collapse-undo
(while (if back
(re-search-backward s nil t)
(re-search-forward s nil t))
(while (meow--search back nil nil t)
(thread-first
(meow--make-selection '(select . visit)
(if back
(point)
(match-beginning 0))
(car isearch-match-data))
(if back
(match-end 0)
(cadr isearch-match-data)
(point)))
(meow--select))
(let ((ov (make-overlay (region-beginning) (region-end))))
Expand All @@ -1648,7 +1611,8 @@ Use negative argument for backward application."
(if back
(goto-char (min (point) (overlay-start ov)))
(goto-char (max (point) (overlay-end ov))))
(delete-overlay ov))))))))
(delete-overlay ov)))))
(isearch--set-state isearch-state))))

(defun meow-start-kmacro ()
"Start kmacro.
Expand Down
6 changes: 6 additions & 0 deletions meow-core.el
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ there's no chance for meow to call an init function."
(add-hook 'suspend-resume-hook 'meow--update-cursor)
(add-hook 'kill-emacs-hook 'meow--on-exit)
(add-hook 'desktop-after-read-hook 'meow--init-buffers)
(add-hook 'lazy-count-update-hook #'meow--lazy-count-hook)
(add-hook 'isearch-mode-end-hook #'meow--post-isearch-function)


(meow--enable-shims)
;; meow-esc-mode fix ESC in TUI
Expand Down Expand Up @@ -206,6 +209,9 @@ there's no chance for meow to call an init function."
(remove-hook 'suspend-resume-hook 'meow--update-cursor)
(remove-hook 'kill-emacs-hook 'meow--on-exit)
(remove-hook 'desktop-after-read-hook 'meow--init-buffers)
(remove-hook 'lazy-count-update-hook #'meow--lazy-count-hook)
(remove-hook 'isearch-mode-end-hook #'meow--post-isearch-function)

(meow--disable-shims)
(meow--remove-modeline-indicator)
(when meow-use-cursor-position-hack
Expand Down
5 changes: 0 additions & 5 deletions meow-face.el
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,6 @@
"Indicator for region direction."
:group 'meow)

(defface meow-search-highlight
'((t (:inherit lazy-highlight)))
"Search target highlight."
:group 'meow)

(defface meow-position-highlight-number
'((((class color) (background dark))
(:inherit default))
Expand Down
77 changes: 69 additions & 8 deletions meow-util.el
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
(require 'cl-lib)
(require 'seq)
(require 'color)
(require 'isearch)

(require 'meow-var)
(require 'meow-keymap)
Expand Down Expand Up @@ -400,14 +401,6 @@ Looks up the state in meow-replace-state-name-list"
(upcase (event-basic-type e))
(event-basic-type e)))

(defun meow--ensure-visible ()
(let ((overlays (overlays-at (1- (point))))
ov expose)
(while (setq ov (pop overlays))
(if (and (invisible-p (overlay-get ov 'invisible))
(setq expose (overlay-get ov 'isearch-open-invisible)))
(funcall expose ov)))))

(defun meow--minibuffer-setup ()
(local-set-key (kbd "<escape>") #'meow-minibuffer-quit)
(setq-local meow-normal-mode nil)
Expand Down Expand Up @@ -696,5 +689,73 @@ that bound to DEF. Otherwise, return DEF."
((null meow-keypad-leader-dispatch)
(alist-get 'leader meow-keymap-alist))))

(defun meow--search (reverse &optional match not-regexp inhibit-lazy-highlight-and-count)
"Search for the next occurrence of MATCH using isearch.
If found, move point to the end of the occurrence,and return point.
REVERSE - If non-nil, the search direction is backward. Otherwise, it is forward.
MATCH - The string to search for, if nil `isearch-repeat' is called.
NOT-REGEXP - If non-nil, do a regular string search instead.
INHIBIT-LAZY-HIGHLIGHT-AND-COUNT - If non-nil disable lazy highlighting and
lazy counting features."
(interactive "P")
(when (and (string-equal match isearch-string)
(equal isearch-regexp (not not-regexp)))
(setq match nil))
(let ((inhibit-redisplay t)
(isearch-lazy-count t)
(isearch-lazy-highlight t))
(when inhibit-lazy-highlight-and-count
(setq isearch-lazy-count nil)
(setq isearch-lazy-highlight nil))
(if (not match)
;; if MATCH is nil, just call `isearch-repeat'
(isearch-repeat (if reverse 'backward 'forward))
(if reverse
(isearch-backward-regexp not-regexp t)
(isearch-forward-regexp not-regexp t))
(isearch-process-search-string
match
(mapconcat 'isearch-text-char-description match "")))
(isearch-update)
(isearch-done))
;; highlight after isearch-done
;; M-x:lazy-highlight-cleanup to cleanup highlight
(unless inhibit-lazy-highlight-and-count
(isearch-lazy-highlight-new-loop))
isearch-success)

(defun meow--lazy-count-hook ()
(when (meow-normal-mode-p)
(save-mark-and-excursion
(meow--remove-search-indicator)
(when isearch-lazy-count-current
(meow--show-indicator (point) (isearch-lazy-count-format)))
;; the active region is the selection after a success search
;; it should no be highlighted
(when (region-active-p)
(dolist (ov isearch-lazy-highlight-overlays)
(let ((ov-start (overlay-start ov))
(ov-end (overlay-end ov))
(reg-start (region-beginning))
(reg-end (region-end)))
;; Check if the overlay region overlaps with the active region
(when (and (<= ov-start reg-end) (>= ov-end reg-start))
;; If they overlap, set the overlay's priority to 0
(setq isearch-lazy-highlight-overlays
(delq ov isearch-lazy-highlight-overlays))
(delete-overlay ov))))))))

(defun meow--post-isearch-function ()
(unless isearch-mode-end-hook-quit
(when (and isearch-success isearch-match-data)
(let ((beg (car isearch-match-data))
(end (cadr isearch-match-data)))
(thread-first
(meow--make-selection '(select . visit)
beg
(if isearch-forward end isearch-other-end))
(meow--select (not isearch-forward)))))))

(provide 'meow-util)
;;; meow-util.el ends here
Loading

0 comments on commit 066c303

Please sign in to comment.