Q: how can I control which window org-deadline uses to display the calendar?

org-deadline temporarily pops up the calendar buffer in a window when setting a deadline, and then closes it again after completing. When there is only one window, it pops a new window at the bottom of the existing frame. When there are multiple windows, it selects one -- I presume with something like get-lru-window -- of the available windows.

The latter is problematic if it takes over one of the other windows that has the information I need in order to set the deadline (date, time, etc.) This is commonly a problem in a window setup such as:

+--------------------+--------------------+
|                    |                    |
|                    |  (B: mu4e header)  |
|                    |                    |
|                    +--------------------+
|  (A: agenda file)  |                    |
|                    |                    |
|                    |                    |
|                    |  (C: mu4e view)    |
|                    |                    |
|                    |                    |
|                    |                    |
+--------------------+--------------------+

When adding a deadline to the agenda file in (A), org-deadline will take over (B) or (C), which contain emails that have the date/time information I need. I'd much prefer that, if I'm calling org-deadline from (A), it would pop a temporary window (D) to contain the calendar buffer as below:

+--------------------+--------------------+
|                    |                    |
|                    |  (B: mu4e header)  |
|                    |                    |
|                    +--------------------+
|  (A: agenda file)  |                    |
|                    |                    |
|                    |                    |
+--------------------+  (C: mu4e view)    |
|                    |                    |
|   (D: calendar)    |                    |
|                    |                    |
+--------------------+--------------------+

So: how would one force org-deadline (and analogous functions) to pop a new, temporary window at the bottom of the active window rather than take over one of the other ones?

PS: I'm aware of dedicated windows, but they don't strike me as the best approach since it's not so much that I want to dedicate buffers to windows as I want to avoid having a function take over one of the "short" ones.

  • I really hope somebody comes back with an answer that gives fine control over new, temporary windows. (popwin.el? display-buffer-alist?) But I think there's an additional wrinkle here because org-deadline uses calendar which itself goes way out of its way to control what window to use. c.f. the comments in calendar-basic-setup. – purple_arrows Oct 6 '14 at 14:34
up vote 10 down vote accepted

Following should do what you want.

(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 (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)))

Calendar uses the function calendar-basic-setup to display the calendar buffer, calendar-basic-setup in turn uses pop-to-buffer which in turn uses display-buffer to display the calendar buffer. Now display-buffer is highly customizable and allows us to provide functions to display a buffer using certain variables we use one such variable display-buffer-alist here.

Basically we are saying emacs to use the function my-position-calendar-buffer to display a buffer matching the regexp \*Calendar\*. The function my-position-calendar-buffer searches for a window displaying org agenda, if it does not find any such window, it does nothing in which case display-buffer will try some other functions to display the buffer. In case a window displaying org-agenda is found the function splits that window vertically and displays the calendar buffer.

I have not tested this throughly (just tried starting calendar with agenda view and without agenda view), it seems to be working but there might be some bugs.

  • 1
    It would be preferable to use something like add-to-list on display-buffer-alist. Using setq overrides other customizations. – Malabarba Oct 6 '14 at 21:37
  • @Malabarba thanks for the suggestion, fixed! – Iqbal Ansari Oct 7 '14 at 0:48

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.