--- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -200,6 +200,64 @@ 'help-customize-face (customize-face v)) 'help-echo (purecopy "mouse-2, RET: customize face")) +(defvar help-link-follow nil + "Information stored by `help-link-follow'. +If this is non-nil, `help-function-def--button-function' will try to +display its location in the \"same\" window.") + +(defun help-link-follow () + "Follow or return from first link in help window. +If this function finds a help window, it will try to display in +that window the buffer referred to by the first link found in its +help buffer. If there is no help window, this function will try +to restore the help window from an earlier followed link." + (interactive) + (cond + ((let* ((buffer (get-buffer "*Help*")) + (window (and buffer (get-buffer-window buffer)))) + (and window + (with-selected-window window + (save-excursion + (let ((button (forward-button (point-min))) + (par (window-parameter window 'quit-restore))) + (if button + (condition-case nil + (progn + (setq help-link-follow (list buffer window par)) + (button-activate button)) + (error (setq help-link-follow nil))) + (user-error "No link found")))))))) + ((and help-link-follow + (buffer-live-p (nth 0 help-link-follow)) + (window-live-p (nth 1 help-link-follow))) + (let* ((window (nth 1 help-link-follow)) + (buffer (window-buffer window))) + (set-window-buffer window (nth 0 help-link-follow)) + (when (nth 2 help-link-follow) + ;; Pretend that the window's buffer was never displayed in this + ;; window to avoid that quitting the help window restores that + ;; buffer in the help window. + (set-window-prev-buffers + window (assq-delete-all buffer (window-prev-buffers window))) + (set-window-parameter + window 'quit-restore (nth 2 help-link-follow))) + (setq help-link-follow nil))) + (t + (setq help-link-follow nil) + (user-error "No help link found")))) + +(defun help-window-quit () + "Quit any help window found." + (interactive) + (let* ((buffer (get-buffer "*Help*")) + (window (and buffer (get-buffer-window buffer)))) + (if window + (quit-restore-window window) + (user-error "No help window found")))) + +(define-key help-map "\C-l" 'help-link-follow) +(define-key help-map "\C-q" 'help-window-quit) + (defun help-function-def--button-function (fun &optional file type) (or file (setq file (find-lisp-object-file-name fun type))) @@ -214,7 +272,10 @@ help-function-def--button-function (let* ((location (find-function-search-for-symbol fun type file)) (position (cdr location))) - (pop-to-buffer (car location)) + (if help-link-follow + (display-buffer + (car location) display-buffer--same-window-action) + (pop-to-buffer (car location))) (run-hooks 'find-function-after-hook) (if position (progn