The following answer will affect clicking on the filename link in the *Help*
buffer after calling either C-h v
aka M-x describe-variable
or C-h f
aka M-x describe-function
. The answer has been tested using Emacs 27, without any user-configuration other than the code snippet hereinbelow. It may also be possible to add an entry to the display-buffer-alist
with a custom function to achieve the desired behavior, but I chose to modify the code directly instead.
A comment by the O.P. in the linked thread, which was cited by the O.P. of the current thread, states (underneath the accepted answer) as follows: "just a quick note - I made it work just changing in help-function-def
and help-variable-def function
calls of pop-to-buffer
to switch-to-buffer
...." By examining the code at issue, I chose to use set-window-buffer
. So that anyone who uses this answer in the future can see that this works, I have included some messages at the outset of the functions ... feel free to comment them out after testing it "as-is" to verify it works as advertised. Don't forget to copy the last two (2) closing parentheses at the tail end of the code snippet ... I separated them so that we can visualize that they close out the with-eval-after-load
and progn
statements ...
(with-eval-after-load 'help-mode
(progn
(defun my-help-function-def--button-function (fun &optional file type)
(message "my-help-function-def--button-function: %s %s %s" fun file type)
(or file
(setq file (find-lisp-object-file-name fun type)))
(if (not file)
(message "Unable to find defining file")
(require 'find-func)
(when (eq file 'C-source)
(setq file
(help-C-file-name (indirect-function fun) 'fun)))
;; Don't use find-function-noselect because it follows
;; aliases (which fails for built-in functions).
(let* ((location (find-function-search-for-symbol fun type file))
(position (cdr location)))
;;; The original behavior is to call `pop-to-buffer' commented out hereinbelow:
;;; (pop-to-buffer (car location))
;;;
;;; The O.P. of the following thread wishes to display the function
;;; definition in the same window as the *Help* buffer:
;;; https://emacs.stackexchange.com/q/63176/2287
(set-window-buffer (selected-window) (car location))
(run-hooks 'find-function-after-hook)
(if position
(progn
;; Widen the buffer if necessary to go to this position.
(when (or (< position (point-min))
(> position (point-max)))
(widen))
(goto-char position))
(message "Unable to find location in file")))))
;;; In Emacs 27, the default behavior is to call `help-function-def--button-function'.
;;; The O.P. of the following thread wishes to display the function definition in
;;; the same window as the *Help* buffer: https://emacs.stackexchange.com/q/63176/2287
(define-button-type 'help-function-def
:supertype 'help-xref
'help-function #'my-help-function-def--button-function
'help-echo (purecopy "mouse-2, RET: find function's definition"))
(define-button-type 'help-variable-def
:supertype 'help-xref
'help-function (lambda (var &optional file)
(message "help-variable-def / help-function: %s %s" var file)
(when (eq file 'C-source)
(setq file (help-C-file-name var 'var)))
(let* ((location (find-variable-noselect var file))
(position (cdr location)))
;;; The original behavior is to call `pop-to-buffer' commented out hereinbelow:
;;; (pop-to-buffer (car location))
;;;
;;; The O.P. of the following thread wishes to display the variable
;;; definition in the same window as the *Help* buffer:
;;; https://emacs.stackexchange.com/q/63176/2287
(set-window-buffer (selected-window) (car location))
(run-hooks 'find-function-after-hook)
(if position
(progn
;; Widen the buffer if necessary to go to this position.
(when (or (< position (point-min))
(> position (point-max)))
(widen))
(goto-char position))
(message "Unable to find location in file"))))
'help-echo (purecopy "mouse-2, RET: find variable's definition"))
))