chiark / gitweb /
dot/emacs, el/dot-emacs.el: Another `display-window' hack: fallback.
[profile] / el / dot-emacs.el
index 6cad98cfbc8f2aea80b6956de962114c7e3a036a..01d3ac51d6e0d0eeeeac71fa72f5c88a732a6d33 100644 (file)
@@ -772,6 +772,45 @@ (setq even-window-sizes nil
       even-window-heights nil
       display-buffer-reuse-frames nil)
 
+(defvar mdw-fallback-window-alist nil
+  "Alist mapping frames to fallback windows.")
+
+(defun mdw-cleanup-fallback-window-alist ()
+  "Remove entries for dead frames and windows from the fallback alist."
+  (let ((prev nil)
+       (cursor mdw-fallback-window-alist))
+    (while cursor
+      (let* ((assoc (car cursor))
+            (tail (cdr cursor)))
+       (cond ((and (frame-live-p (car assoc))
+                   (window-live-p (cdr assoc)))
+              (setq prev cursor))
+             ((null prev)
+              (setq mdw-fallback-window-alist tail))
+             (t
+              (setcdr prev tail)))
+       (setq cursor tail)))))
+
+(defun mdw-set-fallback-window (cancel)
+  "Prefer the selected window for pop-up buffers in this frame.
+With a prefix argument, clear the fallback window."
+  (interactive "P")
+  (let* ((frame (selected-frame)) (window (selected-window))
+        (assoc (assq (selected-frame) mdw-fallback-window-alist)))
+    (cond (cancel
+          (cond (assoc
+                 (setcdr assoc nil)
+                 (message "Fallback window cleared."))
+                (t
+                 (message "No fallback window active in this frame."))))
+         ((window-dedicated-p window)
+          (error "Window is dedicated to its buffer."))
+         (t
+          (if assoc (setcdr assoc window)
+            (push (cons frame window) mdw-fallback-window-alist))
+          (message "Fallback window set.")))
+    (mdw-cleanup-fallback-window-alist)))
+
 (defun mdw-last-window-in-frame-p (window)
   "Return whether WINDOW is the last in its frame."
   (catch 'done
@@ -790,10 +829,17 @@ (defun mdw-display-buffer-in-tolerable-window (buffer alist)
 This is all totally subject to arbitrary change in the future, but the
 emphasis is on predictability rather than crazy DWIMmery."
   (let* ((selected (selected-window)) chosen
+        (fallback (assq (selected-frame) mdw-fallback-window-alist))
         (full-height-p (window-full-height-p selected))
         (full-width-p (window-full-width-p selected)))
     (cond
 
+     ((and fallback (window-live-p (cdr fallback)))
+      ;; There's a fallback window set for this frame.  Use it.
+
+      (setq chosen (cdr fallback))
+      (display-buffer-record-window 'window chosen buffer))
+
      ((and full-height-p full-width-p)
       ;; We're basically the only window in the frame.  If we want to get
       ;; anywhere, we'll have to split the window.