From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.devel Subject: isearch hooks (was: query-replace-interactive not documented) Date: Fri, 18 Jun 2004 23:00:09 +0300 Organization: JURTA Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <87d63wy6ux.fsf_-_@mail.jurta.org> References: <20040528.181649.25475113.wl@gnu.org> <200405291737.i4THbPJ06689@raven.dms.auburn.edu> <878yeyczec.fsf@mail.jurta.org> <87n03aa4jk.fsf@mail.jurta.org> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1087589084 16608 80.91.224.253 (18 Jun 2004 20:04:44 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Fri, 18 Jun 2004 20:04:44 +0000 (UTC) Cc: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Fri Jun 18 22:04:37 2004 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1BbPbJ-0008AJ-00 for ; Fri, 18 Jun 2004 22:04:37 +0200 Original-Received: from lists.gnu.org ([199.232.76.165]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1BbPbI-00064a-00 for ; Fri, 18 Jun 2004 22:04:36 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BbPcP-00046W-JS for emacs-devel@quimby.gnus.org; Fri, 18 Jun 2004 16:05:45 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1BbPcL-000445-HS for emacs-devel@gnu.org; Fri, 18 Jun 2004 16:05:41 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1BbPcJ-00042B-SD for emacs-devel@gnu.org; Fri, 18 Jun 2004 16:05:40 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BbPcJ-00041f-PB for emacs-devel@gnu.org; Fri, 18 Jun 2004 16:05:39 -0400 Original-Received: from [66.33.219.19] (helo=spoon.dreamhost.com) by monty-python.gnu.org with esmtp (Exim 4.34) id 1BbPb9-00024A-Cy; Fri, 18 Jun 2004 16:04:27 -0400 Original-Received: from mail.jurta.org (80-235-34-90-dsl.mus.estpak.ee [80.235.34.90]) by spoon.dreamhost.com (Postfix) with ESMTP id 1EAF913D912; Fri, 18 Jun 2004 13:04:25 -0700 (PDT) Original-To: rms@gnu.org In-Reply-To: (Richard Stallman's message of "Fri, 11 Jun 2004 21:50:53 -0400") User-Agent: Gnus/5.110002 (No Gnus v0.2) Emacs/21.3.50 (gnu/linux) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.4 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:25090 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:25090 Juri Linkov writes: > I noticed that the commentary section of isearch.el has the following > TODO item: > > ;; - Think about incorporating query-replace. isearch.el has also another TODO item: ;; - Hooks and options for failed search. I remember there was a discussion on emacs-devel two months ago about searching across several buffers or Info nodes. Adding hooks for failed and wrapped search will allow to implement these features. The patch below adds two hooks `isearch-wrapped-hook' and `isearch-failed-hook'. When these hooks are not specified, isearch keeps its current behavior: when failed, it displays "Failing I-search" message; and when wrapped, it moves the point to the beginning/end of the buffer. But with using these hooks many useful things are possible. For example, to search across Info nodes `isearch-wrapped-hook' can use `Info-search' to move between Info nodes, and `isearch-failed-hook' to move to the next Info node immediately: (add-hook 'Info-mode-hook (lambda () (set (make-local-variable 'isearch-wrapped-hook) (lambda () (Info-search isearch-string (unless isearch-forward 'backward)) (goto-char (if isearch-forward (point-min) (point-max))) (setq isearch-cmds nil))) (set (make-local-variable 'isearch-failed-hook) (lambda () (isearch-repeat (if isearch-forward 'forward 'backward)))))) Another example is isearching multiple buffers: (defvar my-buffer-list nil) (add-hook 'isearch-mode-hook (lambda () (setq my-buffer-list (cdr (buffer-list))))) (add-hook 'isearch-wrapped-hook (lambda () ;; skip buffers with no isearch-string (while (and my-buffer-list (progn (switch-to-buffer (car my-buffer-list)) (goto-char (point-min)) (prog1 (not (re-search-forward isearch-string nil t)) (setq my-buffer-list (cdr my-buffer-list)))))) (goto-char (if isearch-forward (point-min) (point-max))) (setq isearch-cmds nil))) These examples could be developed further to include them into info.el etc. and to make options to enable hooks. Anyway, I think the change which allows to call hooks can be installed now, since it doesn't change the current behavior. Index: lisp/isearch.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/isearch.el,v retrieving revision 1.228 diff -u -r1.228 isearch.el --- lisp/isearch.el 6 Jun 2004 13:57:39 -0000 1.228 +++ lisp/isearch.el 18 Jun 2004 16:15:25 -0000 @@ -57,48 +57,6 @@ ;; keep the behavior. No point in forcing nonincremental search until ;; the last possible moment. -;; TODO -;; - Integrate the emacs 19 generalized command history. -;; - Think about incorporating query-replace. -;; - Hooks and options for failed search. ;;; Change Log: @@ -199,6 +157,15 @@ (defvar isearch-mode-end-hook nil "Function(s) to call after terminating an incremental search.") +(defvar isearch-wrapped-hook nil + "Function(s) to call when search is wrapped. +If nil, move point to the beginning of the buffer for forward search, +or to the end of the buffer for reverse search.") + +(defvar isearch-failed-hook nil + "Function(s) to call when search is failed. +If nil, ding.") + ;; Search ring. (defvar search-ring nil @@ -990,7 +968,9 @@ ;; If already have what to search for, repeat it. (or isearch-success (progn - (goto-char (if isearch-forward (point-min) (point-max))) + (if isearch-wrapped-hook + (run-hooks 'isearch-wrapped-hook) + (goto-char (if isearch-forward (point-min) (point-max)))) (setq isearch-wrapped t)))) ;; C-s in reverse or C-r in forward, change direction. (setq isearch-forward (not isearch-forward))) @@ -1786,6 +1867,7 @@ (or isearch-success (setq ellipsis nil)) (let ((m (concat (if isearch-success "" "failing ") (if (and isearch-wrapped + (not isearch-wrapped-hook) (if isearch-forward (> (point) isearch-opoint) (< (point) isearch-opoint))) @@ -1876,9 +1961,9 @@ (if isearch-success nil ;; Ding if failed this time after succeeding last time. - (and (nth 3 (car isearch-cmds)) - (ding)) - (goto-char (nth 2 (car isearch-cmds))))) + (and (nth 3 (car isearch-cmds)) (or isearch-failed-hook (ding))) + (goto-char (nth 2 (car isearch-cmds))) + (if isearch-failed-hook (run-hooks 'isearch-failed-hook)))) ;; Called when opening an overlay, and we are still in isearch. -- Juri Linkov http://www.jurta.org/emacs/