aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/isearch.el
diff options
context:
space:
mode:
authorGerd Moellmann <[email protected]>2001-01-17 14:10:25 +0000
committerGerd Moellmann <[email protected]>2001-01-17 14:10:25 +0000
commitc982ab21683e6c01e6488a5a101159b14fb58c56 (patch)
tree154bef1987248c3d9afc6e6659efe65efcc1d5a9 /lisp/isearch.el
parentecd01a0e00eb2cf1b2eb45178e2ce5525708d3a2 (diff)
(isearch-highlight): Set isearch-overlay priority to
1 here rather than each time through isearch-lazy-highlight-new-loop. (isearch-lazy-highlight-max): Variable deleted. (isearch-lazy-highlight-max-at-a-time): New user variable, like isearch-lazy-highlight-max but controls a single invocation of isearch-lazy-highlight-update. (isearch-lazy-highlight-wrapped): Variable recreated. (isearch-lazy-highlight-window-start): New variable. (isearch-lazy-highlight-cleanup): Restored to behavior of before 2-Jan. (isearch-lazy-highlight-remove-overlays): Function deleted; behavior folded into isearch-lazy-highlight-cleanup. "Keep" behavior removed. (isearch-lazy-highlight-new-loop): Restore old behavior of calling isearch-lazy-highlight-update in a loop rather than just once. Test isearch-invalid-regexp here and decide not to start a new loop, rather than testing it each time through isearch-lazy-highlight-update. (isearch-lazy-highlight-search): Function restored. (isearch-lazy-highlight-update): Get called in a timer loop again, but this time highlight more than one match each time through. Only highlight matches in the visible part of the window. Start at point, move in the direction of the search, and wrap around at the edge of the window. Use sit-for to force redisplay and ensure window-start is credible. "Face suppressing" behavior removed; overlay priorities should make it unnecessary, right? (isearch-highlight): Face suppressing behavior removed. (isearch-dehighlight): Face suppressing behavior removed. (isearch-set-lazy-highlight-faces-at): Removed.
Diffstat (limited to 'lisp/isearch.el')
-rw-r--r--lisp/isearch.el310
1 files changed, 147 insertions, 163 deletions
diff --git a/lisp/isearch.el b/lisp/isearch.el
index eb4f9a43f6..5fd9654660 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -593,33 +593,33 @@ is treated as a regexp. See \\[isearch-forward] for more info."
;; Called after each command to update the display.
(if (null unread-command-events)
(progn
- (if (not (input-pending-p))
- (isearch-message))
- (if (and isearch-slow-terminal-mode
- (not (or isearch-small-window
- (pos-visible-in-window-p))))
- (let ((found-point (point)))
- (setq isearch-small-window t)
- (move-to-window-line 0)
- (let ((window-min-height 1))
- (split-window nil (if (< search-slow-window-lines 0)
- (1+ (- search-slow-window-lines))
- (- (window-height)
- (1+ search-slow-window-lines)))))
- (if (< search-slow-window-lines 0)
- (progn (vertical-motion (- 1 search-slow-window-lines))
- (set-window-start (next-window) (point))
- (set-window-hscroll (next-window)
- (window-hscroll))
- (set-window-hscroll (selected-window) 0))
- (other-window 1))
- (goto-char found-point)))
- (if isearch-other-end
- (if (< isearch-other-end (point)) ; isearch-forward?
- (isearch-highlight isearch-other-end (point))
- (isearch-highlight (point) isearch-other-end))
- (isearch-dehighlight nil))
- ))
+ (if (not (input-pending-p))
+ (isearch-message))
+ (if (and isearch-slow-terminal-mode
+ (not (or isearch-small-window
+ (pos-visible-in-window-p))))
+ (let ((found-point (point)))
+ (setq isearch-small-window t)
+ (move-to-window-line 0)
+ (let ((window-min-height 1))
+ (split-window nil (if (< search-slow-window-lines 0)
+ (1+ (- search-slow-window-lines))
+ (- (window-height)
+ (1+ search-slow-window-lines)))))
+ (if (< search-slow-window-lines 0)
+ (progn (vertical-motion (- 1 search-slow-window-lines))
+ (set-window-start (next-window) (point))
+ (set-window-hscroll (next-window)
+ (window-hscroll))
+ (set-window-hscroll (selected-window) 0))
+ (other-window 1))
+ (goto-char found-point)))
+ (if isearch-other-end
+ (if (< isearch-other-end (point)) ; isearch-forward?
+ (isearch-highlight isearch-other-end (point))
+ (isearch-highlight (point) isearch-other-end))
+ (isearch-dehighlight nil))
+ ))
(setq ;; quit-flag nil not for isearch-mode
isearch-adjusted nil
isearch-yank-flag nil)
@@ -638,7 +638,6 @@ is treated as a regexp. See \\[isearch-forward] for more info."
(remove-hook 'mouse-leave-buffer-hook 'isearch-done)
(remove-hook 'kbd-macro-termination-hook 'isearch-done)
-
(setq isearch-lazy-highlight-start nil)
;; Called by all commands that terminate isearch-mode.
@@ -1583,7 +1582,7 @@ If there is no completion possible, say so and continue searching."
isearch-invalid-regexp)
(setq isearch-invalid-regexp "incomplete input")))
(error
- ;; Stack overflow in regexp search, for instance.
+ ;; stack overflow in regexp search.
(setq isearch-invalid-regexp (format "%s" lossage))))
(if isearch-success
@@ -1740,45 +1739,21 @@ If there is no completion possible, say so and continue searching."
(defvar isearch-overlay nil)
-(defsubst isearch-set-lazy-highlight-faces-at (pos face)
- "Set the face property of isearch lazy highlight overlays at POS to FACE.
-If POS is nil, nothing is done."
- (unless (null pos)
- (dolist (ov (overlays-at pos))
- (when (and (not (eq ov isearch-overlay))
- (memq ov isearch-lazy-highlight-overlays)
- (not (eq (overlay-get ov 'face) face)))
- (overlay-put ov 'face face)))))
-
(defun isearch-highlight (beg end)
(unless (or (null search-highlight) (null (display-color-p)))
(cond (isearch-overlay
;; Overlay already exists, just move it.
-
- ;; Check to see if there are any lazy-isearch overlays at
- ;; the same position with their face property suppressed
- ;; (to avoid face clashes), and if so, give them their face
- ;; back.
- (isearch-set-lazy-highlight-faces-at (overlay-start isearch-overlay)
- isearch-lazy-highlight-face)
-
(move-overlay isearch-overlay beg end (current-buffer)))
(t
;; Overlay doesn't exist, create it.
(setq isearch-overlay (make-overlay beg end))
- (overlay-put isearch-overlay 'face isearch)))
-
- ;; Suppress the faces of any lazy-isearch overlays at the new position
- (isearch-set-lazy-highlight-faces-at beg nil)))
+ (overlay-put isearch-overlay 'face isearch)
+ (overlay-put isearch-overlay 'priority 1) ;higher than lazy overlays
+ ))))
(defun isearch-dehighlight (totally)
(when isearch-overlay
- ;; Check to see if there are any lazy-isearch overlays at the same
- ;; position with their face property suppressed (to avoid face
- ;; clashes), and if so, give them their face back.
- (isearch-set-lazy-highlight-faces-at (overlay-start isearch-overlay)
- isearch-lazy-highlight-face)
(delete-overlay isearch-overlay)))
@@ -1820,23 +1795,19 @@ since they have special meaning in a regexp."
;;; When active, *every* match for the current search string is
;;; highlighted: the current one using the normal isearch match color
-;;; and all the others using the unobtrusive `secondary-selection'
-;;; color. The extra highlighting makes it easier to anticipate where
-;;; the cursor will land each time you press C-s or C-r to repeat a
-;;; pending search. Highlighting of these additional matches happens
-;;; in a deferred fashion using "idle timers," so the cycles needed do
-;;; not rob isearch of its usual snappy response.
+;;; and all the others using `isearch-lazy-highlight-face'. The extra
+;;; highlighting makes it easier to anticipate where the cursor will
+;;; land each time you press C-s or C-r to repeat a pending search.
+;;; Highlighting of these additional matches happens in a deferred
+;;; fashion using "idle timers," so the cycles needed do not rob
+;;; isearch of its usual snappy response.
;;; IMPLEMENTATION NOTE: This depends on some isearch internals.
;;; Specifically:
;;; - `isearch-update' is expected to be called (at least) every time
-;;; the search string changes;
+;;; the search string or window-start changes;
;;; - `isearch-string' is expected to contain the current search
;;; string as entered by the user;
-;;; - `isearch-overlay' is expected to contain the overlay used for
-;;; primary isearch match-highlighting;
-;;; - `isearch-opoint' is expected to contain the location where the
-;;; current search began;
;;; - the type of the current search is expected to be given by
;;; `isearch-word' and `isearch-regexp';
;;; - the direction of the current search is expected to be given by
@@ -1877,8 +1848,11 @@ If this is nil, extra highlighting can be \"manually\" removed with
:type 'number
:group 'isearch-lazy-highlight)
-(defcustom isearch-lazy-highlight-max 20
- "*Maximum number of matches to highlight."
+(defcustom isearch-lazy-highlight-max-at-a-time 20
+ "*Maximum matches to highlight at a time (for `isearch-lazy-highlight').
+Larger values may reduce isearch's responsiveness to user input;
+smaller values make matches highlight slowly.
+A value of nil means highlight all matches."
:type '(choice (const :tag "All" nil)
(integer :tag "Some"))
:group 'isearch-lazy-highlight)
@@ -1913,114 +1887,124 @@ If this is nil, extra highlighting can be \"manually\" removed with
(defvar isearch-lazy-highlight-face 'isearch-lazy-highlight-face)
(defvar isearch-lazy-highlight-overlays nil)
-(defvar isearch-lazy-highlight-window nil)
+(defvar isearch-lazy-highlight-wrapped nil)
(defvar isearch-lazy-highlight-start nil)
(defvar isearch-lazy-highlight-end nil)
(defvar isearch-lazy-highlight-timer nil)
(defvar isearch-lazy-highlight-last-string nil)
+(defvar isearch-lazy-highlight-window nil)
+(defvar isearch-lazy-highlight-window-start nil)
-(defun isearch-lazy-highlight-cleanup (&optional remove)
- "Stop lazy highlighting and maybe remove existing highlighting.
-REMOVE non-nil means remove all the existing lazy highlighting.
-
-This function is called when exiting an incremental search."
+(defun isearch-lazy-highlight-cleanup (&optional force)
+ "Stop lazy highlighting and remove extra highlighting from current buffer.
+FORCE non-nil means do it whether or not `isearch-lazy-highlight-cleanup'
+is nil. This function is called when exiting an incremental search if
+`isearch-lazy-highlight-cleanup' is non-nil."
(interactive '(t))
- (if remove
- (isearch-lazy-highlight-remove-overlays))
- (if isearch-lazy-highlight-timer
- (progn
- (cancel-timer isearch-lazy-highlight-timer)
- (setq isearch-lazy-highlight-timer nil))))
-
-(defun isearch-lazy-highlight-remove-overlays (&optional keep-start keep-end)
- "Remove lazy highlight overlays from the current buffer.
-With optional arguments KEEP-START and KEEP-END,
-preserve any overlays in that range."
- (let ((tem isearch-lazy-highlight-overlays))
- (while tem
- (if (or (null keep-start)
- (let ((pos (overlay-start (car tem))))
- (or (< pos keep-start) (> pos keep-end))))
- (progn
- (delete-overlay (car tem))
- (setq isearch-lazy-highlight-overlays
- (delq (car tem) isearch-lazy-highlight-overlays))))
- (setq tem (cdr tem)))))
+ (if (or force isearch-lazy-highlight-cleanup)
+ (while isearch-lazy-highlight-overlays
+ (delete-overlay (car isearch-lazy-highlight-overlays))
+ (setq isearch-lazy-highlight-overlays
+ (cdr isearch-lazy-highlight-overlays))))
+ (when isearch-lazy-highlight-timer
+ (cancel-timer isearch-lazy-highlight-timer)
+ (setq isearch-lazy-highlight-timer nil)))
(defun isearch-lazy-highlight-new-loop ()
- "Clear obsolete highlighting, and queue up to do new highlighting.
+ "Cleanup any previous `isearch-lazy-highlight' loop and begin a new one.
This happens when `isearch-update' is invoked (which can cause the
-search string to change)."
+search string to change or the window to scroll)."
(when (and isearch-lazy-highlight
- (not isearch-invalid-regexp)
- (not (equal isearch-string "")))
-
- ;; If the search string has changed, remove all old overlays.
- (unless (equal isearch-string isearch-lazy-highlight-last-string)
- (isearch-lazy-highlight-remove-overlays)
- (setq isearch-lazy-highlight-window nil))
-
- (if (and isearch-overlay
- (not (overlay-get isearch-overlay 'priority)))
- ;; Make sure the isearch-overlay takes priority
- ;; over any other matches.
- (overlay-put isearch-overlay 'priority 1))
-
- ;; Queue up to display other matches after a short pause.
- (setq isearch-lazy-highlight-timer
- (run-with-idle-timer isearch-lazy-highlight-initial-delay nil
- 'isearch-lazy-highlight-update))))
+ (sit-for 0) ;make sure (window-start) is credible
+ (or (not (equal isearch-string
+ isearch-lazy-highlight-last-string))
+ (not (eq (selected-window)
+ isearch-lazy-highlight-window))
+ (not (= (window-start)
+ isearch-lazy-highlight-window-start))))
+ ;; something important did indeed change
+ (isearch-lazy-highlight-cleanup t) ;kill old loop & remove overlays
+ (when (not isearch-invalid-regexp)
+ (setq isearch-lazy-highlight-window (selected-window)
+ isearch-lazy-highlight-window-start (window-start)
+ isearch-lazy-highlight-start (point)
+ isearch-lazy-highlight-end (point)
+ isearch-lazy-highlight-last-string isearch-string
+ isearch-lazy-highlight-wrapped nil)
+ (setq isearch-lazy-highlight-timer
+ (run-with-idle-timer isearch-lazy-highlight-initial-delay nil
+ 'isearch-lazy-highlight-update)))))
+
+(defun isearch-lazy-highlight-search ()
+ "Search ahead for the next or previous match, for lazy highlighting.
+Attempt to do the search exactly the way the pending isearch would."
+ (let ((case-fold-search isearch-case-fold-search)
+ (choices (cond (isearch-word
+ '(word-search-forward . word-search-backward))
+ (isearch-regexp
+ '(re-search-forward . re-search-backward))
+ (t
+ '(search-forward . search-backward)))))
+ (funcall (if isearch-forward
+ (car choices)
+ (cdr choices))
+ isearch-string
+ (if isearch-forward
+ (if isearch-lazy-highlight-wrapped
+ isearch-lazy-highlight-start
+ (window-end))
+ (if isearch-lazy-highlight-wrapped
+ isearch-lazy-highlight-end
+ (window-start)))
+ t)))
(defun isearch-lazy-highlight-update ()
- "Update highlighting of possible other matches for isearch."
- (unless (and (eq isearch-lazy-highlight-window (selected-window))
- (equal isearch-lazy-highlight-start (window-start)))
-
- ;; The search string or the visible window has changed.
-
- (setq isearch-lazy-highlight-window (selected-window)
- isearch-lazy-highlight-start (window-start)
- isearch-lazy-highlight-end (window-end nil t)
- isearch-lazy-highlight-last-string isearch-string)
-
- ;; If the string is the same, the old overlays are still usable
- ;; if they are still visible in the window.
- (isearch-lazy-highlight-remove-overlays (window-start)
- (window-end nil t))
-
+ "Update highlighting of other matches for current search."
+ (let ((max isearch-lazy-highlight-max-at-a-time)
+ (looping t)
+ nomore)
(save-excursion
(save-match-data
- (let (found)
- (goto-char isearch-lazy-highlight-start)
- (while (and (or (null isearch-lazy-highlight-max)
- (< (length isearch-lazy-highlight-overlays)
- isearch-lazy-highlight-max))
- (< (point) isearch-lazy-highlight-end)
- (let ((case-fold-search isearch-case-fold-search))
- (funcall (cond (isearch-word 'word-search-forward)
- (isearch-regexp 're-search-forward)
- (t 'search-forward))
- isearch-string
- isearch-lazy-highlight-end
- t)))
- ;; Found the next match.
- ;; If it is empty, ignore it and move on.
- (if (= (match-beginning 0) (match-end 0))
- (forward-char 1)
- (let ((ov (make-overlay (match-beginning 0)
- (match-end 0))))
- ;; If OV overlaps the current isearch overlay, suppress
- ;; its face property; otherwise, we sometimes get odd
- ;; looking face combinations.
- (unless (memq isearch-overlay
- (overlays-in (match-beginning 0) (match-end 0)))
- (overlay-put ov 'face isearch-lazy-highlight-face))
-
- (overlay-put ov 'priority 0)
- ;; Don't highlight on any other windows.
- (overlay-put ov 'window isearch-lazy-highlight-window)
-
- (push ov isearch-lazy-highlight-overlays)))))))))
+ (goto-char (if isearch-forward
+ isearch-lazy-highlight-end
+ isearch-lazy-highlight-start))
+ (while looping
+ (let ((found (isearch-lazy-highlight-search)))
+ (when max
+ (setq max (1- max))
+ (if (<= max 0)
+ (setq looping nil)))
+ (if found
+ (let ((mb (match-beginning 0))
+ (me (match-end 0)))
+ (if (= mb me) ;zero-length match
+ (forward-char 1)
+
+ ;; non-zero-length match
+ (let ((ov (make-overlay mb me)))
+ (overlay-put ov 'face isearch-lazy-highlight-face)
+ (overlay-put ov 'priority 0) ;lower than main overlay
+ (overlay-put ov 'window (selected-window))
+ (push ov isearch-lazy-highlight-overlays)))
+ (if isearch-forward
+ (setq isearch-lazy-highlight-end (point))
+ (setq isearch-lazy-highlight-start (point))))
+
+ ;; not found
+ (if isearch-lazy-highlight-wrapped
+ (setq looping nil
+ nomore t)
+ (setq isearch-lazy-highlight-wrapped t)
+ (if isearch-forward
+ (progn
+ (setq isearch-lazy-highlight-end (window-start))
+ (goto-char (window-start)))
+ (setq isearch-lazy-highlight-start (window-end))
+ (goto-char (window-end)))))))
+ (unless nomore
+ (setq isearch-lazy-highlight-timer
+ (run-at-time isearch-lazy-highlight-interval nil
+ 'isearch-lazy-highlight-update)))))))
(defun isearch-resume (search regexp word forward message case-fold)
"Resume an incremental search.