5

People often recommend on emacs.stackexchange.com and stackoverflow.com (in the Emacs tag) that we should learn to "ask Emacs". The built-in Info-mode is not capable of performing a recursive regexp search that can compete with the likes of grep.

Q:  How can I recursively grep the Emacs manual (i.e., all .info files) with a regexp search?

[Keep in mind that some .info files may be gzipped, whereas others will be unzipped. This largely depends upon the install options specified at the time Emacs is built from source.]


In a related thread on reddit.com, @kaushalmodi made an excellent suggestion to use the ag (aka The Silver Searcher) command-line utility in conjunction with the counsel / ivy / swiper packages, and the following function was provided by said author:

https://www.reddit.com/r/emacs/comments/4vvwr9/grepping_the_info_files_versus_infomode/?ref=share&ref_source=link

(defun counsel-ag-emacs-info (&optional initial-input)
  "Search for a pattern in emacs 'info/' directory using ag.
    INITIAL-INPUT can be given as the initial minibuffer input."
  (interactive)
  (counsel-ag initial-input (car Info-default-directory-list)
              " -z" "Search emacs/elisp info"))
lawlist
  • 18,826
  • 5
  • 37
  • 118
  • When I do need to find things in the manual, I usually find looking in the concept index (which is all on one page, so you can do `C-s` or `M-x occur` there) to be better than finding every occurrence of some word. It should include every _significant_ occurrence, and none of the accidental hits that something like `grep` will find. – MAP Aug 04 '16 at 04:43

2 Answers2

3

The following solution relies upon three (3) command-line utilities: find; xargs; and zgrep. In putting together the following function, I discovered that grep cannot see inside gizipped files, and not all versions of zgrep are able to search recursively. Inasmuch as zgrep can handle both gzipped and unzipped .info files, the function includes a search for both.

On OSX find/xargs/zgrep come pre-installed and they are located in the /usr/bin directory; and, the car of Info-default-directory-list contains the built-in Emacs manual consisting of several .info files:

With some command-line utilities, Emacs may complain about exiting abnormally with code 1. The zgrep results in this case are nevertheless complete, and running the same commands in the terminal works perfectly without any error messages.

Just type: M-x ask-emacs

(defun ask-emacs ()
"Grep the .info files that are in the CAR of `Info-default-directory-list'."
(interactive)
  (let* (
      (search-term (read-string "Ask Emacs (regex):  "))
      (search-path (directory-file-name (car Info-default-directory-list)))
      (default-directory (file-name-as-directory search-path))
      (initial-grep-command "-inIE --color=always -C2")
      (grep-command (concat
        "find"
        " "
        search-path
        " "
        "\\( -name \\*.gz -o -name \\*.info \\)"
        " "
        "-print0"
        " "
        "|"
        " "
        "xargs"
        " "
        "-0"
        " "
        "zgrep"
        " "
        initial-grep-command
        " "
        search-term
        " "
        search-path)) )
   (compilation-start grep-command 'grep-mode (lambda (mode) "*grep*") nil) ))

Example


Link to related source with an example to recursively search using zgrep: https://unix.stackexchange.com/a/187753/92940

lawlist
  • 18,826
  • 5
  • 37
  • 118
  • This searches all the documentation that is available in info format: elisp manual, gcc manual, grub manual… This is not a very useful way to find information about Emacs. – Gilles 'SO- stop being evil' Aug 24 '16 at 20:13
  • @Gilles -- I'm sorry you feel that way, but I respectfully disagree. I invested more than an hour working on this answer and I will be using it for my own personal use in the future. I feel that the inability of Emacs to search all of the .info files (in one fell swoop) leaves Emacs users at a disadvantage. Without this (or other similar approach), we might as well resign ourselves to just using Google and forget about **Asking Emacs**. – lawlist Aug 24 '16 at 20:16
  • @Gilles -- I just looked through `. . ./Emacs.app/Contents/Resources/info` (Emacs built `--with-ns`) and was unable to locate the "gcc manual" or "grub manual". This question and answer relates only to searching the built-in .info manuals that come packaged with Emacs -- i.e., those .info files located in the directory `(car Info-default-directory-list)`. If I want to find all `org-agenda-custom-commands` references in the .info files (that come packaged with Emacs) , for example, then this answer is ideal. – lawlist Aug 24 '16 at 20:38
  • 1
    It depends how your OS is organized. On Windows you'd probably have no info manuals except those bundled with Emacs. But on Linux it's typical to have all the info manuals in the same directory. Picking the first element of `Info-default-directory-list` is a gamble, it may or may not be the directory where the Emacs manuals are. It depends both on the OS and on the user configuration. – Gilles 'SO- stop being evil' Aug 24 '16 at 20:41
1

Another possibility:

In Dired, in a directory in Info-default-directory-list:

  1. Use % g (command dired-mark-files-containing-regexp) to mark the Info files containing matches for your regexp.

  2. M-: (multi-isearch-files-regexp (dired-get-marked-files)), then type your regexp to search for matches (in the Info files that have matches). (You can turn that into a command if you want.)


If you use Icicles then instead of step 2 you can do M-: (icicle-search nil nil (format ".*%s.*" REGEXP) t (dired-get-marked-files)), where REGEXP is your regexp. (You can turn that into a command if you want.)

Completion candidates are the lines with REGEXP matches in the Info files. You can type an input pattern to match any of them. Use C-down to cycle among matches, or use C-RET or C-mouse-2 to access any of the matches individually (i.e., in any order).

If REGEXP itself can match more than one line then use it as is, instead of (format ".*%s.*" REGEXP).

Drew
  • 75,699
  • 9
  • 109
  • 225