Jak kontrolować, w którym oknie wyświetlany jest bufor?

13

P: Jak mogę kontrolować, które okno org-deadlineużywa do wyświetlania kalendarza?

org-deadlinetymczasowo wyświetla calendarbufor w oknie podczas ustawiania terminu, a następnie zamyka go ponownie po zakończeniu. Gdy jest tylko jedno okno, pojawia się nowe okno na dole istniejącej ramki. Kiedy jest wiele okien, wybiera jedno - przypuszczam z czymś podobnym get-lru-window- z dostępnych okien.

To ostatnie jest problematyczne, jeśli przejmuje jedno z pozostałych okien, które zawierają informacje potrzebne do ustalenia terminu (data, godzina itp.). Jest to zwykle problem w konfiguracji okna, takiej jak:

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

Dodając termin do pliku agendy w (A), org-deadlineprzejmie (B) lub (C), które zawierają e-maile zawierające potrzebne mi informacje o dacie / godzinie. Wolałbym, że jeśli dzwonię org-deadlinez (A), wyskakuje tymczasowe okno (D) zawierające calendarbufor, jak poniżej:

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

Więc: w jaki sposób zmusić org-deadline(i analogiczne funkcje), by otworzyło nowe, tymczasowe okno na dole aktywnego okna, zamiast przejmować jedno z pozostałych?

PS: Zdaję sobie sprawę z dedykowanych okien , ale nie wydają mi się najlepszym podejściem, ponieważ nie chodzi o to, że chcę poświęcić bufory oknom, ponieważ chcę uniknąć przejęcia funkcji przez jeden z „krótkich” te.

Dan
źródło
Naprawdę mam nadzieję, że ktoś wróci z odpowiedzią, która daje doskonałą kontrolę nad nowymi, tymczasowymi oknami. ( popwin.el ?? display-buffer-alist) Ale myślę, że tutaj jest dodatkowy zmarszczek, ponieważ org-deadlinezastosowania, calendarktóre same w sobie wykraczają daleko poza to, aby kontrolować, którego okna użyć. por. komentarze w calendar-basic-setup.
purple_arrows

Odpowiedzi:

10

Następujące powinny robić, co chcesz.

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

Kalendarz używa funkcji calendar-basic-setupdo wyświetlania bufora kalendarza, calendar-basic-setupz kolei używa, pop-to-bufferktóry z kolei używa display-bufferdo wyświetlania bufora kalendarza. Teraz display-bufferjest wysoce konfigurowalny i pozwala nam udostępniać funkcje do wyświetlania bufora przy użyciu pewnych zmiennych, których używamy tutaj jedną taką zmienną display-buffer-alist.

Mówimy w zasadzie, że emacs używa funkcji my-position-calendar-bufferdo wyświetlenia bufora pasującego do wyrażenia regularnego \*Calendar\*. Funkcja my-position-calendar-bufferwyszukuje okno wyświetlające porządek obrad, jeśli nie znajdzie takiego okna, nie robi nic, w takim przypadku display-bufferspróbuje wyświetlić inne funkcje do wyświetlenia bufora. W przypadku znalezienia okna wyświetlającego porządek obrad, funkcja dzieli okno w pionie i wyświetla bufor kalendarza.

Nie przetestowałem tego dokładnie (po prostu spróbowałem uruchomić kalendarz z widokiem agendy i bez widoku agendy), wydaje się, że działa, ale mogą być pewne błędy.

Iqbal Ansari
źródło
1
Lepiej byłoby użyć czegoś takiego jak add-to-listna display-buffer-alist. Używanie setqzastępuje inne dostosowania.
Malabarba
@Malabarba dzięki za sugestię, naprawione!
Iqbal Ansari