;;; help-mode+.el --- Extensions to `help-mode.el' ;; ;; Filename: help-mode+.el ;; Description: Extensions to `help-mode.el' ;; Author: Drew Adams ;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") ;; Copyright (C) 2004-2018, Drew Adams, all rights reserved. ;; Created: Sat Nov 06 15:14:12 2004 ;; Version: 0 ;; Package-Requires: () ;; Last-Updated: Mon Jan 1 13:28:45 2018 (-0800) ;; By: dradams ;; Update #: 215 ;; URL: https://www.emacswiki.org/emacs/download/help-mode%2b.el ;; Doc URL: https://emacswiki.org/emacs/HelpPlus ;; Keywords: help ;; Compatibility: GNU Emacs: 22.x, 23.x, 24.x, 25.x, 26.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: ;; ;; 2018/01/1 dadams ;; help-make-xrefs: ;; Bug #12686: Promote type tests after cond tests to be inside them with the match tests. ;; 2014/01/17 dadams ;; Do not redefine help-mode for Emacs 24+. ;; 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 (when (< emacs-major-version 24) ; Emacs 24+ does not use `view-mode', so no need. (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" major-mode 'help-mode) (view-mode) (make-local-variable 'view-no-disable-on-exit) (setq view-no-disable-on-exit t 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. ;; ;; Also a partial fix for Emacs bug #24842. ;; ;;;###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. ;; $$$$$ Should I do it here too? (Have not done so yet.) (when 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)) ((and (match-string 3) ; `variable' &c (or (boundp sym) ; `variable' doesn't ensure ; it's actually bound (get sym 'variable-documentation))) (help-xref-button 8 'help-variable sym)) ((and (match-string 4) ; `function' &c (fboundp sym)) ; similarly (help-xref-button 8 'help-function sym)) ((and (match-string 5) ; `face' (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. "\\= (current-column) col) (looking-at "\\(\\sw\\|\\s_\\)+$")) (let ((sym (intern-soft (match-string 0)))) (when (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