diff options
Diffstat (limited to 'lisp/help-mode.el')
-rw-r--r-- | lisp/help-mode.el | 128 |
1 files changed, 111 insertions, 17 deletions
diff --git a/lisp/help-mode.el b/lisp/help-mode.el index 79710a18073..87f26651e01 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -30,13 +30,11 @@ ;;; Code: (require 'cl-lib) -(eval-when-compile (require 'easymenu)) (defvar help-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map (make-composed-keymap button-buffer-map special-mode-map)) - (define-key map [mouse-2] 'help-follow-mouse) (define-key map "l" 'help-go-back) (define-key map "r" 'help-go-forward) (define-key map "\C-c\C-b" 'help-go-back) @@ -44,7 +42,9 @@ (define-key map [XF86Back] 'help-go-back) (define-key map [XF86Forward] 'help-go-forward) (define-key map "\C-c\C-c" 'help-follow-symbol) - (define-key map "\r" 'help-follow) + (define-key map "s" 'help-view-source) + (define-key map "i" 'help-goto-info) + (define-key map "c" 'help-customize) map) "Keymap for Help mode.") @@ -54,30 +54,81 @@ ["Show Help for Symbol" help-follow-symbol :help "Show the docs for the symbol at point"] ["Previous Topic" help-go-back - :help "Go back to previous topic in this help buffer"] + :help "Go back to previous topic in this help buffer" + :active help-xref-stack] ["Next Topic" help-go-forward - :help "Go back to next topic in this help buffer"] + :help "Go back to next topic in this help buffer" + :active help-xref-forward-stack] ["Move to Previous Button" backward-button :help "Move to the Previous Button in the help buffer"] ["Move to Next Button" forward-button - :help "Move to the Next Button in the help buffer"])) + :help "Move to the Next Button in the help buffer"] + ["View Source" help-view-source + :help "Go to the source file for the current help item"] + ["Goto Info" help-goto-info + :help "Go to the info node for the current help item"] + ["Customize" help-customize + :help "Customize variable or face"])) + +(defun help-mode-context-menu (menu) + (define-key menu [help-mode-separator] menu-bar-separator) + (let ((easy-menu (make-sparse-keymap "Help-Mode"))) + (easy-menu-define nil easy-menu nil + '("Help-Mode" + ["Previous Topic" help-go-back + :help "Go back to previous topic in this help buffer" + :active help-xref-stack] + ["Next Topic" help-go-forward + :help "Go back to next topic in this help buffer" + :active help-xref-forward-stack])) + (dolist (item (reverse (lookup-key easy-menu [menu-bar help-mode]))) + (when (consp item) + (define-key menu (vector (car item)) (cdr item))))) + + (when (and + ;; First check if `help-fns--list-local-commands' + ;; used `where-is-internal' to call this function + ;; with wrong `last-input-event'. + (eq (current-buffer) (window-buffer (posn-window (event-start last-input-event)))) + (mouse-posn-property (event-start last-input-event) 'mouse-face)) + (define-key menu [help-mode-push-button] + '(menu-item "Follow Link" (lambda (event) + (interactive "e") + (push-button event)) + :help "Follow the link at click"))) + + menu) + +(defvar help-mode-tool-bar-map + (let ((map (make-sparse-keymap))) + (tool-bar-local-item "close" 'quit-window 'quit map + :help "Quit help" + :vert-only t) + (define-key-after map [separator-1] menu-bar-separator) + (tool-bar-local-item "search" 'isearch-forward 'search map + :help "Search" :vert-only t) + (tool-bar-local-item-from-menu 'help-go-back "left-arrow" map help-mode-map + :rtl "right-arrow" :vert-only t) + (tool-bar-local-item-from-menu 'help-go-forward "right-arrow" map help-mode-map + :rtl "left-arrow" :vert-only t) + map)) (defvar-local help-xref-stack nil "A stack of ways by which to return to help buffers after following xrefs. -Used by `help-follow' and `help-xref-go-back'. +Used by `help-follow-symbol' and `help-xref-go-back'. An element looks like (POSITION FUNCTION ARGS...). To use the element, do (apply FUNCTION ARGS) then goto the point.") (put 'help-xref-stack 'permanent-local t) (defvar-local help-xref-forward-stack nil "A stack used to navigate help forwards after using the back button. -Used by `help-follow' and `help-xref-go-forward'. +Used by `help-follow-symbol' and `help-xref-go-forward'. An element looks like (POSITION FUNCTION ARGS...). To use the element, do (apply FUNCTION ARGS) then goto the point.") (put 'help-xref-forward-stack 'permanent-local t) (defvar-local help-xref-stack-item nil - "An item for `help-follow' in this buffer to push onto `help-xref-stack'. + "An item for `help-follow-symbol' to push onto `help-xref-stack'. The format is (FUNCTION ARGS...).") (put 'help-xref-stack-item 'permanent-local t) @@ -89,6 +140,15 @@ The format is (FUNCTION ARGS...).") (setq-default help-xref-stack nil help-xref-stack-item nil) (setq-default help-xref-forward-stack nil help-xref-forward-stack-item nil) +(defvar help-mode-syntax-table + (let ((table (make-syntax-table emacs-lisp-mode-syntax-table))) + ;; Treat single quotes as parens so that forward-sexp does not + ;; break when a quoted string contains punctuation. + (modify-syntax-entry ?‘ "(’ " table) + (modify-syntax-entry ?’ ")‘ " table) + table) + "Syntax table used in `help-mode'.") + (defcustom help-mode-hook nil "Hook run by `help-mode'." :type 'hook @@ -308,6 +368,7 @@ The format is (FUNCTION ARGS...).") 'help-echo (purecopy "mouse-2, RET: show corresponding NEWS announcement")) (defvar bookmark-make-record-function) +(defvar help-mode--current-data nil) ;;;###autoload (define-derived-mode help-mode special-mode "Help" @@ -317,6 +378,10 @@ Commands: \\{help-mode-map}" (setq-local revert-buffer-function #'help-mode-revert-buffer) + (add-hook 'context-menu-functions 'help-mode-context-menu 5 t) + (setq-local tool-bar-map + help-mode-tool-bar-map) + (setq-local help-mode--current-data nil) (setq-local bookmark-make-record-function #'help-bookmark-make-record)) @@ -438,7 +503,7 @@ Each element has the form (NAME TESTFUN DESCFUN) where: "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 +references for selection with `help-follow-symbol'. 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 @@ -458,14 +523,13 @@ that." (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'"). + ;; Skip the first bit, which has already been buttonized. (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) + (set-syntax-table help-mode-syntax-table) ;; The following should probably be abstracted out. (unwind-protect (progn @@ -618,7 +682,7 @@ See `help-make-xrefs'." (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 + (with-syntax-table help-mode-syntax-table (save-excursion (save-restriction (narrow-to-region from to) @@ -706,6 +770,34 @@ See `help-make-xrefs'." (help-xref-go-forward (current-buffer)) (user-error "No next help buffer"))) +(defun help-view-source () + "View the source of the current help item." + (interactive nil help-mode) + (unless (plist-get help-mode--current-data :file) + (error "Source file for the current help item is not defined")) + (help-function-def--button-function + (plist-get help-mode--current-data :symbol) + (plist-get help-mode--current-data :file) + (plist-get help-mode--current-data :type))) + +(defun help-goto-info () + "View the *info* node of the current help item." + (interactive nil help-mode) + (unless help-mode--current-data + (error "No symbol to look up in the current buffer")) + (info-lookup-symbol (plist-get help-mode--current-data :symbol) + 'emacs-lisp-mode)) + +(defun help-customize () + "Customize variable or face whose doc string is shown in the current buffer." + (interactive nil help-mode) + (let ((sym (plist-get help-mode--current-data :symbol))) + (unless (or (boundp sym) (facep sym)) + (user-error "No variable or face to customize")) + (cond + ((boundp sym) (customize-variable sym)) + ((facep sym) (customize-face sym))))) + (defun help-do-xref (_pos function args) "Call the help cross-reference function FUNCTION with args ARGS. Things are set up properly so that the resulting help-buffer has @@ -719,6 +811,7 @@ a proper [back] button." ;; The doc string is meant to explain what buttons do. (defun help-follow-mouse () "Follow the cross-reference that you click on." + (declare (obsolete nil "28.1")) (interactive) (error "No cross-reference here")) @@ -727,6 +820,7 @@ a proper [back] button." "Follow cross-reference at point. For the cross-reference format, see `help-make-xrefs'." + (declare (obsolete nil "28.1")) (interactive) (user-error "No cross-reference here")) @@ -778,8 +872,8 @@ help buffer by other means." (&optional no-file no-context posn)) (defun help-bookmark-make-record () - "Create and return a help-mode bookmark record. -Implements `bookmark-make-record-function' for help-mode buffers." + "Create and return a `help-mode' bookmark record. +Implements `bookmark-make-record-function' for `help-mode' buffers." (unless (car help-xref-stack-item) (error "Cannot create bookmark - help command not known")) `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT) @@ -792,7 +886,7 @@ Implements `bookmark-make-record-function' for help-mode buffers." ;;;###autoload (defun help-bookmark-jump (bookmark) - "Jump to help-mode bookmark BOOKMARK. + "Jump to `help-mode' bookmark BOOKMARK. Handler function for record returned by `help-bookmark-make-record'. BOOKMARK is a bookmark name or a bookmark record." (let ((help-fn (bookmark-prop-get bookmark 'help-fn)) |