The function at issue is
pop-to-buffer, which is called within
xref--show-xref-buffer. The variable
xref-show-xrefs-function is set with the default value of
xref--show-xref-buffer. Thus, it is relatively simple to set the variable
xref-show-xrefs-function to a user-defined function. The example below replaces
xref--show-xref-buffer with a new function that calls a custom display-buffer function instead of
pop-to-buffer. Over the past few years, there have been a few threads on stackexchange/stackoverflow seeking to modify the default behavior of
pop-to-buffer, and there are a variety of approaches such as customizing the
display-buffer-alist, or installing additional libraries designed to trump the default behavior of displaying buffers in favor of a user-defined approach, or changing the
split-window-sensibly) to something else, and the list of other options/ideas goes on .... Inasmuch as the O.P. has indicated previously adjusting the variable
split-width-threshold, @lawlist did not invest any time attempting to customize that variable and/or the companion variable for splitting in the opposite direction (i.e.,
dired-do-find-regexp is bound in Emacs 25 to the capital letter
dired-mode. The following code will present the user with four options when performing a search at the outset, e.g., display the target buffer left, right, above, or below. Please feel free to hard-wire it to a particular direction (by passing the optional DIRECTION argument [
my-xref-display-buffer) if that seems more appealing. The sky is the limit in terms of customization, e.g., control size of the new window, etc. However, further customization is beyond the scope of this limited example.
(defun my-xref--show-xref-buffer (xrefs alist)
(let ((xref-alist (xref--analyze xrefs)))
(with-current-buffer (get-buffer-create xref-buffer-name)
(let ((inhibit-read-only t))
(setq xref--window (assoc-default 'window alist))
(defun my-display-buffer (buffer-or-name alist direction &optional size pixelwise)
"BUFFER: The buffer that will be displayed.
ALIST: See the doc-string of `display-buffer' for more information.
DIRECTION: Must use one of these symbols: 'left 'right 'below 'above
SIZE: See the doc-string for `split-window'.
PIXELWISE: See the doc-string for `split-window'.
There are three possibilities:
- (1) If a window on the frame already displays the target buffer,
then just reuse the same window.
- (2) If there is already a window in the specified direction in relation
to the selected window, then display the target buffer in said window.
- (3) If there is no window in the specified direction, then create one
in that direction and display the target buffer in said window."
(if (bufferp buffer-or-name)
((get-buffer-window buffer (selected-frame)))
(split-window (selected-window) size direction pixelwise)))))
(window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
(defun my-xref-display-buffer (buffer &optional direction alist)
"Display an xref results buffer in the desired direction: l/r/a/b."
(let ((char (read-char-exclusive (concat
(propertize "l" 'face '(:foreground "red"))
(propertize "eft" 'face '(:foreground "blue"))
" | ["
(propertize "r" 'face '(:foreground "red"))
(propertize "ight" 'face '(:foreground "blue"))
" | ["
(propertize "a" 'face '(:foreground "red"))
(propertize "bove" 'face '(:foreground "blue"))
" | ["
(propertize "b" 'face '(:foreground "red"))
(propertize "elow" 'face '(:foreground "blue"))))))
((eq char ?l)
((eq char ?r)
((eq char ?a)
((eq char ?b)
;;; FIXME: @lawlist may add a loop similar to `org-capture'
;;; whereby a new `read-char-exclusive' will be initiated if
;;; a user did not initially choose a valid option (l/r/a/b).
(let ((debug-on-quit nil)
(msg (concat "my-xref-display-buffer: "
"You did not select l/r/a/b "
(signal 'quit `(,msg)))))))))
(select-window (my-display-buffer buffer alist direction))))
(setq xref-show-xrefs-function 'my-xref--show-xref-buffer)