Dernière modification
Modifié(e) :
< ;; Copyright (C) 2004-2012, Drew Adams, all rights reserved.
à
> ;; Copyright (C) 2004-2013, Drew Adams, all rights reserved.
Modifié(e) :
< ;; Last-Updated: Thu Aug 23 13:06:14 2012 (-0700)
à
> ;; Last-Updated: Fri Dec 28 13:17:48 2012 (-0800)
Modifié(e) :
< ;; Update #: 105
< ;; URL: http://www.emacswiki.org/cgi-bin/wiki/help-mode+.el
< ;; Doc URL: http://emacswiki.org/emacs/HelpPlus
à
> ;; Update #: 141
> ;; URL: http://www.emacswiki.org/help-mode+.el
> ;; Doc URL: http://emacswiki.org/HelpPlus
Modifié(e) :
< ;; Compatibility: GNU Emacs: 22.x, 23.x
à
> ;; Compatibility: GNU Emacs: 22.x, 23.x, 24.x
Ajouté(e) :
> ;; `help-make-xrefs' - Put symbol clause first, so cross-xref links
> ;; show doc for both fun and var, if available.
Ajouté(e) :
> ;; 2012/10/25 dadams
> ;; Added redefinition of help-make-xrefs.
Ajouté(e) :
> ;; Quiet the byte-compiler.
> (defvar help-forward-label)
> (defvar help-xref-override-view-map)
Ajouté(e) :
> ;; REPLACES ORIGINAL IN `help-mode.el'.
> ;; Show all doc possible for a symbol that is any 2 or 3 of fn, var, and face.
> ;; See Emacs bug #12686.
> ;;;###autoload
> (defun help-make-xrefs (&optional buffer)
> "Parse and hyperlink documentation cross-references in the given BUFFER.
> Find cross-reference information in a buffer and activate such cross
> references for selection with `help-follow'. Cross-references have
> the canonical form `...' and the type of reference may be
> disambiguated by the preceding word(s) used in
> `help-xref-symbol-regexp'. Faces only get cross-referenced if
> preceded or followed by the word `face'. Variables without
> variable documentation do not get cross-referenced, unless
> preceded by the word `variable' or `option'.
> If the variable `help-xref-mule-regexp' is non-nil, find also
> cross-reference information related to multilingual environment
> \(e.g., coding-systems). This variable is also used to disambiguate
> the type of reference as the same way as `help-xref-symbol-regexp'.
> A special reference `back' is made to return back through a stack of
> help buffers. Variable `help-back-label' specifies the text for
> that."
> (interactive "b")
> (with-current-buffer (or buffer (current-buffer))
> (save-excursion
> (goto-char (point-min))
> ;; Skip the header-type info, though it might be useful to parse
> ;; it at some stage (e.g. "function in `library'").
> (forward-paragraph)
> (let ((old-modified (buffer-modified-p)))
> (let ((stab (syntax-table))
> (case-fold-search t)
> (inhibit-read-only t))
> (set-syntax-table emacs-lisp-mode-syntax-table)
> ;; The following should probably be abstracted out.
> (unwind-protect
> (progn
> ;; Info references
> (save-excursion
> (while (re-search-forward help-xref-info-regexp nil t)
> (let ((data (match-string 2)))
> (save-match-data
> (unless (string-match "^([^)]+)" data)
> (setq data (concat "(emacs)" data)))
> (setq data ;; possible newlines if para filled
> (replace-regexp-in-string "[ \t\n]+" " " data t t)))
> (help-xref-button 2 'help-info data))))
> ;; URLs
> (save-excursion
> (while (re-search-forward help-xref-url-regexp nil t)
> (let ((data (match-string 1)))
> (help-xref-button 1 'help-url data))))
> ;; Mule related keywords. Do this before trying
> ;; `help-xref-symbol-regexp' because some of Mule
> ;; keywords have variable or function definitions.
> (if help-xref-mule-regexp
> (save-excursion
> (while (re-search-forward help-xref-mule-regexp nil t)
> (let* ((data (match-string 7))
> (sym (intern-soft data)))
> (cond
> ((match-string 3) ; coding system
> (and sym (coding-system-p sym)
> (help-xref-button 6 'help-coding-system sym)))
> ((match-string 4) ; input method
> (and (assoc data input-method-alist)
> (help-xref-button 7 'help-input-method data)))
> ((or (match-string 5) (match-string 6)) ; charset
> (and sym (charsetp sym)
> (help-xref-button 7 'help-character-set sym)))
> ((assoc data input-method-alist)
> (help-xref-button 7 'help-character-set data))
> ((and sym (coding-system-p sym))
> (help-xref-button 7 'help-coding-system sym))
> ((and sym (charsetp sym))
> (help-xref-button 7 'help-character-set sym)))))))
> ;; Quoted symbols
> (save-excursion
> (while (re-search-forward help-xref-symbol-regexp nil t)
> (let* ((data (match-string 8))
> (sym (intern-soft data)))
> (when sym
> (cond
> ((or (and (or (boundp sym) ; var & fn
> (get sym 'variable-documentation))
> (fboundp sym))
> (and (fboundp sym) ; fn & face
> (facep sym))
> (and (or (boundp sym) ; var & face
> (get sym 'variable-documentation))
> (facep sym)))
> ;; Var, function, or face -- doc all, if possible.
> (help-xref-button 8 'help-symbol sym))
> ((match-string 3) ; `variable' &c
> (and (or (boundp sym) ; `variable' doesn't ensure
> ; it's actually bound
> (get sym 'variable-documentation))
> (help-xref-button 8 'help-variable sym)))
> ((match-string 4) ; `function' &c
> (and (fboundp sym) ; similarly
> (help-xref-button 8 'help-function sym)))
> ((match-string 5) ; `face'
> (and (facep sym)
> (help-xref-button 8 'help-face sym)))
> ((match-string 6)) ; nothing for `symbol'
> ((match-string 7)
> ;; this used:
> ;; #'(lambda (arg)
> ;; (let ((location
> ;; (find-function-noselect arg)))
> ;; (pop-to-buffer (car location))
> ;; (goto-char (cdr location))))
> (help-xref-button 8 'help-function-def sym))
> ((and
> (facep sym)
> (save-match-data (looking-at "[ \t\n]+face\\W")))
> (help-xref-button 8 'help-face sym))
> ((and
> (or (boundp sym)
> (get sym 'variable-documentation))
> (or
> (documentation-property
> sym 'variable-documentation)
> (if (or (> emacs-major-version 24)
> (and (= emacs-major-version 24)
> (> emacs-minor-version 2)))
> (documentation-property
> (indirect-variable sym)
> 'variable-documentation)
> (condition-case nil
> (documentation-property
> (indirect-variable sym)
> 'variable-documentation)
> (cyclic-variable-indirection nil)))))
> (help-xref-button 8 'help-variable sym))
> ((fboundp sym)
> (help-xref-button 8 'help-function sym)))))))
> ;; An obvious case of a key substitution:
> (save-excursion
> (while (re-search-forward
> ;; Assume command name is only word and symbol
> ;; characters to get things like `use M-x foo->bar'.
> ;; Command required to end with word constituent
> ;; to avoid `.' at end of a sentence.
> "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t)
> (let ((sym (intern-soft (match-string 1))))
> (if (fboundp sym)
> (help-xref-button 1 'help-function sym)))))
> ;; Look for commands in whole keymap substitutions:
> (save-excursion
> ;; Make sure to find the first keymap.
> (goto-char (point-min))
> ;; Find a header and the column at which the command
> ;; name will be found.
> ;; If the keymap substitution isn't the last thing in
> ;; the doc string, and if there is anything on the same
> ;; line after it, this code won't recognize the end of it.
> (while (re-search-forward "^key +binding\n\\(-+ +\\)-+\n\n"
> nil t)
> (let ((col (- (match-end 1) (match-beginning 1))))
> (while
> (and (not (eobp))
> ;; Stop at a pair of blank lines.
> (not (looking-at "\n\\s-*\n")))
> ;; Skip a single blank line.
> (and (eolp) (forward-line))
> (end-of-line)
> (skip-chars-backward "^ \t\n")
> (if (and (>= (current-column) col)
> (looking-at "\\(\\sw\\|\\s_\\)+$"))
> (let ((sym (intern-soft (match-string 0))))
> (if (fboundp sym)
> (help-xref-button 0 'help-function sym))))
> (forward-line))))))
> (set-syntax-table stab))
> ;; Delete extraneous newlines at the end of the docstring
> (goto-char (point-max))
> (while (and (not (bobp)) (bolp))
> (delete-char -1))
> (insert "\n")
> (when (or help-xref-stack (and (boundp 'help-xref-forward-stack)
> help-xref-forward-stack))
> (insert "\n"))
> ;; Make a back-reference in this buffer if appropriate.
> (when help-xref-stack
> (help-insert-xref-button help-back-label 'help-back
> (current-buffer)))
> ;; Make a forward-reference in this buffer if appropriate.
> (when (and (boundp 'help-xref-forward-stack) help-xref-forward-stack)
> (when help-xref-stack
> (insert "\t"))
> (help-insert-xref-button help-forward-label 'help-forward
> (current-buffer)))
> (when (or help-xref-stack (and (boundp 'help-xref-forward-stack)
> help-xref-forward-stack))
> (insert "\n")))
> (when (< emacs-major-version 24)
> ;; View mode steals RET from us.
> (set (make-local-variable 'minor-mode-overriding-map-alist)
> (list (cons 'view-mode help-xref-override-view-map))))
> (when (or (> emacs-major-version 24)
> (and (= emacs-major-version 24)
> (> emacs-minor-version 2)))
> (set-buffer-modified-p old-modified))))))
;;; help-mode+.el --- Extensions to `help-mode.el' ;; ;; Filename: help-mode+.el ;; Description: Extensions to `help-mode.el' ;; Author: Drew Adams ;; Maintainer: Drew Adams ;; Copyright (C) 2004-2013, Drew Adams, all rights reserved. ;; Created: Sat Nov 06 15:14:12 2004 ;; Version: 21.0 ;; Last-Updated: Fri Dec 28 13:17:48 2012 (-0800) ;; By: dradams ;; Update #: 141 ;; URL: http://www.emacswiki.org/help-mode+.el ;; Doc URL: http://emacswiki.org/HelpPlus ;; Keywords: help ;; Compatibility: GNU Emacs: 22.x, 23.x, 24.x ;; ;; Features that might be required by this library: ;; ;; `button', `help-mode', `view'. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Commentary: ;; ;; Extensions to `help-mode.el' ;; ;; ;; ***** NOTE: The following functions defined in `help-mode.el' ;; have been REDEFINED HERE: ;; ;; `help-make-xrefs' - Put symbol clause first, so cross-xref links ;; show doc for both fun and var, if available. ;; `help-mode' - If `one-window-p', then delete Help frame. ;; `help-xref-on-pp' - Library names are buttonized. ;; ;; ;; Put this in your initialization file (`~/.emacs'): ;; ;; (require 'help-mode+) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Change Log: ;; ;; 2012/10/25 dadams ;; Added redefinition of help-make-xrefs. ;; 2011/01/04 dadams ;; Removed autoload cookie from non-interactive function. ;; 2007/12/14 dadams ;; Added redefinition of help-mode. ;; Removed pop-to-help-buffer and help-origin-buffer to (new) help+.el. ;; 2006/07/11 dadams ;; Added: help-origin-buffer, pop-to-help-toggle. Bound latter to C-h C-o. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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, 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; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth ;; Floor, Boston, MA 02110-1301, USA. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Code: (require 'help-mode) ;; Quiet the byte-compiler. (defvar help-forward-label) (defvar help-xref-override-view-map) ;;;;;;;;;;;;;;;;;;;;;;;; ;; REPLACES ORIGINAL IN `help-mode.el'. ;; Deletes frame if `one-window-p'. ;; ;;;###autoload (defun help-mode () "Major mode for viewing help text and navigating references in it. Entry to this mode runs the normal hook `help-mode-hook'. Commands: \\{help-mode-map}" (interactive) (kill-all-local-variables) (use-local-map help-mode-map) (setq mode-name "Help") (setq major-mode 'help-mode) (view-mode) (make-local-variable 'view-no-disable-on-exit) (setq view-no-disable-on-exit t) (setq view-exit-action (lambda (buffer) (or (window-minibuffer-p (selected-window)) (when (eq (window-buffer) (get-buffer "*Help*")) (if (one-window-p t) (delete-frame) (delete-window)))))) (run-mode-hooks 'help-mode-hook)) ;; REPLACES ORIGINAL IN `help-mode.el'. ;; Show all doc possible for a symbol that is any 2 or 3 of fn, var, and face. ;; See Emacs bug #12686. ;;;###autoload (defun help-make-xrefs (&optional buffer) "Parse and hyperlink documentation cross-references in the given BUFFER. Find cross-reference information in a buffer and activate such cross references for selection with `help-follow'. Cross-references have the canonical form `...' and the type of reference may be disambiguated by the preceding word(s) used in `help-xref-symbol-regexp'. Faces only get cross-referenced if preceded or followed by the word `face'. Variables without variable documentation do not get cross-referenced, unless preceded by the word `variable' or `option'. If the variable `help-xref-mule-regexp' is non-nil, find also cross-reference information related to multilingual environment \(e.g., coding-systems). This variable is also used to disambiguate the type of reference as the same way as `help-xref-symbol-regexp'. A special reference `back' is made to return back through a stack of help buffers. Variable `help-back-label' specifies the text for that." (interactive "b") (with-current-buffer (or buffer (current-buffer)) (save-excursion (goto-char (point-min)) ;; Skip the header-type info, though it might be useful to parse ;; it at some stage (e.g. "function in `library'"). (forward-paragraph) (let ((old-modified (buffer-modified-p))) (let ((stab (syntax-table)) (case-fold-search t) (inhibit-read-only t)) (set-syntax-table emacs-lisp-mode-syntax-table) ;; The following should probably be abstracted out. (unwind-protect (progn ;; Info references (save-excursion (while (re-search-forward help-xref-info-regexp nil t) (let ((data (match-string 2))) (save-match-data (unless (string-match "^([^)]+)" data) (setq data (concat "(emacs)" data))) (setq data ;; possible newlines if para filled (replace-regexp-in-string "[ \t\n]+" " " data t t))) (help-xref-button 2 'help-info data)))) ;; URLs (save-excursion (while (re-search-forward help-xref-url-regexp nil t) (let ((data (match-string 1))) (help-xref-button 1 'help-url data)))) ;; Mule related keywords. Do this before trying ;; `help-xref-symbol-regexp' because some of Mule ;; keywords have variable or function definitions. (if help-xref-mule-regexp (save-excursion (while (re-search-forward help-xref-mule-regexp nil t) (let* ((data (match-string 7)) (sym (intern-soft data))) (cond ((match-string 3) ; coding system (and sym (coding-system-p sym) (help-xref-button 6 'help-coding-system sym))) ((match-string 4) ; input method (and (assoc data input-method-alist) (help-xref-button 7 'help-input-method data))) ((or (match-string 5) (match-string 6)) ; charset (and sym (charsetp sym) (help-xref-button 7 'help-character-set sym))) ((assoc data input-method-alist) (help-xref-button 7 'help-character-set data)) ((and sym (coding-system-p sym)) (help-xref-button 7 'help-coding-system sym)) ((and sym (charsetp sym)) (help-xref-button 7 'help-character-set sym))))))) ;; Quoted symbols (save-excursion (while (re-search-forward help-xref-symbol-regexp nil t) (let* ((data (match-string 8)) (sym (intern-soft data))) (when sym (cond ((or (and (or (boundp sym) ; var & fn (get sym 'variable-documentation)) (fboundp sym)) (and (fboundp sym) ; fn & face (facep sym)) (and (or (boundp sym) ; var & face (get sym 'variable-documentation)) (facep sym))) ;; Var, function, or face -- doc all, if possible. (help-xref-button 8 'help-symbol sym)) ((match-string 3) ; `variable' &c (and (or (boundp sym) ; `variable' doesn't ensure ; it's actually bound (get sym 'variable-documentation)) (help-xref-button 8 'help-variable sym))) ((match-string 4) ; `function' &c (and (fboundp sym) ; similarly (help-xref-button 8 'help-function sym))) ((match-string 5) ; `face' (and (facep sym) (help-xref-button 8 'help-face sym))) ((match-string 6)) ; nothing for `symbol' ((match-string 7) ;; this used: ;; #'(lambda (arg) ;; (let ((location ;; (find-function-noselect arg))) ;; (pop-to-buffer (car location)) ;; (goto-char (cdr location)))) (help-xref-button 8 'help-function-def sym)) ((and (facep sym) (save-match-data (looking-at "[ \t\n]+face\\W"))) (help-xref-button 8 'help-face sym)) ((and (or (boundp sym) (get sym 'variable-documentation)) (or (documentation-property sym 'variable-documentation) (if (or (> emacs-major-version 24) (and (= emacs-major-version 24) (> emacs-minor-version 2))) (documentation-property (indirect-variable sym) 'variable-documentation) (condition-case nil (documentation-property (indirect-variable sym) 'variable-documentation) (cyclic-variable-indirection nil))))) (help-xref-button 8 'help-variable sym)) ((fboundp sym) (help-xref-button 8 'help-function sym))))))) ;; An obvious case of a key substitution: (save-excursion (while (re-search-forward ;; Assume command name is only word and symbol ;; characters to get things like `use M-x foo->bar'. ;; Command required to end with word constituent ;; to avoid `.' at end of a sentence. "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t) (let ((sym (intern-soft (match-string 1)))) (if (fboundp sym) (help-xref-button 1 'help-function sym))))) ;; Look for commands in whole keymap substitutions: (save-excursion ;; Make sure to find the first keymap. (goto-char (point-min)) ;; Find a header and the column at which the command ;; name will be found. ;; If the keymap substitution isn't the last thing in ;; the doc string, and if there is anything on the same ;; line after it, this code won't recognize the end of it. (while (re-search-forward "^key +binding\n\\(-+ +\\)-+\n\n" nil t) (let ((col (- (match-end 1) (match-beginning 1)))) (while (and (not (eobp)) ;; Stop at a pair of blank lines. (not (looking-at "\n\\s-*\n"))) ;; Skip a single blank line. (and (eolp) (forward-line)) (end-of-line) (skip-chars-backward "^ \t\n") (if (and (>= (current-column) col) (looking-at "\\(\\sw\\|\\s_\\)+$")) (let ((sym (intern-soft (match-string 0)))) (if (fboundp sym) (help-xref-button 0 'help-function sym)))) (forward-line)))))) (set-syntax-table stab)) ;; Delete extraneous newlines at the end of the docstring (goto-char (point-max)) (while (and (not (bobp)) (bolp)) (delete-char -1)) (insert "\n") (when (or help-xref-stack (and (boundp 'help-xref-forward-stack) help-xref-forward-stack)) (insert "\n")) ;; Make a back-reference in this buffer if appropriate. (when help-xref-stack (help-insert-xref-button help-back-label 'help-back (current-buffer))) ;; Make a forward-reference in this buffer if appropriate. (when (and (boundp 'help-xref-forward-stack) help-xref-forward-stack) (when help-xref-stack (insert "\t")) (help-insert-xref-button help-forward-label 'help-forward (current-buffer))) (when (or help-xref-stack (and (boundp 'help-xref-forward-stack) help-xref-forward-stack)) (insert "\n"))) (when (< emacs-major-version 24) ;; View mode steals RET from us. (set (make-local-variable 'minor-mode-overriding-map-alist) (list (cons 'view-mode help-xref-override-view-map)))) (when (or (> emacs-major-version 24) (and (= emacs-major-version 24) (> emacs-minor-version 2))) (set-buffer-modified-p old-modified)))))) ;; REPLACES ORIGINAL IN `help-mode.el'. ;; Buttonizes names of libraries also. ;; To see the effect, try `C-h v features', and click on a library name. ;; ;; 2006-01-20: This no longer works, because the call to this function ;; from `describe-variable was commented out in `help-fns.el'. ;; (defun help-xref-on-pp (from to) "Add xrefs for symbols in `pp's output between FROM and TO." (if (> (- to from) 5000) nil (with-syntax-table emacs-lisp-mode-syntax-table (save-excursion (save-restriction (narrow-to-region from to) (goto-char (point-min)) (condition-case nil (while (not (eobp)) (cond ((looking-at "\"") (forward-sexp 1)) ((looking-at "#<") (search-forward ">" nil 'move)) ((looking-at "\\(\\(\\sw\\|\\s_\\)+\\)") (let* ((sym (intern-soft (match-string 1))) (type (cond ((fboundp sym) 'help-function) ((or (memq sym '(t nil)) (keywordp sym)) nil) ((and sym (boundp sym)) 'help-variable) ((and sym (locate-library (symbol-name sym))) 'help-library)))) (when type (help-xref-button 1 type sym))) (goto-char (match-end 1))) (t (forward-char 1)))) (error nil))))))) (define-button-type 'help-library :supertype 'help-xref 'help-function #'(lambda (x) (find-library (symbol-name x))) 'help-echo (purecopy "mouse-2, RET: find this library")) ;; $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;; REPLACES ORIGINAL IN `help-mode.el'. ;; Provide a tooltip for whatever is under the mouse. ;; This can't be done here - the message needs to be done via an idle timer, ;; whenever mouse is over any name. Perhaps combine with eldoc. ;; ;; ;;;###autoload ;; (defun help-follow-mouse (click) ;; "Follow the cross-reference that you CLICK on." ;; (interactive "e") ;; (let* ((start (event-start click)) ;; (window (car start)) ;; (pos (car (cdr start)))) ;; (with-current-buffer (window-buffer window) ;; (message "Display help on `%s'" ;; (save-excursion ;; (goto-char pos) (skip-syntax-backward "w_") ;; (buffer-substring (point) ;; (progn (skip-syntax-forward "w_") ;; (point))))) ;; (help-follow pos)))) ;; After a certain idle time, use function `mouse-position', and pick ;; up the symbol under the pointer. Then display a message that ;; clicking mouse-2 will display help on the symbol. ;;;;;;;;;;;;;;;;;;;;;;;;;;; (provide 'help-mode+) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; help-mode+.el ends here