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.el224
1 files changed, 138 insertions, 86 deletions
diff --git a/lisp/help-mode.el b/lisp/help-mode.el
index ee68d253cb8..8b5e48edad1 100644
--- a/lisp/help-mode.el
+++ b/lisp/help-mode.el
@@ -31,22 +31,23 @@
(require 'cl-lib)
-(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 "l" 'help-go-back)
- (define-key map "r" 'help-go-forward)
- (define-key map "\C-c\C-b" 'help-go-back)
- (define-key map "\C-c\C-f" 'help-go-forward)
- (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 "s" 'help-view-source)
- (define-key map "i" 'help-goto-info)
- (define-key map "c" 'help-customize)
- map)
- "Keymap for Help mode.")
+(defvar-keymap help-mode-map
+ :doc "Keymap for Help mode."
+ :parent (make-composed-keymap button-buffer-map
+ special-mode-map)
+ "n" #'help-goto-next-page
+ "p" #'help-goto-previous-page
+ "l" #'help-go-back
+ "r" #'help-go-forward
+ "C-c C-b" #'help-go-back
+ "C-c C-f" #'help-go-forward
+ "<XF86Back>" #'help-go-back
+ "<XF86Forward>" #'help-go-forward
+ "C-c C-c" #'help-follow-symbol
+ "s" #'help-view-source
+ "I" #'help-goto-lispref-info
+ "i" #'help-goto-info
+ "c" #'help-customize)
(easy-menu-define help-mode-menu help-mode-map
"Menu for Help mode."
@@ -265,7 +266,9 @@ The format is (FUNCTION ARGS...).")
(let* ((location
(find-function-search-for-symbol fun type file))
(position (cdr location)))
- (pop-to-buffer (car location))
+ (if help-window-keep-selected
+ (pop-to-buffer-same-window (car location))
+ (pop-to-buffer (car location)))
(run-hooks 'find-function-after-hook)
(if position
(progn
@@ -273,6 +276,10 @@ The format is (FUNCTION ARGS...).")
(when (or (< position (point-min))
(> position (point-max)))
(widen))
+ ;; Save mark for the old location, unless the point is not
+ ;; actually going to move.
+ (unless (= (point) position)
+ (push-mark nil t))
(goto-char position))
(message "Unable to find location in file")))))
@@ -287,7 +294,10 @@ The format is (FUNCTION ARGS...).")
(setq file (locate-library file t))
(if (and file (file-readable-p file))
(progn
- (pop-to-buffer (find-file-noselect file))
+ (if help-window-keep-selected
+ (pop-to-buffer-same-window
+ (find-file-noselect file))
+ (pop-to-buffer (find-file-noselect file)))
(widen)
(goto-char (point-min))
(if (re-search-forward
@@ -306,7 +316,9 @@ The format is (FUNCTION ARGS...).")
(setq file (help-C-file-name var 'var)))
(let* ((location (find-variable-noselect var file))
(position (cdr location)))
- (pop-to-buffer (car location))
+ (if help-window-keep-selected
+ (pop-to-buffer-same-window (car location))
+ (pop-to-buffer (car location)))
(run-hooks 'find-function-after-hook)
(if position
(progn
@@ -327,7 +339,9 @@ The format is (FUNCTION ARGS...).")
(let* ((location
(find-function-search-for-symbol fun 'defface file))
(position (cdr location)))
- (pop-to-buffer (car location))
+ (if help-window-keep-selected
+ (pop-to-buffer-same-window (car location))
+ (pop-to-buffer (car location)))
(if position
(progn
;; Widen the buffer if necessary to go to this position.
@@ -369,9 +383,18 @@ The format is (FUNCTION ARGS...).")
:supertype 'help-xref
'help-function
(lambda (file pos)
- (view-buffer-other-window (find-file-noselect file))
+ (if help-window-keep-selected
+ (view-buffer (find-file-noselect file))
+ (view-buffer-other-window (find-file-noselect file)))
(goto-char pos))
'help-echo (purecopy "mouse-2, RET: show corresponding NEWS announcement"))
+
+;;;###autoload
+(defun help-mode--add-function-link (str fun)
+ (make-text-button (copy-sequence str) nil
+ 'type 'help-function
+ 'help-args (list fun)))
+
(defvar bookmark-make-record-function)
(defvar help-mode--current-data nil)
@@ -379,7 +402,8 @@ The format is (FUNCTION ARGS...).")
;;;###autoload
(define-derived-mode help-mode special-mode "Help"
"Major mode for viewing help text and navigating references in it.
-Entry to this mode runs the normal hook `help-mode-hook'.
+Also see the `help-enable-variable-value-editing' variable.
+
Commands:
\\{help-mode-map}"
(setq-local revert-buffer-function
@@ -389,17 +413,21 @@ Commands:
help-mode-tool-bar-map)
(setq-local help-mode--current-data nil)
(setq-local bookmark-make-record-function
- #'help-bookmark-make-record))
+ #'help-bookmark-make-record)
+ (unless search-default-mode
+ (isearch-fold-quotes-mode)))
;;;###autoload
(defun help-mode-setup ()
"Enter Help mode in the current buffer."
+ (declare (obsolete nil "29.1"))
(help-mode)
(setq buffer-read-only nil))
;;;###autoload
(defun help-mode-finish ()
"Finalize Help mode setup in current buffer."
+ (declare (obsolete nil "29.1"))
(when (derived-mode-p 'help-mode)
(setq buffer-read-only t)
(help-make-xrefs (current-buffer))))
@@ -424,6 +452,7 @@ Commands:
"\\(symbol\\|program\\|property\\)\\|" ; Don't link
"\\(source \\(?:code \\)?\\(?:of\\|for\\)\\)\\)"
"[ \t\n]+\\)?"
+ "\\(\\\\\\+\\)?"
"['`‘]\\(\\(?:\\sw\\|\\s_\\)+\\|`\\)['’]"))
"Regexp matching doc string references to symbols.
@@ -484,17 +513,16 @@ restore it properly when going back."
;;;###autoload
(defun help-buffer ()
"Return the name of a buffer for inserting help.
-If `help-xref-following' is non-nil, this is the name of the
-current buffer. Signal an error if this buffer is not derived
-from `help-mode'.
+If `help-xref-following' is non-nil and the current buffer is
+derived from `help-mode', this is the name of the current buffer.
+
Otherwise, return \"*Help*\", creating a buffer with that name if
it does not already exist."
- (buffer-name ;for with-output-to-temp-buffer
- (if (not help-xref-following)
- (get-buffer-create "*Help*")
- (unless (derived-mode-p 'help-mode)
- (error "Current buffer is not in Help mode"))
- (current-buffer))))
+ (buffer-name ;for with-output-to-temp-buffer
+ (if (and help-xref-following
+ (derived-mode-p 'help-mode))
+ (current-buffer)
+ (get-buffer-create "*Help*"))))
(defvar describe-symbol-backends
`((nil ,#'fboundp ,(lambda (s _b _f) (describe-function s)))
@@ -513,6 +541,12 @@ Each element has the form (NAME TESTFUN DESCFUN) where:
and a frame), inserts the description of that symbol in the current buffer
and returns that text as well.")
+(defcustom help-clean-buttons nil
+ "If non-nil, remove quotes around link buttons."
+ :version "29.1"
+ :type 'boolean
+ :group 'help)
+
;;;###autoload
(defun help-make-xrefs (&optional buffer)
"Parse and hyperlink documentation cross-references in the given BUFFER.
@@ -600,27 +634,28 @@ that."
;; Quoted symbols
(save-excursion
(while (re-search-forward help-xref-symbol-regexp nil t)
- (let* ((data (match-string 8))
- (sym (intern-soft data)))
- (if sym
- (cond
- ((match-string 3) ; `variable' &c
- (and (or (boundp sym) ; `variable' doesn't ensure
+ (when-let ((sym (intern-soft (match-string 9))))
+ (if (match-string 8)
+ (delete-region (match-beginning 8)
+ (match-end 8))
+ (cond
+ ((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)
- (help-xref-button 8 'help-function-def sym))
- ((cl-some (lambda (x) (funcall (nth 1 x) sym))
- describe-symbol-backends)
- (help-xref-button 8 'help-symbol sym)))))))
+ (get sym 'variable-documentation))
+ (help-xref-button 9 'help-variable sym)))
+ ((match-string 4) ; `function' &c
+ (and (fboundp sym) ; similarly
+ (help-xref-button 9 'help-function sym)))
+ ((match-string 5) ; `face'
+ (and (facep sym)
+ (help-xref-button 9 'help-face sym)))
+ ((match-string 6)) ; nothing for `symbol'
+ ((match-string 7)
+ (help-xref-button 9 'help-function-def sym))
+ ((cl-some (lambda (x) (funcall (nth 1 x) sym))
+ describe-symbol-backends)
+ (help-xref-button 9 'help-symbol sym)))))))
;; An obvious case of a key substitution:
(save-excursion
(while (re-search-forward
@@ -631,34 +666,7 @@ that."
"\\<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-p "\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))))))
+ (help-xref-button 1 'help-function sym))))))
(set-syntax-table stab))
;; Delete extraneous newlines at the end of the docstring
(goto-char (point-max))
@@ -687,12 +695,26 @@ that."
MATCH-NUMBER is the subexpression of interest in the last matched
regexp. TYPE is the type of button to use. Any remaining arguments are
passed to the button's help-function when it is invoked.
-See `help-make-xrefs'."
+See `help-make-xrefs'.
+
+This function removes quotes surrounding the match if the
+variable `help-clean-buttons' is non-nil."
;; Don't mung properties we've added specially in some instances.
- (unless (button-at (match-beginning match-number))
- (make-text-button (match-beginning match-number)
- (match-end match-number)
- 'type type 'help-args args)))
+ (let ((beg (match-beginning match-number))
+ (end (match-end match-number)))
+ (unless (button-at beg)
+ (make-text-button beg end 'type type 'help-args args)
+ (when (and help-clean-buttons
+ (> beg (point-min))
+ (save-excursion
+ (goto-char (1- beg))
+ (looking-at "['`‘]"))
+ (< end (point-max))
+ (save-excursion
+ (goto-char end)
+ (looking-at "['’]")))
+ (delete-region end (1+ end))
+ (delete-region (1- beg) beg)))))
;;;###autoload
(defun help-insert-xref-button (string type &rest args)
@@ -795,6 +817,26 @@ See `help-make-xrefs'."
(help-xref-go-forward (current-buffer))
(user-error "No next help buffer")))
+(defun help-goto-next-page ()
+ "Go to the next page (if any) in the current buffer.
+The help buffers are divided into \"pages\" by the ^L character."
+ (interactive nil help-mode)
+ (push-mark)
+ (forward-page)
+ (unless (eobp)
+ (forward-line 1)))
+
+(defun help-goto-previous-page ()
+ "Go to the previous page (if any) in the current buffer.
+(If not at the start of a page, go to the start of the current page.)
+
+The help buffers are divided into \"pages\" by the ^L character."
+ (interactive nil help-mode)
+ (push-mark)
+ (backward-page (if (looking-back "\f\n" (- (point) 5)) 2 1))
+ (unless (bobp)
+ (forward-line 1)))
+
(defun help-view-source ()
"View the source of the current help item."
(interactive nil help-mode)
@@ -811,7 +853,16 @@ See `help-make-xrefs'."
(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))
+ 'emacs-lisp-mode
+ help-window-keep-selected))
+
+(defun help-goto-lispref-info ()
+ "View the Emacs Lisp manual *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-only))
(defun help-customize ()
"Customize variable or face whose doc string is shown in the current buffer."
@@ -921,6 +972,7 @@ BOOKMARK is a bookmark name or a bookmark record."
(pop-to-buffer "*Help*")
(goto-char position)))
+(put 'help-bookmark-jump 'bookmark-handler-type "Help")
(provide 'help-mode)