don't require grep in vc-git
[bpt/emacs.git] / lisp / info-look.el
index 5e51fcc..5bbaa37 100644 (file)
@@ -1,7 +1,7 @@
-;;; info-look.el --- major-mode-sensitive Info index lookup facility
+;;; info-look.el --- major-mode-sensitive Info index lookup facility -*- lexical-binding: t -*-
 ;; An older version of this was known as libc.el.
 
-;; Copyright (C) 1995-1999, 2001-2011 Free Software Foundation, Inc.
+;; Copyright (C) 1995-1999, 2001-2014 Free Software Foundation, Inc.
 
 ;; Author: Ralph Schleicher <rs@nunatak.allgaeu.org>
 ;;         (did not show signs of life (Nov 2001)  -stef)
 ;; Really cool code to lookup info indexes.
 ;; Try especially info-lookup-symbol (aka C-h S).
 
+;; Some additional sources of (Tex)info files for non-GNU packages:
+;;
+;; Scheme: <URL:http://groups.csail.mit.edu/mac/ftpdir/scm/r5rs.info.tar.gz>
+;; LaTeX:
+;;  <URL:ftp://ctan.tug.org/tex-archive/info/latex2e-help-texinfo/latex2e.texi>
+;;  (or CTAN mirrors)
+;; Perl: <URL:ftp://ftp.cpan.org/pub/CPAN/doc/manual/texinfo/> (or CPAN mirrors)
+
 ;;; Code:
 
 (require 'info)
@@ -127,9 +135,9 @@ OTHER-MODES is a list of cross references to other help modes.")
 
 (defun info-lookup-add-help (&rest arg)
   "Add or update a help specification.
-Function arguments are one or more options of the form
+Function arguments are specified as keyword/argument pairs:
 
-    KEYWORD ARGUMENT
+    \(KEYWORD . ARGUMENT)
 
 KEYWORD is either `:topic', `:mode', `:regexp', `:ignore-case',
  `:doc-spec', `:parse-rule', or `:other-modes'.
@@ -252,7 +260,7 @@ minibuffer.  In the minibuffer, use M-n to yank the default argument
 value into the minibuffer so you can edit it.  The default symbol is the
 one found at point.
 
-With prefix arg a query for the symbol help mode is offered."
+With prefix arg MODE a query for the symbol help mode is offered."
   (interactive
    (info-lookup-interactive-arguments 'symbol current-prefix-arg))
   (info-lookup 'symbol symbol mode))
@@ -266,7 +274,7 @@ In the minibuffer, use M-n to yank the default file name
 into the minibuffer so you can edit it.
 The default file name is the one found at point.
 
-With prefix arg a query for the file help mode is offered."
+With prefix arg MODE a query for the file help mode is offered."
   (interactive
    (info-lookup-interactive-arguments 'file current-prefix-arg))
   (info-lookup 'file file mode))
@@ -298,6 +306,21 @@ If optional argument QUERY is non-nil, query for the help mode."
        (when (string-match (caar file-name-alist) file-name)
          (setq info-lookup-mode (cdar file-name-alist)))
        (setq file-name-alist (cdr file-name-alist)))))
+
+  ;; If major-mode has no setups in info-lookup-alist, under any topic, then
+  ;; search up through derived-mode-parent to find a parent mode which does
+  ;; have some setups.  This means that a `define-derived-mode' with no
+  ;; setups of its own will select its parent mode for lookups, if one of
+  ;; its parents has some setups.  Good for example on `makefile-gmake-mode'
+  ;; and similar derivatives of `makefile-mode'.
+  ;;
+  (let ((mode major-mode)) ;; Look for `mode' with some setups.
+    (while (and mode (not info-lookup-mode))
+      (dolist (topic-cell info-lookup-alist) ;; Usually only two topics here.
+        (if (info-lookup->mode-value (car topic-cell) mode)
+            (setq info-lookup-mode mode)))
+      (setq mode (get mode 'derived-mode-parent))))
+
   (or info-lookup-mode (setq info-lookup-mode major-mode)))
 
 (defun info-lookup-change-mode (topic)
@@ -357,7 +380,7 @@ If optional argument QUERY is non-nil, query for the help mode."
        (setq node (nth 0 (car doc-spec))
              prefix (nth 2 (car doc-spec))
              suffix (nth 3 (car doc-spec)))
-       (when (condition-case error-data
+       (when (condition-case nil
                  (progn
                    ;; Don't need Index menu fontifications here, and
                    ;; they slow down the lookup.
@@ -473,7 +496,7 @@ If optional argument QUERY is non-nil, query for the help mode."
                        (t (nth 1 (car doc-spec)))))
       (with-current-buffer buffer
        (message "Processing Info node `%s'..." node)
-       (when (condition-case error-data
+       (when (condition-case nil
                  (progn
                    (Info-goto-node node)
                    (setq doc-found t))
@@ -641,44 +664,42 @@ Return nil if there is nothing appropriate in the buffer near point."
                         info-lookup-mode
                       (info-lookup-change-mode 'file)))))
 
+(defun info-lookup-completions-at-point (topic mode)
+  "Try to complete a help item."
+  (or mode (setq mode (info-lookup-select-mode)))
+  (when (info-lookup->mode-value topic mode)
+    (let ((modes (info-lookup-quick-all-modes topic mode))
+          (start (point))
+          try)
+      (while (and (not try) modes)
+        (setq mode (car modes)
+              modes (cdr modes)
+              try (info-lookup-guess-default* topic mode))
+        (goto-char start))
+      (when try
+        (let ((completions (info-lookup->completions topic mode)))
+          (when completions
+            (when (info-lookup->ignore-case topic mode)
+              (setq completions
+                    (lambda (string pred action)
+                      (let ((completion-ignore-case t))
+                        (complete-with-action
+                         action completions string pred)))))
+            (save-excursion
+              ;; Find the original symbol and zap it.
+              (end-of-line)
+              (while (and (search-backward try nil t)
+                          (< start (point))))
+              (list (match-beginning 0) (match-end 0) completions
+                    :exclusive 'no))))))))
+
 (defun info-complete (topic mode)
   "Try to complete a help item."
   (barf-if-buffer-read-only)
-  (or mode (setq mode (info-lookup-select-mode)))
-  (or (info-lookup->mode-value topic mode)
-      (error "No %s completion available for `%s'" topic mode))
-  (let ((modes (info-lookup-quick-all-modes topic mode))
-       (start (point))
-       try)
-    (while (and (not try) modes)
-      (setq mode (car modes)
-           modes (cdr modes)
-           try (info-lookup-guess-default* topic mode))
-      (goto-char start))
-    (and (not try)
-        (error "Found no %S to complete" topic))
-    (let ((completions (info-lookup->completions topic mode))
-         (completion-ignore-case (info-lookup->ignore-case topic mode))
-         completion)
-      (setq completion (try-completion try completions))
-      (cond ((not completion)
-            (ding)
-            (message "No match"))
-           ((stringp completion)
-            (or (assoc completion completions)
-                (setq completion (completing-read
-                                  (format "Complete %S: " topic)
-                                  completions nil t completion
-                                  info-lookup-history)))
-            ;; Find the original symbol and zap it.
-            (end-of-line)
-            (while (and (search-backward try nil t)
-                        (< start (point))))
-            (replace-match "")
-            (insert completion))
-           (t
-            (message "%s is complete"
-                     (capitalize (prin1-to-string topic))))))))
+  (let ((data (info-lookup-completions-at-point topic mode)))
+    (if (null data)
+        (error "No %s completion available for `%s' at point" topic mode)
+      (completion-in-region (nth 0 data) (nth 1 data) (nth 2 data)))))
 
 \f
 ;;; Initialize some common modes.
@@ -734,7 +755,7 @@ Return nil if there is nothing appropriate in the buffer near point."
  :parse-rule "\\$[^({]\\|\\.[_A-Z]*\\|[_a-zA-Z0-9-]+\\|##\\|\\+="
  :doc-spec   '(
                ;; "(automake)Macro Index" is autoconf macros used in
-               ;; configure.in, not Makefile.am, so don't have that here.
+               ;; configure.ac, not Makefile.am, so don't have that here.
                ("(automake)Variable Index" nil "^[ \t]*`" "'")
                ;; In automake 1.4 macros and variables were a combined node.
                ("(automake)Macro and Variable Index" nil "^[ \t]*`" "'")
@@ -860,8 +881,11 @@ Return nil if there is nothing appropriate in the buffer near point."
 (info-lookup-maybe-add-help
  :mode 'latex-mode
  :regexp "\\\\\\([a-zA-Z]+\\|[^a-zA-Z]\\)"
- :doc-spec '(("(latex)Command Index" nil
-             "`" "\\({[^}]*}\\)?'")))
+ :doc-spec `((,(if (Info-find-file "latex2e" t)
+                  ;; From http://home.gna.org/latexrefman
+                  "(latex2e)Command Index"
+                "(latex)Command Index")
+             nil "`" "\\({[^}]*}\\)?'")))
 
 (info-lookup-maybe-add-help
  :mode 'emacs-lisp-mode