Annotation of GNUtools/emacs/lisp/isearch.el, revision 1.1.1.1

1.1       root        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: ; in loaddefs.el
                     21: ;(defvar search-last-string ""
                     22: ;  "Last string search for by a search command.
                     23: ;This does not include direct calls to the primitive search functions,
                     24: ;and does not include searches that are aborted.")
                     25: ;(defvar search-last-regexp ""
                     26: ;  "Last string searched for by a regexp search command.
                     27: ;This does not include direct calls to the primitive search functions,
                     28: ;and does not include searches that are aborted.")
                     29: ;
                     30: ;(defconst search-repeat-char ?\C-s
                     31: ;  "Character to repeat incremental search forwards.")
                     32: ;(defconst search-reverse-char ?\C-r
                     33: ;  "Character to repeat incremental search backwards.")
                     34: ;(defconst search-exit-char ?\e
                     35: ;  "Character to exit incremental search.")
                     36: ;(defconst search-delete-char ?\177
                     37: ;  "Character to delete from incremental search string.")
                     38: ;(defconst search-quote-char ?\C-q
                     39: ;  "Character to quote special characters for incremental search.")
                     40: ;(defconst search-yank-word-char ?\C-w
                     41: ;  "Character to pull next word from buffer into search string.")
                     42: ;(defconst search-yank-line-char ?\C-y
                     43: ;  "Character to pull rest of line from buffer into search string.")
                     44: ;(defconst search-exit-option t
                     45: ;  "Non-nil means random control characters terminate incremental search.")
                     46: ;
                     47: ;(defvar search-slow-window-lines 1
                     48: ;  "*Number of lines in slow search display windows.")
                     49: ;(defconst search-slow-speed 1200
                     50: ;  "*Highest terminal speed at which to use \"slow\" style incremental search.
                     51: ;This is the style where a one-line window is created to show the line
                     52: ;that the search has reached.")
                     53: 
                     54: ;; This function does all the work of incremental search.
                     55: ;; The functions attached to ^R and ^S are trivial,
                     56: ;; merely calling this one, but they are always loaded by default
                     57: ;; whereas this file can optionally be autoloadable.
                     58: ;; This is the only entry point in this file.
                     59: 
                     60: (defun isearch (forward &optional regexp)
                     61:   (let ((search-string "")
                     62:        (search-message "")
                     63:        (cmds nil)
                     64:        (success t)
                     65:        (wrapped nil)
                     66:        (barrier (point))
                     67:        adjusted
                     68:        (invalid-regexp nil)
                     69:        (slow-terminal-mode (and (<= (baud-rate) search-slow-speed)
                     70:                                 (> (window-height)
                     71:                                    (* 4 search-slow-window-lines))))
                     72:        (other-end nil)    ;Start of last match if fwd, end if backwd.
                     73:        (small-window nil)              ;if t, using a small window
                     74:        (found-point nil)               ;to restore point from a small window
                     75:        ;; This is the window-start value found by the search.
                     76:        (found-start nil)
                     77:        (opoint (point))
                     78:        (inhibit-quit t))  ;Prevent ^G from quitting immediately.
                     79:     (isearch-push-state)
                     80:     (save-window-excursion
                     81:      (catch 'search-done
                     82:        (while t
                     83:         (or (>= unread-command-char 0)
                     84:             (progn
                     85:               (or (input-pending-p)
                     86:                   (isearch-message))
                     87:               (if (and slow-terminal-mode
                     88:                        (not (or small-window (pos-visible-in-window-p))))
                     89:                   (progn
                     90:                     (setq small-window t)
                     91:                     (setq found-point (point))
                     92:                     (move-to-window-line 0)
                     93:                     (let ((window-min-height 1))
                     94:                       (split-window nil (if (< search-slow-window-lines 0)
                     95:                                             (1+ (- search-slow-window-lines))
                     96:                                           (- (window-height)
                     97:                                              (1+ search-slow-window-lines)))))
                     98:                     (if (< search-slow-window-lines 0)
                     99:                         (progn (vertical-motion (- 1 search-slow-window-lines))
                    100:                                (set-window-start (next-window) (point))
                    101:                                (set-window-hscroll (next-window)
                    102:                                                    (window-hscroll))
                    103:                                (set-window-hscroll (selected-window) 0))
                    104:                       (other-window 1))
                    105:                     (goto-char found-point)))))
                    106:         (let ((char (if quit-flag
                    107:                         ?\C-g
                    108:                       (read-char))))
                    109:           (setq quit-flag nil adjusted nil)
                    110:           ;; Meta character means exit search.
                    111:           (cond ((and (>= char 128)
                    112:                       search-exit-option)
                    113:                  (setq unread-command-char char)
                    114:                  (throw 'search-done t))
                    115:                 ((eq char search-exit-char)
                    116:                  ;; Esc means exit search normally.
                    117:                  ;; Except, if first thing typed, it means do nonincremental
                    118:                  (if (= 0 (length search-string))
                    119:                      (nonincremental-search forward regexp))
                    120:                  (throw 'search-done t))
                    121:                 ((= char ?\C-g)
                    122:                  ;; ^G means the user tried to quit.
                    123:                  (ding)
                    124:                  (discard-input)
                    125:                  (if success
                    126:                      ;; If search is successful, move back to starting point
                    127:                      ;; and really do quit.
                    128:                      (progn (goto-char opoint)
                    129:                             (signal 'quit nil))
                    130:                    ;; If search is failing, rub out until it is once more
                    131:                    ;;  successful.
                    132:                    (while (not success) (isearch-pop))))
                    133:                 ((or (eq char search-repeat-char)
                    134:                      (eq char search-reverse-char))
                    135:                  (if (eq forward (eq char search-repeat-char))
                    136:                      ;; C-s in forward or C-r in reverse.
                    137:                      (if (equal search-string "")
                    138:                          ;; If search string is empty, use last one.
                    139:                          (setq search-string
                    140:                                (if regexp
                    141:                                    search-last-regexp search-last-string)
                    142:                                search-message
                    143:                                (mapconcat 'text-char-description
                    144:                                           search-string ""))
                    145:                        ;; If already have what to search for, repeat it.
                    146:                        (or success
                    147:                            (progn (goto-char (if forward (point-min) (point-max)))
                    148:                                   (setq wrapped t))))
                    149:                    ;; C-s in reverse or C-r in forward, change direction.
                    150:                    (setq forward (not forward)))
                    151:                  (setq barrier (point)) ; For subsequent \| if regexp.
                    152:                  (setq success t)
                    153:                  (or (equal search-string "")
                    154:                      (isearch-search))
                    155:                  (isearch-push-state))
                    156:                 ((= char search-delete-char)
                    157:                  ;; Rubout means discard last input item and move point
                    158:                  ;; back.  If buffer is empty, just beep.
                    159:                  (if (null (cdr cmds))
                    160:                      (ding)
                    161:                    (isearch-pop)))
                    162:                 (t
                    163:                  (cond ((or (eq char search-yank-word-char)
                    164:                             (eq char search-yank-line-char))
                    165:                         ;; ^W means gobble next word from buffer.
                    166:                         ;; ^Y means gobble rest of line from buffer.
                    167:                         (let ((word (save-excursion
                    168:                                       (and (not forward) other-end
                    169:                                            (goto-char other-end))
                    170:                                       (buffer-substring
                    171:                                        (point)
                    172:                                        (save-excursion
                    173:                                          (if (eq char search-yank-line-char)
                    174:                                              (end-of-line)
                    175:                                            (forward-word 1))
                    176:                                          (point))))))
                    177:                           (if regexp
                    178:                               (setq word (regexp-quote word)))
                    179:                           (setq search-string (concat search-string word)
                    180:                                 search-message
                    181:                                   (concat search-message
                    182:                                           (mapconcat 'text-char-description
                    183:                                                      word "")))))
                    184:                         ;; Any other control char =>
                    185:                         ;;  unread it and exit the search normally.
                    186:                         ((and search-exit-option
                    187:                               (/= char search-quote-char)
                    188:                               (or (= char ?\177)
                    189:                                   (and (< char ? ) (/= char ?\t) (/= char ?\r))))
                    190:                          (setq unread-command-char char)
                    191:                          (throw 'search-done t))
                    192:                         (t
                    193:                          ;; Any other character => add it to the
                    194:                          ;;  search string and search.
                    195:                          (cond ((= char search-quote-char)
                    196:                                 (setq char (read-quoted-char
                    197:                                             (isearch-message t))))
                    198:                                ((= char ?\r)
                    199:                                 ;; unix braindeath
                    200:                                 (setq char ?\n)))
                    201:                          (setq search-string (concat search-string
                    202:                                                      (char-to-string char))
                    203:                                search-message (concat search-message
                    204:                                                       (text-char-description char)))))
                    205:                  (if (and (not success)
                    206:                           ;; unsuccessful regexp search may become
                    207:                           ;;  successful by addition of characters which
                    208:                           ;;  make search-string valid
                    209:                           (not regexp))
                    210:                      nil
                    211:                    ;; If a regexp search may have been made more
                    212:                    ;; liberal, retreat the search start.
                    213:                    ;; Go back to place last successful search started
                    214:                    ;; or to the last ^S/^R (barrier), whichever is nearer.
                    215:                    (and regexp success cmds
                    216:                         (cond ((and (memq char '(?* ??))
                    217:                                     ;; Don't treat *, ? as special
                    218:                                     ;; within [] or after \.
                    219:                                     (not (nth 6 (car cmds))))
                    220:                                (setq adjusted t)
                    221:                                ;; This used to use element 2
                    222:                                ;; in a reverse search, but it seems that 5
                    223:                                ;; (which is the end of the old match)
                    224:                                ;; is better in that case too.
                    225:                                (let ((cs (nth 5 ; old other-end.
                    226:                                               (car (cdr cmds)))))
                    227:                                  ;; (car cmds) is after last search;
                    228:                                  ;; (car (cdr cmds)) is from before it.
                    229:                                  (setq cs (or cs barrier))
                    230:                                  (goto-char
                    231:                                   (if forward
                    232:                                       (max cs barrier)
                    233:                                     (min cs barrier)))))
                    234:                               ((eq char ?\|)
                    235:                                (setq adjusted t)
                    236:                                (goto-char barrier))))
                    237:                    ;; In reverse regexp search, adding a character at
                    238:                    ;; the end may cause zero or many more chars to be
                    239:                    ;; matched, in the string following point.
                    240:                    ;; Allow all those possibiities without moving point as
                    241:                    ;; long as the match does not extend past search origin.
                    242:                    (if (and regexp (not forward) (not adjusted)
                    243:                             (condition-case ()
                    244:                                 (looking-at search-string)
                    245:                               (error nil))
                    246:                             (<= (match-end 0) (min opoint barrier)))
                    247:                        (setq success t invalid-regexp nil
                    248:                              other-end (match-end 0))
                    249:                      ;; Not regexp, not reverse, or no match at point.
                    250:                      (if (and other-end (not adjusted))
                    251:                          (goto-char (if forward other-end
                    252:                                       (min opoint barrier (1+ other-end)))))
                    253:                      (isearch-search)))
                    254:                  (isearch-push-state))))))
                    255:      (setq found-start (window-start (selected-window)))
                    256:      (setq found-point (point)))
                    257:     (if (> (length search-string) 0)
                    258:        (if regexp
                    259:            (setq search-last-regexp search-string)
                    260:            (setq search-last-string search-string)))
                    261:     ;; If we displayed a single-line window, set point in this window. 
                    262:     (if small-window
                    263:        (goto-char found-point))
                    264:     ;; If there was movement, mark the starting position.
                    265:     ;; Maybe should test difference between and set mark iff > threshold.
                    266:     (if (/= (point) opoint)
                    267:        (push-mark opoint)
                    268:       (message ""))
                    269:     (or small-window
                    270:        ;; Exiting the save-window-excursion clobbers this; restore it.
                    271:        (set-window-start (selected-window) found-start t))))
                    272: 
                    273: (defun isearch-message (&optional c-q-hack ellipsis)
                    274:   ;; If about to search, and previous search regexp was invalid,
                    275:   ;; check that it still is.  If it is valid now,
                    276:   ;; let the message we display while searching say that it is valid.
                    277:   (and invalid-regexp ellipsis
                    278:        (condition-case ()
                    279:           (progn (re-search-forward search-string (point) t)
                    280:                  (setq invalid-regexp nil))
                    281:         (error nil)))
                    282:   ;; If currently failing, display no ellipsis.
                    283:   (or success (setq ellipsis nil))
                    284:   (let ((m (concat (if success "" "failing ")
                    285:                   (if wrapped "wrapped ")
                    286:                   (if regexp "regexp " "")
                    287:                   "I-search"
                    288:                   (if forward ": " " backward: ")
                    289:                   search-message
                    290:                   (if c-q-hack "^Q" "")
                    291:                   (if invalid-regexp
                    292:                       (concat " [" invalid-regexp "]")
                    293:                     ""))))
                    294:     (aset m 0 (upcase (aref m 0)))
                    295:     (let ((cursor-in-echo-area ellipsis))
                    296:       (if c-q-hack m (message "%s" m)))))
                    297: 
                    298: (defun isearch-pop ()
                    299:   (setq cmds (cdr cmds))
                    300:   (let ((cmd (car cmds)))
                    301:     (setq search-string (car cmd)
                    302:          search-message (car (cdr cmd))
                    303:          success (nth 3 cmd)
                    304:          forward (nth 4 cmd)
                    305:          other-end (nth 5 cmd)
                    306:          invalid-regexp (nth 6 cmd)
                    307:          wrapped (nth 7 cmd)
                    308:          barrier (nth 8 cmd))
                    309:     (goto-char (car (cdr (cdr cmd))))))
                    310: 
                    311: (defun isearch-push-state ()
                    312:   (setq cmds (cons (list search-string search-message (point)
                    313:                         success forward other-end invalid-regexp
                    314:                         wrapped barrier)
                    315:                   cmds)))
                    316: 
                    317: (defun isearch-search ()
                    318:   (isearch-message nil t)
                    319:   (condition-case lossage
                    320:       (let ((inhibit-quit nil))
                    321:        (if regexp (setq invalid-regexp nil))
                    322:        (setq success
                    323:              (funcall
                    324:               (if regexp
                    325:                   (if forward 're-search-forward 're-search-backward)
                    326:                 (if forward 'search-forward 'search-backward))
                    327:               search-string nil t))
                    328:        (if success
                    329:            (setq other-end
                    330:                  (if forward (match-beginning 0) (match-end 0)))))
                    331:     (quit (setq unread-command-char ?\C-g)
                    332:          (setq success nil))
                    333:     (invalid-regexp (setq invalid-regexp (car (cdr lossage)))
                    334:                    (if (string-match "\\`Premature \\|\\`Unmatched \\|\\`Invalid "
                    335:                                      invalid-regexp)
                    336:                        (setq invalid-regexp "incomplete input"))))
                    337:   (if success
                    338:       nil
                    339:     ;; Ding if failed this time after succeeding last time.
                    340:     (and (nth 3 (car cmds))
                    341:         (ding))
                    342:     (goto-char (nth 2 (car cmds)))))
                    343: 
                    344: ;; This is called from incremental-search
                    345: ;; if the first input character is the exit character.
                    346: ;; The interactive-arg-reader uses free variables `forward' and `regexp'
                    347: ;; which are bound by `incremental-search'.
                    348: 
                    349: ;; We store the search string in `search-string'
                    350: ;; which has been bound already by `incremental-search'
                    351: ;; so that, when we exit, it is copied into `search-last-string'.
                    352: 
                    353: (defun nonincremental-search (forward regexp)
                    354:   (let (message char function string inhibit-quit)
                    355:     (let ((cursor-in-echo-area t))
                    356:       ;; Prompt assuming not word search,
                    357:       (setq message (if regexp 
                    358:                        (if forward "Regexp search: "
                    359:                          "Regexp search backward: ")
                    360:                      (if forward "Search: " "Search backward: ")))
                    361:       (message "%s" message)
                    362:       ;; Read 1 char and switch to word search if it is ^W.
                    363:       (setq char (read-char)))
                    364:     (if (eq char search-yank-word-char)
                    365:        (setq message (if forward "Word search: " "Word search backward: "))
                    366:       ;; Otherwise let that 1 char be part of the search string.
                    367:       (setq unread-command-char char))
                    368:     (setq function
                    369:          (if (eq char search-yank-word-char)
                    370:              (if forward 'word-search-forward 'word-search-backward)
                    371:            (if regexp
                    372:                (if forward 're-search-forward 're-search-backward)
                    373:              (if forward 'search-forward 'search-backward))))
                    374:     ;; Read the search string with corrected prompt.
                    375:     (setq string (read-string message))
                    376:     (let ((var (if regexp 'search-last-regexp 'search-last-string)))
                    377:       ;; Empty means use default.
                    378:       (if (= 0 (length string))
                    379:          (setq string (symbol-value var))
                    380:        ;; Set last search string now so it is set even if we fail.
                    381:        (set var string)))
                    382:     ;; Since we used the minibuffer, we should be available for redo.
                    383:     (setq command-history (cons (list function string) command-history))
                    384:     ;; Go ahead and search.
                    385:     (funcall function string)))

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.