Skip to content

Instantly share code, notes, and snippets.

@timjstewart
Last active September 27, 2022 15:54
Show Gist options
  • Save timjstewart/b1000911c12d5ffe670aa60814cbd4f4 to your computer and use it in GitHub Desktop.
Save timjstewart/b1000911c12d5ffe670aa60814cbd4f4 to your computer and use it in GitHub Desktop.
Organize Emacs windows
(defun tjs/configure-dired ()
(dired-hide-details-mode 1))
(defun tjs/major-mode-equals (buffer major-mode)
(message (format "Testing buffer: %s" buffer))
(let ((result (equal major-mode (tjs/buffer-major-mode buffer))))
(message (if result
(format "Mode match: %s" major-mode)
(format "No Mode match: %s" major-mode)))
result))
(defun tjs/buffer-major-mode (buffer-or-string)
"Return the major mode of the *buffer-or-string*."
(buffer-local-value 'major-mode
(if (bufferp buffer-or-string)
buffer-or-string
(get-buffer buffer-or-string))))
(defun tjs/side-window-p (window)
(assoc 'window-side (window-parameters window)))
(defun tjs/side-window-for-major-mode (major-mode alist)
(find-if
(lambda (window)
(and (tjs/side-window-p window)
(equal major-mode (tjs/buffer-major-mode (window-buffer window)))))
(window-list)))
(defun tjs/display-buffer-by-mode (buffer alist)
(let ((window
(tjs/side-window-for-major-mode (tjs/buffer-major-mode buffer) alist)))
(if window
(window--display-buffer buffer window 'reuse alist))))
;;; set dotspacemacs-activate-window-purpose-mode to nil
;;; see: https://github.com/syl20bnr/spacemacs/issues/15302
(defun tjs/window-setup ()
(interactive)
(add-hook 'dired-mode-hook 'tjs/configure-dired)
;; The window-purpose package rudely sets this variable and that breaks
;; #'display-buffer-alist. Unset this var to fix the issue until there is a
;; fix.
(setq display-buffer-overriding-action nil)
;; ;; Make top and bottom windows span the entire width of the window (or at
;; ;; least try)
;; (setq window-sides-vertical t)
;; ;; delete a frame when quitting its only window
;; (setq frame-auto-hide-function 'delete-frame)
(setq display-buffer-alist
`(((lambda (buffer alist)
(tjs/major-mode-equals buffer 'dired-mode))
(tjs/display-buffer-by-mode
display-buffer-in-side-window)
(side . bottom)
(slot . 0))
((lambda (buffer alist)
(tjs/major-mode-equals buffer 'org-mode))
(tjs/display-buffer-by-mode
display-buffer-in-side-window)
(side . right)
(slot . 0))
((lambda (buffer alist)
(tjs/major-mode-equals buffer 'messages-buffer-mode))
(tjs/display-buffer-by-mode
display-buffer-in-side-window)
(side . bottom)
(slot . 1)))))
(tjs/window-setup)
@timjstewart1024
Copy link

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Window Organization
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun tjs/buffer-major-mode (buffer-or-string)
  "Return the major mode of the *buffer-or-string*."
  (with-current-buffer buffer-or-string major-mode))
  ;; (let* ((buffer (get-buffer buffer-or-string))
  ;;        (major-mode (buffer-local-value 'major-mode buffer)))
  ;;   (message (format "Getting major mode for buffer-or-string: %s buffer: %s is-buffer: %s -> %s"
  ;;                    buffer-or-string
  ;;                    buffer
  ;;                    (bufferp buffer-or-string)
  ;;                    major-mode))
  ;;   major-mode))

(defun tjs/major-mode-equals (buffer major-mode)
  (message (format "Testing buffer: %s with mode %s for mode: %s" buffer (tjs/buffer-major-mode buffer) major-mode))
  (let ((result (equal major-mode (tjs/buffer-major-mode buffer))))
    (message (if result
                 (format "Mode match: %s" major-mode)
               (format "No Mode match: %s" major-mode)))
    result))

(defun tjs/side-window-p (window)
  (assoc 'window-side (window-parameters window)))

(defun tjs/side-window-for-major-mode (major-mode alist)
  (find-if
   (lambda (window)
     (and (tjs/side-window-p window)
          (equal major-mode (tjs/buffer-major-mode (window-buffer window)))))
   (window-list)))

(defun tjs/display-buffer-by-mode (buffer alist)
  (message (format "Looking for side window for buffer: %s with mode of: %s" buffer (tjs/buffer-major-mode buffer)))
  (let ((window
         (tjs/side-window-for-major-mode (tjs/buffer-major-mode buffer) alist)))
    (if window
        (progn
          (message (format "Found side window in mode: %s for buffer in mode: %s"
                           (tjs/buffer-major-mode (window-buffer window))
                           (tjs/buffer-major-mode buffer)))
          (window--display-buffer buffer window 'reuse alist))
      (progn
        (message (format "no window found"))
        nil))))

;;; set dotspacemacs-activate-window-purpose-mode to nil
;;; see: https://github.com/syl20bnr/spacemacs/issues/15302

(defun tjs/window-setup ()
  ;; The window-purpose package rudely sets this variable and that breaks
  ;; #'display-buffer-alist. Unset this var to fix the issue until there is a
  ;; fix.
  (setq display-buffer-overriding-action nil
        dotspacemacs-activate-window-purpose-mode t)

  ;; ;; Make top and bottom windows span the entire width of the window (or at
  ;; ;; least try)
  ;; (setq window-sides-vertical t)

  ;; ;; delete a frame when quitting its only window
  ;; (setq frame-auto-hide-function 'delete-frame)

  (setq display-buffer-alist
        `(((lambda (buffer alist)
             (tjs/major-mode-equals buffer 'dired-mode))
           (tjs/display-buffer-by-mode
            display-buffer-in-side-window)
           (side . bottom)
           (slot . -1))

          ((lambda (buffer alist)
             (tjs/major-mode-equals buffer 'org-mode))
           (tjs/display-buffer-by-mode
            display-buffer-in-side-window)
           (side . right)
           (slot . 0))

          ("\\*Messages"
           (tjs/display-buffer-by-mode
            display-buffer-in-side-window)
           (side . bottom)
           (slot . 1)))))

(tjs/window-setup)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment