From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.devel Subject: Type Ahead Find Date: Fri, 18 Mar 2005 21:45:29 +0200 Organization: JURTA Message-ID: <87k6o4eo2u.fsf@jurta.org> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1111177015 8136 80.91.229.2 (18 Mar 2005 20:16:55 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Fri, 18 Mar 2005 20:16:55 +0000 (UTC) Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Mar 18 21:16:54 2005 Original-Received: from lists.gnu.org ([199.232.76.165]) by ciao.gmane.org with esmtp (Exim 4.43) id 1DCNrv-0006jS-Rd for ged-emacs-devel@m.gmane.org; Fri, 18 Mar 2005 21:14:52 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1DCO8T-0001jJ-Vd for ged-emacs-devel@m.gmane.org; Fri, 18 Mar 2005 15:31:57 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1DCO8C-0001et-KB for emacs-devel@gnu.org; Fri, 18 Mar 2005 15:31:40 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1DCO8B-0001eS-I8 for emacs-devel@gnu.org; Fri, 18 Mar 2005 15:31:40 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1DCO8B-0001eB-GN for emacs-devel@gnu.org; Fri, 18 Mar 2005 15:31:39 -0500 Original-Received: from [194.126.101.98] (helo=MXR-3.estpak.ee) by monty-python.gnu.org with esmtp (Exim 4.34) id 1DCNqM-0003ua-Qu for emacs-devel@gnu.org; Fri, 18 Mar 2005 15:13:15 -0500 Original-Received: from mail.neti.ee (80-235-42-231-dsl.mus.estpak.ee [80.235.42.231]) by MXR-3.estpak.ee (Postfix) with ESMTP id 402E2A9E5C for ; Fri, 18 Mar 2005 22:13:09 +0200 (EET) Original-To: emacs-devel@gnu.org User-Agent: Gnus/5.110002 (No Gnus v0.2) Emacs/22.0.50 (gnu/linux) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org X-MailScanner-To: ged-emacs-devel@m.gmane.org Xref: news.gmane.org gmane.emacs.devel:34742 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:34742 Many modern applications provide a feature called "type-ahead find". In fact, this is rather a poor imitation of Emacs incremental search with many limitations. But it allows to narrow the search only to specific text part (such as e.g. in Firefox typing a ' before the search string searches only links) which is currently not easily implementable in Emacs. However, a simple 4-line change in isearch.el will allow this. The idea is to add a new variable to hold a predicate function which, when called on the new search position, will return nil when the current search point should be skipped. Such a function, when defined, will be used instead of the default `isearch-range-invisible' to allow searching even in hidden parts. One of possible uses of such a variable is to search only references, menu items, indexes and links in Info manuals with simple code like this: (set (make-local-variable 'isearch-success-function) (lambda () (save-match-data (setq isearch-error (or (Info-get-token (point) "[hf]t?tp://" "[hf]t?tp://\\([^ \t\n\"`({<>})']+\\)") (Info-get-token (point) "\\*note[ \n\t]+" "\\*note[ \n\t]+\\([^:]*\\):\\(:\\|[ \n\t]*(\\)?") (Info-get-token (point) "\\* +" "\\* +\\([^:]*\\)::") (Info-get-token (point) "\\* +" "\\* +\\(.*\\): ")))))) It displays the name of the current objects under point in square brackets, so e.g. `C-s gnu' in the top node of the Emacs manual produces: I-search: gnu [GNU Free Documentation License] where `GNU Free Documentation License' is the menu item and node name under the search point. This change will also allow to implement links-only search in the Emacs w3m browser with the following simple code: (set (make-local-variable 'isearch-success-function) (lambda () (save-match-data (setq isearch-error (w3m-anchor))))) which will display a link under the search point in square brackets: I-search: gnu [http://www.gnu.org/] This change has many other possible uses like for example searching only in comments with: (set (make-local-variable 'isearch-success-function) (lambda () (save-match-data (save-excursion (comment-beginning))))) All this can be done with a new variable `isearch-success-function'. In contrast with `isearch-search-fun-function' which mainly is used to widen the search space (e.g. to other Info nodes, etc.), the new variable `isearch-success-function' narrows the standard search space to specific buffer regions. It removes the need to write a complicated search function for `isearch-search-fun-function'. The patch below also fixes lazy highlighting to support `isearch-success-function' with changing `isearch-lazy-highlight-search' to look more like `isearch-search', i.e. to add a similar retry-success while-loop, which also with using of `isearch-range-invisible' (when `isearch-success-function' is nil) reduces the amount of created overlays that currently are created in the hidden text. The test for `(not isearch-error)' was removed from `isearch-lazy-highlight-new-loop' to allow displaying the names in square brackets (`isearch-lazy-highlight-search' takes care about incomplete regexps). There is also a similar change in info.el. The actual code that would use this new variable and user interface for its activating is a separate question. Index: lisp/isearch.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/isearch.el,v retrieving revision 1.261 diff -u -w -b -r1.261 isearch.el --- lisp/isearch.el 18 Mar 2005 09:59:31 -0000 1.261 +++ lisp/isearch.el 18 Mar 2005 19:32:34 -0000 @@ -165,6 +165,9 @@ "Function to save a function restoring the mode-specific isearch state to the search status stack.") +(defvar isearch-success-function nil + "Function to report whether the new search match is considered successful.") + ;; Search ring. (defvar search-ring nil @@ -2056,8 +2059,10 @@ (not isearch-success) (bobp) (eobp) (= (match-beginning 0) (match-end 0)) + (if isearch-success-function + (funcall isearch-success-function) (not (isearch-range-invisible - (match-beginning 0) (match-end 0)))) + (match-beginning 0) (match-end 0))))) (setq retry nil))) (setq isearch-just-started nil) (if isearch-success @@ -2369,7 +2374,6 @@ isearch-lazy-highlight-window-end)))) ;; something important did indeed change (lazy-highlight-cleanup t) ;kill old loop & remove overlays - (when (not isearch-error) (setq isearch-lazy-highlight-start-limit beg isearch-lazy-highlight-end-limit end) (setq isearch-lazy-highlight-window (selected-window) @@ -2384,7 +2388,7 @@ (unless (equal isearch-string "") (setq isearch-lazy-highlight-timer (run-with-idle-timer lazy-highlight-initial-delay nil - 'isearch-lazy-highlight-update)))))) + 'isearch-lazy-highlight-update))))) (defun isearch-lazy-highlight-search () "Search ahead for the next or previous match, for lazy highlighting. @@ -2393,6 +2397,10 @@ (isearch-regexp isearch-lazy-highlight-regexp) (search-spaces-regexp search-whitespace-regexp)) (condition-case nil + (let ((retry t) + (success nil)) + (while retry + (setq success (funcall (isearch-search-fun) isearch-lazy-highlight-last-string (if isearch-forward @@ -2404,7 +2412,14 @@ (if isearch-lazy-highlight-wrapped isearch-lazy-highlight-end (window-start)))) - t) + t)) + (if (or (not success) + (if isearch-success-function + (funcall isearch-success-function) + (not (isearch-range-invisible + (match-beginning 0) (match-end 0))))) + (setq retry nil))) + success) (error nil)))) (defun isearch-lazy-highlight-update () Index: lisp/info.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/info.el,v retrieving revision 1.421 diff -u -r1.421 info.el --- lisp/info.el 16 Mar 2005 07:32:43 -0000 1.421 +++ lisp/info.el 18 Mar 2005 19:33:20 -0000 @@ -1505,9 +1505,11 @@ (while (and (not give-up) (save-match-data (or (null found) - (if backward - (isearch-range-invisible found beg-found) - (isearch-range-invisible beg-found found)) + (if isearch-success-function + (not (funcall isearch-success-function)) + (if backward + (isearch-range-invisible found beg-found) + (isearch-range-invisible beg-found found))) ;; Skip node header line (and (save-excursion (forward-line -1) (looking-at "\^_")) @@ -1593,9 +1595,11 @@ (while (and (not give-up) (save-match-data (or (null found) - (if backward - (isearch-range-invisible found beg-found) - (isearch-range-invisible beg-found found)) + (if isearch-success-function + (not (funcall isearch-success-function)) + (if backward + (isearch-range-invisible found beg-found) + (isearch-range-invisible beg-found found))) ;; Skip node header line (and (save-excursion (forward-line -1) (looking-at "\^_")) -- Juri Linkov http://www.jurta.org/emacs/