From what I understand, Emacs splits windows by first trying a horizontal split and then a vertical split. I'm fine with that behavior, except when in fullscreen
mode. I've tried several of the solutions posted in the answers to this very similar question and they almost work. So, I can set it so the new window appears to the right of the current one whenever the current window is wide enough, and below otherwise, in most cases by using this bit of code:
(with-eval-after-load "window"
(defcustom split-window-below nil
"If non-nil, vertical splits produce new windows below."
:group 'windows
:type 'boolean)
(defcustom split-window-right nil
"If non-nil, horizontal splits produce new windows to the right."
:group 'windows
:type 'boolean)
(fmakunbound #'split-window-sensibly)
(defun split-window-sensibly
(&optional window)
(setq window (or window (selected-window)))
(or (and (window-splittable-p window t)
;; Split window horizontally.
(split-window window nil (if split-window-right 'left 'right)))
(and (window-splittable-p window)
;; Split window vertically.
(split-window window nil (if split-window-below 'above 'below)))
(and (eq window (frame-root-window (window-frame window)))
(not (window-minibuffer-p window))
;; If WINDOW is the only window on its frame and is not the
;; minibuffer window, try to split it horizontally disregarding the
;; value of `split-width-threshold'.
(let ((split-width-threshold 0))
(when (window-splittable-p window t)
(split-window window nil (if split-window-right
'left
'right))))))))
(setq-default split-height-threshold 4
split-width-threshold 160) ; the reasonable limit for horizontal splits
However, when opening a calendar buffer, the buffer appears on the right of the current window no matter how narrow it is.
I tried looking into the definition of the calendar
function, but I can't quite figure out how to make it behave the way I want it to---I'm very new to elisp
and Emacs in general. Looking at the answer to this question I found the following seems to work but only when calling calendar
from the org-agenda
buffer:
(defun my-window-displaying-agenda-p (window)
(equal (with-current-buffer (window-buffer window) major-mode)
'org-agenda-mode))
(defun my-position-calendar-buffer (buffer alist)
(let ((agenda-window (car (cl-remove-if-not #'my-window-displaying-agenda-p (window-list)))))
(when agenda-window
(let ((desired-window (split-window agenda-window nil 'below)))
(set-window-buffer desired-window buffer)
desired-window))))
(add-to-list 'display-buffer-alist (cons "\\*Calendar\\*" (cons #'my-position-calendar-buffer nil)))
I can sort of see how to tweak the function my-position-calendar-buffer
so that the calendar always shows at the bottom, say. But I'd like to have the position of the calendar buffer depend on the window width, and would like to understand how to get a unified solution to both problems.