1226a1227,1328 > (defun isearch-unread-key-sequence (keylist) > "Unread the given key-sequence KEYLIST, being careful with scroll-bar or > mode-line events." > (cancel-kbd-macro-events) > (apply 'isearch-unread keylist) > ;; If the event was a scroll-bar or mode-line click, the event will have > ;; been prefixed by a symbol such as vertical-scroll-bar. We must remove > ;; it here, because this symbol will be attached to the event again next > ;; time it gets read by read-key-sequence. > ;; > ;; (Old comment from isearch-other-meta-char: "Note that we don't have to > ;; modify the event anymore in 21 because read_key_sequence no longer > ;; modifies events to produce fake prefix keys.") > (if (and (> (length keylist) 1) > (symbolp (car keylist)) > (listp (cadr keylist)) > (not (numberp (posn-point > (event-start (cadr keylist) ))))) > (pop unread-command-events))) > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > ;; scrolling within isearch-mode. Alan Mackenzie (acm@muc.de), 2003/2/24 > ;; > ;; The idea here is that certain vertical scrolling commands (like C-l > ;; (recenter)) should be usable WITHIN isearch mode. For a command to be > ;; suitable, it must NOT alter the buffer, swap to another buffer or frame, > ;; tamper with isearch's state, or move point. It is unacceptable for the > ;; search string to be scrolled out of the current window. If a command > ;; attempts this, we scroll the text back again. > ;; > ;; Horizontal scrolling commands are currently not catered for. > ;; > ;; We implement this feature with a property called isearch-scroll. If a > ;; command's symbol has the value t for this property it is a scrolling > ;; command. > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > > (defcustom isearch-allow-scroll nil > "If non-nil, certain scrolling commands are allowed during incremental search." > :type 'boolean > :group 'isearch) > > (defun isearch-string-out-of-window (isearch-point) > "Is the search string currently outside of the window? Return nil if it's > completely visible, or if point is visible, together with as much of the > search string as will fit; 'above if we need to scroll the text downwards; > 'below, if upwards." > (let ((w-start (window-start)) > (w-end (window-end nil t)) > (w-L1 (save-excursion (move-to-window-line 1) (point))) > (w-L-1 (save-excursion (move-to-window-line -1) (point))) > start end) ; start and end of search string in buffer > (if isearch-forward > (setq end isearch-point start (or isearch-other-end isearch-point)) > (setq start isearch-point end (or isearch-other-end isearch-point))) > (cond ((or (and (>= start w-start) (<= end w-end)) > (if isearch-forward > (and (>= isearch-point w-L-1) (< isearch-point w-end)) ; point on Line -1 > (and (>= isearch-point w-start) (< isearch-point w-L1)))) ; point on Line 0 > nil) > ((and (< start w-start) > (< isearch-point w-L-1)) > 'above) > (t 'below)))) > > (defun isearch-back-into-window (above isearch-point) > "Scroll the window to bring the search string back into view, restoring > point to ISEARCH-POINT in the process. ABOVE is t when the search string is > above the top of the window, nil when it is beneath the bottom." > (let (start end) > (if isearch-forward > (setq end isearch-point start (or isearch-other-end isearch-point)) > (setq start isearch-point end (or isearch-other-end isearch-point))) > (if above > (progn > (goto-char start) > (recenter 0) > (when (>= isearch-point (window-end nil t)) > (goto-char isearch-point) > (recenter -1))) > (goto-char end) > (recenter -1) > (when (< isearch-point (window-start)) > (goto-char isearch-point) > (recenter 0)))) > (goto-char isearch-point)) > > (defun isearch-reread-key-sequence-naturally (keylist) > "Reread the current key sequence KEYLIST with isearch-mode's own keymap > deactivated. Return the key sequence as a string/vector." > (isearch-unread-key-sequence keylist) > (let (overriding-terminal-local-map) > (read-key-sequence nil))) ; This will go through function-key-map, if nec. > > (defun isearch-lookup-scroll-key (key) > "If the supplied key sequence, KEY, is bound to a scrolling command, return > this command (always a symbol), otherwise nil." > (let* ((overriding-terminal-local-map nil) > (binding (key-binding key))) > (and binding (symbolp binding) (commandp binding) > (eq (get binding 'isearch-scroll) t) > binding))) 1230,1236c1332,1349 < (defun isearch-other-meta-char () < "Exit the search normally and reread this key sequence. < But only if `search-exit-option' is non-nil, the default. < If it is the symbol `edit', the search string is edited in the minibuffer < and the meta character is unread so that it applies to editing the string." < (interactive) < (let* ((key (this-command-keys)) --- > (defun isearch-other-meta-char (&optional arg) > "See if the current key-sequence can be converted to something usable in > isearch-mode, either by converting it with the function-key-map, downcasing a > key with C-, or finding a \"scrolling command\" bound to it. \(In > the last case, we may have to read more events.\) If so, either unread the > converted sequence or execute the command. > > Otherwise, if `search-exit-option' is non-nil (the default) unread the > key-sequence and exit the search normally. If it is the symbol `edit', the > search string is edited in the minibuffer and the meta character is unread so > that it applies to editing the string. > > ARG is the prefix argument. It will be transmitted through to the scrolling > command or to the command which exits isearch-mode." > (interactive "P") > (let* ((key (if current-prefix-arg ; not nec the same as ARG > (substring (this-command-keys) universal-argument-num-events) > (this-command-keys))) 1238c1351,1352 < (keylist (listify-key-sequence key))) --- > (keylist (listify-key-sequence key)) > scroll-command isearch-point) 1289a1404,1420 > ;; Handle a scrolling function. > ((and isearch-allow-scroll > (progn (setq key (isearch-reread-key-sequence-naturally keylist)) > (setq keylist (listify-key-sequence key)) > (setq main-event (aref key 0)) > (setq scroll-command (isearch-lookup-scroll-key key)))) > ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a > ;; complete key sequence, possibly as modified by function-key-map, > ;; not merely the one or two event fragment which invoked > ;; isearch-other-meta-char in the first place. > (setq isearch-point (point)) > (setq prefix-arg arg) > (command-execute scroll-command) > (let ((ab-bel (isearch-string-out-of-window isearch-point))) > (if ab-bel > (isearch-back-into-window (eq ab-bel 'above) isearch-point))) > (isearch-update)) 1292,1306c1423,1424 < (cancel-kbd-macro-events) < (apply 'isearch-unread keylist) < < ;; Properly handle scroll-bar and mode-line clicks for < ;; which a dummy prefix event was generated as (aref key < ;; 0). Note that we don't have to modify the event < ;; anymore in 21 because read_key_sequence no longer modifies < ;; events to produce fake prefix keys. < (when (and (> (length key) 1) < (symbolp (aref key 0)) < (listp (aref key 1)) < (not (numberp (posn-point < (event-start (aref key 1)))))) < (pop unread-command-events) < (setq main-event (car unread-command-events))) --- > (isearch-unread-key-sequence keylist) > (setq main-event (car unread-command-events)) 1336,1337c1454,1456 < (isearch-clean-overlays)))) < (t;; otherwise nil --- > (isearch-clean-overlays) > (setq prefix-arg arg)))) > (t;; otherwise nil 1999a2119 > (defvar isearch-lazy-highlight-window-end nil) 2034c2154,2156 < isearch-lazy-highlight-window-start)))) --- > isearch-lazy-highlight-window-start)) > (not (= (window-end) ; Window may have been split/joined. > isearch-lazy-highlight-window-end)))) 2039a2162 > isearch-lazy-highlight-window-end (window-end)