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.el116
1 files changed, 97 insertions, 19 deletions
diff --git a/lisp/help-mode.el b/lisp/help-mode.el
index f931a255093..0f4c5cd61ee 100644
--- a/lisp/help-mode.el
+++ b/lisp/help-mode.el
@@ -40,6 +40,7 @@
(define-key help-mode-map [mouse-2] 'help-follow-mouse)
(define-key help-mode-map "\C-c\C-b" 'help-go-back)
+(define-key help-mode-map "\C-c\C-f" 'help-go-forward)
(define-key help-mode-map "\C-c\C-c" 'help-follow-symbol)
;; Documentation only, since we use minor-mode-overriding-map-alist.
(define-key help-mode-map "\r" 'help-follow)
@@ -52,13 +53,28 @@ To use the element, do (apply FUNCTION ARGS) then goto the point.")
(put 'help-xref-stack 'permanent-local t)
(make-variable-buffer-local 'help-xref-stack)
+(defvar help-xref-forward-stack nil
+ "The stack of used to navigate help forwards after using the back button.
+Used by `help-follow' 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)
+(make-variable-buffer-local 'help-xref-forward-stack)
+
(defvar help-xref-stack-item nil
"An item for `help-follow' in this buffer to push onto `help-xref-stack'.
The format is (FUNCTION ARGS...).")
(put 'help-xref-stack-item 'permanent-local t)
(make-variable-buffer-local 'help-xref-stack-item)
+(defvar help-xref-stack-forward-item nil
+ "An item for `help-go-back' to push onto `help-xref-forward-stack'.
+The format is (FUNCTION ARGS...).")
+(put 'help-xref-stack-forward-item 'permanent-local t)
+(make-variable-buffer-local 'help-xref-stack-forward-item)
+
(setq-default help-xref-stack nil help-xref-stack-item nil)
+(setq-default help-xref-forward-stack nil help-xref-forward-stack-item nil)
(defcustom help-mode-hook nil
"Hook run by `help-mode'."
@@ -123,6 +139,11 @@ The format is (FUNCTION ARGS...).")
'help-function #'help-xref-go-back
'help-echo (purecopy "mouse-2, RET: go back to previous help buffer"))
+(define-button-type 'help-forward
+ :supertype 'help-xref
+ 'help-function #'help-xref-go-forward
+ 'help-echo (purecopy "mouse-2, RET: move forward to next help buffer"))
+
(define-button-type 'help-info
:supertype 'help-xref
'help-function #'info
@@ -200,13 +221,22 @@ Commands:
(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))
- (one-window-p t)
- (delete-window))))
+ (set (make-local-variable 'view-no-disable-on-exit) t)
+ ;; With Emacs 22 `view-exit-action' could delete the selected window
+ ;; disregarding whether the help buffer was shown in that window at
+ ;; all. Since `view-exit-action' is called with the help buffer as
+ ;; argument it seems more appropriate to have it work on the buffer
+ ;; only and leave it to `view-mode-exit' to delete any associated
+ ;; window(s).
+ (setq view-exit-action
+ (lambda (buffer)
+ ;; Use `with-current-buffer' to make sure that `bury-buffer'
+ ;; also removes BUFFER from the selected window.
+ (with-current-buffer buffer
+ (bury-buffer))))
+
(run-mode-hooks 'help-mode-hook))
;;;###autoload
@@ -216,16 +246,23 @@ Commands:
;;;###autoload
(defun help-mode-finish ()
- (let ((entry (assq (selected-window) view-return-to-alist)))
- (if entry
- ;; When entering Help mode from the Help window,
- ;; such as by following a link, preserve the same
- ;; meaning for the q command.
- ;; (setcdr entry (cons (selected-window) help-return-method))
- nil
- (setq view-return-to-alist
- (cons (cons (selected-window) help-return-method)
- view-return-to-alist))))
+ (if (eq help-window t)
+ ;; If `help-window' is t, `view-return-to-alist' is handled by
+ ;; `with-help-window'. In this case set `help-window' to the
+ ;; selected window since now is the only moment where we can
+ ;; unambiguously identify it.
+ (setq help-window (selected-window))
+ (let ((entry (assq (selected-window) view-return-to-alist)))
+ (if entry
+ ;; When entering Help mode from the Help window,
+ ;; such as by following a link, preserve the same
+ ;; meaning for the q command.
+ ;; (setcdr entry (cons (selected-window) help-return-method))
+ nil
+ (setq view-return-to-alist
+ (cons (cons (selected-window) help-return-method)
+ view-return-to-alist)))))
+
(when (eq major-mode 'help-mode)
;; View mode's read-only status of existing *Help* buffer is lost
;; by with-output-to-temp-buffer.
@@ -242,6 +279,9 @@ Commands:
(defvar help-back-label (purecopy "[back]")
"Label to use by `help-make-xrefs' for the go-back reference.")
+(defvar help-forward-label (purecopy "[forward]")
+ "Label to use by `help-make-xrefs' for the go-forward reference.")
+
(defconst help-xref-symbol-regexp
(purecopy (concat "\\(\\<\\(\\(variable\\|option\\)\\|" ; Link to var
"\\(function\\|command\\)\\|" ; Link to function
@@ -286,7 +326,8 @@ because we want to record the \"previous\" position of point so we can
restore it properly when going back."
(with-current-buffer (help-buffer)
(when help-xref-stack-item
- (push (cons (point) help-xref-stack-item) help-xref-stack))
+ (push (cons (point) help-xref-stack-item) help-xref-stack)
+ (setq help-xref-forward-stack nil))
(when interactive-p
(let ((tail (nthcdr 10 help-xref-stack)))
;; Truncate the stack.
@@ -296,6 +337,7 @@ restore it properly when going back."
(defvar help-xref-following nil
"Non-nil when following a help cross-reference.")
+;;;###autoload
(defun help-buffer ()
(buffer-name ;for with-output-to-temp-buffer
(if help-xref-following
@@ -477,11 +519,19 @@ that."
(while (and (not (bobp)) (bolp))
(delete-char -1))
(insert "\n")
+ (when (or help-xref-stack help-xref-forward-stack)
+ (insert "\n"))
;; Make a back-reference in this buffer if appropriate.
(when help-xref-stack
- (insert "\n")
(help-insert-xref-button help-back-label 'help-back
- (current-buffer))
+ (current-buffer)))
+ ;; Make a forward-reference in this buffer if appropriate.
+ (when 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 help-xref-forward-stack)
(insert "\n")))
;; View mode steals RET from us.
(set (make-local-variable 'minor-mode-overriding-map-alist)
@@ -600,6 +650,7 @@ help buffer."
"From BUFFER, go back to previous help buffer text using `help-xref-stack'."
(let (item position method args)
(with-current-buffer buffer
+ (push (cons (point) help-xref-stack-item) help-xref-forward-stack)
(when help-xref-stack
(setq item (pop help-xref-stack)
;; Clear the current item so that it won't get pushed
@@ -615,6 +666,26 @@ help buffer."
(set-window-point (get-buffer-window buffer) position)
(goto-char position)))))
+(defun help-xref-go-forward (buffer)
+ "From BUFFER, go forward to next help buffer."
+ (let (item position method args)
+ (with-current-buffer buffer
+ (push (cons (point) help-xref-stack-item) help-xref-stack)
+ (when help-xref-forward-stack
+ (setq item (pop help-xref-forward-stack)
+ ;; Clear the current item so that it won't get pushed
+ ;; by the function we're about to call. TODO: We could also
+ ;; push it onto a "forward" stack and add a `forw' button.
+ help-xref-stack-item nil
+ position (car item)
+ method (cadr item)
+ args (cddr item))))
+ (apply method args)
+ (with-current-buffer buffer
+ (if (get-buffer-window buffer)
+ (set-window-point (get-buffer-window buffer) position)
+ (goto-char position)))))
+
(defun help-go-back ()
"Go back to previous topic in this help buffer."
(interactive)
@@ -622,6 +693,13 @@ help buffer."
(help-xref-go-back (current-buffer))
(error "No previous help buffer")))
+(defun help-go-forward ()
+ "Go back to next topic in this help buffer."
+ (interactive)
+ (if help-xref-forward-stack
+ (help-xref-go-forward (current-buffer))
+ (error "No next help buffer")))
+
(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