¿Cómo controlar en qué ventana se muestra un búfer?

13

P: ¿cómo puedo controlar qué ventana org-deadlineusa para mostrar el calendario?

org-deadlineaparece temporalmente el calendarbúfer en una ventana al establecer una fecha límite, y luego lo cierra nuevamente después de completarlo. Cuando solo hay una ventana, aparece una nueva ventana en la parte inferior del marco existente. Cuando hay varias ventanas, selecciona una, supongo con algo así get-lru-window, de las ventanas disponibles.

Esto último es problemático si se hace cargo de una de las otras ventanas que tiene la información que necesito para establecer la fecha límite (fecha, hora, etc.) Esto es comúnmente un problema en una configuración de ventana como:

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

Al agregar una fecha límite al archivo de agenda en (A), org-deadlinese hará cargo de (B) o (C), que contienen correos electrónicos que tienen la información de fecha / hora que necesito. Preferiría mucho que, si estoy llamando org-deadlinedesde (A), se abrirá una ventana temporal (D) para contener el calendarbúfer como se muestra a continuación:

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

Entonces: ¿cómo forzaría uno org-deadline(y funciones análogas) a abrir una nueva ventana temporal en la parte inferior de la ventana activa en lugar de tomar el control de una de las otras?

PD: Soy consciente de las ventanas dedicadas , pero no me parecen el mejor enfoque, ya que no es tanto que quiera dedicar buffers a Windows , sino evitar que una función se haga cargo de uno de los "cortos" unos.

Dan
fuente
Realmente espero que alguien regrese con una respuesta que brinde un control preciso sobre ventanas nuevas y temporales. ( popwin.el ?? display-buffer-alist) Pero creo que hay una arruga adicional aquí porque org-deadlineusa la calendarque se sale de su camino para controlar qué ventana usar. cf los comentarios en calendar-basic-setup.
purple_arrows

Respuestas:

10

Los siguientes deben hacer lo que quieras.

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

Calendario usa la función calendar-basic-setuppara mostrar el búfer de calendario, calendar-basic-setupa su vez usa el pop-to-bufferque a su vez usa display-bufferpara mostrar el búfer de calendario. Ahora display-bufferes altamente personalizable y nos permite proporcionar funciones para mostrar un búfer utilizando ciertas variables, aquí usamos una de esas variables display-buffer-alist.

Básicamente estamos diciendo que emacs use la función my-position-calendar-bufferpara mostrar un búfer que coincida con la expresión regular \*Calendar\*. La función my-position-calendar-bufferbusca una ventana que muestre la agenda de la organización, si no encuentra dicha ventana, no hace nada, en cuyo caso display-bufferintentará otras funciones para mostrar el búfer. En caso de que se encuentre una ventana que muestre org-agenda, la función divide esa ventana verticalmente y muestra el búfer de calendario.

No he probado esto completamente (solo intenté iniciar el calendario con la vista de agenda y sin vista de agenda), parece estar funcionando, pero puede haber algunos errores.

Iqbal Ansari
fuente
1
Sería preferible usar algo como add-to-listen display-buffer-alist. El uso setqanula otras personalizaciones.
Malabarba
@Malabarba gracias por la sugerencia, arreglado!
Iqbal Ansari