bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#31807: 27.0; `info-apropos' bad name or bad matching


From: Drew Adams
Subject: bug#31807: 27.0; `info-apropos' bad name or bad matching
Date: Thu, 14 Jun 2018 13:45:38 -0700 (PDT)

> > If you want to keep the current behavior then I'd suggest
> > having two different commands AND, for the one that does
> > literal string matching, change the name to something that
> > does not include "apropos" in the name.
> 
> I'm okay with a new command, but it should have a new name.  How about
> info-apropos-regexp?  The old command must keep its name, for the same
> reason we cannot change its behavior.
> 
> > When I get some time I'll take a closer look.
> 
> Thanks.

Here's the code I've included in my library `info+.el'.

You may want to use it in `info.el'.  Or not.

If you want to rename `info-apropos' here to `info-apropos-regexp', do so.

And you might want other changes, too.  It should be pretty clear what
the essential changes are, versus others that you might not want to make.
(I untabify, I use `add-to-list' for backward compatibility, and I use
a separate window if invoked outside Info.)

HTH.


;; REPLACE ORIGINAL in `info.el':
;;
;; Added optional arg LITERALP.  Use apropos matching, not literal-string 
matching,
;; by default.  Prefix arg matches literally.
;; Use other window, unless already in Info.
;;
(defun info-apropos (pattern &optional literalp)
  "Search indexes of all known Info files on your system for apropos PATTERN.
Build a menu of the possible matches.

With a prefix arg, match PATTERN as a literal string, not as a regexp
or keywords.

Just as for commands such as `apropos', PATTERN can be a word, a list
of words (separated by spaces), or a regexp (using some regexp special
characters).  If it is a word, search for matches for that word as a
substring.  If it is a list of words, search for matches for any
two (or more) of those words."
  (interactive (list (apropos-read-pattern "index entries") current-prefix-arg))
  (apropos-parse-pattern pattern)
  (if (equal apropos-regexp "")
      (Info-find-node Info-apropos-file "Top")
    (let ((nodes  Info-apropos-nodes)
          nodename)
      (while (and nodes  (not (string-match apropos-regexp (nth 1 (car 
nodes)))))
        (setq nodes  (cdr nodes)))
      ;; Use another window, if not already in Info.
      (unless (eq major-mode 'Info-mode) (pop-to-buffer "*info*"))
      (if nodes
          (Info-find-node Info-apropos-file (caar nodes))
        (setq nodename  (format "Index for '%s'" apropos-regexp))
        (push (list nodename
                    apropos-regexp
                    (Info-apropos-matches apropos-regexp (and (not literalp) 
'REGEXP)))
              Info-apropos-nodes)
        (Info-find-node Info-apropos-file nodename)))))


;; REPLACE ORIGINAL in `info.el':
;;
;; Added optional arg REGEXP-P.
;;
(defun Info-apropos-matches (string &optional regexp-p)
  "Collect STRING matches from all known Info files on your system.
Return a list of matches where each element is in the format
\((FILENAME INDEXTEXT NODENAME LINENUMBER)).

Non-nil optional REGEXP-P means interpret STRING as a regexp, instead
of trying to match it literally."
  ;; Emacs 23 has an `interactive' spec here, for no reason.
  (unless (string= string "")
    (let ((pattern       (format "\n\\* +\\([^\n]*\\(%s\\)[^\n]*\\):[ \t]+\
\\([^\n]+\\)\\.\\(?:[ \t\n]*(line +\\([0-9]+\\))\\)?"
                                 (if regexp-p string (regexp-quote string))))
          (ohist         Info-history)
          (ohist-list    Info-history-list)
          (current-node  Info-current-node)
          (current-file  Info-current-file)
          manuals matches node nodes)
      (let ((Info-fontify-maximum-menu-size  nil))
        (Info-directory)
        ;; `current-node' and `current-file' are nil if you invoke 
`info-apropos' as
        ;; the first Info command.  (`info-apropos' loads `info.el'.)  In that 
case,
        ;; use `(DIR)Top', to avoid an error after search is complete.
        (unless current-node (setq current-file  Info-current-file
                                   current-node  Info-current-node))
        (message "Searching indices...")
        (goto-char (point-min))
        (re-search-forward "\\* Menu: *\n" nil t)
        ;; Ensure no duplicates in MANUALS, so the `dolist' runs faster.
        (while (re-search-forward "\\*.*: *(\\([^)]+\\))" nil t)
          (add-to-list 'manuals (match-string 1)))
        (dolist (manual  (nreverse manuals))
          (message "Searching %s" manual)
          (condition-case err
              (if (setq nodes  (Info-index-nodes (Info-find-file manual)))
                  (save-excursion
                    (Info-find-node manual (car nodes))
                    (while
                        (progn
                          (goto-char (point-min))
                          (while (re-search-forward pattern nil t)
                            (let ((entry     (match-string-no-properties 1))
                                  (nodename  (match-string-no-properties 3))
                                  (line      (match-string-no-properties 4)))
                              (add-text-properties
                               (- (match-beginning 2) (match-beginning 1))
                               (- (match-end 2) (match-beginning 1))
                               '(face info-index-match) entry)
                              (setq matches  (cons (list manual entry nodename 
line)
                                                   matches))))
                          (setq nodes  (cdr nodes)
                                node   (car nodes)))
                      (Info-goto-node node))))
            (error (message "%s" (if (eq (car-safe err) 'error) (nth 1 err) 
err))
                   (sit-for 1 t)))))
      (Info-find-node current-file current-node)
      (setq Info-history       ohist
            Info-history-list  ohist-list)
      (message "Searching indices...done")
      (or (nreverse matches)  t))))





reply via email to

[Prev in Thread] Current Thread [Next in Thread]