Mercurial > emacs
changeset 18236:f249cd470d71
(isearch-hide-immediately): New variable.
(isearch-close-unecessary-overlays): New function.
(isearch-range-invisible): Use them.
(search-invisible): Changed the semantics,
the default value and updated the doc string.
(isearch-opened-overlays): New variable.
(isearch-mode): Initialize it.
(isearch-switch-frame-handler): Call isearch-clean-overlays.
(isearch-exit, isearch-cancel, isearch-abort): Likewise.
(isearch-other-meta-char, isearch-search):
Support the new meaning for search-invisible.
(isearch-open-necessary-overlays, isearch-open-overlay-temporary)
(isearch-clean-overlays): New functions.
(isearch-range-invisible): If we are inside overlays that can be
opened, open them, add them to isearch-opened-overlays and say
that the range is visible.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Fri, 13 Jun 1997 21:30:38 +0000 |
parents | 43ce16d5f31e |
children | 69bb3a2c95b3 |
files | lisp/isearch.el |
diffstat | 1 files changed, 170 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/isearch.el Fri Jun 13 05:49:57 1997 +0000 +++ b/lisp/isearch.el Fri Jun 13 21:30:38 1997 +0000 @@ -161,9 +161,26 @@ :type 'boolean :group 'isearch) -(defvar search-invisible nil - "*Non-nil means incremental search can match text hidden by an overlay. -\(This applies when using `outline.el'.)") +(defcustom search-invisible 'open + "If t incremental search can match hidden text. +nil means don't match invisible text. +If the value is `open', if the text matched is made invisible by +an overlay having an `invisible' property and that overlay has a property +`isearch-open-invisible', then incremental search will show the contents. +\(This applies when using `outline.el' and `hideshow.el'.)" + :type '(choice (const :tag "Match hidden text" t) + (const :tag "Open overlays" open) + (const :tag "Don't match hidden text" t)) + :group 'isearch) + +(defcustom isearch-hide-immediately t + "If t hide the previous match if needed. +This has efect iff `search-invisible' is set to `open' and it means +that if the current match is out of one of the previously shown +regions hide is right away, as opposed to hiding it at the end of +isearch." + :type 'boolean + :group 'isearch) (defvar isearch-mode-hook nil "Function(s) to call after starting up an incremental search.") @@ -368,6 +385,8 @@ ;; New value of isearch-forward after isearch-edit-string. (defvar isearch-new-forward nil) +;; Accumulate here the overlays opened during searching. +(defvar isearch-opened-overlays nil) ;; Minor-mode-alist changes - kind of redundant with the ;; echo area, but if isearching in multiple windows, it can be useful. @@ -505,6 +524,7 @@ isearch-opoint (point) search-ring-yank-pointer nil + isearch-opened-overlays nil regexp-search-ring-yank-pointer nil) (looking-at "") (setq isearch-window-configuration @@ -640,6 +660,7 @@ (interactive) ;; Is this necessary? ;; First terminate isearch-mode. (isearch-done) + (isearch-clean-overlays) (handle-switch-frame (car (cdr (isearch-last-command-char))))) @@ -655,7 +676,8 @@ (= 0 (length isearch-string))) (let ((isearch-nonincremental t)) (isearch-edit-string))) - (isearch-done)) + (isearch-done) + (isearch-clean-overlays)) (defun isearch-edit-string () @@ -815,6 +837,7 @@ (interactive) (goto-char isearch-opoint) (isearch-done t) + (isearch-clean-overlays) (signal 'quit nil)) ; and pass on quit signal (defun isearch-abort () @@ -830,6 +853,7 @@ (progn (goto-char isearch-opoint) (setq isearch-success nil) (isearch-done t) ; exit isearch + (isearch-clean-overlays) (signal 'quit nil)) ; and pass on quit signal ;; If search is failing, or has an incomplete regexp, ;; rub out until it is once more successful. @@ -1122,8 +1146,10 @@ (windowp window)) (save-excursion (set-buffer (window-buffer window)) - (isearch-done)) - (isearch-done)))) + (isearch-done) + (isearch-clean-overlays)) + (isearch-done) + (isearch-clean-overlays)))) (t;; otherwise nil (isearch-process-search-string key key))))) @@ -1420,7 +1446,7 @@ isearch-string nil t)) ;; Clear RETRY unless we matched some invisible text ;; and we aren't supposed to do that. - (if (or search-invisible + (if (or (eq search-invisible t) (not isearch-success) (bobp) (eobp) (= (match-beginning 0) (match-end 0)) @@ -1454,28 +1480,150 @@ (ding)) (goto-char (nth 2 (car isearch-cmds))))) + +;;; Called when opening an overlay, and we are still in isearch. +(defun isearch-open-overlay-temporary (ov) + (message "temporary called") + (if (not (null (overlay-get ov 'isearch-open-invisible-temporary))) + ;; Some modes would want to open the overlays temporary during + ;; isearch in their own way, they should set the + ;; `isearch-open-invisible-temporary' to a function doing this. + (funcall (overlay-get ov 'isearch-open-invisible-temporary) ov nil) + ;; Store the values for the `invisible' and `intangible' + ;; properties, and then set them to nil. This way the text hidden + ;; by this overlay becomes visible. + + ;; Do we realy need to set the `intangible' property to t? Can we + ;; have the point inside an overlay with an `intangible' property? + ;; In 19.34 this does not exist so I cannot test it. + (overlay-put ov 'isearch-invisible (overlay-get ov 'invisible)) + (overlay-put ov 'isearch-intangible (overlay-get ov 'intangible)) + (overlay-put ov 'invisible nil) + (overlay-put ov 'intangible nil))) + + +;;; This is called at the end of isearch. I will open the overlays +;;; that contain the latest match. Obviously in case of a C-g the +;;; point returns to the original location which surely is not contain +;;; in any of these overlays, se we are safe in this case too. +(defun isearch-open-necessary-overlays (ov) + (let ((inside-overlay (and (> (point) (overlay-start ov)) + (< (point) (overlay-end ov)))) + ;; If this exists it means that the overlay was opened using + ;; this function, not by us tweaking the overlay properties. + (fct-temp (overlay-get ov 'isearch-open-invisible-temporary))) + (when (or inside-overlay (not fct-temp)) + ;; restore the values for the `invisible' and `intangible' + ;; properties + (overlay-put ov 'invisible (overlay-get ov 'isearch-invisible)) + (overlay-put ov 'intangible (overlay-get ov 'isearch-intangible)) + (overlay-put ov 'isearch-invisible nil) + (overlay-put ov 'isearch-intangible nil)) + (if inside-overlay + (funcall (overlay-get ov 'isearch-open-invisible) ov) + (if fct-temp + (funcall fct-temp ov t))))) + +;;; This is called when exiting isearch. It closes the temporary +;;; opened overlays, except the ones that contain the latest match. +(defun isearch-clean-overlays () + (when isearch-opened-overlays + ;; Use a cycle instead of a mapcar here? + (mapcar + (function isearch-open-necessary-overlays) isearch-opened-overlays) + (setq isearch-opened-overlays nil))) + +;;; Verify if the current match is outside of each element of +;;; `isearch-opened-overlays', if so close that overlay. +(defun isearch-close-unecessary-overlays (begin end) + (let ((ov-list isearch-opened-overlays) + ov + inside-overlay + fct-temp) + (setq isearch-opened-overlays nil) + (while ov-list + (setq ov (car ov-list)) + (setq ov-list (cdr ov-list)) + (setq inside-overlay (or (and (> begin (overlay-start ov)) + (< begin (overlay-end ov))) + (and (> end (overlay-start ov)) + (< end (overlay-end ov))))) + ;; If this exists it means that the overlay was opened using + ;; this function, not by us tweaking the overlay properties. + (setq fct-temp (overlay-get ov 'isearch-open-invisible-temporary)) + (if inside-overlay + (setq isearch-opened-overlays (cons ov isearch-opened-overlays)) + (if fct-temp + (funcall fct-temp ov t) + (overlay-put ov 'invisible (overlay-get ov 'isearch-invisible)) + (overlay-put ov 'intangible (overlay-get ov 'isearch-intangible)) + (overlay-put ov 'isearch-invisible nil) + (overlay-put ov 'isearch-intangible nil)))))) + (defun isearch-range-invisible (beg end) "Return t if all the bext from BEG to END is invisible." (and (/= beg end) ;; Check that invisibility runs up to END. (save-excursion (goto-char beg) - ;; If the following character is currently invisible, - ;; skip all characters with that same `invisible' property value. - ;; Do that over and over. - (while (and (< (point) end) - (let ((prop - (get-char-property (point) 'invisible))) - (if (eq buffer-invisibility-spec t) - prop - (or (memq prop buffer-invisibility-spec) - (assq prop buffer-invisibility-spec))))) - (if (get-text-property (point) 'invisible) - (goto-char (next-single-property-change (point) 'invisible - nil end)) - (goto-char (next-overlay-change (point))))) + (let + ;; can-be-opened keeps track if we can open some overlays. + ((can-be-opened (eq search-invisible 'open)) + ;; the list of overlays that could be opened + (crt-overlays nil)) + (when (and can-be-opened isearch-hide-immediately) + (isearch-close-unecessary-overlays beg end)) + ;; If the following character is currently invisible, + ;; skip all characters with that same `invisible' property value. + ;; Do that over and over. + (while (and (< (point) end) + (let ((prop + (get-char-property (point) 'invisible))) + (if (eq buffer-invisibility-spec t) + prop + (or (memq prop buffer-invisibility-spec) + (assq prop buffer-invisibility-spec))))) + (if (get-text-property (point) 'invisible) + (progn + (goto-char (next-single-property-change (point) 'invisible + nil end)) + ;; if text is hidden by an `invisible' text property + ;; we cannot open it at all. + (setq can-be-opened nil)) + (unless (null can-be-opened) + (let ((overlays (overlays-at (point))) + ov-list + o + invis-prop) + (while overlays + (setq o (car overlays) + invis-prop (overlay-get o 'invisible)) + (if (or (memq invis-prop buffer-invisibility-spec) + (assq invis-prop buffer-invisibility-spec)) + (if (overlay-get o 'isearch-open-invisible) + (setq ov-list (cons o ov-list)) + ;; We found one overlay that cannot be + ;; opened, that means the whole chunk + ;; cannot be opened. + (setq can-be-opened nil))) + (setq overlays (cdr overlays))) + (if can-be-opened + ;; It makes sense to append to the open + ;; overlays list only if we know that this is + ;; t. + (setq crt-overlays (append ov-list crt-overlays)))) + (goto-char (next-overlay-change (point)))))) ;; See if invisibility reaches up thru END. - (>= (point) end)))) + (if (>= (point) end) + (if (and (not (null can-be-opened)) (consp crt-overlays)) + (progn + (setq isearch-opened-overlays + (append isearch-opened-overlays crt-overlays)) + ;; maybe use a cycle instead of mapcar? + (mapcar (function isearch-open-overlay-temporary) + crt-overlays) + nil) + t)))))) ;;; Highlighting