split-root で Eclipsライクなコンパイルウインドウ表示

anything-display-functionを使ってanything.elのウィンドウ表示を制御する - Emacs/Lisp/Drill - Emacsグループ でその存在を知った split-root

コンパイルバッファ(*compilation*)を表示する際に重宝している。


開発HPに、Eclipseスタイルのコンパイルウインドウを実現するサンプルがあるが、
そのままだと、状況によっては nilアクセスで落ちてしまうので、自分なりに修正してみた。

(require 'split-root)

;; to pop up compilation buffers at the bottom (OPTIONAL)
(require 'compile)
(defvar compilation-window nil
  "The window opened for displaying a compilation buffer.")

(setq compilation-window-height 14)

(defun my-display-buffer (buffer &optional not-this-window)
  (if (or (compilation-buffer-p buffer)
          (equal (buffer-name buffer) "*Shell Command Output*"))
      (unless (and compilation-window (window-live-p compilation-window))
        (setq compilation-window (split-root-window compilation-window-height))
        (set-window-buffer compilation-window buffer))
    (let ((display-buffer-function nil))
      (display-buffer buffer not-this-window))))

(setq display-buffer-function 'my-display-buffer)

上記コードの my-display-bufferを、下記のように修正

(defun my-display-buffer (buffer &optional not-this-window)
  (if (or (compilation-buffer-p buffer)
          (equal (buffer-name buffer) "*Shell Command Output*"))
      (progn 
        (unless (and my-compilation-window (window-live-p my-compilation-window))
          (setq my-compilation-window (split-root-window compilation-window-height))
          (set-window-buffer my-compilation-window buffer))
        my-compilation-window)
    (let ((display-buffer-function nil))
      (display-buffer buffer not-this-window))))


しかし、emacs23ならば display-buffer-function ではなく、split-window-preferred-function を使うことで、もう少しエレガント(?)に出来る

(when (>= emacs-major-version 23)

  (defun my-split-window-by-split-root (window)
    (if (or (compilation-buffer-p buffer)
            (equal name-of-buffer "*Shell Command Output*"))
        (split-root-window compilation-window-height)
      (split-window-sensibly window)))
  
  (setq split-window-preferred-function 'my-split-window-by-split-root))