57 |
;; keep the behavior. No point in forcing nonincremental search until |
;; keep the behavior. No point in forcing nonincremental search until |
58 |
;; the last possible moment. |
;; the last possible moment. |
59 |
|
|
|
;; TODO |
|
|
;; - Integrate the emacs 19 generalized command history. |
|
|
;; - Hooks and options for failed search. |
|
|
|
|
|
;;; Change Log: |
|
|
|
|
|
;; Changes before those recorded in ChangeLog: |
|
|
|
|
|
;; Revision 1.4 92/09/14 16:26:02 liberte |
|
|
;; Added prefix args to isearch-forward, etc. to switch between |
|
|
;; string and regular expression searching. |
|
|
;; Added some support for lemacs. |
|
|
;; Added general isearch-highlight option - but only for lemacs so far. |
|
|
;; Added support for frame switching in emacs 19. |
|
|
;; Added word search option to isearch-edit-string. |
|
|
;; Renamed isearch-quit to isearch-abort. |
|
|
;; Numerous changes to comments and doc strings. |
|
|
;; |
|
|
;; Revision 1.3 92/06/29 13:10:08 liberte |
|
|
;; Moved modal isearch-mode handling into isearch-mode. |
|
|
;; Got rid of buffer-local isearch variables. |
|
|
;; isearch-edit-string used by ring adjustments, completion, and |
|
|
;; nonincremental searching. C-s and C-r are additional exit commands. |
|
|
;; Renamed all regex to regexp. |
|
|
;; Got rid of found-start and found-point globals. |
|
|
;; Generalized handling of upper-case chars. |
|
|
|
|
|
;; Revision 1.2 92/05/27 11:33:57 liberte |
|
|
;; Emacs version 19 has a search ring, which is supported here. |
|
|
;; Other fixes found in the version 19 isearch are included here. |
|
|
;; |
|
|
;; Also see variables search-caps-disable-folding, |
|
|
;; search-nonincremental-instead, search-whitespace-regexp, and |
|
|
;; commands isearch-toggle-regexp, isearch-edit-string. |
|
|
;; |
|
|
;; semi-modal isearching is supported. |
|
|
|
|
|
;; Changes for 1.1 |
|
|
;; 3/18/92 Fixed invalid-regexp. |
|
|
;; 3/18/92 Fixed yanking in regexps. |
|
|
|
|
60 |
;;; Code: |
;;; Code: |
61 |
|
|
62 |
|
|
157 |
(defvar isearch-mode-end-hook nil |
(defvar isearch-mode-end-hook nil |
158 |
"Function(s) to call after terminating an incremental search.") |
"Function(s) to call after terminating an incremental search.") |
159 |
|
|
160 |
|
(defvar isearch-wrap-function nil |
161 |
|
"Function to call to wrap the search when search is failed. |
162 |
|
If nil, move point to the beginning of the buffer for a forward search, |
163 |
|
or to the end of the buffer for a backward search.") |
164 |
|
|
165 |
|
(defvar isearch-push-state-function nil |
166 |
|
"Function to save a function restoring the mode-specific isearch state |
167 |
|
to the search status stack.") |
168 |
|
|
169 |
;; Search ring. |
;; Search ring. |
170 |
|
|
171 |
(defvar search-ring nil |
(defvar search-ring nil |
744 |
|
|
745 |
;; The search status structure and stack. |
;; The search status structure and stack. |
746 |
|
|
747 |
(defsubst isearch-string (frame) |
(defsubst isearch-string-state (frame) |
748 |
"Return the search string in FRAME." |
"Return the search string in FRAME." |
749 |
(aref frame 0)) |
(aref frame 0)) |
750 |
(defsubst isearch-message-string (frame) |
(defsubst isearch-message-state (frame) |
751 |
"Return the search string to display to the user in FRAME." |
"Return the search string to display to the user in FRAME." |
752 |
(aref frame 1)) |
(aref frame 1)) |
753 |
(defsubst isearch-point (frame) |
(defsubst isearch-point-state (frame) |
754 |
"Return the point in FRAME." |
"Return the point in FRAME." |
755 |
(aref frame 2)) |
(aref frame 2)) |
756 |
(defsubst isearch-success (frame) |
(defsubst isearch-success-state (frame) |
757 |
"Return the success flag in FRAME." |
"Return the success flag in FRAME." |
758 |
(aref frame 3)) |
(aref frame 3)) |
759 |
(defsubst isearch-forward-flag (frame) |
(defsubst isearch-forward-state (frame) |
760 |
"Return the searching-forward flag in FRAME." |
"Return the searching-forward flag in FRAME." |
761 |
(aref frame 4)) |
(aref frame 4)) |
762 |
(defsubst isearch-other-end (frame) |
(defsubst isearch-other-end-state (frame) |
763 |
"Return the other end of the match in FRAME." |
"Return the other end of the match in FRAME." |
764 |
(aref frame 5)) |
(aref frame 5)) |
765 |
(defsubst isearch-word (frame) |
(defsubst isearch-word-state (frame) |
766 |
"Return the search-by-word flag in FRAME." |
"Return the search-by-word flag in FRAME." |
767 |
(aref frame 6)) |
(aref frame 6)) |
768 |
(defsubst isearch-invalid-regexp (frame) |
(defsubst isearch-invalid-regexp-state (frame) |
769 |
"Return the regexp error message in FRAME, or nil if its regexp is valid." |
"Return the regexp error message in FRAME, or nil if its regexp is valid." |
770 |
(aref frame 7)) |
(aref frame 7)) |
771 |
(defsubst isearch-wrapped (frame) |
(defsubst isearch-wrapped-state (frame) |
772 |
"Return the search-wrapped flag in FRAME." |
"Return the search-wrapped flag in FRAME." |
773 |
(aref frame 8)) |
(aref frame 8)) |
774 |
(defsubst isearch-barrier (frame) |
(defsubst isearch-barrier-state (frame) |
775 |
"Return the barrier value in FRAME." |
"Return the barrier value in FRAME." |
776 |
(aref frame 9)) |
(aref frame 9)) |
777 |
(defsubst isearch-within-brackets (frame) |
(defsubst isearch-within-brackets-state (frame) |
778 |
"Return the in-character-class flag in FRAME." |
"Return the in-character-class flag in FRAME." |
779 |
(aref frame 10)) |
(aref frame 10)) |
780 |
(defsubst isearch-case-fold-search (frame) |
(defsubst isearch-case-fold-search-state (frame) |
781 |
"Return the case-folding flag in FRAME." |
"Return the case-folding flag in FRAME." |
782 |
(aref frame 11)) |
(aref frame 11)) |
783 |
|
(defsubst isearch-pop-fun-state (frame) |
784 |
|
"Return the function restoring the mode-specific isearch state in FRAME." |
785 |
|
(aref frame 12)) |
786 |
|
|
787 |
(defun isearch-top-state () |
(defun isearch-top-state () |
788 |
(let ((cmd (car isearch-cmds))) |
(let ((cmd (car isearch-cmds))) |
789 |
(setq isearch-string (isearch-string cmd) |
(setq isearch-string (isearch-string-state cmd) |
790 |
isearch-message (isearch-message-string cmd) |
isearch-message (isearch-message-state cmd) |
791 |
isearch-success (isearch-success cmd) |
isearch-success (isearch-success-state cmd) |
792 |
isearch-forward (isearch-forward-flag cmd) |
isearch-forward (isearch-forward-state cmd) |
793 |
isearch-other-end (isearch-other-end cmd) |
isearch-other-end (isearch-other-end-state cmd) |
794 |
isearch-word (isearch-word cmd) |
isearch-word (isearch-word-state cmd) |
795 |
isearch-invalid-regexp (isearch-invalid-regexp cmd) |
isearch-invalid-regexp (isearch-invalid-regexp-state cmd) |
796 |
isearch-wrapped (isearch-wrapped cmd) |
isearch-wrapped (isearch-wrapped-state cmd) |
797 |
isearch-barrier (isearch-barrier cmd) |
isearch-barrier (isearch-barrier-state cmd) |
798 |
isearch-within-brackets (isearch-within-brackets cmd) |
isearch-within-brackets (isearch-within-brackets-state cmd) |
799 |
isearch-case-fold-search (isearch-case-fold-search cmd)) |
isearch-case-fold-search (isearch-case-fold-search-state cmd)) |
800 |
(goto-char (isearch-point cmd)))) |
(if (functionp (isearch-pop-fun-state cmd)) |
801 |
|
(funcall (isearch-pop-fun-state cmd) cmd)) |
802 |
|
(goto-char (isearch-point-state cmd)))) |
803 |
|
|
804 |
(defun isearch-pop-state () |
(defun isearch-pop-state () |
805 |
(setq isearch-cmds (cdr isearch-cmds)) |
(setq isearch-cmds (cdr isearch-cmds)) |
811 |
isearch-success isearch-forward isearch-other-end |
isearch-success isearch-forward isearch-other-end |
812 |
isearch-word |
isearch-word |
813 |
isearch-invalid-regexp isearch-wrapped isearch-barrier |
isearch-invalid-regexp isearch-wrapped isearch-barrier |
814 |
isearch-within-brackets isearch-case-fold-search) |
isearch-within-brackets isearch-case-fold-search |
815 |
|
(if isearch-push-state-function |
816 |
|
(funcall isearch-push-state-function))) |
817 |
isearch-cmds))) |
isearch-cmds))) |
818 |
|
|
819 |
|
|
999 |
(defun isearch-cancel () |
(defun isearch-cancel () |
1000 |
"Terminate the search and go back to the starting point." |
"Terminate the search and go back to the starting point." |
1001 |
(interactive) |
(interactive) |
1002 |
|
(if (functionp (isearch-pop-fun-state (car (last isearch-cmds)))) |
1003 |
|
(funcall (isearch-pop-fun-state (car (last isearch-cmds))) |
1004 |
|
(car (last isearch-cmds)))) |
1005 |
(goto-char isearch-opoint) |
(goto-char isearch-opoint) |
1006 |
(isearch-done t) |
(isearch-done t) ; exit isearch |
1007 |
(isearch-clean-overlays) |
(isearch-clean-overlays) |
1008 |
(signal 'quit nil)) ; and pass on quit signal |
(signal 'quit nil)) ; and pass on quit signal |
1009 |
|
|
1010 |
(defun isearch-abort () |
(defun isearch-abort () |
1011 |
"Abort incremental search mode if searching is successful, signaling quit. |
"Abort incremental search mode if searching is successful, signaling quit. |
1017 |
(if isearch-success |
(if isearch-success |
1018 |
;; If search is successful, move back to starting point |
;; If search is successful, move back to starting point |
1019 |
;; and really do quit. |
;; and really do quit. |
1020 |
(progn (goto-char isearch-opoint) |
(progn |
1021 |
(setq isearch-success nil) |
(setq isearch-success nil) |
1022 |
(isearch-done t) ; exit isearch |
(isearch-cancel)) |
|
(isearch-clean-overlays) |
|
|
(signal 'quit nil)) ; and pass on quit signal |
|
1023 |
;; If search is failing, or has an incomplete regexp, |
;; If search is failing, or has an incomplete regexp, |
1024 |
;; rub out until it is once more successful. |
;; rub out until it is once more successful. |
1025 |
(while (or (not isearch-success) isearch-invalid-regexp) |
(while (or (not isearch-success) isearch-invalid-regexp) |
1044 |
;; If already have what to search for, repeat it. |
;; If already have what to search for, repeat it. |
1045 |
(or isearch-success |
(or isearch-success |
1046 |
(progn |
(progn |
1047 |
(goto-char (if isearch-forward (point-min) (point-max))) |
(if isearch-wrap-function |
1048 |
|
(funcall isearch-wrap-function) |
1049 |
|
(goto-char (if isearch-forward (point-min) (point-max)))) |
1050 |
(setq isearch-wrapped t)))) |
(setq isearch-wrapped t)))) |
1051 |
;; C-s in reverse or C-r in forward, change direction. |
;; C-s in reverse or C-r in forward, change direction. |
1052 |
(setq isearch-forward (not isearch-forward))) |
(setq isearch-forward (not isearch-forward))) |
1088 |
(interactive) |
(interactive) |
1089 |
(setq isearch-regexp (not isearch-regexp)) |
(setq isearch-regexp (not isearch-regexp)) |
1090 |
(if isearch-regexp (setq isearch-word nil)) |
(if isearch-regexp (setq isearch-word nil)) |
1091 |
|
(setq isearch-success t isearch-adjusted t) |
1092 |
(isearch-update)) |
(isearch-update)) |
1093 |
|
|
1094 |
(defun isearch-toggle-case-fold () |
(defun isearch-toggle-case-fold () |
1101 |
(isearch-message-prefix nil nil isearch-nonincremental) |
(isearch-message-prefix nil nil isearch-nonincremental) |
1102 |
isearch-message |
isearch-message |
1103 |
(if isearch-case-fold-search "in" ""))) |
(if isearch-case-fold-search "in" ""))) |
1104 |
(setq isearch-adjusted t) |
(setq isearch-success t isearch-adjusted t) |
1105 |
(sit-for 1) |
(sit-for 1) |
1106 |
(isearch-update)) |
(isearch-update)) |
1107 |
|
|
1108 |
(defun isearch-query-replace () |
(defun isearch-query-replace (&optional regexp-flag) |
1109 |
"Start query-replace with string to replace from last search string." |
"Start query-replace with string to replace from last search string." |
1110 |
(interactive) |
(interactive) |
1111 |
(barf-if-buffer-read-only) |
(barf-if-buffer-read-only) |
1112 |
|
(if regexp-flag (setq isearch-regexp t)) |
1113 |
(let ((case-fold-search isearch-case-fold-search)) |
(let ((case-fold-search isearch-case-fold-search)) |
1114 |
(isearch-done) |
(isearch-done) |
1115 |
(isearch-clean-overlays) |
(isearch-clean-overlays) |
1116 |
(and isearch-forward isearch-other-end (goto-char isearch-other-end)) |
(if (and (< isearch-other-end (point)) |
1117 |
|
(not (and transient-mark-mode mark-active |
1118 |
|
(< isearch-opoint (point))))) |
1119 |
|
(goto-char isearch-other-end)) |
1120 |
|
(set query-replace-from-history-variable |
1121 |
|
(cons isearch-string |
1122 |
|
(symbol-value query-replace-from-history-variable))) |
1123 |
(perform-replace |
(perform-replace |
1124 |
isearch-string |
isearch-string |
1125 |
(query-replace-read-to isearch-string "Query replace" isearch-regexp) |
(query-replace-read-to |
1126 |
t isearch-regexp isearch-word))) |
isearch-string |
1127 |
|
(if isearch-regexp "Query replace regexp" "Query replace") |
1128 |
|
isearch-regexp) |
1129 |
|
t isearch-regexp isearch-word nil nil |
1130 |
|
(if (and transient-mark-mode mark-active) (region-beginning)) |
1131 |
|
(if (and transient-mark-mode mark-active) (region-end))))) |
1132 |
|
|
1133 |
(defun isearch-query-replace-regexp () |
(defun isearch-query-replace-regexp () |
1134 |
"Start query-replace-regexp with string to replace from last search string." |
"Start query-replace-regexp with string to replace from last search string." |
1135 |
(interactive) |
(interactive) |
1136 |
(let ((query-replace-interactive t) |
(isearch-query-replace t)) |
|
(case-fold-search isearch-case-fold-search)) |
|
|
;; Put search string into the right ring |
|
|
(setq isearch-regexp t) |
|
|
(isearch-done) |
|
|
(isearch-clean-overlays) |
|
|
(and isearch-forward isearch-other-end (goto-char isearch-other-end)) |
|
|
(call-interactively 'query-replace-regexp))) |
|
1137 |
|
|
1138 |
|
|
1139 |
(defun isearch-delete-char () |
(defun isearch-delete-char () |
1331 |
;; We have to check 2 stack frames because the last might be |
;; We have to check 2 stack frames because the last might be |
1332 |
;; invalid just because of a backslash. |
;; invalid just because of a backslash. |
1333 |
(or (not isearch-invalid-regexp) |
(or (not isearch-invalid-regexp) |
1334 |
(not (isearch-invalid-regexp (cadr isearch-cmds))) |
(not (isearch-invalid-regexp-state (cadr isearch-cmds))) |
1335 |
allow-invalid)) |
allow-invalid)) |
1336 |
(if to-barrier |
(if to-barrier |
1337 |
(progn (goto-char isearch-barrier) |
(progn (goto-char isearch-barrier) |
1346 |
;; Also skip over postfix operators -- though horrid, |
;; Also skip over postfix operators -- though horrid, |
1347 |
;; 'ab?\{5,6\}+\{1,2\}*' is perfectly legal. |
;; 'ab?\{5,6\}+\{1,2\}*' is perfectly legal. |
1348 |
(while (and previous |
(while (and previous |
1349 |
(or (isearch-invalid-regexp frame) |
(or (isearch-invalid-regexp-state frame) |
1350 |
(let* ((string (isearch-string frame)) |
(let* ((string (isearch-string-state frame)) |
1351 |
(lchar (aref string (1- (length string))))) |
(lchar (aref string (1- (length string))))) |
1352 |
;; The operators aren't always operators; check |
;; The operators aren't always operators; check |
1353 |
;; backslashes. This doesn't handle the case of |
;; backslashes. This doesn't handle the case of |
1355 |
;; being special, but then we should fall back to |
;; being special, but then we should fall back to |
1356 |
;; the barrier anyway because it's all optional. |
;; the barrier anyway because it's all optional. |
1357 |
(if (isearch-backslash |
(if (isearch-backslash |
1358 |
(isearch-string (car previous))) |
(isearch-string-state (car previous))) |
1359 |
(eq lchar ?\}) |
(eq lchar ?\}) |
1360 |
(memq lchar '(?* ?? ?+)))))) |
(memq lchar '(?* ?? ?+)))))) |
1361 |
(setq stack previous previous (cdr previous) frame (car stack))) |
(setq stack previous previous (cdr previous) frame (car stack))) |
1363 |
;; `stack' now refers the most recent valid regexp that is not at |
;; `stack' now refers the most recent valid regexp that is not at |
1364 |
;; all optional in its last term. Now dig one level deeper and find |
;; all optional in its last term. Now dig one level deeper and find |
1365 |
;; what matched before that. |
;; what matched before that. |
1366 |
(let ((last-other-end (or (isearch-other-end (car previous)) |
(let ((last-other-end (or (isearch-other-end-state (car previous)) |
1367 |
isearch-barrier))) |
isearch-barrier))) |
1368 |
(goto-char (if isearch-forward |
(goto-char (if isearch-forward |
1369 |
(max last-other-end isearch-barrier) |
(max last-other-end isearch-barrier) |
1626 |
(let ((ab-bel (isearch-string-out-of-window isearch-point))) |
(let ((ab-bel (isearch-string-out-of-window isearch-point))) |
1627 |
(if ab-bel |
(if ab-bel |
1628 |
(isearch-back-into-window (eq ab-bel 'above) isearch-point) |
(isearch-back-into-window (eq ab-bel 'above) isearch-point) |
1629 |
(or (eq (point) isearch-point) |
(goto-char isearch-point))) |
|
(goto-char isearch-point)))) |
|
1630 |
(isearch-update)) |
(isearch-update)) |
1631 |
(search-exit-option |
(search-exit-option |
1632 |
(let (window) |
(let (window) |
1900 |
;; If currently failing, display no ellipsis. |
;; If currently failing, display no ellipsis. |
1901 |
(or isearch-success (setq ellipsis nil)) |
(or isearch-success (setq ellipsis nil)) |
1902 |
(let ((m (concat (if isearch-success "" "failing ") |
(let ((m (concat (if isearch-success "" "failing ") |
1903 |
|
(if isearch-adjusted "pending " "") |
1904 |
(if (and isearch-wrapped |
(if (and isearch-wrapped |
1905 |
|
(not isearch-wrap-function) |
1906 |
(if isearch-forward |
(if isearch-forward |
1907 |
(> (point) isearch-opoint) |
(> (point) isearch-opoint) |
1908 |
(< (point) isearch-opoint))) |
(< (point) isearch-opoint))) |
1997 |
(if isearch-success |
(if isearch-success |
1998 |
nil |
nil |
1999 |
;; Ding if failed this time after succeeding last time. |
;; Ding if failed this time after succeeding last time. |
2000 |
(and (isearch-success (car isearch-cmds)) |
(and (isearch-success-state (car isearch-cmds)) |
2001 |
(ding)) |
(ding)) |
2002 |
(goto-char (isearch-point (car isearch-cmds))))) |
(if (functionp (isearch-pop-fun-state (car isearch-cmds))) |
2003 |
|
(funcall (isearch-pop-fun-state (car isearch-cmds)) (car isearch-cmds))) |
2004 |
|
(goto-char (isearch-point-state (car isearch-cmds))))) |
2005 |
|
|
2006 |
|
|
2007 |
;; Called when opening an overlay, and we are still in isearch. |
;; Called when opening an overlay, and we are still in isearch. |