aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2003-11-01 17:00:02 +0000
committerEli Zaretskii2003-11-01 17:00:02 +0000
commit1e491f1bb8aee4406b7cbb2869a24f7508e650bf (patch)
tree86c6944ecc821c4cf8f8664e8c0de48bbd3cbaae
parent867bae0b00ac9aa22648a9d82d49bc40e2ecc83b (diff)
downloademacs-1e491f1bb8aee4406b7cbb2869a24f7508e650bf.tar.gz
emacs-1e491f1bb8aee4406b7cbb2869a24f7508e650bf.zip
(isearch-unread-key-sequence): New function, extracted from
isearch-other-meta-char. (top level): (put 'foo 'isearch-scroll) on all Emacs's "scrollable" standard functions. (isearch-allow-scroll): New customizable variable. (isearch-string-out-of-window, isearch-back-into-window) (isearch-reread-key-sequence-naturally) (isearch-lookup-scroll-key): New functions. (isearch-other-meta-char): Doc string and functionality enhanced. Now accepts a prefix argument. (isearch-lazy-highlight-window-end): New variable. (isearch-lazy-highlight-new-loop): Pay attention to the window's end (thru isearch-lazy-highlight-window-end), not only its start.
-rw-r--r--lisp/isearch.el222
1 files changed, 195 insertions, 27 deletions
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 01285aedf05..d84510eb7a2 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -242,7 +242,8 @@ Default value, nil, means edit the string instead."
242 (while l 242 (while l
243 (set-char-table-default table (car l) 'isearch-printing-char) 243 (set-char-table-default table (car l) 'isearch-printing-char)
244 (setq l (cdr l)))) 244 (setq l (cdr l))))
245 ;; Make function keys, etc, exit the search. 245 ;; Make function keys, etc, which aren't bound to a scrolling-function
246 ;; exit the search.
246 (define-key map [t] 'isearch-other-control-char) 247 (define-key map [t] 'isearch-other-control-char)
247 ;; Control chars, by default, end isearch mode transparently. 248 ;; Control chars, by default, end isearch mode transparently.
248 ;; We need these explicit definitions because, in a dense keymap, 249 ;; We need these explicit definitions because, in a dense keymap,
@@ -1224,18 +1225,176 @@ might return the position of the end of the line."
1224 (goto-char isearch-barrier))) 1225 (goto-char isearch-barrier)))
1225 (isearch-process-search-char last-command-char)) 1226 (isearch-process-search-char last-command-char))
1226 1227
1228(defun isearch-unread-key-sequence (keylist)
1229 "Unread the given key-sequence KEYLIST.
1230Scroll-bar or mode-line events are processed appropriately."
1231 (cancel-kbd-macro-events)
1232 (apply 'isearch-unread keylist)
1233 ;; If the event was a scroll-bar or mode-line click, the event will have
1234 ;; been prefixed by a symbol such as vertical-scroll-bar. We must remove
1235 ;; it here, because this symbol will be attached to the event again next
1236 ;; time it gets read by read-key-sequence.
1237 ;;
1238 ;; (Old comment from isearch-other-meta-char: "Note that we don't have to
1239 ;; modify the event anymore in 21 because read_key_sequence no longer
1240 ;; modifies events to produce fake prefix keys.")
1241 (if (and (> (length keylist) 1)
1242 (symbolp (car keylist))
1243 (listp (cadr keylist))
1244 (not (numberp (posn-point
1245 (event-start (cadr keylist) )))))
1246 (pop unread-command-events)))
1247
1248;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1249;; scrolling within Isearch mode. Alan Mackenzie (acm@muc.de), 2003/2/24
1250;;
1251;; The idea here is that certain vertical scrolling commands (like C-l
1252;; `recenter') should be usable WITHIN Isearch mode. For a command to be
1253;; suitable, it must NOT alter the buffer, swap to another buffer or frame,
1254;; tamper with isearch's state, or move point. It is unacceptable for the
1255;; search string to be scrolled out of the current window. If a command
1256;; attempts this, we scroll the text back again.
1257;;
1258;; We implement this feature with a property called `isearch-scroll'.
1259;; If a command's symbol has the value t for this property it is a
1260;; scrolling command. The feature needs to be enabled by setting the
1261;; customizable variable `isearch-allow-scroll' to a non-nil value.
1262;;
1263;; The universal argument commands (e.g. C-u) in simple.el are marked
1264;; as scrolling commands, and isearch.el has been amended to allow
1265;; prefix arguments to be passed through to scrolling commands. Thus
1266;; M-0 C-l will scroll point to the top of the window.
1267;;
1268;; Horizontal scrolling commands are currently not catered for.
1269;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1270
1271;; Set the isearch-scroll property on some standard functions:
1272;; Scroll-bar functions:
1273(if (fboundp 'scroll-bar-toolkit-scroll)
1274 (put 'scroll-bar-toolkit-scroll 'isearch-scroll t))
1275(if (fboundp 'mac-handle-scroll-bar-event)
1276 (put 'mac-handle-scroll-bar-event 'isearch-scroll t))
1277(if (fboundp 'w32-handle-scroll-bar-event)
1278 (put 'w32-handle-scroll-bar-event 'isearch-scroll t))
1279
1280;; Commands which scroll the window:
1281(put 'recenter 'isearch-scroll t)
1282(put 'reposition-window 'isearch-scroll t)
1283(put 'scroll-up 'isearch-scroll t)
1284(put 'scroll-down 'isearch-scroll t)
1285
1286;; Commands which act on the other window
1287(put 'list-buffers 'isearch-scroll t)
1288(put 'scroll-other-window 'isearch-scroll t)
1289(put 'scroll-other-window-down 'isearch-scroll t)
1290(put 'beginning-of-buffer-other-window 'isearch-scroll t)
1291(put 'end-of-buffer-other-window 'isearch-scroll t)
1292
1293;; Commands which change the window layout
1294(put 'delete-other-windows 'isearch-scroll t)
1295(put 'balance-windows 'isearch-scroll t)
1296(put 'split-window-vertically 'isearch-scroll t)
1297(put 'enlarge-window 'isearch-scroll t)
1298
1299;; Universal argument commands
1300(put 'universal-argument 'isearch-scroll t)
1301(put 'negative-argument 'isearch-scroll t)
1302(put 'digit-argument 'isearch-scroll t)
1303
1304(defcustom isearch-allow-scroll nil
1305 "If non-nil, scrolling commands are allowed during incremental search."
1306 :type 'boolean
1307 :group 'isearch)
1308
1309(defun isearch-string-out-of-window (isearch-point)
1310 "Test whether the search string is currently outside of the window.
1311Return nil if it's completely visible, or if point is visible,
1312together with as much of the search string as will fit; the symbol
1313`above' if we need to scroll the text downwards; the symbol `below',
1314if upwards."
1315 (let ((w-start (window-start))
1316 (w-end (window-end nil t))
1317 (w-L1 (save-excursion (move-to-window-line 1) (point)))
1318 (w-L-1 (save-excursion (move-to-window-line -1) (point)))
1319 start end) ; start and end of search string in buffer
1320 (if isearch-forward
1321 (setq end isearch-point start (or isearch-other-end isearch-point))
1322 (setq start isearch-point end (or isearch-other-end isearch-point)))
1323 (cond ((or (and (>= start w-start) (<= end w-end))
1324 (if isearch-forward
1325 (and (>= isearch-point w-L-1) (< isearch-point w-end)) ; point on Line -1
1326 (and (>= isearch-point w-start) (< isearch-point w-L1)))) ; point on Line 0
1327 nil)
1328 ((and (< start w-start)
1329 (< isearch-point w-L-1))
1330 'above)
1331 (t 'below))))
1332
1333(defun isearch-back-into-window (above isearch-point)
1334 "Scroll the window to bring the search string back into view.
1335Restore point to ISEARCH-POINT in the process. ABOVE is t when the
1336search string is above the top of the window, nil when it is beneath
1337the bottom."
1338 (let (start end)
1339 (if isearch-forward
1340 (setq end isearch-point start (or isearch-other-end isearch-point))
1341 (setq start isearch-point end (or isearch-other-end isearch-point)))
1342 (if above
1343 (progn
1344 (goto-char start)
1345 (recenter 0)
1346 (when (>= isearch-point (window-end nil t))
1347 (goto-char isearch-point)
1348 (recenter -1)))
1349 (goto-char end)
1350 (recenter -1)
1351 (when (< isearch-point (window-start))
1352 (goto-char isearch-point)
1353 (recenter 0))))
1354 (goto-char isearch-point))
1355
1356(defun isearch-reread-key-sequence-naturally (keylist)
1357 "Reread key sequence KEYLIST with Isearch mode's keymap deactivated.
1358Return the key sequence as a string/vector."
1359 (isearch-unread-key-sequence keylist)
1360 (let (overriding-terminal-local-map)
1361 (read-key-sequence nil))) ; This will go through function-key-map, if nec.
1362
1363(defun isearch-lookup-scroll-key (key-seq)
1364 "If KEY-SEQ is bound to a scrolling command, return it as a symbol.
1365Otherwise return nil."
1366 (let* ((overriding-terminal-local-map nil)
1367 (binding (key-binding key-seq)))
1368 (and binding (symbolp binding) (commandp binding)
1369 (eq (get binding 'isearch-scroll) t)
1370 binding)))
1227 1371
1228(defalias 'isearch-other-control-char 'isearch-other-meta-char) 1372(defalias 'isearch-other-control-char 'isearch-other-meta-char)
1229 1373
1230(defun isearch-other-meta-char () 1374(defun isearch-other-meta-char (&optional arg)
1231 "Exit the search normally and reread this key sequence. 1375 "Process a miscellaneous key sequence in Isearch mode.
1232But only if `search-exit-option' is non-nil, the default. 1376
1233If it is the symbol `edit', the search string is edited in the minibuffer 1377Try to convert the current key-sequence to something usable in Isearch
1234and the meta character is unread so that it applies to editing the string." 1378mode, either by converting it with `function-key-map', downcasing a
1235 (interactive) 1379key with C-<upper case>, or finding a \"scrolling command\" bound to
1236 (let* ((key (this-command-keys)) 1380it. \(In the last case, we may have to read more events.) If so,
1381either unread the converted sequence or execute the command.
1382
1383Otherwise, if `search-exit-option' is non-nil (the default) unread the
1384key-sequence and exit the search normally. If it is the symbol
1385`edit', the search string is edited in the minibuffer and the meta
1386character is unread so that it applies to editing the string.
1387
1388ARG is the prefix argument. It will be transmitted through to the
1389scrolling command or to the command whose key-sequence exits
1390Isearch mode."
1391 (interactive "P")
1392 (let* ((key (if current-prefix-arg ; not nec the same as ARG
1393 (substring (this-command-keys) universal-argument-num-events)
1394 (this-command-keys)))
1237 (main-event (aref key 0)) 1395 (main-event (aref key 0))
1238 (keylist (listify-key-sequence key))) 1396 (keylist (listify-key-sequence key))
1397 scroll-command isearch-point)
1239 (cond ((and (= (length key) 1) 1398 (cond ((and (= (length key) 1)
1240 (let ((lookup (lookup-key function-key-map key))) 1399 (let ((lookup (lookup-key function-key-map key)))
1241 (not (or (null lookup) (integerp lookup) 1400 (not (or (null lookup) (integerp lookup)
@@ -1287,23 +1446,27 @@ and the meta character is unread so that it applies to editing the string."
1287 ((eq search-exit-option 'edit) 1446 ((eq search-exit-option 'edit)
1288 (apply 'isearch-unread keylist) 1447 (apply 'isearch-unread keylist)
1289 (isearch-edit-string)) 1448 (isearch-edit-string))
1449 ;; Handle a scrolling function.
1450 ((and isearch-allow-scroll
1451 (progn (setq key (isearch-reread-key-sequence-naturally keylist))
1452 (setq keylist (listify-key-sequence key))
1453 (setq main-event (aref key 0))
1454 (setq scroll-command (isearch-lookup-scroll-key key))))
1455 ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a
1456 ;; complete key sequence, possibly as modified by function-key-map,
1457 ;; not merely the one or two event fragment which invoked
1458 ;; isearch-other-meta-char in the first place.
1459 (setq isearch-point (point))
1460 (setq prefix-arg arg)
1461 (command-execute scroll-command)
1462 (let ((ab-bel (isearch-string-out-of-window isearch-point)))
1463 (if ab-bel
1464 (isearch-back-into-window (eq ab-bel 'above) isearch-point)))
1465 (isearch-update))
1290 (search-exit-option 1466 (search-exit-option
1291 (let (window) 1467 (let (window)
1292 (cancel-kbd-macro-events) 1468 (isearch-unread-key-sequence keylist)
1293 (apply 'isearch-unread keylist) 1469 (setq main-event (car unread-command-events))
1294
1295 ;; Properly handle scroll-bar and mode-line clicks for
1296 ;; which a dummy prefix event was generated as (aref key
1297 ;; 0). Note that we don't have to modify the event
1298 ;; anymore in 21 because read_key_sequence no longer modifies
1299 ;; events to produce fake prefix keys.
1300 (when (and (> (length key) 1)
1301 (symbolp (aref key 0))
1302 (listp (aref key 1))
1303 (not (numberp (posn-point
1304 (event-start (aref key 1))))))
1305 (pop unread-command-events)
1306 (setq main-event (car unread-command-events)))
1307 1470
1308 ;; If we got a mouse click event, that event contains the 1471 ;; If we got a mouse click event, that event contains the
1309 ;; window clicked on. maybe it was read with the buffer 1472 ;; window clicked on. maybe it was read with the buffer
@@ -1333,8 +1496,9 @@ and the meta character is unread so that it applies to editing the string."
1333 (isearch-done) 1496 (isearch-done)
1334 (isearch-clean-overlays)) 1497 (isearch-clean-overlays))
1335 (isearch-done) 1498 (isearch-done)
1336 (isearch-clean-overlays)))) 1499 (isearch-clean-overlays)
1337 (t;; otherwise nil 1500 (setq prefix-arg arg))))
1501 (t;; otherwise nil
1338 (isearch-process-search-string key key))))) 1502 (isearch-process-search-string key key)))))
1339 1503
1340(defun isearch-quote-char () 1504(defun isearch-quote-char ()
@@ -1997,6 +2161,7 @@ A value of nil means highlight all matches."
1997(defvar isearch-lazy-highlight-last-string nil) 2161(defvar isearch-lazy-highlight-last-string nil)
1998(defvar isearch-lazy-highlight-window nil) 2162(defvar isearch-lazy-highlight-window nil)
1999(defvar isearch-lazy-highlight-window-start nil) 2163(defvar isearch-lazy-highlight-window-start nil)
2164(defvar isearch-lazy-highlight-window-end nil)
2000(defvar isearch-lazy-highlight-case-fold-search nil) 2165(defvar isearch-lazy-highlight-case-fold-search nil)
2001(defvar isearch-lazy-highlight-regexp nil) 2166(defvar isearch-lazy-highlight-regexp nil)
2002 2167
@@ -2031,12 +2196,15 @@ search string to change or the window to scroll)."
2031 (not (eq isearch-lazy-highlight-regexp 2196 (not (eq isearch-lazy-highlight-regexp
2032 isearch-regexp)) 2197 isearch-regexp))
2033 (not (= (window-start) 2198 (not (= (window-start)
2034 isearch-lazy-highlight-window-start)))) 2199 isearch-lazy-highlight-window-start))
2200 (not (= (window-end) ; Window may have been split/joined.
2201 isearch-lazy-highlight-window-end))))
2035 ;; something important did indeed change 2202 ;; something important did indeed change
2036 (isearch-lazy-highlight-cleanup t) ;kill old loop & remove overlays 2203 (isearch-lazy-highlight-cleanup t) ;kill old loop & remove overlays
2037 (when (not isearch-invalid-regexp) 2204 (when (not isearch-invalid-regexp)
2038 (setq isearch-lazy-highlight-window (selected-window) 2205 (setq isearch-lazy-highlight-window (selected-window)
2039 isearch-lazy-highlight-window-start (window-start) 2206 isearch-lazy-highlight-window-start (window-start)
2207 isearch-lazy-highlight-window-end (window-end)
2040 isearch-lazy-highlight-start (point) 2208 isearch-lazy-highlight-start (point)
2041 isearch-lazy-highlight-end (point) 2209 isearch-lazy-highlight-end (point)
2042 isearch-lazy-highlight-last-string isearch-string 2210 isearch-lazy-highlight-last-string isearch-string