diff options
| author | Jim Blandy | 1991-07-23 23:29:49 +0000 |
|---|---|---|
| committer | Jim Blandy | 1991-07-23 23:29:49 +0000 |
| commit | 0ce259f5b14ece89d94fa484c3a12d0e0a062a49 (patch) | |
| tree | 56a8a2576d1ae031718f72fe6c0c43be578fa897 | |
| parent | 462c10945e696f96cd6636cd7193de0654d1ca1c (diff) | |
| download | emacs-0ce259f5b14ece89d94fa484c3a12d0e0a062a49.tar.gz emacs-0ce259f5b14ece89d94fa484c3a12d0e0a062a49.zip | |
Initial revision
| -rw-r--r-- | lisp/isearch-old.el | 623 |
1 files changed, 623 insertions, 0 deletions
diff --git a/lisp/isearch-old.el b/lisp/isearch-old.el new file mode 100644 index 00000000000..57e04fc3956 --- /dev/null +++ b/lisp/isearch-old.el | |||
| @@ -0,0 +1,623 @@ | |||
| 1 | ;; Incremental search | ||
| 2 | ;; Copyright (C) 1985, 1986 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | ;; This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | ;; it under the terms of the GNU General Public License as published by | ||
| 8 | ;; the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | ;; any later version. | ||
| 10 | |||
| 11 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;; GNU General Public License for more details. | ||
| 15 | |||
| 16 | ;; You should have received a copy of the GNU General Public License | ||
| 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | |||
| 20 | ;;;###autoload | ||
| 21 | (defvar search-last-string "" "\ | ||
| 22 | Last string search for by a non-regexp search command. | ||
| 23 | This does not include direct calls to the primitive search functions, | ||
| 24 | and does not include searches that are aborted.") | ||
| 25 | |||
| 26 | ;;;###autoload | ||
| 27 | (defvar search-last-regexp "" "\ | ||
| 28 | Last string searched for by a regexp search command. | ||
| 29 | This does not include direct calls to the primitive search functions, | ||
| 30 | and does not include searches that are aborted.") | ||
| 31 | |||
| 32 | |||
| 33 | ;;;###autoload | ||
| 34 | (defconst search-repeat-char ?\C-s "\ | ||
| 35 | *Character to repeat incremental search forwards.") | ||
| 36 | ;;;###autoload | ||
| 37 | (defconst search-reverse-char ?\C-r "\ | ||
| 38 | *Character to repeat incremental search backwards.") | ||
| 39 | ;;;###autoload | ||
| 40 | (defconst search-exit-char ?\C-m "\ | ||
| 41 | *Character to exit incremental search.") | ||
| 42 | ;;;###autoload | ||
| 43 | (defconst search-delete-char ?\177 "\ | ||
| 44 | *Character to delete from incremental search string.") | ||
| 45 | ;;;###autoload | ||
| 46 | (defconst search-quote-char ?\C-q "\ | ||
| 47 | *Character to quote special characters for incremental search.") | ||
| 48 | ;;;###autoload | ||
| 49 | (defconst search-yank-word-char ?\C-w "\ | ||
| 50 | *Character to pull next word from buffer into search string.") | ||
| 51 | ;;;###autoload | ||
| 52 | (defconst search-yank-line-char ?\C-y "\ | ||
| 53 | *Character to pull rest of line from buffer into search string.") | ||
| 54 | ;;;###autoload | ||
| 55 | (defconst search-ring-advance-char ?\M-n "\ | ||
| 56 | *Character to pull next (more recent) search string from the ring of same.") | ||
| 57 | ;;;###autoload | ||
| 58 | (defconst search-ring-retreat-char ?\M-p "\ | ||
| 59 | *Character to pull previous (older) search string from the ring of same.") | ||
| 60 | |||
| 61 | ;;;###autoload | ||
| 62 | (defconst search-exit-option t "\ | ||
| 63 | *Non-nil means random control characters terminate incremental search.") | ||
| 64 | |||
| 65 | ;;;###autoload | ||
| 66 | (defvar search-slow-window-lines 1 "\ | ||
| 67 | *Number of lines in slow search display windows. | ||
| 68 | These are the short windows used during incremental search on slow terminals. | ||
| 69 | Negative means put the slow search window at the top (normally it's at bottom) | ||
| 70 | and the value is minus the number of lines.") | ||
| 71 | |||
| 72 | ;;;###autoload | ||
| 73 | (defvar search-slow-speed 1200 "\ | ||
| 74 | *Highest terminal speed at which to use \"slow\" style incremental search. | ||
| 75 | This is the style where a one-line window is created to show the line | ||
| 76 | that the search has reached.") | ||
| 77 | |||
| 78 | (defconst search-upper-case t | ||
| 79 | "*Non-nil means an upper-case letter as search input means case-sensitive. | ||
| 80 | Any upper-case letter given explicitly as input to the incremental search | ||
| 81 | has the effect of turning off `case-fold-search' for the rest of this search. | ||
| 82 | Deleting the letter from the search string cancels the effect.") | ||
| 83 | |||
| 84 | (fset 'search-forward-regexp 're-search-forward) | ||
| 85 | (fset 'search-backward-regexp 're-search-backward) | ||
| 86 | |||
| 87 | (defvar search-ring nil | ||
| 88 | "List of recent non-regexp incremental searches. | ||
| 89 | Each element is a cons cell of the form (STRING . UPPERCASE-FLAG).") | ||
| 90 | |||
| 91 | (defvar regexp-search-ring nil | ||
| 92 | "List of recent regexp incremental searches. | ||
| 93 | Each element is a cons cell of the form (STRING . UPPERCASE-FLAG).") | ||
| 94 | |||
| 95 | (defconst search-ring-max 16 | ||
| 96 | "*Maximum length of search ring before oldest elements are thrown away.") | ||
| 97 | |||
| 98 | (defvar search-ring-yank-pointer nil | ||
| 99 | "The tail of the search ring whose car is the last thing searched for.") | ||
| 100 | |||
| 101 | (defvar regexp-search-ring-yank-pointer nil | ||
| 102 | "The tail of the regular expression search ring whose car is the last | ||
| 103 | thing searched for.") | ||
| 104 | |||
| 105 | |||
| 106 | ;;;###autoload | ||
| 107 | (defun isearch-forward () | ||
| 108 | "Do incremental search forward. | ||
| 109 | As you type characters, they add to the search string and are found. | ||
| 110 | Type Delete to cancel characters from end of search string. | ||
| 111 | Type RET to exit, leaving point at location found. | ||
| 112 | Type C-s to search again forward, C-r to search again backward. | ||
| 113 | Type C-w to yank word from buffer onto end of search string and search for it. | ||
| 114 | Type C-y to yank rest of line onto end of search string, etc. | ||
| 115 | Type C-q to quote control character to search for it. | ||
| 116 | Other control and meta characters terminate the search | ||
| 117 | and are then executed normally. | ||
| 118 | The above special characters are mostly controlled by parameters; | ||
| 119 | do M-x apropos on search-.*-char to find them. | ||
| 120 | C-g while searching or when search has failed | ||
| 121 | cancels input back to what has been found successfully. | ||
| 122 | C-g when search is successful aborts and moves point to starting point." | ||
| 123 | (interactive) | ||
| 124 | (isearch t)) | ||
| 125 | ;;;###autoload | ||
| 126 | (define-key global-map "\C-s" 'isearch-forward) | ||
| 127 | |||
| 128 | ;;;###autoload | ||
| 129 | (defun isearch-forward-regexp () | ||
| 130 | "Do incremental search forward for regular expression. | ||
| 131 | Like ordinary incremental search except that your input | ||
| 132 | is treated as a regexp. See \\[isearch-forward] for more info." | ||
| 133 | (interactive) | ||
| 134 | (isearch t t)) | ||
| 135 | ;;;###autoload | ||
| 136 | (define-key esc-map "\C-s" 'isearch-forward-regexp) | ||
| 137 | |||
| 138 | ;;;###autoload | ||
| 139 | (defun isearch-backward () | ||
| 140 | "Do incremental search backward. | ||
| 141 | See \\[isearch-forward] for more information." | ||
| 142 | (interactive) | ||
| 143 | (isearch nil)) | ||
| 144 | ;;;###autoload | ||
| 145 | (define-key global-map "\C-r" 'isearch-backward) | ||
| 146 | |||
| 147 | ;;;###autoload | ||
| 148 | (defun isearch-backward-regexp () | ||
| 149 | "Do incremental search backward for regular expression. | ||
| 150 | Like ordinary incremental search except that your input | ||
| 151 | is treated as a regexp. See \\[isearch-forward] for more info." | ||
| 152 | (interactive) | ||
| 153 | (isearch nil t)) | ||
| 154 | ;;;###autoload | ||
| 155 | (define-key esc-map "\C-r" 'isearch-backward-regexp) | ||
| 156 | |||
| 157 | |||
| 158 | ;; This function does all the work of incremental search. | ||
| 159 | ;; The functions attached to ^R and ^S are trivial, | ||
| 160 | ;; merely calling this one, but they are always loaded by default | ||
| 161 | ;; whereas this file can optionally be autoloadable. | ||
| 162 | ;; This is the only entry point in this file. | ||
| 163 | |||
| 164 | ;; OP-FUN is a function to be called after each input character is processed. | ||
| 165 | ;; (It is not called after characters that exit the search.) | ||
| 166 | |||
| 167 | (defun isearch (forward &optional regexp op-fun) | ||
| 168 | (let ((search-string "") | ||
| 169 | (search-message "") | ||
| 170 | ;; List of previous states during this search. | ||
| 171 | (history nil) | ||
| 172 | ;; t means search is currently successful. | ||
| 173 | (success t) | ||
| 174 | ;; Set once the search has wrapped around the end of the buffer. | ||
| 175 | (wrapped nil) | ||
| 176 | ;; Nominal starting point for searching | ||
| 177 | ;; Usually this is the same as the opoint, | ||
| 178 | ;; but it is changed by wrapping | ||
| 179 | ;; and also by repeating the search. | ||
| 180 | (barrier (point)) | ||
| 181 | ;; Set temporarily when adding a character to a regexp | ||
| 182 | ;; enables it to match more rather than fewer places in the buffer. | ||
| 183 | liberalized | ||
| 184 | ;; Set temporarily by yanking text into the search string. | ||
| 185 | yank-flag | ||
| 186 | (invalid-regexp nil) | ||
| 187 | ;; non-nil means an explicit uppercase letter seen in the input | ||
| 188 | (uppercase-flag nil) | ||
| 189 | ;; Non-nil means start using a small window | ||
| 190 | ;; if the search moves outside what is currently on the screen. | ||
| 191 | (slow-terminal-mode (and (<= baud-rate search-slow-speed) | ||
| 192 | (> (window-height) | ||
| 193 | (* 4 search-slow-window-lines)))) | ||
| 194 | ;; t means a small window is currently in use. | ||
| 195 | (small-window nil) ;if t, using a small window | ||
| 196 | ;; These variables preserve information from the small window | ||
| 197 | ;; through exit from the save-window-excursion. | ||
| 198 | (found-point nil) | ||
| 199 | (found-start nil) | ||
| 200 | ;; Point is at one end of the last match. | ||
| 201 | ;; This variable records the other end of that match. | ||
| 202 | (other-end nil) | ||
| 203 | ;; Value of point at start of search, | ||
| 204 | ;; for moving the cursor back on quitting. | ||
| 205 | (opoint (point)) | ||
| 206 | (inhibit-quit t) ;Prevent ^G from quitting, so we can read it. | ||
| 207 | ;; The screen we're working on; if this changes, we exit isearch. | ||
| 208 | (screen (if (fboundp 'selected-screen) (selected-screen)))) | ||
| 209 | |||
| 210 | (isearch-push-state) | ||
| 211 | (save-window-excursion | ||
| 212 | (catch 'search-done | ||
| 213 | (while t | ||
| 214 | (or (and (numberp unread-command-char) (>= unread-command-char 0)) | ||
| 215 | (progn | ||
| 216 | (or (input-pending-p) | ||
| 217 | (isearch-message)) | ||
| 218 | (if (and slow-terminal-mode | ||
| 219 | (not (or small-window (pos-visible-in-window-p)))) | ||
| 220 | (progn | ||
| 221 | (setq small-window t) | ||
| 222 | (setq found-point (point)) | ||
| 223 | (move-to-window-line 0) | ||
| 224 | (let ((window-min-height 1)) | ||
| 225 | (split-window nil (if (< search-slow-window-lines 0) | ||
| 226 | (1+ (- search-slow-window-lines)) | ||
| 227 | (- (window-height) | ||
| 228 | (1+ search-slow-window-lines))))) | ||
| 229 | (if (< search-slow-window-lines 0) | ||
| 230 | (progn (vertical-motion (- 1 search-slow-window-lines)) | ||
| 231 | (set-window-start (next-window) (point)) | ||
| 232 | (set-window-hscroll (next-window) | ||
| 233 | (window-hscroll)) | ||
| 234 | (set-window-hscroll (selected-window) 0)) | ||
| 235 | (other-window 1)) | ||
| 236 | (goto-char found-point))))) | ||
| 237 | (let ((char (if quit-flag | ||
| 238 | ?\C-g | ||
| 239 | (read-event)))) | ||
| 240 | (setq quit-flag nil liberalized nil yank-flag nil) | ||
| 241 | (cond ((and (or (not (integerp char)) | ||
| 242 | (and (>= char 128) | ||
| 243 | (not (= char search-ring-advance-char)) | ||
| 244 | (not (= char search-ring-retreat-char)))) | ||
| 245 | search-exit-option) | ||
| 246 | (setq unread-command-char char) | ||
| 247 | (throw 'search-done t)) | ||
| 248 | |||
| 249 | ;; If the user switches to a different screen, exit. | ||
| 250 | ((not (eq screen last-event-screen)) | ||
| 251 | (setq unread-command-char char) | ||
| 252 | (throw 'search-done t)) | ||
| 253 | |||
| 254 | ((eq char search-exit-char) | ||
| 255 | ;; RET means exit search normally. | ||
| 256 | ;; Except, if first thing typed, it means do nonincremental | ||
| 257 | (if (= 0 (length search-string)) | ||
| 258 | (nonincremental-search forward regexp)) | ||
| 259 | (throw 'search-done t)) | ||
| 260 | ((= char ?\C-g) | ||
| 261 | ;; ^G means the user tried to quit. | ||
| 262 | (ding) | ||
| 263 | (discard-input) | ||
| 264 | (if success | ||
| 265 | ;; If search is successful, move back to starting point | ||
| 266 | ;; and really do quit. | ||
| 267 | (progn (goto-char opoint) | ||
| 268 | (signal 'quit nil)) | ||
| 269 | ;; If search is failing, rub out until it is once more | ||
| 270 | ;; successful. | ||
| 271 | (while (not success) (isearch-pop)))) | ||
| 272 | ((or (eq char search-repeat-char) | ||
| 273 | (eq char search-reverse-char)) | ||
| 274 | (if (eq forward (eq char search-repeat-char)) | ||
| 275 | ;; C-s in forward or C-r in reverse. | ||
| 276 | (if (equal search-string "") | ||
| 277 | ;; If search string is empty, use last one. | ||
| 278 | (isearch-get-string-from-ring) | ||
| 279 | ;; If already have what to search for, repeat it. | ||
| 280 | (or success | ||
| 281 | (progn (goto-char (if forward (point-min) (point-max))) | ||
| 282 | (setq wrapped t)))) | ||
| 283 | ;; C-s in reverse or C-r in forward, change direction. | ||
| 284 | (setq forward (not forward))) | ||
| 285 | (setq barrier (point)) ; For subsequent \| if regexp. | ||
| 286 | (setq success t) | ||
| 287 | (or (equal search-string "") | ||
| 288 | (progn | ||
| 289 | ;; If repeating a search that found an empty string, | ||
| 290 | ;; ensure we advance. Test history to make sure we | ||
| 291 | ;; actually have done a search already; otherwise, | ||
| 292 | ;; the match data will be random. | ||
| 293 | (if (and (cdr history) | ||
| 294 | (= (match-end 0) (match-beginning 0))) | ||
| 295 | (forward-char (if forward 1 -1))) | ||
| 296 | (isearch-search))) | ||
| 297 | (isearch-push-state)) | ||
| 298 | ((= char search-delete-char) | ||
| 299 | ;; Rubout means discard last input item and move point | ||
| 300 | ;; back. If buffer is empty, just beep. | ||
| 301 | (if (null (cdr history)) | ||
| 302 | (ding) | ||
| 303 | (isearch-pop))) | ||
| 304 | ((= char search-ring-advance-char) | ||
| 305 | (isearch-pop) | ||
| 306 | (if regexp | ||
| 307 | (let ((length (length regexp-search-ring))) | ||
| 308 | (if (zerop length) | ||
| 309 | () | ||
| 310 | (setq regexp-search-ring-yank-pointer | ||
| 311 | (nthcdr (% (+ 1 (- length (length regexp-search-ring-yank-pointer))) | ||
| 312 | length) | ||
| 313 | regexp-search-ring)) | ||
| 314 | (isearch-get-string-from-ring))) | ||
| 315 | (let ((length (length search-ring))) | ||
| 316 | (if (zerop length) | ||
| 317 | () | ||
| 318 | (setq search-ring-yank-pointer | ||
| 319 | (nthcdr (% (+ 1 (- length (length search-ring-yank-pointer))) | ||
| 320 | length) | ||
| 321 | search-ring)) | ||
| 322 | (isearch-get-string-from-ring)))) | ||
| 323 | (isearch-push-state) | ||
| 324 | (isearch-search)) | ||
| 325 | ((= char search-ring-retreat-char) | ||
| 326 | (isearch-pop) | ||
| 327 | (if regexp | ||
| 328 | (let ((length (length regexp-search-ring))) | ||
| 329 | (if (zerop length) | ||
| 330 | () | ||
| 331 | (setq regexp-search-ring-yank-pointer | ||
| 332 | (nthcdr (% (+ (- length (length regexp-search-ring-yank-pointer)) | ||
| 333 | (1- length)) | ||
| 334 | length) | ||
| 335 | regexp-search-ring)) | ||
| 336 | (isearch-get-string-from-ring))) | ||
| 337 | (let ((length (length search-ring))) | ||
| 338 | (if (zerop length) | ||
| 339 | () | ||
| 340 | (setq search-ring-yank-pointer | ||
| 341 | (nthcdr (% (+ (- length (length search-ring-yank-pointer)) | ||
| 342 | (1- length)) | ||
| 343 | length) | ||
| 344 | search-ring)) | ||
| 345 | (isearch-get-string-from-ring)))) | ||
| 346 | (isearch-push-state) | ||
| 347 | (isearch-search)) | ||
| 348 | (t | ||
| 349 | (cond ((or (eq char search-yank-word-char) | ||
| 350 | (eq char search-yank-line-char)) | ||
| 351 | ;; ^W means gobble next word from buffer. | ||
| 352 | ;; ^Y means gobble rest of line from buffer. | ||
| 353 | (let ((word (save-excursion | ||
| 354 | (and (not forward) other-end | ||
| 355 | (goto-char other-end)) | ||
| 356 | (buffer-substring | ||
| 357 | (point) | ||
| 358 | (save-excursion | ||
| 359 | (if (eq char search-yank-line-char) | ||
| 360 | (end-of-line) | ||
| 361 | (forward-word 1)) | ||
| 362 | (point)))))) | ||
| 363 | (if regexp | ||
| 364 | (setq word (regexp-quote word))) | ||
| 365 | (setq search-string (concat search-string word) | ||
| 366 | search-message | ||
| 367 | (concat search-message | ||
| 368 | (mapconcat 'text-char-description | ||
| 369 | word "")) | ||
| 370 | ;; Don't move cursor in reverse search. | ||
| 371 | yank-flag t))) | ||
| 372 | ;; Any other control char => | ||
| 373 | ;; unread it and exit the search normally. | ||
| 374 | ((and search-exit-option | ||
| 375 | (/= char search-quote-char) | ||
| 376 | (or (>= char ?\177) | ||
| 377 | (and (< char ? ) | ||
| 378 | (/= char ?\t) | ||
| 379 | (/= char ?\n)))) | ||
| 380 | (setq unread-command-char char) | ||
| 381 | (throw 'search-done t)) | ||
| 382 | (t | ||
| 383 | ;; Any other character => add it to the | ||
| 384 | ;; search string and search. | ||
| 385 | (cond ((= char search-quote-char) | ||
| 386 | (setq char (read-quoted-char | ||
| 387 | (isearch-message t)))) | ||
| 388 | ((= char ?\r) | ||
| 389 | ;; RET translates to newline. | ||
| 390 | (setq char ?\n))) | ||
| 391 | (setq search-string (concat search-string | ||
| 392 | (char-to-string char)) | ||
| 393 | search-message (concat search-message | ||
| 394 | (text-char-description char)) | ||
| 395 | uppercase-flag (or uppercase-flag | ||
| 396 | (not (= char (downcase char))))))) | ||
| 397 | (if (and (not success) | ||
| 398 | ;; unsuccessful regexp search may become | ||
| 399 | ;; successful by addition of characters which | ||
| 400 | ;; make search-string valid | ||
| 401 | (not regexp)) | ||
| 402 | nil | ||
| 403 | ;; Check for chars that can make a regexp more liberal. | ||
| 404 | ;; They can make a regexp match sooner | ||
| 405 | ;; or make it succeed instead of failing. | ||
| 406 | ;; So go back to place last successful search started | ||
| 407 | ;; or to the last ^S/^R (barrier), whichever is nearer. | ||
| 408 | (and regexp history | ||
| 409 | (cond ((and (memq char '(?* ??)) | ||
| 410 | ;; Don't treat *, ? as special | ||
| 411 | ;; within [] or after \. | ||
| 412 | (not (nth 6 (car history)))) | ||
| 413 | (setq liberalized t) | ||
| 414 | ;; This used to use element 2 | ||
| 415 | ;; in a reverse search, but it seems that 5 | ||
| 416 | ;; (which is the end of the old match) | ||
| 417 | ;; is better in that case too. | ||
| 418 | (let ((cs (nth 5 ; old other-end. | ||
| 419 | (car (cdr history))))) | ||
| 420 | ;; (car history) is after last search; | ||
| 421 | ;; (car (cdr history)) is from before it. | ||
| 422 | (setq cs (or cs barrier)) | ||
| 423 | (goto-char | ||
| 424 | (if forward | ||
| 425 | (max cs barrier) | ||
| 426 | (min cs barrier))))) | ||
| 427 | ((eq char ?\|) | ||
| 428 | (setq liberalized t) | ||
| 429 | (goto-char barrier)))) | ||
| 430 | ;; Turn off case-sensitivity if string requests it. | ||
| 431 | (let ((case-fold-search | ||
| 432 | (and case-fold-search | ||
| 433 | (not (and uppercase-flag | ||
| 434 | search-upper-case))))) | ||
| 435 | ;; In reverse search, adding stuff at | ||
| 436 | ;; the end may cause zero or many more chars to be | ||
| 437 | ;; matched, in the string following point. | ||
| 438 | ;; Allow all those possibilities without moving point as | ||
| 439 | ;; long as the match does not extend past search origin. | ||
| 440 | (if (and (not forward) (not liberalized) | ||
| 441 | (condition-case () | ||
| 442 | (looking-at (if regexp search-string | ||
| 443 | (regexp-quote search-string))) | ||
| 444 | (error nil)) | ||
| 445 | (or yank-flag | ||
| 446 | ;; Used to have (min opoint barrier) | ||
| 447 | ;; instead of barrier. | ||
| 448 | ;; This lost when wrapping. | ||
| 449 | (<= (match-end 0) barrier))) | ||
| 450 | (setq success t invalid-regexp nil | ||
| 451 | other-end (match-end 0)) | ||
| 452 | ;; Not regexp, not reverse, or no match at point. | ||
| 453 | (if (and other-end (not liberalized)) | ||
| 454 | (goto-char (if forward other-end | ||
| 455 | ;; Used to have opoint inside the min. | ||
| 456 | ;; This lost when wrapping. | ||
| 457 | (min barrier (1+ other-end))))) | ||
| 458 | (isearch-search)))) | ||
| 459 | (isearch-push-state)))) | ||
| 460 | (if op-fun (funcall op-fun)))) | ||
| 461 | (setq found-start (window-start (selected-window))) | ||
| 462 | (setq found-point (point))) | ||
| 463 | (if (> (length search-string) 0) | ||
| 464 | (if (and regexp (not (member search-string regexp-search-ring))) | ||
| 465 | (progn | ||
| 466 | (setq regexp-search-ring (cons (cons search-string uppercase-flag) | ||
| 467 | regexp-search-ring) | ||
| 468 | regexp-search-ring-yank-pointer regexp-search-ring) | ||
| 469 | (if (> (length regexp-search-ring) regexp-search-ring-max) | ||
| 470 | (setcdr (nthcdr (1- search-ring-max) regexp-search-ring) nil))) | ||
| 471 | (if (not (member search-string search-ring)) | ||
| 472 | (progn | ||
| 473 | (setq search-ring (cons (cons search-string uppercase-flag) | ||
| 474 | search-ring) | ||
| 475 | search-ring-yank-pointer search-ring) | ||
| 476 | (if (> (length search-ring) search-ring-max) | ||
| 477 | (setcdr (nthcdr (1- search-ring-max) search-ring) nil)))))) | ||
| 478 | ;; If we displayed a single-line window, set point in this window. | ||
| 479 | (if small-window | ||
| 480 | (goto-char found-point)) | ||
| 481 | ;; If there was movement, mark the starting position. | ||
| 482 | ;; Maybe should test difference between and set mark iff > threshold. | ||
| 483 | (if (/= (point) opoint) | ||
| 484 | (push-mark opoint) | ||
| 485 | (message "")) | ||
| 486 | (or small-window | ||
| 487 | ;; Exiting the save-window-excursion clobbers this; restore it. | ||
| 488 | (set-window-start (selected-window) found-start t)))) | ||
| 489 | |||
| 490 | (defun isearch-message (&optional c-q-hack ellipsis) | ||
| 491 | ;; If about to search, and previous search regexp was invalid, | ||
| 492 | ;; check that it still is. If it is valid now, | ||
| 493 | ;; let the message we display while searching say that it is valid. | ||
| 494 | (and invalid-regexp ellipsis | ||
| 495 | (condition-case () | ||
| 496 | (progn (re-search-forward search-string (point) t) | ||
| 497 | (setq invalid-regexp nil)) | ||
| 498 | (error nil))) | ||
| 499 | ;; If currently failing, display no ellipsis. | ||
| 500 | (or success (setq ellipsis nil)) | ||
| 501 | (let ((m (concat (if success "" "failing ") | ||
| 502 | (if wrapped "wrapped ") | ||
| 503 | (if (or (not case-fold-search) | ||
| 504 | (and uppercase-flag search-upper-case)) | ||
| 505 | "case-sensitive ") | ||
| 506 | (if regexp "regexp " "") | ||
| 507 | "I-search" | ||
| 508 | (if forward ": " " backward: ") | ||
| 509 | search-message | ||
| 510 | (if c-q-hack "^Q" "") | ||
| 511 | (if invalid-regexp | ||
| 512 | (concat " [" invalid-regexp "]") | ||
| 513 | "")))) | ||
| 514 | (aset m 0 (upcase (aref m 0))) | ||
| 515 | (let ((cursor-in-echo-area ellipsis)) | ||
| 516 | (if c-q-hack m (message "%s" m))))) | ||
| 517 | |||
| 518 | ;; Get the search string from the "front" of the ring of previous searches. | ||
| 519 | (defun isearch-get-string-from-ring () | ||
| 520 | (let ((elt (car (if regexp | ||
| 521 | (or regexp-search-ring-yank-pointer regexp-search-ring) | ||
| 522 | (or search-ring-yank-pointer search-ring))))) | ||
| 523 | ;; ELT describes the most recent search or where we have rotated the ring. | ||
| 524 | (if elt | ||
| 525 | (setq search-string (car elt) | ||
| 526 | uppercase-flag (cdr elt)) | ||
| 527 | (setq search-string "" uppercase-flag nil))) | ||
| 528 | ;; Let's give this one the benefit of the doubt. | ||
| 529 | (setq invalid-regexp nil) | ||
| 530 | (setq search-message (mapconcat 'text-char-description search-string ""))) | ||
| 531 | |||
| 532 | (defun isearch-pop () | ||
| 533 | (setq history (cdr history)) | ||
| 534 | (let ((cmd (car history))) | ||
| 535 | (setq search-string (car cmd) | ||
| 536 | search-message (car (cdr cmd)) | ||
| 537 | success (nth 3 cmd) | ||
| 538 | forward (nth 4 cmd) | ||
| 539 | other-end (nth 5 cmd) | ||
| 540 | invalid-regexp (nth 6 cmd) | ||
| 541 | wrapped (nth 7 cmd) | ||
| 542 | barrier (nth 8 cmd) | ||
| 543 | uppercase-flag (nth 9 cmd)) | ||
| 544 | (goto-char (car (cdr (cdr cmd)))))) | ||
| 545 | |||
| 546 | (defun isearch-push-state () | ||
| 547 | (setq history (cons (list search-string search-message (point) | ||
| 548 | success forward other-end invalid-regexp | ||
| 549 | wrapped barrier uppercase-flag) | ||
| 550 | history))) | ||
| 551 | |||
| 552 | (defun isearch-search () | ||
| 553 | (let ((case-fold-search | ||
| 554 | (and case-fold-search | ||
| 555 | (not (and uppercase-flag | ||
| 556 | search-upper-case))))) | ||
| 557 | (isearch-message nil t) | ||
| 558 | (condition-case lossage | ||
| 559 | (let ((inhibit-quit nil)) | ||
| 560 | (if regexp (setq invalid-regexp nil)) | ||
| 561 | (setq success | ||
| 562 | (funcall | ||
| 563 | (if regexp | ||
| 564 | (if forward 're-search-forward 're-search-backward) | ||
| 565 | (if forward 'search-forward 'search-backward)) | ||
| 566 | search-string nil t)) | ||
| 567 | (if success | ||
| 568 | (setq other-end | ||
| 569 | (if forward (match-beginning 0) (match-end 0))))) | ||
| 570 | (quit (setq unread-command-char ?\C-g) | ||
| 571 | (setq success nil)) | ||
| 572 | (invalid-regexp (setq invalid-regexp (car (cdr lossage))) | ||
| 573 | (if (string-match "\\`Premature \\|\\`Unmatched \\|\\`Invalid " | ||
| 574 | invalid-regexp) | ||
| 575 | (setq invalid-regexp "incomplete input")))) | ||
| 576 | (if success | ||
| 577 | nil | ||
| 578 | ;; Ding if failed this time after succeeding last time. | ||
| 579 | (and (nth 3 (car history)) | ||
| 580 | (ding)) | ||
| 581 | (goto-char (nth 2 (car history)))))) | ||
| 582 | |||
| 583 | ;; This is called from incremental-search | ||
| 584 | ;; if the first input character is the exit character. | ||
| 585 | ;; The interactive-arg-reader uses free variables `forward' and `regexp' | ||
| 586 | ;; which are bound by `incremental-search'. | ||
| 587 | |||
| 588 | ;; We store the search string in `search-string' | ||
| 589 | ;; which has been bound already by `incremental-search' | ||
| 590 | ;; so that, when we exit, it is copied into `search-last-string'. | ||
| 591 | |||
| 592 | (defun nonincremental-search (forward regexp) | ||
| 593 | (let (message char function string inhibit-quit) | ||
| 594 | (let ((cursor-in-echo-area t)) | ||
| 595 | ;; Prompt assuming not word search, | ||
| 596 | (setq message (if regexp | ||
| 597 | (if forward "Regexp search: " | ||
| 598 | "Regexp search backward: ") | ||
| 599 | (if forward "Search: " "Search backward: "))) | ||
| 600 | (message "%s" message) | ||
| 601 | ;; Read 1 char and switch to word search if it is ^W. | ||
| 602 | (setq char (read-event))) | ||
| 603 | (if (and (numberp char) (eq char search-yank-word-char)) | ||
| 604 | (setq message (if forward "Word search: " "Word search backward: ")) | ||
| 605 | ;; Otherwise let that 1 char be part of the search string. | ||
| 606 | (setq unread-command-char char)) | ||
| 607 | (setq function | ||
| 608 | (if (eq char search-yank-word-char) | ||
| 609 | (if forward 'word-search-forward 'word-search-backward) | ||
| 610 | (if regexp | ||
| 611 | (if forward 're-search-forward 're-search-backward) | ||
| 612 | (if forward 'search-forward 'search-backward)))) | ||
| 613 | ;; Read the search string with corrected prompt. | ||
| 614 | (setq string (read-string message)) | ||
| 615 | ;; Empty means use default. | ||
| 616 | (if (= 0 (length string)) | ||
| 617 | (setq string search-last-string) | ||
| 618 | ;; Set last search string now so it is set even if we fail. | ||
| 619 | (setq search-last-string string)) | ||
| 620 | ;; Since we used the minibuffer, we should be available for redo. | ||
| 621 | (setq command-history (cons (list function string) command-history)) | ||
| 622 | ;; Go ahead and search. | ||
| 623 | (funcall function string))) | ||