summaryrefslogtreecommitdiff
path: root/lisp/help-mode.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/help-mode.el')
-rw-r--r--lisp/help-mode.el128
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))