Как контролировать, в каком окне отображается буфер?

13

Вопрос: как я могу контролировать, какое окно org-deadlineиспользуется для отображения календаря?

org-deadlineвременно устанавливает calendarбуфер в окне при установке крайнего срока, а затем снова закрывает его после завершения. Когда есть только одно окно, оно открывает новое окно внизу существующего фрейма. Когда имеется несколько окон, он выбирает одно - я полагаю, что-то вроде get-lru-window- из доступных окон.

Последнее проблематично, если оно занимает одно из других окон, в котором есть информация, которая мне нужна, чтобы установить крайний срок (дата, время и т. Д.). Обычно это проблема в настройке окна, например:

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

При добавлении крайнего срока в файл повестки дня в (A), org-deadlineбудут использоваться (B) или (C), которые содержат электронные письма с информацией о дате / времени, которая мне нужна. Я бы предпочел, чтобы, если я звоню org-deadlineиз (A), во всплывающем временном окне (D) содержался calendarбуфер, как показано ниже:

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

Итак: как можно заставить org-deadline(и аналогичные функции) открыть новое временное окно в нижней части активного окна, а не захватить одно из других?

PS: я знаю о выделенных окнах , но они не кажутся мне лучшим подходом, так как я не столько хочу выделять буферы окнам, сколько хочу, чтобы одна функция не заняла одно из «коротких» из них.

Дэн
источник
Я действительно надеюсь, что кто-то вернется с ответом, который дает прекрасный контроль над новыми временными окнами. ( popwin.el ?? display-buffer-alist) Но я думаю, что здесь есть дополнительная складка, потому что org-deadlineиспользование, calendarкоторое само по себе делает все возможное, чтобы контролировать, какое окно использовать. см. комментарии в calendar-basic-setup.
purple_arrows

Ответы:

10

Следующие должны делать то, что вы хотите.

(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-basic-setupдля отображения буфера календаря, calendar-basic-setupв свою очередь использует, pop-to-bufferкоторый в свою очередь использует display-bufferдля отображения буфера календаря. Теперь display-bufferон легко настраивается и позволяет нам предоставлять функции для отображения буфера, используя определенные переменные, здесь мы используем одну такую ​​переменную display-buffer-alist.

По сути, мы говорим, что emacs использует функцию my-position-calendar-bufferдля отображения буфера, соответствующего регулярному выражению \*Calendar\*. Функция my-position-calendar-bufferищет окно, отображающее повестку дня org, если оно не находит ни одного такого окна, она ничего не делает, в этом случае display-bufferона попытается использовать некоторые другие функции для отображения буфера. В случае обнаружения окна, отображающего org-повестки дня, функция разбивает это окно по вертикали и отображает буфер календаря.

Я не проверил это тщательно (только попробовал запустить календарь с видом на повестку дня и без представления на повестке дня), похоже, он работает, но могут быть некоторые ошибки.

Икбал Ансари
источник
1
Было бы предпочтительнее использовать что-то вроде add-to-listна display-buffer-alist. Использование setqпереопределяет другие настройки.
Малабарба
@ Malabarba спасибо за предложение, исправлено!
Икбал Ансари