From: Juri Linkov <juri@jurta.org>
To: emacs-devel@gnu.org
Subject: isearch multiple buffers
Date: Sat, 06 Oct 2007 22:52:46 +0300 [thread overview]
Message-ID: <87odfcggvl.fsf@jurta.org> (raw)
Below is a patch that implements a feature allowing isearch to search
multiple files/buffers. I wrote documentation strings and comments
in every new function, so for details please look there.
This general feature is implemented in isearch.el and can be used by other
packages. add-log.el is the first package that uses it, and below is also
a patch for add-log.el that allows C-s to search through a set of all
ChangeLog files in one directory:
Index: lisp/add-log.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/add-log.el,v
retrieving revision 1.196
diff -c -r1.196 add-log.el
*** lisp/add-log.el 20 Sep 2007 14:06:13 -0000 1.196
--- lisp/add-log.el 6 Oct 2007 19:43:40 -0000
***************
*** 760,766 ****
'change-log-resolve-conflict)
(set (make-local-variable 'adaptive-fill-regexp) "\\s *")
(set (make-local-variable 'font-lock-defaults)
! '(change-log-font-lock-keywords t nil nil backward-paragraph)))
;; It might be nice to have a general feature to replace this. The idea I
;; have is a variable giving a regexp matching text which should not be
--- 760,792 ----
'change-log-resolve-conflict)
(set (make-local-variable 'adaptive-fill-regexp) "\\s *")
(set (make-local-variable 'font-lock-defaults)
! '(change-log-font-lock-keywords t nil nil backward-paragraph))
! (add-hook 'isearch-mode-hook 'isearch-buffers-init nil t)
! (set (make-local-variable 'isearch-search-fun-function)
! 'isearch-buffers-search-fun)
! (set (make-local-variable 'isearch-wrap-function)
! 'isearch-buffers-wrap)
! (set (make-local-variable 'isearch-push-state-function)
! 'isearch-buffers-push-state)
! (set (make-local-variable 'isearch-buffers-next-buffer-function)
! 'change-log-isearch-next-buffer))
!
! (defun change-log-isearch-next-buffer (&optional buffer wrap)
! "Return the next buffer for multiple buffers isearch.
! A sequence of buffers is formed by ChangeLog files with decreasing
! numeric file name suffixes in the directory of the initial ChangeLog
! file were isearch was started."
! (let* ((name (change-log-name))
! (files (cons name (sort (file-expand-wildcards (concat name "[-.][0-9]*"))
! (lambda (a b)
! (version< (substring b (length name))
! (substring a (length name)))))))
! (files (if isearch-forward files (reverse files))))
! (find-file-noselect
! (if wrap
! (car files)
! (cadr (member (file-name-nondirectory (buffer-file-name buffer))
! files))))))
;; It might be nice to have a general feature to replace this. The idea I
;; have is a variable giving a regexp matching text which should not be
Index: lisp/isearch.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/isearch.el,v
retrieving revision 1.303
diff -c -r1.303 isearch.el
*** lisp/isearch.el 29 Aug 2007 05:28:05 -0000 1.303
--- lisp/isearch.el 6 Oct 2007 19:48:51 -0000
***************
*** 2035,2042 ****
(if isearch-forward (< pos2 pos1) (> pos2 pos1))))
(setq pos1 pos2)
(set-match-data match-data)))))
! (if pos1
! (goto-char pos1))
pos1))
(defun isearch-search ()
--- 2035,2046 ----
(if isearch-forward (< pos2 pos1) (> pos2 pos1))))
(setq pos1 pos2)
(set-match-data match-data)))))
! (when pos1
! ;; When using multiple buffers isearch, switch to the new buffer here,
! ;; because `save-excursion' above doesn't allow doing it inside funcall.
! (if isearch-buffers-current-buffer
! (switch-to-buffer isearch-buffers-current-buffer))
! (goto-char pos1))
pos1))
(defun isearch-search ()
***************
*** 2243,2248 ****
--- 2247,2344 ----
(setq isearch-hidden t)))))))
\f
+ ;; Search multiple buffers
+
+ (defvar isearch-buffers-current-buffer nil
+ "The buffer where the search currently stays.
+ The value is nil when the search still is in the initial buffer.")
+
+ (defvar isearch-buffers-next-buffer-function nil
+ "Function to call to get the next buffer to search.
+ The first argument of this function is the CURRENT-BUFFER that defined
+ the base buffer relative to which to find the next buffer. When the
+ isearch direction is backward (when isearch-forward is nil), this
+ function should return the previous buffer.
+
+ If the second argument of this function WRAP is non-nil, then it
+ should return the first buffer in a buffer sequence; and for the
+ backward search, it should return the last buffer in a sequence.")
+
+ (defun isearch-buffers-init ()
+ "Set up isearch to search multiple buffers.
+ Intended to be added to `isearch-mode-hook'."
+ (setq isearch-buffers-current-buffer nil))
+
+ (defun isearch-buffers-search-fun ()
+ "Return the proper search function, for isearch in multiple buffers."
+ (lambda (string bound noerror)
+ (let ((search-fun
+ ;; Use standard functions to search within one buffer
+ (cond
+ (isearch-word
+ (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))))
+ found buffer)
+ (or
+ ;; 1. First try searching in the initial buffer
+ (funcall search-fun string bound noerror)
+ ;; 2. If the above search fails, start visiting next/prev buffers
+ ;; successively, and search the string in them. Do this only
+ ;; when bound is nil (i.e. not while lazy-highlighting search
+ ;; strings in the current buffer).
+ (unless bound
+ (if isearch-buffers-current-buffer
+ (condition-case nil
+ (progn
+ (while (not found)
+ (setq buffer (funcall isearch-buffers-next-buffer-function buffer))
+ (with-current-buffer buffer
+ (goto-char (if isearch-forward (point-min) (point-max)))
+ (setq isearch-barrier (point) isearch-opoint (point))
+ ;; After visiting the next/prev buffer search the
+ ;; string in them again, until the function in
+ ;; isearch-buffers-next-buffer-function raises an error
+ ;; at the beginning/end of the buffer list.
+ (setq found (funcall search-fun string bound noerror))))
+ (if buffer (setq isearch-buffers-current-buffer buffer))
+ ;; Return point of the new search result
+ found)
+ ;; Return nil when isearch-buffers-next-buffer-function fails
+ (error nil))
+ (signal 'search-failed (list string "initial buffer"))))))))
+
+ (defun isearch-buffers-wrap ()
+ "Wrap the multiple buffers search when search is failed.
+ Switch buffer to the first buffer for a forward search,
+ or to the last buffer for a backward search.
+ Set `isearch-buffers-current-buffer' to the current buffer to display
+ the isearch suffix message [initial buffer] only when isearch leaves
+ the initial buffer."
+ (if isearch-buffers-current-buffer
+ (progn
+ (switch-to-buffer
+ (funcall isearch-buffers-next-buffer-function (current-buffer) t))
+ (goto-char (if isearch-forward (point-min) (point-max))))
+ (setq isearch-buffers-current-buffer (current-buffer))
+ (setq isearch-wrapped nil)))
+
+ (defun isearch-buffers-push-state ()
+ "Save a function restoring the state of multiple buffers search.
+ Save the current buffer to the additional state parameter in the
+ search status stack."
+ `(lambda (cmd)
+ (isearch-buffers-pop-state cmd ,(current-buffer))))
+
+ (defun isearch-buffers-pop-state (cmd buffer)
+ "Restore the multiple buffers search state.
+ Switch to the buffer restored from the search status stack."
+ (unless (equal buffer (current-buffer))
+ (switch-to-buffer (setq isearch-buffers-current-buffer buffer))))
+
+ \f
;; General utilities
(defun isearch-no-upper-case-p (string regexp-flag)
--
Juri Linkov
http://www.jurta.org/emacs/
next reply other threads:[~2007-10-06 19:52 UTC|newest]
Thread overview: 164+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-06 19:52 Juri Linkov [this message]
2007-10-07 15:37 ` isearch multiple buffers Dan Nicolaescu
2007-10-08 18:03 ` Richard Stallman
2007-10-08 19:18 ` Juri Linkov
2007-10-08 19:59 ` Eric Hanchrow
2007-10-08 22:52 ` Juri Linkov
2007-10-11 9:25 ` Johan Bockgård
2007-10-11 9:45 ` Juri Linkov
2007-10-11 14:14 ` Stefan Monnier
2007-10-11 23:48 ` Juri Linkov
2007-10-11 17:41 ` Richard Stallman
2007-10-11 23:52 ` Juri Linkov
2007-10-12 8:42 ` Johan Bockgård
2007-10-12 15:59 ` Richard Stallman
2007-10-12 16:37 ` Stefan Monnier
2007-10-20 0:08 ` Juri Linkov
2007-10-21 7:26 ` Richard Stallman
2007-10-21 20:37 ` Juri Linkov
2007-10-21 23:39 ` Miles Bader
2007-10-21 23:50 ` Lennart Borgman (gmail)
2007-10-22 0:51 ` Stefan Monnier
2007-10-22 1:01 ` Miles Bader
2007-10-23 7:12 ` Richard Stallman
2007-10-23 8:17 ` David Kastrup
2007-10-23 17:53 ` Richard Stallman
2007-10-23 20:04 ` Eli Zaretskii
2007-10-23 21:44 ` Andreas Schwab
2007-10-24 4:22 ` Eli Zaretskii
2007-10-25 2:10 ` Richard Stallman
2007-10-24 8:33 ` Richard Stallman
2007-10-23 20:01 ` Eli Zaretskii
2007-10-23 23:33 ` Miles Bader
2007-10-24 0:52 ` Stefan Monnier
2007-10-24 4:18 ` Eli Zaretskii
2007-10-24 5:51 ` Stefan Monnier
2007-10-24 19:00 ` Eli Zaretskii
2007-10-24 4:16 ` Eli Zaretskii
2007-10-24 4:51 ` Miles Bader
2007-10-24 18:58 ` Eli Zaretskii
2007-10-24 23:55 ` Miles Bader
2007-10-25 4:15 ` Eli Zaretskii
2007-10-25 6:21 ` Miles Bader
2007-10-25 20:55 ` Juri Linkov
2007-10-25 21:42 ` Eli Zaretskii
2007-10-25 11:02 ` Robert J. Chassell
2007-10-25 22:08 ` Eli Zaretskii
2007-10-26 1:30 ` Robert J. Chassell
2007-10-26 9:32 ` Eli Zaretskii
2007-10-26 10:05 ` Robert J. Chassell
2007-10-29 0:08 ` Michael Olson
2007-10-26 15:16 ` Dan Nicolaescu
2007-10-26 15:32 ` Juanma Barranquero
2007-10-26 15:36 ` David Kastrup
2007-10-26 15:42 ` Juanma Barranquero
2007-10-26 18:42 ` Stefan Monnier
2007-10-26 19:23 ` Eli Zaretskii
2007-10-26 18:52 ` Eli Zaretskii
2007-10-26 18:49 ` Eli Zaretskii
2007-10-26 19:21 ` Eli Zaretskii
2007-10-26 19:41 ` Dan Nicolaescu
2007-10-26 20:01 ` Jason Rumney
2007-10-26 20:19 ` David Kastrup
2007-10-26 20:01 ` Eli Zaretskii
2007-10-26 20:38 ` Stefan Monnier
2007-10-27 13:57 ` Richard Stallman
2007-10-27 15:01 ` Eli Zaretskii
2007-10-28 13:50 ` Richard Stallman
2007-10-27 17:28 ` Dan Nicolaescu
2007-10-27 22:16 ` Eli Zaretskii
2007-10-28 13:50 ` Richard Stallman
2007-10-28 13:50 ` Richard Stallman
2007-10-28 16:45 ` desupporting X10 and old X11 releases (was: Re: isearch multiple buffers) Dan Nicolaescu
2007-10-29 7:30 ` desupporting X10 and old X11 releases Jan Djärv
2007-10-29 19:42 ` Eli Zaretskii
2007-10-30 7:33 ` Jan Djärv
2007-10-29 23:35 ` Richard Stallman
2007-10-30 13:52 ` Ulrich Mueller
2007-10-31 7:46 ` Richard Stallman
2007-10-29 9:21 ` desupporting X10 and old X11 releases (was: Re: isearch multiple buffers) Richard Stallman
2007-10-29 9:21 ` Richard Stallman
2007-10-28 18:38 ` abandon K&R C ?(was: " Dan Nicolaescu
2007-10-29 9:21 ` Richard Stallman
2007-10-29 19:46 ` Eli Zaretskii
2007-10-29 23:41 ` abandon K&R C ? Miles Bader
2007-10-29 7:21 ` isearch multiple buffers Jan Djärv
2007-10-29 23:35 ` Richard Stallman
2007-10-31 3:35 ` remove support for Sun windows (was Re: isearch multiple buffers) Dan Nicolaescu
2007-10-31 23:57 ` Richard Stallman
2007-11-01 3:09 ` Dan Nicolaescu
2007-11-01 7:44 ` isearch multiple buffers Jan Djärv
2007-11-09 8:26 ` List of platforms to delete (was: Re: isearch multiple buffers) Dan Nicolaescu
2007-10-25 6:47 ` isearch multiple buffers martin rudalics
2007-10-25 7:02 ` Miles Bader
2007-10-25 8:26 ` Juanma Barranquero
2007-10-25 11:08 ` David Kastrup
2007-10-25 11:19 ` Juanma Barranquero
2007-10-25 14:03 ` David Kastrup
2007-10-25 14:08 ` Juanma Barranquero
2007-10-25 20:54 ` Juri Linkov
2007-10-25 21:56 ` Juanma Barranquero
2007-10-25 7:45 ` 8.3 filename restriction Kenichi Handa
2007-10-25 10:53 ` tomas
2007-10-25 22:01 ` Eli Zaretskii
2007-10-25 12:36 ` martin rudalics
2007-10-25 22:11 ` Eli Zaretskii
2007-10-25 21:48 ` Eli Zaretskii
2007-10-26 3:48 ` Richard Stallman
2007-10-22 0:33 ` isearch multiple buffers Juri Linkov
2007-10-22 23:48 ` Juri Linkov
2007-10-23 7:12 ` Richard Stallman
2007-10-23 7:12 ` Richard Stallman
2007-10-23 23:59 ` Juri Linkov
2007-10-24 0:32 ` Drew Adams
2007-10-24 16:31 ` buffer order [was: isearch multiple buffers] Drew Adams
2007-10-25 0:47 ` buffer order Miles Bader
2007-10-24 21:33 ` isearch multiple buffers Juri Linkov
2007-10-24 22:52 ` Drew Adams
2007-10-24 8:33 ` Richard Stallman
2007-10-24 21:23 ` Juri Linkov
2007-10-25 9:01 ` Richard Stallman
2007-10-25 20:57 ` Juri Linkov
2007-10-25 21:51 ` Drew Adams
2007-10-26 23:05 ` Juri Linkov
2007-10-27 0:01 ` Lennart Borgman (gmail)
2007-10-27 0:19 ` Drew Adams
2007-10-27 7:22 ` Lennart Borgman (gmail)
2007-10-27 16:20 ` Drew Adams
2007-10-27 22:54 ` Juri Linkov
2007-10-27 23:37 ` Drew Adams
2007-10-28 1:31 ` Juri Linkov
2007-10-28 13:50 ` Richard Stallman
2007-10-28 15:03 ` Juri Linkov
2007-10-29 9:21 ` Richard Stallman
2007-10-27 23:41 ` Richard Stallman
2007-10-28 0:18 ` Drew Adams
2007-10-28 1:32 ` Juri Linkov
2007-10-28 3:22 ` Drew Adams
2007-10-28 4:14 ` Luc Teirlinck
2007-10-28 10:52 ` Juri Linkov
2007-10-27 0:13 ` Drew Adams
2007-10-27 2:10 ` Miles Bader
2007-10-27 2:39 ` Drew Adams
2007-10-27 3:46 ` Miles Bader
2007-10-27 4:29 ` Drew Adams
2007-10-27 23:27 ` Juri Linkov
2007-10-28 0:10 ` Drew Adams
2007-10-28 1:33 ` Juri Linkov
2007-10-27 13:58 ` Richard Stallman
2007-10-27 16:20 ` Drew Adams
2007-10-27 22:47 ` Juri Linkov
2007-10-27 23:26 ` Drew Adams
2007-10-28 13:51 ` Richard Stallman
2007-10-25 9:01 ` Richard Stallman
2007-10-09 20:03 ` Richard Stallman
2008-07-20 0:40 ` Juri Linkov
2008-07-20 4:11 ` Miles Bader
2008-07-20 19:34 ` Juri Linkov
2008-07-20 17:21 ` Richard M Stallman
2008-07-20 19:38 ` Juri Linkov
2008-07-21 3:29 ` Richard M Stallman
2008-07-21 9:07 ` Juri Linkov
2008-07-21 6:53 ` Thomas Link
2008-07-21 9:09 ` Juri Linkov
2008-07-21 10:42 ` Thomas Link
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87odfcggvl.fsf@jurta.org \
--to=juri@jurta.org \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.