75 |
;; Added word search option to isearch-edit-string. |
;; Added word search option to isearch-edit-string. |
76 |
;; Renamed isearch-quit to isearch-abort. |
;; Renamed isearch-quit to isearch-abort. |
77 |
;; Numerous changes to comments and doc strings. |
;; Numerous changes to comments and doc strings. |
78 |
;; |
;; |
79 |
;; Revision 1.3 92/06/29 13:10:08 liberte |
;; Revision 1.3 92/06/29 13:10:08 liberte |
80 |
;; Moved modal isearch-mode handling into isearch-mode. |
;; Moved modal isearch-mode handling into isearch-mode. |
81 |
;; Got rid of buffer-local isearch variables. |
;; Got rid of buffer-local isearch variables. |
102 |
;;; Code: |
;;; Code: |
103 |
|
|
104 |
|
|
105 |
;;; Some additional options and constants. |
;; Some additional options and constants. |
106 |
|
|
107 |
(defgroup isearch nil |
(defgroup isearch nil |
108 |
"Incremental search minor mode." |
"Incremental search minor mode." |
171 |
If the value is `open', if the text matched is made invisible by |
If the value is `open', if the text matched is made invisible by |
172 |
an overlay having an `invisible' property and that overlay has a property |
an overlay having an `invisible' property and that overlay has a property |
173 |
`isearch-open-invisible', then incremental search will show the contents. |
`isearch-open-invisible', then incremental search will show the contents. |
174 |
\(This applies when using `outline.el' and `hideshow.el'.)" |
\(This applies when using `outline.el' and `hideshow.el'.) |
175 |
|
See also `reveal-mode' if you want overlays to automatically be opened |
176 |
|
whenever point is in one of them." |
177 |
:type '(choice (const :tag "Match hidden text" t) |
:type '(choice (const :tag "Match hidden text" t) |
178 |
(const :tag "Open overlays" open) |
(const :tag "Open overlays" open) |
179 |
(const :tag "Don't match hidden text" nil)) |
(const :tag "Don't match hidden text" nil)) |
184 |
This variable makes a difference when `search-invisible' is set to `open'. |
This variable makes a difference when `search-invisible' is set to `open'. |
185 |
It means that after search makes some invisible text visible |
It means that after search makes some invisible text visible |
186 |
to show the match, it makes the text invisible again when the match moves. |
to show the match, it makes the text invisible again when the match moves. |
187 |
Ordinarily the text becomes invisible again at the end of the search." |
Ordinarily the text becomes invisible again at the end of the search." |
188 |
:type 'boolean |
:type 'boolean |
189 |
:group 'isearch) |
:group 'isearch) |
190 |
|
|
191 |
(defcustom isearch-resume-enabled t |
(defcustom isearch-resume-enabled t |
199 |
(defvar isearch-mode-end-hook nil |
(defvar isearch-mode-end-hook nil |
200 |
"Function(s) to call after terminating an incremental search.") |
"Function(s) to call after terminating an incremental search.") |
201 |
|
|
202 |
;;; Search ring. |
;; Search ring. |
203 |
|
|
204 |
(defvar search-ring nil |
(defvar search-ring nil |
205 |
"List of search string sequences.") |
"List of search string sequences.") |
228 |
:type 'boolean |
:type 'boolean |
229 |
:group 'isearch) |
:group 'isearch) |
230 |
|
|
231 |
;;; Define isearch-mode keymap. |
;; Define isearch-mode keymap. |
232 |
|
|
233 |
(defvar isearch-mode-map |
(defvar isearch-mode-map |
234 |
(let* ((i 0) |
(let* ((i 0) |
245 |
;; Make function keys, etc, exit the search. |
;; Make function keys, etc, exit the search. |
246 |
(define-key map [t] 'isearch-other-control-char) |
(define-key map [t] 'isearch-other-control-char) |
247 |
;; Control chars, by default, end isearch mode transparently. |
;; Control chars, by default, end isearch mode transparently. |
248 |
;; We need these explicit definitions because, in a dense keymap, |
;; We need these explicit definitions because, in a dense keymap, |
249 |
;; the binding for t does not affect characters. |
;; the binding for t does not affect characters. |
250 |
;; We use a dense keymap to save space. |
;; We use a dense keymap to save space. |
251 |
(while (< i ?\ ) |
(while (< i ?\ ) |
284 |
(error "Inconsistency in isearch.el")) |
(error "Inconsistency in isearch.el")) |
285 |
(define-key map "\e\e\e" 'isearch-cancel) |
(define-key map "\e\e\e" 'isearch-cancel) |
286 |
(define-key map [escape escape escape] 'isearch-cancel) |
(define-key map [escape escape escape] 'isearch-cancel) |
287 |
|
|
288 |
(define-key map "\C-q" 'isearch-quote-char) |
(define-key map "\C-q" 'isearch-quote-char) |
289 |
|
|
290 |
(define-key map "\r" 'isearch-exit) |
(define-key map "\r" 'isearch-exit) |
292 |
(define-key map "\t" 'isearch-printing-char) |
(define-key map "\t" 'isearch-printing-char) |
293 |
(define-key map " " 'isearch-whitespace-chars) |
(define-key map " " 'isearch-whitespace-chars) |
294 |
(define-key map [?\S-\ ] 'isearch-whitespace-chars) |
(define-key map [?\S-\ ] 'isearch-whitespace-chars) |
295 |
|
|
296 |
(define-key map "\C-w" 'isearch-yank-word-or-char) |
(define-key map "\C-w" 'isearch-yank-word-or-char) |
297 |
(define-key map "\C-y" 'isearch-yank-line) |
(define-key map "\C-y" 'isearch-yank-line) |
298 |
|
|
302 |
(define-key map "?" 'isearch-*-char) |
(define-key map "?" 'isearch-*-char) |
303 |
(define-key map "|" 'isearch-|-char) |
(define-key map "|" 'isearch-|-char) |
304 |
|
|
305 |
;;; Turned off because I find I expect to get the global definition--rms. |
;; Turned off because I find I expect to get the global definition--rms. |
306 |
;;; ;; Instead bind C-h to special help command for isearch-mode. |
;; ;; Instead bind C-h to special help command for isearch-mode. |
307 |
;;; (define-key map "\C-h" 'isearch-mode-help) |
;; (define-key map "\C-h" 'isearch-mode-help) |
308 |
|
|
309 |
(define-key map "\M-n" 'isearch-ring-advance) |
(define-key map "\M-n" 'isearch-ring-advance) |
310 |
(define-key map "\M-p" 'isearch-ring-retreat) |
(define-key map "\M-p" 'isearch-ring-retreat) |
356 |
(defvar isearch-forward nil) ; Searching in the forward direction. |
(defvar isearch-forward nil) ; Searching in the forward direction. |
357 |
(defvar isearch-regexp nil) ; Searching for a regexp. |
(defvar isearch-regexp nil) ; Searching for a regexp. |
358 |
(defvar isearch-word nil) ; Searching for words. |
(defvar isearch-word nil) ; Searching for words. |
359 |
|
(defvar isearch-hidden nil) ; Non-nil if the string exists but is invisible. |
360 |
|
|
361 |
|
(defvar isearch-cmds nil |
362 |
|
"Stack of search status sets. |
363 |
|
Each set is a list of the form: |
364 |
|
(STRING MESSAGE POINT SUCCESS FORWARD OTHER-END WORD |
365 |
|
INVALID-REGEXP WRAPPED BARRIER WITHIN-BRACKETS CASE-FOLD-SEARCH)") |
366 |
|
|
|
(defvar isearch-cmds nil) ; Stack of search status sets. |
|
367 |
(defvar isearch-string "") ; The current search string. |
(defvar isearch-string "") ; The current search string. |
368 |
(defvar isearch-message "") ; text-char-description version of isearch-string |
(defvar isearch-message "") ; text-char-description version of isearch-string |
369 |
|
|
388 |
|
|
389 |
(defvar isearch-adjusted nil) |
(defvar isearch-adjusted nil) |
390 |
(defvar isearch-slow-terminal-mode nil) |
(defvar isearch-slow-terminal-mode nil) |
391 |
;;; If t, using a small window. |
;; If t, using a small window. |
392 |
(defvar isearch-small-window nil) |
(defvar isearch-small-window nil) |
393 |
(defvar isearch-opoint 0) |
(defvar isearch-opoint 0) |
394 |
;;; The window configuration active at the beginning of the search. |
;; The window configuration active at the beginning of the search. |
395 |
(defvar isearch-window-configuration nil) |
(defvar isearch-window-configuration nil) |
396 |
|
|
397 |
;; Flag to indicate a yank occurred, so don't move the cursor. |
;; Flag to indicate a yank occurred, so don't move the cursor. |
398 |
(defvar isearch-yank-flag nil) |
(defvar isearch-yank-flag nil) |
399 |
|
|
400 |
;;; A function to be called after each input character is processed. |
;; A function to be called after each input character is processed. |
401 |
;;; (It is not called after characters that exit the search.) |
;; (It is not called after characters that exit the search.) |
402 |
;;; It is only set from an optional argument to `isearch-mode'. |
;; It is only set from an optional argument to `isearch-mode'. |
403 |
(defvar isearch-op-fun nil) |
(defvar isearch-op-fun nil) |
404 |
|
|
405 |
;;; Is isearch-mode in a recursive edit for modal searching. |
;; Is isearch-mode in a recursive edit for modal searching. |
406 |
(defvar isearch-recursive-edit nil) |
(defvar isearch-recursive-edit nil) |
407 |
|
|
408 |
;;; Should isearch be terminated after doing one search? |
;; Should isearch be terminated after doing one search? |
409 |
(defvar isearch-nonincremental nil) |
(defvar isearch-nonincremental nil) |
410 |
|
|
411 |
;; New value of isearch-forward after isearch-edit-string. |
;; New value of isearch-forward after isearch-edit-string. |
436 |
(define-key global-map "\C-r" 'isearch-backward) |
(define-key global-map "\C-r" 'isearch-backward) |
437 |
(define-key esc-map "\C-r" 'isearch-backward-regexp) |
(define-key esc-map "\C-r" 'isearch-backward-regexp) |
438 |
|
|
439 |
;;; Entry points to isearch-mode. |
;; Entry points to isearch-mode. |
440 |
|
|
441 |
(defun isearch-forward (&optional regexp-p no-recursive-edit) |
(defun isearch-forward (&optional regexp-p no-recursive-edit) |
442 |
"\ |
"\ |
444 |
With a prefix argument, do an incremental regular expression search instead. |
With a prefix argument, do an incremental regular expression search instead. |
445 |
\\<isearch-mode-map> |
\\<isearch-mode-map> |
446 |
As you type characters, they add to the search string and are found. |
As you type characters, they add to the search string and are found. |
447 |
The following non-printing keys are bound in `isearch-mode-map'. |
The following non-printing keys are bound in `isearch-mode-map'. |
448 |
|
|
449 |
Type \\[isearch-delete-char] to cancel characters from end of search string. |
Type \\[isearch-delete-char] to cancel characters from end of search string. |
450 |
Type \\[isearch-exit] to exit, leaving point at location found. |
Type \\[isearch-exit] to exit, leaving point at location found. |
475 |
Type \\[isearch-complete] to complete the search string using the search ring. |
Type \\[isearch-complete] to complete the search string using the search ring. |
476 |
|
|
477 |
If an input method is turned on in the current buffer, that input |
If an input method is turned on in the current buffer, that input |
478 |
method is also active while you are typing a characters to search. To |
method is also active while you are typing characters to search. To |
479 |
toggle the input method, type \\[isearch-toggle-input-method]. It |
toggle the input method, type \\[isearch-toggle-input-method]. It |
480 |
also toggles the input method in the current buffer. |
also toggles the input method in the current buffer. |
481 |
|
|
483 |
\\[isearch-toggle-specified-input-method], and specify an input method |
\\[isearch-toggle-specified-input-method], and specify an input method |
484 |
you want to use. |
you want to use. |
485 |
|
|
486 |
The above keys, bound in `isearch-mode-map', are often controlled by |
The above keys, bound in `isearch-mode-map', are often controlled by |
487 |
options; do M-x apropos on search-.* to find them. |
options; do M-x apropos on search-.* to find them. |
488 |
Other control and meta characters terminate the search |
Other control and meta characters terminate the search |
489 |
and are then executed normally (depending on `search-exit-option'). |
and are then executed normally (depending on `search-exit-option'). |
535 |
;;(defvar isearch-commands '(isearch-forward isearch-backward |
;;(defvar isearch-commands '(isearch-forward isearch-backward |
536 |
;; isearch-forward-regexp isearch-backward-regexp) |
;; isearch-forward-regexp isearch-backward-regexp) |
537 |
;; "List of commands for which isearch-mode does not recursive-edit.") |
;; "List of commands for which isearch-mode does not recursive-edit.") |
538 |
|
|
539 |
|
|
540 |
(defun isearch-mode (forward &optional regexp op-fun recursive-edit word-p) |
(defun isearch-mode (forward &optional regexp op-fun recursive-edit word-p) |
541 |
"Start isearch minor mode. Called by `isearch-forward', etc. |
"Start isearch minor mode. Called by `isearch-forward', etc. |
611 |
(add-hook 'mouse-leave-buffer-hook 'isearch-done) |
(add-hook 'mouse-leave-buffer-hook 'isearch-done) |
612 |
(add-hook 'kbd-macro-termination-hook 'isearch-done) |
(add-hook 'kbd-macro-termination-hook 'isearch-done) |
613 |
|
|
614 |
;; isearch-mode can be made modal (in the sense of not returning to |
;; isearch-mode can be made modal (in the sense of not returning to |
615 |
;; the calling function until searching is completed) by entering |
;; the calling function until searching is completed) by entering |
616 |
;; a recursive-edit and exiting it when done isearching. |
;; a recursive-edit and exiting it when done isearching. |
617 |
(if recursive-edit |
(if recursive-edit |
618 |
(let ((isearch-recursive-edit t)) |
(let ((isearch-recursive-edit t)) |
623 |
;; Some high level utilities. Others below. |
;; Some high level utilities. Others below. |
624 |
|
|
625 |
(defun isearch-update () |
(defun isearch-update () |
626 |
;; Called after each command to update the display. |
;; Called after each command to update the display. |
627 |
(if (and (null unread-command-events) |
(if (and (null unread-command-events) |
628 |
(null executing-kbd-macro)) |
(null executing-kbd-macro)) |
629 |
(progn |
(progn |
630 |
(if (not (input-pending-p)) |
(if (not (input-pending-p)) |
631 |
(isearch-message)) |
(isearch-message)) |
632 |
(if (and isearch-slow-terminal-mode |
(if (and isearch-slow-terminal-mode |
633 |
(not (or isearch-small-window |
(not (or isearch-small-window |
634 |
(pos-visible-in-window-p)))) |
(pos-visible-in-window-p)))) |
635 |
(let ((found-point (point))) |
(let ((found-point (point))) |
636 |
(setq isearch-small-window t) |
(setq isearch-small-window t) |
734 |
(defun isearch-update-ring (string &optional regexp) |
(defun isearch-update-ring (string &optional regexp) |
735 |
"Add STRING to the beginning of the search ring. |
"Add STRING to the beginning of the search ring. |
736 |
REGEXP says which ring to use." |
REGEXP says which ring to use." |
737 |
(if regexp |
(if regexp |
738 |
(if (or (null regexp-search-ring) |
(if (or (null regexp-search-ring) |
739 |
(not (string= string (car regexp-search-ring)))) |
(not (string= string (car regexp-search-ring)))) |
740 |
(progn |
(progn |
750 |
(if (> (length search-ring) search-ring-max) |
(if (> (length search-ring) search-ring-max) |
751 |
(setcdr (nthcdr (1- search-ring-max) search-ring) nil)))))) |
(setcdr (nthcdr (1- search-ring-max) search-ring) nil)))))) |
752 |
|
|
753 |
;;; Switching buffers should first terminate isearch-mode. |
;; Switching buffers should first terminate isearch-mode. |
754 |
;;; ;; For Emacs 19, the frame switch event is handled. |
;; ;; For Emacs 19, the frame switch event is handled. |
755 |
;;; (defun isearch-switch-frame-handler () |
;; (defun isearch-switch-frame-handler () |
756 |
;;; (interactive) ;; Is this necessary? |
;; (interactive) ;; Is this necessary? |
757 |
;;; ;; First terminate isearch-mode. |
;; ;; First terminate isearch-mode. |
758 |
;;; (isearch-done) |
;; (isearch-done) |
759 |
;;; (isearch-clean-overlays) |
;; (isearch-clean-overlays) |
760 |
;;; (handle-switch-frame (car (cdr last-command-char)))) |
;; (handle-switch-frame (car (cdr last-command-char)))) |
761 |
|
|
762 |
|
|
763 |
;; Commands active while inside of the isearch minor mode. |
;; Commands active while inside of the isearch minor mode. |
768 |
search and `search-nonincremental-instead' is non-nil, do a |
search and `search-nonincremental-instead' is non-nil, do a |
769 |
nonincremental search instead via `isearch-edit-string'." |
nonincremental search instead via `isearch-edit-string'." |
770 |
(interactive) |
(interactive) |
771 |
(if (and search-nonincremental-instead |
(if (and search-nonincremental-instead |
772 |
(= 0 (length isearch-string))) |
(= 0 (length isearch-string))) |
773 |
(let ((isearch-nonincremental t)) |
(let ((isearch-nonincremental t)) |
774 |
(isearch-edit-string))) |
(isearch-edit-string))) |
840 |
) |
) |
841 |
|
|
842 |
;; Actually terminate isearching until editing is done. |
;; Actually terminate isearching until editing is done. |
843 |
;; This is so that the user can do anything without failure, |
;; This is so that the user can do anything without failure, |
844 |
;; like switch buffers and start another isearch, and return. |
;; like switch buffers and start another isearch, and return. |
845 |
(condition-case err |
(condition-case err |
846 |
(isearch-done t t) |
(isearch-done t t) |
848 |
|
|
849 |
(isearch-message) ;; for read-char |
(isearch-message) ;; for read-char |
850 |
(unwind-protect |
(unwind-protect |
851 |
(let* (;; Why does following read-char echo? |
(let* (;; Why does following read-char echo? |
852 |
;;(echo-keystrokes 0) ;; not needed with above message |
;;(echo-keystrokes 0) ;; not needed with above message |
853 |
(e (let ((cursor-in-echo-area t)) |
(e (let ((cursor-in-echo-area t)) |
854 |
(read-event))) |
(read-event))) |
882 |
(mapconcat 'isearch-text-char-description |
(mapconcat 'isearch-text-char-description |
883 |
isearch-new-string ""))) |
isearch-new-string ""))) |
884 |
;; Always resume isearching by restarting it. |
;; Always resume isearching by restarting it. |
885 |
(isearch-mode isearch-forward |
(isearch-mode isearch-forward |
886 |
isearch-regexp |
isearch-regexp |
887 |
isearch-op-fun |
isearch-op-fun |
888 |
nil |
nil |
889 |
isearch-word) |
isearch-word) |
890 |
|
|
915 |
;; Reinvoke the pending search. |
;; Reinvoke the pending search. |
916 |
(isearch-search) |
(isearch-search) |
917 |
(isearch-update) |
(isearch-update) |
918 |
(if isearch-nonincremental |
(if isearch-nonincremental |
919 |
(progn |
(progn |
920 |
;; (sit-for 1) ;; needed if isearch-done does: (message "") |
;; (sit-for 1) ;; needed if isearch-done does: (message "") |
921 |
(isearch-done)))) |
(isearch-done)))) |
978 |
(or (if isearch-regexp |
(or (if isearch-regexp |
979 |
(car regexp-search-ring) |
(car regexp-search-ring) |
980 |
(car search-ring)) |
(car search-ring)) |
981 |
"") |
(error "No previous search string")) |
982 |
isearch-message |
isearch-message |
983 |
(mapconcat 'isearch-text-char-description |
(mapconcat 'isearch-text-char-description |
984 |
isearch-string "") |
isearch-string "") |
1080 |
(isearch-yank-string (x-get-selection))) |
(isearch-yank-string (x-get-selection))) |
1081 |
|
|
1082 |
|
|
1083 |
(defun isearch-mouse-2 (click arg) |
(defun isearch-mouse-2 (click) |
1084 |
"Handle mouse-2 in Isearch mode. |
"Handle mouse-2 in Isearch mode. |
1085 |
For a click in the echo area, invoke `isearch-yank-x-selection'. |
For a click in the echo area, invoke `isearch-yank-x-selection'. |
1086 |
Otherwise invoke whatever mouse-2 is bound to outside of Isearch." |
Otherwise invoke whatever mouse-2 is bound to outside of Isearch." |
1087 |
(interactive "e\nP") |
(interactive "e") |
1088 |
(let* ((w (posn-window (event-start click))) |
(let* ((w (posn-window (event-start click))) |
1089 |
(overriding-terminal-local-map nil) |
(overriding-terminal-local-map nil) |
1090 |
(key (vector (event-basic-type click))) |
(key (vector (event-basic-type click))) |
1091 |
(binding (key-binding key))) |
;; FIXME: `key-binding' should accept an event as argument |
1092 |
|
;; and do all the overlay/text-properties lookup etc... |
1093 |
|
(binding (with-current-buffer |
1094 |
|
(if (window-live-p w) (window-buffer w) (current-buffer)) |
1095 |
|
(key-binding key)))) |
1096 |
(if (and (window-minibuffer-p w) |
(if (and (window-minibuffer-p w) |
1097 |
(not (minibuffer-window-active-p w))) ; in echo area |
(not (minibuffer-window-active-p w))) ; in echo area |
1098 |
(isearch-yank-x-selection) |
(isearch-yank-x-selection) |
1099 |
(when binding |
(when (functionp binding) |
1100 |
;; Kluge to allow passing ARG to functions that support it, |
(call-interactively binding))))) |
|
;; like mouse-yank-at-click. |
|
|
(if (equal (cadr (interactive-form binding)) "e\nP") |
|
|
(funcall binding click arg) |
|
|
(funcall binding click)))))) |
|
1101 |
|
|
1102 |
|
|
1103 |
(defun isearch-yank-internal (jumpform) |
(defun isearch-yank-internal (jumpform) |
1121 |
"Pull next character or word from buffer into search string." |
"Pull next character or word from buffer into search string." |
1122 |
(interactive) |
(interactive) |
1123 |
(isearch-yank-internal |
(isearch-yank-internal |
1124 |
(lambda () |
(lambda () |
1125 |
(if (or (= (char-syntax (or (char-after) 0)) ?w) |
(if (or (= (char-syntax (or (char-after) 0)) ?w) |
1126 |
(= (char-syntax (or (char-after (1+ (point))) 0)) ?w)) |
(= (char-syntax (or (char-after (1+ (point))) 0)) ?w)) |
1127 |
(forward-word 1) |
(forward-word 1) |
1135 |
(defun isearch-yank-line () |
(defun isearch-yank-line () |
1136 |
"Pull rest of line from buffer into search string." |
"Pull rest of line from buffer into search string." |
1137 |
(interactive) |
(interactive) |
1138 |
(isearch-yank-internal (lambda () (line-end-position)))) |
(isearch-yank-internal 'line-end-position)) |
1139 |
|
|
1140 |
|
|
1141 |
(defun isearch-search-and-update () |
(defun isearch-search-and-update () |
1142 |
;; Do the search and update the display. |
;; Do the search and update the display. |
1143 |
(if (and (not isearch-success) |
(when (or isearch-success |
1144 |
;; unsuccessful regexp search may become |
;; unsuccessful regexp search may become |
1145 |
;; successful by addition of characters which |
;; successful by addition of characters which |
1146 |
;; make isearch-string valid |
;; make isearch-string valid |
1147 |
(not isearch-regexp)) |
isearch-regexp |
1148 |
nil |
;; If the string was found but was completely invisible, |
1149 |
|
;; it might now be partly visible, so try again. |
1150 |
|
(prog1 isearch-hidden (setq isearch-hidden nil))) |
1151 |
;; In reverse search, adding stuff at |
;; In reverse search, adding stuff at |
1152 |
;; the end may cause zero or many more chars to be |
;; the end may cause zero or many more chars to be |
1153 |
;; matched, in the string following point. |
;; matched, in the string following point. |
1163 |
(regexp-quote isearch-string)))) |
(regexp-quote isearch-string)))) |
1164 |
(error nil)) |
(error nil)) |
1165 |
(or isearch-yank-flag |
(or isearch-yank-flag |
1166 |
(<= (match-end 0) |
(<= (match-end 0) |
1167 |
(min isearch-opoint isearch-barrier)))) |
(min isearch-opoint isearch-barrier)))) |
1168 |
(progn |
(progn |
1169 |
(setq isearch-success t |
(setq isearch-success t |
1170 |
isearch-invalid-regexp nil |
isearch-invalid-regexp nil |
1171 |
isearch-within-brackets nil |
isearch-within-brackets nil |
1172 |
isearch-other-end (match-end 0)) |
isearch-other-end (match-end 0)) |
1176 |
;; Not regexp, not reverse, or no match at point. |
;; Not regexp, not reverse, or no match at point. |
1177 |
(if (and isearch-other-end (not isearch-adjusted)) |
(if (and isearch-other-end (not isearch-adjusted)) |
1178 |
(goto-char (if isearch-forward isearch-other-end |
(goto-char (if isearch-forward isearch-other-end |
1179 |
(min isearch-opoint |
(min isearch-opoint |
1180 |
isearch-barrier |
isearch-barrier |
1181 |
(1+ isearch-other-end))))) |
(1+ isearch-other-end))))) |
1182 |
(isearch-search) |
(isearch-search) |
1183 |
)) |
)) |
1195 |
(defun isearch-*-char () |
(defun isearch-*-char () |
1196 |
"Handle * and ? specially in regexps." |
"Handle * and ? specially in regexps." |
1197 |
(interactive) |
(interactive) |
1198 |
(if isearch-regexp |
(if isearch-regexp |
1199 |
(let ((idx (length isearch-string))) |
(let ((idx (length isearch-string))) |
1200 |
(while (and (> idx 0) |
(while (and (> idx 0) |
1201 |
(eq (aref isearch-string (1- idx)) ?\\)) |
(eq (aref isearch-string (1- idx)) ?\\)) |
1214 |
(max cs isearch-barrier) |
(max cs isearch-barrier) |
1215 |
(min cs isearch-barrier))))))) |
(min cs isearch-barrier))))))) |
1216 |
(isearch-process-search-char last-command-char)) |
(isearch-process-search-char last-command-char)) |
1217 |
|
|
1218 |
|
|
1219 |
(defun isearch-|-char () |
(defun isearch-|-char () |
1220 |
"If in regexp search, jump to the barrier." |
"If in regexp search, jump to the barrier." |
1301 |
(when (and (> (length key) 1) |
(when (and (> (length key) 1) |
1302 |
(symbolp (aref key 0)) |
(symbolp (aref key 0)) |
1303 |
(listp (aref key 1)) |
(listp (aref key 1)) |
1304 |
(not (numberp (posn-point |
(not (numberp (posn-point |
1305 |
(event-start (aref key 1)))))) |
(event-start (aref key 1)))))) |
1306 |
(pop unread-command-events) |
(pop unread-command-events) |
1307 |
(setq main-event (car unread-command-events))) |
(setq main-event (car unread-command-events))) |
1315 |
;; obviously wrong for the case that a down-mouse event |
;; obviously wrong for the case that a down-mouse event |
1316 |
;; on another window invokes this function. The event |
;; on another window invokes this function. The event |
1317 |
;; will contain the window clicked on and that window's |
;; will contain the window clicked on and that window's |
1318 |
;; buffer is certainaly not always in Isearch mode. |
;; buffer is certainly not always in Isearch mode. |
1319 |
;; |
;; |
1320 |
;; Leave the code in, but check for current buffer not |
;; Leave the code in, but check for current buffer not |
1321 |
;; being in Isearch mode for now, until someone tells |
;; being in Isearch mode for now, until someone tells |
1377 |
"Match all whitespace chars, if in regexp mode. |
"Match all whitespace chars, if in regexp mode. |
1378 |
If you want to search for just a space, type \\<isearch-mode-map>\\[isearch-quote-char] SPC." |
If you want to search for just a space, type \\<isearch-mode-map>\\[isearch-quote-char] SPC." |
1379 |
(interactive) |
(interactive) |
1380 |
(if isearch-regexp |
(if isearch-regexp |
1381 |
(if (and search-whitespace-regexp (not isearch-within-brackets) |
(if (and search-whitespace-regexp (not isearch-within-brackets) |
1382 |
(not isearch-invalid-regexp)) |
(not isearch-invalid-regexp)) |
1383 |
(isearch-process-search-string search-whitespace-regexp " ") |
(isearch-process-search-string search-whitespace-regexp " ") |
1391 |
|
|
1392 |
(defun isearch-process-search-char (char) |
(defun isearch-process-search-char (char) |
1393 |
;; Append the char to the search string, update the message and re-search. |
;; Append the char to the search string, update the message and re-search. |
1394 |
(isearch-process-search-string |
(isearch-process-search-string |
1395 |
(char-to-string char) |
(char-to-string char) |
1396 |
(if (>= char ?\200) |
(if (>= char ?\200) |
1397 |
(char-to-string char) |
(char-to-string char) |
1398 |
(isearch-text-char-description char)))) |
(isearch-text-char-description char)))) |
1506 |
(progn |
(progn |
1507 |
(if completion-auto-help |
(if completion-auto-help |
1508 |
(with-output-to-temp-buffer "*Isearch completions*" |
(with-output-to-temp-buffer "*Isearch completions*" |
1509 |
(display-completion-list |
(display-completion-list |
1510 |
(all-completions isearch-string alist)))) |
(all-completions isearch-string alist)))) |
1511 |
t) |
t) |
1512 |
(and completion |
(and completion |
1559 |
(isearch-top-state)) |
(isearch-top-state)) |
1560 |
|
|
1561 |
(defun isearch-push-state () |
(defun isearch-push-state () |
1562 |
(setq isearch-cmds |
(setq isearch-cmds |
1563 |
(cons (list isearch-string isearch-message (point) |
(cons (list isearch-string isearch-message (point) |
1564 |
isearch-success isearch-forward isearch-other-end |
isearch-success isearch-forward isearch-other-end |
1565 |
isearch-word |
isearch-word |
1566 |
isearch-invalid-regexp isearch-wrapped isearch-barrier |
isearch-invalid-regexp isearch-wrapped isearch-barrier |
1567 |
isearch-within-brackets isearch-case-fold-search) |
isearch-within-brackets isearch-case-fold-search) |
1620 |
""))) |
""))) |
1621 |
|
|
1622 |
|
|
1623 |
;;; Searching |
;; Searching |
1624 |
|
|
1625 |
|
(defvar isearch-search-fun-function nil "Override `isearch-function-fun'.") |
1626 |
|
|
1627 |
|
(defun isearch-search-fun () |
1628 |
|
"Return the function to use for the search. |
1629 |
|
Can be changed via `isearch-search-fun-function' for special needs." |
1630 |
|
(if isearch-search-fun-function |
1631 |
|
(funcall isearch-search-fun-function) |
1632 |
|
(cond |
1633 |
|
(isearch-word |
1634 |
|
(if isearch-forward 'word-search-forward 'word-search-backward)) |
1635 |
|
(isearch-regexp |
1636 |
|
(if isearch-forward 're-search-forward 're-search-backward)) |
1637 |
|
(t |
1638 |
|
(if isearch-forward 'search-forward 'search-backward))))) |
1639 |
|
|
1640 |
(defun isearch-search () |
(defun isearch-search () |
1641 |
;; Do the search with the current search string. |
;; Do the search with the current search string. |
1653 |
(while retry |
(while retry |
1654 |
(setq isearch-success |
(setq isearch-success |
1655 |
(funcall |
(funcall |
1656 |
(cond (isearch-word |
(isearch-search-fun) |
|
(if isearch-forward |
|
|
'word-search-forward 'word-search-backward)) |
|
|
(isearch-regexp |
|
|
(if isearch-forward |
|
|
're-search-forward 're-search-backward)) |
|
|
(t |
|
|
(if isearch-forward 'search-forward 'search-backward))) |
|
1657 |
isearch-string nil t)) |
isearch-string nil t)) |
1658 |
;; Clear RETRY unless we matched some invisible text |
;; Clear RETRY unless we matched some invisible text |
1659 |
;; and we aren't supposed to do that. |
;; and we aren't supposed to do that. |
1672 |
(quit (isearch-unread ?\C-g) |
(quit (isearch-unread ?\C-g) |
1673 |
(setq isearch-success nil)) |
(setq isearch-success nil)) |
1674 |
|
|
1675 |
(invalid-regexp |
(invalid-regexp |
1676 |
(setq isearch-invalid-regexp (car (cdr lossage))) |
(setq isearch-invalid-regexp (car (cdr lossage))) |
1677 |
(setq isearch-within-brackets (string-match "\\`Unmatched \\[" |
(setq isearch-within-brackets (string-match "\\`Unmatched \\[" |
1678 |
isearch-invalid-regexp)) |
isearch-invalid-regexp)) |
1692 |
(goto-char (nth 2 (car isearch-cmds))))) |
(goto-char (nth 2 (car isearch-cmds))))) |
1693 |
|
|
1694 |
|
|
1695 |
;;; Called when opening an overlay, and we are still in isearch. |
;; Called when opening an overlay, and we are still in isearch. |
1696 |
(defun isearch-open-overlay-temporary (ov) |
(defun isearch-open-overlay-temporary (ov) |
1697 |
(if (not (null (overlay-get ov 'isearch-open-invisible-temporary))) |
(if (not (null (overlay-get ov 'isearch-open-invisible-temporary))) |
1698 |
;; Some modes would want to open the overlays temporary during |
;; Some modes would want to open the overlays temporary during |
1699 |
;; isearch in their own way, they should set the |
;; isearch in their own way, they should set the |
1700 |
;; `isearch-open-invisible-temporary' to a function doing this. |
;; `isearch-open-invisible-temporary' to a function doing this. |
1712 |
(overlay-put ov 'intangible nil))) |
(overlay-put ov 'intangible nil))) |
1713 |
|
|
1714 |
|
|
1715 |
;;; This is called at the end of isearch. It will open the overlays |
;; This is called at the end of isearch. It will open the overlays |
1716 |
;;; that contain the latest match. Obviously in case of a C-g the |
;; that contain the latest match. Obviously in case of a C-g the |
1717 |
;;; point returns to the original location which surely is not contain |
;; point returns to the original location which surely is not contain |
1718 |
;;; in any of these overlays, se we are safe in this case too. |
;; in any of these overlays, se we are safe in this case too. |
1719 |
(defun isearch-open-necessary-overlays (ov) |
(defun isearch-open-necessary-overlays (ov) |
1720 |
(let ((inside-overlay (and (> (point) (overlay-start ov)) |
(let ((inside-overlay (and (> (point) (overlay-start ov)) |
1721 |
(< (point) (overlay-end ov)))) |
(< (point) (overlay-end ov)))) |
1722 |
;; If this exists it means that the overlay was opened using |
;; If this exists it means that the overlay was opened using |
1723 |
;; this function, not by us tweaking the overlay properties. |
;; this function, not by us tweaking the overlay properties. |
1734 |
(if fct-temp |
(if fct-temp |
1735 |
(funcall fct-temp ov t))))) |
(funcall fct-temp ov t))))) |
1736 |
|
|
1737 |
;;; This is called when exiting isearch. It closes the temporary |
;; This is called when exiting isearch. It closes the temporary |
1738 |
;;; opened overlays, except the ones that contain the latest match. |
;; opened overlays, except the ones that contain the latest match. |
1739 |
(defun isearch-clean-overlays () |
(defun isearch-clean-overlays () |
1740 |
(when isearch-opened-overlays |
(when isearch-opened-overlays |
1741 |
(mapc 'isearch-open-necessary-overlays isearch-opened-overlays) |
(mapc 'isearch-open-necessary-overlays isearch-opened-overlays) |
1750 |
(and (> end1 start0) (<= end1 end0)))) |
(and (> end1 start0) (<= end1 end0)))) |
1751 |
|
|
1752 |
|
|
1753 |
;;; Verify if the current match is outside of each element of |
;; Verify if the current match is outside of each element of |
1754 |
;;; `isearch-opened-overlays', if so close that overlay. |
;; `isearch-opened-overlays', if so close that overlay. |
1755 |
|
|
1756 |
(defun isearch-close-unnecessary-overlays (begin end) |
(defun isearch-close-unnecessary-overlays (begin end) |
1757 |
(let ((overlays isearch-opened-overlays)) |
(let ((overlays isearch-opened-overlays)) |
1773 |
|
|
1774 |
(defun isearch-range-invisible (beg end) |
(defun isearch-range-invisible (beg end) |
1775 |
"Return t if all the text from BEG to END is invisible." |
"Return t if all the text from BEG to END is invisible." |
1776 |
(and (/= beg end) |
(when (/= beg end) |
1777 |
;; Check that invisibility runs up to END. |
;; Check that invisibility runs up to END. |
1778 |
(save-excursion |
(save-excursion |
1779 |
(goto-char beg) |
(goto-char beg) |
1780 |
(let ( |
(let (;; can-be-opened keeps track if we can open some overlays. |
1781 |
;; can-be-opened keeps track if we can open some overlays. |
(can-be-opened (eq search-invisible 'open)) |
1782 |
(can-be-opened (eq search-invisible 'open)) |
;; the list of overlays that could be opened |
1783 |
;; the list of overlays that could be opened |
(crt-overlays nil)) |
1784 |
(crt-overlays nil)) |
(when (and can-be-opened isearch-hide-immediately) |
1785 |
(when (and can-be-opened isearch-hide-immediately) |
(isearch-close-unnecessary-overlays beg end)) |
1786 |
(isearch-close-unnecessary-overlays beg end)) |
;; If the following character is currently invisible, |
1787 |
;; If the following character is currently invisible, |
;; skip all characters with that same `invisible' property value. |
1788 |
;; skip all characters with that same `invisible' property value. |
;; Do that over and over. |
1789 |
;; Do that over and over. |
(while (and (< (point) end) |
1790 |
(while (and (< (point) end) |
(let ((prop |
1791 |
(let ((prop |
(get-char-property (point) 'invisible))) |
1792 |
(get-char-property (point) 'invisible))) |
(if (eq buffer-invisibility-spec t) |
1793 |
(if (eq buffer-invisibility-spec t) |
prop |
1794 |
prop |
(or (memq prop buffer-invisibility-spec) |
1795 |
(or (memq prop buffer-invisibility-spec) |
(assq prop buffer-invisibility-spec))))) |
1796 |
(assq prop buffer-invisibility-spec))))) |
(if (get-text-property (point) 'invisible) |
1797 |
(if (get-text-property (point) 'invisible) |
(progn |
1798 |
(progn |
(goto-char (next-single-property-change (point) 'invisible |
1799 |
(goto-char (next-single-property-change (point) 'invisible |
nil end)) |
1800 |
nil end)) |
;; if text is hidden by an `invisible' text property |
1801 |
;; if text is hidden by an `invisible' text property |
;; we cannot open it at all. |
1802 |
;; we cannot open it at all. |
(setq can-be-opened nil)) |
1803 |
(setq can-be-opened nil)) |
(when can-be-opened |
1804 |
(unless (null can-be-opened) |
(let ((overlays (overlays-at (point))) |
1805 |
(let ((overlays (overlays-at (point))) |
ov-list |
1806 |
ov-list |
o |
1807 |
o |
invis-prop) |
1808 |
invis-prop) |
(while overlays |
1809 |
(while overlays |
(setq o (car overlays) |
1810 |
(setq o (car overlays) |
invis-prop (overlay-get o 'invisible)) |
1811 |
invis-prop (overlay-get o 'invisible)) |
(if (if (eq buffer-invisibility-spec t) |
1812 |
(if (if (eq buffer-invisibility-spec t) |
invis-prop |
1813 |
invis-prop |
(or (memq invis-prop buffer-invisibility-spec) |
1814 |
(or (memq invis-prop buffer-invisibility-spec) |
(assq invis-prop buffer-invisibility-spec))) |
1815 |
(assq invis-prop buffer-invisibility-spec))) |
(if (overlay-get o 'isearch-open-invisible) |
1816 |
(if (overlay-get o 'isearch-open-invisible) |
(setq ov-list (cons o ov-list)) |
1817 |
(setq ov-list (cons o ov-list)) |
;; We found one overlay that cannot be |
1818 |
;; We found one overlay that cannot be |
;; opened, that means the whole chunk |
1819 |
;; opened, that means the whole chunk |
;; cannot be opened. |
1820 |
;; cannot be opened. |
(setq can-be-opened nil))) |
1821 |
(setq can-be-opened nil))) |
(setq overlays (cdr overlays))) |
1822 |
(setq overlays (cdr overlays))) |
(if can-be-opened |
1823 |
(if can-be-opened |
;; It makes sense to append to the open |
1824 |
;; It makes sense to append to the open |
;; overlays list only if we know that this is |
1825 |
;; overlays list only if we know that this is |
;; t. |
1826 |
;; t. |
(setq crt-overlays (append ov-list crt-overlays))))) |
1827 |
(setq crt-overlays (append ov-list crt-overlays))))) |
(goto-char (next-overlay-change (point))))) |
1828 |
(goto-char (next-overlay-change (point))))) |
;; See if invisibility reaches up thru END. |
1829 |
;; See if invisibility reaches up thru END. |
(if (>= (point) end) |
1830 |
(if (>= (point) end) |
(if (and can-be-opened (consp crt-overlays)) |
1831 |
(if (and (not (null can-be-opened)) (consp crt-overlays)) |
(progn |
1832 |
(progn |
(setq isearch-opened-overlays |
1833 |
(setq isearch-opened-overlays |
(append isearch-opened-overlays crt-overlays)) |
1834 |
(append isearch-opened-overlays crt-overlays)) |
(mapc 'isearch-open-overlay-temporary crt-overlays) |
1835 |
(mapc 'isearch-open-overlay-temporary crt-overlays) |
nil) |
1836 |
nil) |
(setq isearch-hidden t))))))) |
|
t)))))) |
|
1837 |
|
|
1838 |
|
|
1839 |
;;; Highlighting |
;; Highlighting |
1840 |
|
|
1841 |
(defvar isearch-overlay nil) |
(defvar isearch-overlay nil) |
1842 |
|
|
1858 |
(delete-overlay isearch-overlay))) |
(delete-overlay isearch-overlay))) |
1859 |
|
|
1860 |
|
|
1861 |
;;; General utilities |
;; General utilities |
1862 |
|
|
1863 |
|
|
1864 |
(defun isearch-no-upper-case-p (string regexp-flag) |
(defun isearch-no-upper-case-p (string regexp-flag) |
1865 |
"Return t if there are no upper case chars in STRING. |
"Return t if there are no upper case chars in STRING. |
1866 |
If REGEXP-FLAG is non-nil, disregard letters preceded by `\\' (but not `\\\\') |
If REGEXP-FLAG is non-nil, disregard letters preceded by `\\' (but not `\\\\') |
1867 |
since they have special meaning in a regexp." |
since they have special meaning in a regexp." |
1868 |
(let (quote-flag (i 0) (len (length string)) found) |
(let (quote-flag (i 0) (len (length string)) found) |
1869 |
(while (and (not found) (< i len)) |
(while (and (not found) (< i len)) |
1870 |
(let ((char (aref string i))) |
(let ((char (aref string i))) |
1871 |
(if (and regexp-flag (eq char ?\\)) |
(if (and regexp-flag (eq char ?\\)) |
1872 |
(setq quote-flag (not quote-flag)) |
(setq quote-flag (not quote-flag)) |
1873 |
(if (and (not quote-flag) (not (eq char (downcase char)))) |
(if (and (not quote-flag) (not (eq char (downcase char)))) |
1874 |
(setq found t)))) |
(setq found t)) |
1875 |
|
(setq quote-flag nil))) |
1876 |
(setq i (1+ i))) |
(setq i (1+ i))) |
1877 |
(not found))) |
(not found))) |
1878 |
|
|
1892 |
(append char-or-events unread-command-events))) |
(append char-or-events unread-command-events))) |
1893 |
|
|
1894 |
|
|
1895 |
;;; isearch-lazy-highlight feature |
;; isearch-lazy-highlight feature |
1896 |
;;; by Bob Glickstein <http://www.zanshin.com/~bobg/> |
;; by Bob Glickstein <http://www.zanshin.com/~bobg/> |
1897 |
|
|
1898 |
;;; When active, *every* match for the current search string is |
;; When active, *every* match for the current search string is |
1899 |
;;; highlighted: the current one using the normal isearch match color |
;; highlighted: the current one using the normal isearch match color |
1900 |
;;; and all the others using `isearch-lazy-highlight-face'. The extra |
;; and all the others using `isearch-lazy-highlight-face'. The extra |
1901 |
;;; highlighting makes it easier to anticipate where the cursor will |
;; highlighting makes it easier to anticipate where the cursor will |
1902 |
;;; land each time you press C-s or C-r to repeat a pending search. |
;; land each time you press C-s or C-r to repeat a pending search. |
1903 |
;;; Highlighting of these additional matches happens in a deferred |
;; Highlighting of these additional matches happens in a deferred |
1904 |
;;; fashion using "idle timers," so the cycles needed do not rob |
;; fashion using "idle timers," so the cycles needed do not rob |
1905 |
;;; isearch of its usual snappy response. |
;; isearch of its usual snappy response. |
1906 |
|
|
1907 |
;;; IMPLEMENTATION NOTE: This depends on some isearch internals. |
;; IMPLEMENTATION NOTE: This depends on some isearch internals. |
1908 |
;;; Specifically: |
;; Specifically: |
1909 |
;;; - `isearch-update' is expected to be called (at least) every time |
;; - `isearch-update' is expected to be called (at least) every time |
1910 |
;;; the search string or window-start changes; |
;; the search string or window-start changes; |
1911 |
;;; - `isearch-string' is expected to contain the current search |
;; - `isearch-string' is expected to contain the current search |
1912 |
;;; string as entered by the user; |
;; string as entered by the user; |
1913 |
;;; - the type of the current search is expected to be given by |
;; - the type of the current search is expected to be given by |
1914 |
;;; `isearch-word' and `isearch-regexp'; |
;; `isearch-word' and `isearch-regexp'; |
1915 |
;;; - the direction of the current search is expected to be given by |
;; - the direction of the current search is expected to be given by |
1916 |
;;; `isearch-forward'; |
;; `isearch-forward'; |
1917 |
;;; - the variable `isearch-invalid-regexp' is expected to be true |
;; - the variable `isearch-invalid-regexp' is expected to be true |
1918 |
;;; iff `isearch-string' is an invalid regexp. |
;; iff `isearch-string' is an invalid regexp. |
1919 |
|
|
1920 |
(defgroup isearch-lazy-highlight nil |
(defgroup isearch-lazy-highlight nil |
1921 |
"Lazy highlighting feature for incremental search." |
"Lazy highlighting feature for incremental search." |
2049 |
(defun isearch-lazy-highlight-search () |
(defun isearch-lazy-highlight-search () |
2050 |
"Search ahead for the next or previous match, for lazy highlighting. |
"Search ahead for the next or previous match, for lazy highlighting. |
2051 |
Attempt to do the search exactly the way the pending isearch would." |
Attempt to do the search exactly the way the pending isearch would." |
2052 |
(let ((case-fold-search isearch-case-fold-search) |
(let ((case-fold-search isearch-case-fold-search)) |
2053 |
(choices (cond (isearch-word |
(funcall (isearch-search-fun) |
|
'(word-search-forward . word-search-backward)) |
|
|
(isearch-regexp |
|
|
'(re-search-forward . re-search-backward)) |
|
|
(t |
|
|
'(search-forward . search-backward))))) |
|
|
(funcall (if isearch-forward |
|
|
(car choices) |
|
|
(cdr choices)) |
|
2054 |
isearch-string |
isearch-string |
2055 |
(if isearch-forward |
(if isearch-forward |
2056 |
(if isearch-lazy-highlight-wrapped |
(if isearch-lazy-highlight-wrapped |
2122 |
isearch-message message |
isearch-message message |
2123 |
isearch-case-fold-search case-fold) |
isearch-case-fold-search case-fold) |
2124 |
(isearch-search)) |
(isearch-search)) |
2125 |
|
|
2126 |
;;; isearch.el ends here |
;;; isearch.el ends here |