Download Git
;;; pydoc-info.el --- Search and browse the Python documentation in Info
;; Copyright (C) 2011 Jonathan Waltman
;; Author: Jonathan Waltman <jonathan.waltman@gmail.com>
;; Created: 1 Feb 2011
;; Version: 0.2
;; Keywords: python, info, docs
;; 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 3 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, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; pydoc-info provides routines to better search and browse the Python
;; documentation in Info.
;; Features:
;;
;; - Improved Info-lookup support for Python allows quick access to
;; the documentation using `info-lookup-symbol' (C-h S) with symbol
;; completion for every Python object documented in the standard
;; library.
;;
;; - Hide superfluous *note: references. Prevent Info from displaying
;; "*note:" or "see" in front of cross-references when browsing the
;; Python documentation. This does not affect how other Info
;; documents are displayed and is controlled by the variable
;; `pydoc-info-hide-note-references'.
;; Installation:
;;
;; Before using this package, you may need to download and install the
;; latest Python Info files:
;;
;; wget https://bitbucket.org/jonwaltman/pydoc-info/downloads/python.info.gz
;; gunzip python.info
;; sudo cp python.info /usr/share/info
;; sudo install-info --info-dir=/usr/share/info python.info
;;
;; Then add the following to your ~/.emacs.d/init.el:
;;
;; (add-to-list 'load-path "/path/to/pydoc-info")
;; (require 'pydoc-info)
;; Extending:
;;
;; The Info-lookup support provided by this package is not limited to
;; the standard Python documentation. It can easily be extended to
;; work with other Python packages that also use Sphinx for
;; documentation and have generated the necessary Info files.
;;
;; For example, the documentation for Sphinx can be compiled to the
;; Info file "sphinx.info" and you have added it to your `INFOPATH'.
;; By adding the following code to your `init.el', you can use
;; `info-lookup-symbol' to search the documentation for both Sphinx
;; and the standard Python modules.
;;
;; (pydoc-info-add-help '("python" "sphinx"))
;; Notes:
;;
;; pydoc-info is designed to work with Info files produced from the
;; "new" Python documentation (v2.6 and above). The "new"
;; documentation is written in ReStructuredText and built using
;; Sphinx. The previous Python Info files were generated from the old
;; documentation written in LaTeX.
;;
;; Texinfo support is a recent addition to Sphinx and is currently
;; limited to the latest development branch. The Info files
;; referenced here are not part of the official Python distribution.
;;
;; The current `info-lookup' support in "python.el" (circa v24.0) is
;; based on the older Info files and doesn't work with the newer
;; versions.
;; Please email bug reports and suggestions to the author, or submit
;; them at https://bitbucket.org/jonwaltman/pydoc-info/issues
;;; Code:
;;;###autoload
(require 'info-look)
(defcustom pydoc-info-hide-note-references t
"Non-nil if note references should be hidden in Python Info
documents.
This variable is used by `pydoc-info-after-insert-file-contents'
which advises the function `info-insert-file-contents'."
:group 'pydoc-info)
;; Is there a better way to do this?
(defadvice info-insert-file-contents (after
pydoc-info-after-insert-file-contents
activate)
"Hack to make `Info-hide-note-references' buffer-local and
automatically set to `hide' if it can be determined that this
file was created from a Texinfo file generated by Docutils or
Sphinx.
This is only performed if `pydoc-info-hide-note-references' is
non-nil."
(when pydoc-info-hide-note-references
(set (make-local-variable 'Info-hide-note-references)
(default-value 'Info-hide-note-references))
(save-excursion
(save-restriction
(widen) (goto-char (point-min))
(when (re-search-forward
"Generated by \\(Sphinx\\|Docutils\\)"
(save-excursion (search-forward "\x1f" nil t)) t)
(set (make-local-variable 'Info-hide-note-references)
'hide))))))
;;;###autoload
(defun pydoc-info-add-help (files &rest more-specs)
"Add help specifications for a list of Info FILES.
The added specifications are tailored for use with Info files
generated from Sphinx documents.
MORE-SPECS are additional or overriding values passed to
`info-lookup-add-help'."
(info-lookup-reset)
(let (doc-spec)
(dolist (f files)
(push (list (format "(%s)Python Module Index" f)
'pydoc-info-lookup-transform-entry) doc-spec)
(push (list (format "(%s)Index" f)
'pydoc-info-lookup-transform-entry) doc-spec))
(apply 'info-lookup-add-help
:mode 'python-mode
:parse-rule 'pydoc-info-python-symbol-at-point
:doc-spec doc-spec
more-specs)))
;;;###autoload
(pydoc-info-add-help '("python"))
(defvar python-dotty-syntax-table)
(defun pydoc-info-python-symbol-at-point ()
"Return the current Python symbol."
(require 'python)
(with-syntax-table python-dotty-syntax-table
(current-word)))
(defun pydoc-info-lookup-transform-entry (item)
"Transform a Python index entry to a help item."
(let* ((py-re "\\([[:alnum:]_.]+\\)(?)?"))
(cond
;; foo.bar --> foo.bar
((string-match (concat "\\`" py-re "\\'") item)
item)
;; keyword; foo --> foo
;; statement; foo --> foo
((string-match (concat "\\`\\(keyword\\|statement\\);? " py-re) item)
(replace-regexp-in-string " " "." (match-string 2 item)))
;; foo (built-in ...) --> foo
((string-match (concat "\\`" py-re " (built-in .+)") item)
(replace-regexp-in-string " " "." (match-string 1 item)))
;; foo.bar (module) --> foo.bar
((string-match (concat "\\`" py-re " (module)") item)
(replace-regexp-in-string " " "." (match-string 1 item)))
;; baz (in module foo.bar) --> foo.bar.baz
((string-match (concat "\\`" py-re " (in module \\(.+\\))") item)
(replace-regexp-in-string " " "." (concat (match-string 2 item) " "
(match-string 1 item))))
;; Bar (class in foo.bar) --> foo.bar.Bar
((string-match (concat "\\`" py-re " (class in \\(.+\\))") item)
(replace-regexp-in-string " " "." (concat (match-string 2 item) " "
(match-string 1 item))))
;; bar (foo.Foo method) --> foo.Foo.bar
((string-match
(concat "\\`" py-re " (\\(.+\\) \\(method\\|attribute\\))") item)
(replace-regexp-in-string " " "." (concat (match-string 2 item) " "
(match-string 1 item))))
;; foo (C ...) --> foo
((string-match (concat "\\`" py-re " (C .*)") item)
(match-string 1 item))
;; operator; foo --> foo
((string-match "\\`operator; \\(.*\\)" item)
(match-string 1 item))
;; Python Enhancement Proposals; PEP XXX --> PEP XXX
((string-match "\\`Python Enhancement Proposals; \\(PEP .*\\)" item)
(match-string 1 item))
;; RFC; RFC XXX --> RFC XXX
((string-match "\\`RFC; \\(RFC .*\\)" item)
(match-string 1 item))
(t
item))))
(provide 'pydoc-info)
;;; pydoc-info.el ends here