>>>>> "RC" == Robert J Chassell <[EMAIL PROTECTED]> writes:

    RC> "Bradley M. Kuhn" <[EMAIL PROTECTED]> writes:

    RC>    * I would like a feature that works similar to
    RC>      what M-x grep would give me for searching a man
    RC>      page.  I have never been able to find one in
    RC>      the Emacs browser.  Basically, I'd like to
    RC>      search an info file for a particular string of
    RC>      text, and see a context of where they appear,
    RC>      and be able to browse via C-x ` for each
    RC>      location (like one does for grep's and
    RC>      compiles).

    RC> This is a great idea!  I, too, would like it. 

I believe info-grep.el below does what is requested.

This is not at all a polished code. I'm just throwing out
some ideas hoping that emacs gurus on this list might
improve upon this.

If people like this idea, I'll submit this to gnu.emacs.sources
later.  Feedback would be appreciated.

I tested this on GNU Emacs 20.6 on Debian GNU/Linux.

;;; info-grep.el --- easier interface to `M-x grep' for info files

;; Copyright (c) 2000 Richard Y. Kim

;; Author: Richard Y. Kim, <[EMAIL PROTECTED]>
;; Maintainer: Richard Y. Kim, <[EMAIL PROTECTED]>
;; Created: Sat Jun 17 01:40:49 2000
;; Version: $Id: info-grep.el,v 1.3 2000/06/17 09:21:52 ryk Exp $
;; Keywords:

;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of
;; the License, or (at your option) any later version.

;; This program is distributed in the hope that it will be
;; useful, but WITHOUT ANY WARRANTY; without even the implied
;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
;; PURPOSE.  See the GNU General Public License for more details.

;; You should have received a copy of the GNU General Public
;; License along with this program; if not, write to the Free
;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
;; MA 02111-1307 USA

;;; Commentary:

;;    This provides Info-grep command which is a wrapper around the
;;    built-in `M-x grep' command for easier use for info
;;    files. Info-grep takes one regexp argument.  It then figures out
;;    the proper command-line arguments to pass along to the `grep'
;;    command.  The search result appears in the *grep* buffer which
;;    can be stepped via the `M-x next-error' command in the
;;    usual manner.
;;
;;    The biggest flaw in the code is that it does not handle
;;    compressed files.  Is there a version of grep program that
;;    uncompresses files like the "z" option to the `tar' command?
;;
;;    Info file names with spaces won't work.
;;
;;    Using Info-grep on the "dir" file does *not* result in
;;    searching all info files!
;;
;;    Color highlighting the matched regexp in the info buffer might
;;    be useful in the future.

;;; Change Log:
;;;
;;; 1.3 - first release to [EMAIL PROTECTED] list.

;;; Code:

(eval-after-load "info"
  '(let ()
     (define-key Info-mode-map "G" 'Info-grep)))

(defun Info-grep (regexp)
  "Grep the current info file for REGEXP.
For split info files, this searches all split files.
Unfortunately, compressed files are not supported yet."
  (interactive
   (list (read-string "Regexp to grep: "
                      Info-last-search nil Info-last-search)))
  (let ((file (Info-locate-file Info-current-file t)))
    ;;(widen)
    ;;(Info-goto-node "*")
    (grep (format "grep -n -e \"%s\" %s %s" regexp file (concat file "-*")))))

(defadvice next-error (before widen-buffer activate compile)
  "Widen the current buffer since the target line is usually
not in the current buffer."
  (widen))

(defadvice next-error (after select-info-node activate compile)
  "Select the info node the cursor is in."
  (and (eq major-mode 'Info-mode)
       (Info-select-node)))

;; Info-locate-file consists mostly of code ripped out of
;; Info-find-node.  If info-grep.el is deemed useful, then
;; I'll generate a patch to info.el which uses Info-locate-file.
;;
;; Given FILENAME locate actual file name.
;; If FILENAME is "dir", then simply return "dir".
;; If the file is found, then the fullpath name is returned.
;; If not, then nil is returned.
(defun Info-locate-file ( filename &optional fullpath-p )
  (let (temp temp-downcase found)
    (setq filename (substitute-in-file-name filename))
    (if (string= (downcase filename) "dir")
        "dir"
      (let ((dirs (if (string-match "^\\./" filename)
                      ;; If specified name starts with `./'
                      ;; then just try current directory.
                      '("./")
                    (if (file-name-absolute-p filename)
                        ;; No point in searching for an
                        ;; absolute file name
                        '(nil)
                      (if Info-additional-directory-list
                          (append Info-directory-list
                                  Info-additional-directory-list)
                        Info-directory-list)))))
        ;; Search the directory list for file FILENAME.
        (while (and dirs (not found))
          (setq temp (expand-file-name filename (car dirs)))
          (setq temp-downcase
                (expand-file-name (downcase filename) (car dirs)))
          ;; Try several variants of specified name.
          (let ((suffix-list Info-suffix-list))
            (while (and suffix-list (not found))
              (cond ((info-file-exists-p
                      (info-insert-file-contents-1
                       temp (car (car suffix-list))))
                     (setq found (if fullpath-p
                                     (concat temp (car (car suffix-list)))
                                   temp)))
                    ((info-file-exists-p
                      (info-insert-file-contents-1
                       temp-downcase (car (car suffix-list))))
                     (setq found (if fullpath-p
                                     (concat temp-downcase (car (car suffix-list)))))))
              (setq suffix-list (cdr suffix-list))))
          (setq dirs (cdr dirs)))
        found))))

;;This worked at one point, but what I have above is better.
;;This will probably never be used, but it is here as a good
;;example on how to use defadvice for interactive forms.
;;
;;(defadvice grep (before info-mode-support activate compile)
;;  "Grep the current info file."
;;  (interactive
;;   (let ((file (Info-locate-file Info-current-file t))
;;       (regexp (read-string "Regexp: " Info-last-search nil Info-last-search)))
;;     ;;(widen)
;;     (Info-goto-node "*")
;;     (list (format "grep -n -e \"%s\" %s %s" regexp file (concat file "-*"))))))

;;; info-grep.el ends here

Reply via email to