Como controlar em qual janela um buffer é exibido?

13

P: como posso controlar qual janela é org-deadlineusada para exibir o calendário?

org-deadlineabre temporariamente o calendarbuffer em uma janela ao definir um prazo e, em seguida, fecha-o novamente após a conclusão. Quando existe apenas uma janela, ela abre uma nova janela na parte inferior do quadro existente. Quando há várias janelas, ele seleciona uma - presumo que seja algo parecido get-lru-window- entre as janelas disponíveis.

O último é problemático se ele assumir uma das outras janelas com as informações necessárias para definir o prazo (data, hora etc.). Geralmente, esse é um problema em uma configuração de janela, como:

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

Ao adicionar um prazo ao arquivo da agenda em (A), org-deadlineassumirá o controle (B) ou (C), que contém e-mails com as informações de data / hora de que preciso. Eu prefiro muito isso, se eu estiver ligandoorg-deadline de (A), ele abriria uma janela temporária (D) para conter o calendarbuffer, conforme abaixo:

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

Então: como uma força org-deadline (e funções análogas) uma nova janela temporária na parte inferior da janela ativa, em vez de assumir uma das outras?

PS: Estou ciente das janelas dedicadas , mas elas não me parecem a melhor abordagem, pois não é tanto o fato de eu querer dedicar buffers para as janelas quanto evitar evitar que uma função assuma um dos "curtos" uns.

Dan
fonte
Eu realmente espero que alguém volte com uma resposta que dê um bom controle sobre janelas novas e temporárias. ( popwin.el ?? display-buffer-alist) Mas acho que há uma ruga adicional aqui, porque os org-deadlineusos calendarque se esforçam muito para controlar qual janela usar. cf os comentários em calendar-basic-setup.
purple_arrows

Respostas:

10

A seguir, faça o que você deseja.

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

O calendário usa a função calendar-basic-setuppara exibir o buffer do calendário; calendar-basic-setuppor sua vez, usa o pop-to-bufferque, por sua vez, usa display-bufferpara exibir o buffer do calendário. Agora display-bufferé altamente personalizável e nos permite fornecer funções para exibir um buffer usando determinadas variáveis ​​que usamos display-buffer-alistaqui.

Basicamente, estamos dizendo ao emacs para usar a função my-position-calendar-buffer para exibir um buffer correspondente ao regexp \*Calendar\*. A funçãomy-position-calendar-buffer procura uma janela exibindo a agenda organizacional; se não encontrar nenhuma janela, não fará nada; nesse caso display-buffer, tentará outras funções para exibir o buffer. Caso seja encontrada uma janela exibindo a agenda organizacional, a função divide essa janela verticalmente e exibe o buffer do calendário.

Eu não testei isso completamente (tentei iniciar o calendário com a exibição da agenda e sem a exibição da agenda), parece estar funcionando, mas pode haver alguns erros.

Iqbal Ansari
fonte
1
Seria preferível usar algo como add-to-listno display-buffer-alist. O uso setqsubstitui outras personalizações.
Malabarba
@ Malabarba obrigado pela sugestão, corrigida!
Iqbal Ansari