From 18fbb9985fe5c5cd0f5d04e77627dd83c403c1d1 Mon Sep 17 00:00:00 2001 From: Ihor Radchenko Date: Sun, 7 Apr 2024 13:34:13 +0300 Subject: [PATCH] Honor `display-buffer-alist' when creating dialogues * lisp/org-macs.el (org-display-buffer-split): New function to display just the new buffer and current buffer visible in the frame. To be used as `display-buffer' ACTION parameter. * lisp/org-agenda.el (org-agenda-get-restriction-and-command): (org-agenda-fit-window-to-buffer): (org-agenda-prepare-window): (org-agenda-switch-to): * lisp/org-capture.el (org-capture-place-template): * lisp/org-goto.el (org-goto-location): * lisp/org-src.el (org-src-switch-to-buffer): * lisp/org.el (org-tree-to-indirect-buffer): (org-fast-todo-selection): (org-add-log-note): (org-fast-tag-selection): (org-submit-bug-report): * lisp/ox.el (org-export--dispatch-ui): Get rid of calling `delete-other-windows' manually. Instead, make use of `org-display-buffer-slip' + `pop-to-buffer'/`display-buffer'. This way, user overrides in `display-buffer-alist' are honored. * lisp/org-plot.el (org-plot/gnuplot): * lisp/org.el (org-offer-links-in-entry): When `delete-other-windows' cannot be avoided, make it ignore errors in the frames where displaying a lone window is forbidden. --- lisp/org-agenda.el | 14 ++++++-------- lisp/org-capture.el | 6 +++--- lisp/org-goto.el | 8 ++++---- lisp/org-macs.el | 20 ++++++++++++++++++++ lisp/org-plot.el | 6 +++++- lisp/org-src.el | 7 ++++--- lisp/org.el | 41 ++++++++++++++++++++++------------------- lisp/ox.el | 4 +--- 8 files changed, 65 insertions(+), 41 deletions(-) diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index a9eb31072..97e247ebe 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -3123,8 +3123,7 @@ Agenda views are separated by `org-agenda-block-separator'." c entry key type match prefixes rmheader header-end custom1 desc line lines left right n n1) (save-window-excursion - (delete-other-windows) - (switch-to-buffer-other-window " *Agenda Commands*") + (pop-to-buffer " *Agenda Commands*" '(org-display-buffer-split)) (erase-buffer) (insert (eval-when-compile (let ((header @@ -3321,7 +3320,7 @@ s Search for keywords S Like s, but only TODO entries (fboundp 'fit-window-to-buffer) (if (and (= (cdr org-agenda-window-frame-fractions) 1.0) (= (car org-agenda-window-frame-fractions) 1.0)) - (delete-other-windows) + (display-buffer (current-buffer) '(display-buffer-full-frame)) (org-fit-window-to-buffer nil (floor (* (frame-height) (cdr org-agenda-window-frame-fractions))) @@ -3938,11 +3937,9 @@ FILTER-ALIST is an alist of filters we need to apply when (switch-to-buffer-other-tab abuf) (user-error "Your version of Emacs does not have tab bar support"))) ((eq org-agenda-window-setup 'only-window) - (delete-other-windows) - (pop-to-buffer-same-window abuf)) + (pop-to-buffer abuf '(display-buffer-full-frame))) ((eq org-agenda-window-setup 'reorganize-frame) - (delete-other-windows) - (switch-to-buffer-other-window abuf))) + (pop-to-buffer abuf '(org-display-buffer-split)))) (setq org-agenda-tag-filter (cdr (assq 'tag filter-alist))) (setq org-agenda-category-filter (cdr (assq 'cat filter-alist))) (setq org-agenda-effort-filter (cdr (assq 'effort filter-alist))) @@ -9531,7 +9528,8 @@ displayed Org file fills the frame." (pos (marker-position marker))) (unless buffer (user-error "Trying to switch to non-existent buffer")) (pop-to-buffer-same-window buffer) - (when delete-other-windows (delete-other-windows)) + (when delete-other-windows + (display-buffer (current-buffer) '(display-buffer-full-frame))) (widen) (goto-char pos) (when (derived-mode-p 'org-mode) diff --git a/lisp/org-capture.el b/lisp/org-capture.el index 8ce11cb75..da14f45c0 100644 --- a/lisp/org-capture.el +++ b/lisp/org-capture.el @@ -1174,9 +1174,9 @@ When INHIBIT-WCONF-STORE is non-nil, don't store the window configuration, as it may have been stored before." (unless inhibit-wconf-store (org-capture-put :return-to-wconf (current-window-configuration))) - (delete-other-windows) - (switch-to-buffer-other-window - (org-capture-get-indirect-buffer (org-capture-get :buffer) "CAPTURE")) + (pop-to-buffer + (org-capture-get-indirect-buffer (org-capture-get :buffer) "CAPTURE") + '(org-display-buffer-split)) (widen) (org-fold-show-all) (goto-char (org-capture-get :pos)) diff --git a/lisp/org-goto.el b/lisp/org-goto.el index 84847f4c7..ab5ab9e0f 100644 --- a/lisp/org-goto.el +++ b/lisp/org-goto.el @@ -215,12 +215,12 @@ position or nil." (help (or help org-goto-help))) (save-excursion (save-window-excursion - (delete-other-windows) (and (get-buffer "*org-goto*") (kill-buffer "*org-goto*")) - (pop-to-buffer-same-window - (condition-case nil + (pop-to-buffer + (condition-case nil (make-indirect-buffer (current-buffer) "*org-goto*" t) - (error (make-indirect-buffer (current-buffer) "*org-goto*" t)))) + (error (make-indirect-buffer (current-buffer) "*org-goto*" t))) + '(display-buffer-full-frame)) (let (temp-buffer-show-function temp-buffer-show-hook) (with-output-to-temp-buffer "*Org Help*" (princ (format help (if org-goto-auto-isearch diff --git a/lisp/org-macs.el b/lisp/org-macs.el index fe0e84f6b..c0332e068 100644 --- a/lisp/org-macs.el +++ b/lisp/org-macs.el @@ -1722,6 +1722,26 @@ The error string will be appended with ERR-MSG, when it is a string." (mapcar (lambda (command) (format-spec command spec)) process))) (_ (error "No valid command to process %S%s" source err-msg))))) +(defun org-display-buffer-split (buffer alist) + "Display BUFFER in the current frame split in two parts. +The frame will display two buffers - current buffer and BUFFER. +ALIST is an association list of action symbols and values. See +Info node `(elisp) Buffer Display Action Alists' for details of +such alists. + +Use `display-buffer-in-direction' internally. + +This is an action function for buffer display, see Info +node `(elisp) Buffer Display Action Functions'. It should be +called only by `display-buffer' or a function directly or +indirectly called by the latter." + (let ((window-configuration (current-window-configuration))) + (ignore-errors (delete-other-windows)) + (or (display-buffer-in-direction buffer alist) + (display-buffer-pop-up-window buffer alist) + (prog1 nil + (set-window-configuration window-configuration))))) + (provide 'org-macs) ;; Local variables: diff --git a/lisp/org-plot.el b/lisp/org-plot.el index 0b8b9a22a..283d99380 100644 --- a/lisp/org-plot.el +++ b/lisp/org-plot.el @@ -643,7 +643,11 @@ line directly before or after the table." (interactive) (org-require-package 'gnuplot) (save-window-excursion - (delete-other-windows) + ;; `gnuplot-send-buffer-to-gnuplot' will display *gnuplot* buffer + ;; if `gnuplot-display-process' is non-nil. Make it visible while + ;; gnuplot is processing the data, preferably as a split, and + ;; restore old window configuration after gnuplot finishes. + (ignore-errors (delete-other-windows)) (when (get-buffer "*gnuplot*") ; reset *gnuplot* if it already running (with-current-buffer "*gnuplot*" (goto-char (point-max)))) diff --git a/lisp/org-src.el b/lisp/org-src.el index dde8f8449..6bdd74ed0 100644 --- a/lisp/org-src.el +++ b/lisp/org-src.el @@ -1031,9 +1031,10 @@ Raise an error when current buffer is not a source editing buffer." (pop-to-buffer-same-window buffer)) (_ (switch-to-buffer-other-frame buffer)))) (`reorganize-frame - (when (eq context 'edit) (delete-other-windows)) - (switch-to-buffer-other-window buffer) - (when (eq context 'exit) (delete-other-windows))) + (pcase context + (`edit (pop-to-buffer buffer '(org-display-buffer-split))) + (`exit (pop-to-buffer buffer '(display-buffer-full-frame))) + (_ (switch-to-buffer-other-window buffer)))) (`switch-invisibly (set-buffer buffer)) (_ (message "Invalid value %s for `org-src-window-setup'" diff --git a/lisp/org.el b/lisp/org.el index b0748738f..6a1bc2efd 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -6389,8 +6389,7 @@ frame is not changed." ((or (eq org-indirect-buffer-display 'new-frame) (and arg (eq org-indirect-buffer-display 'dedicated-frame))) (select-frame (make-frame)) - (delete-other-windows) - (pop-to-buffer-same-window ibuf) + (pop-to-buffer ibuf '(display-buffer-full-frame)) (org-set-frame-title heading)) ((eq org-indirect-buffer-display 'dedicated-frame) (raise-frame @@ -6398,8 +6397,7 @@ frame is not changed." (frame-live-p org-indirect-dedicated-frame) org-indirect-dedicated-frame) (setq org-indirect-dedicated-frame (make-frame))))) - (delete-other-windows) - (pop-to-buffer-same-window ibuf) + (pop-to-buffer ibuf '(display-buffer-full-frame)) (org-set-frame-title (concat "Indirect: " heading))) ((eq org-indirect-buffer-display 'current-window) (pop-to-buffer-same-window ibuf)) @@ -8764,7 +8762,12 @@ there is one, return it." (t ; we have to select a link (save-excursion (save-window-excursion - (delete-other-windows) + ;; We have no direct control over how + ;; `with-output-to-temp-buffer' displays the buffer. Try + ;; to gain more space, makign sure that only the Org + ;; buffer and the *Select link* buffer are displayed for + ;; the duration of selection. + (ignore-errors (delete-other-windows)) (with-output-to-temp-buffer "*Select Link*" (dolist (l links) (cond @@ -10057,9 +10060,9 @@ where CURRENT-TODO-KEYWORD belongs over on in another sequence." ;; Select todo keyword list buffer, and display it unless EXPERT-INTERFACE. (if expert-interface (set-buffer (get-buffer-create " *Org todo*")) - (delete-other-windows) - (set-window-buffer (split-window-vertically) (get-buffer-create " *Org todo*")) - (switch-to-buffer-other-window " *Org todo*")) + (pop-to-buffer + (get-buffer-create (get-buffer-create " *Org todo*")) + '(org-display-buffer-split (direction . down)))) ;; Fill text in *Org todo* buffer. (erase-buffer) ;; Copy `org-done-keywords' from the original Org buffer to be @@ -10783,11 +10786,10 @@ items are State notes." (remove-hook 'post-command-hook 'org-add-log-note) (setq org-log-setup nil) (setq org-log-note-window-configuration (current-window-configuration)) - (delete-other-windows) (move-marker org-log-note-return-to (point)) - (pop-to-buffer-same-window (marker-buffer org-log-note-marker)) + (pop-to-buffer (marker-buffer org-log-note-marker) '(display-buffer-full-frame)) (goto-char org-log-note-marker) - (switch-to-buffer-other-window "*Org Note*") + (pop-to-buffer "*Org Note*" '(org-display-buffer-split)) (erase-buffer) (if (memq org-log-note-how '(time state)) (org-store-log-note) @@ -12217,9 +12219,9 @@ Returns the new tags string, or nil to not change the current settings." ;; Select tag list buffer, and display it unless EXPERT-INTERFACE. (if expert-interface (set-buffer (get-buffer-create " *Org tags*")) - (delete-other-windows) - (set-window-buffer (split-window-vertically) (get-buffer-create " *Org tags*")) - (switch-to-buffer-other-window " *Org tags*")) + (pop-to-buffer + (get-buffer-create " *Org tags*") + '(org-display-buffer-split (direction . down)))) ;; Fill text in *Org tags* buffer. (erase-buffer) (setq-local org-done-keywords done-keywords) @@ -12361,9 +12363,9 @@ Returns the new tags string, or nil to not change the current settings." (org-fast-tag-show-exit (setq exit-after-next (not exit-after-next))) (setq expert-interface nil) - (delete-other-windows) - (set-window-buffer (split-window-vertically) " *Org tags*") - (switch-to-buffer-other-window " *Org tags*") + (pop-to-buffer + " *Org tags*" + '((org-display-buffer-split (direction down)))) (org-fit-window-to-buffer))) ;; Quit. ((or ?\C-g @@ -18975,8 +18977,9 @@ information about your Org version and configuration." (org-version nil 'full) (let (list) (save-window-excursion - (pop-to-buffer-same-window (get-buffer-create "*Warn about privacy*")) - (delete-other-windows) + (pop-to-buffer + (get-buffer-create "*Warn about privacy*") + '(display-buffer-full-frame)) (erase-buffer) (insert "You are about to submit a bug report to the Org mailing list. diff --git a/lisp/ox.el b/lisp/ox.el index 186da4ed3..95d046bbb 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -7329,9 +7329,7 @@ back to standard interface." (save-window-excursion ;; At first call, create frame layout in order to display menu. (unless (get-buffer "*Org Export Dispatcher*") - (delete-other-windows) - (switch-to-buffer-other-window - (get-buffer-create "*Org Export Dispatcher*")) + (pop-to-buffer "*Org Export Dispatcher*" '(org-display-buffer-split)) (setq cursor-type nil) (setq header-line-format (let ((propertize-help-key