bw/bw.el
2012-09-20 20:35:58 +02:00

133 lines
4.1 KiB
EmacsLisp

;;; bw.el --- Show stuff in a bottom window
;; Copyright (C) 2012 Tom Willemsen
;; Author: Tom Willemsen <slash@drd>
;; Keywords: convenience
;; Version: 0
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Show stuff in a bottom window. The idea is taken from ide-skel,
;; which is a very nice extension, but doesn't fit into my workflow at
;; all, the only really nice thing is that all *buffers* appear in a
;; specialized window.
;;; Usage:
;; Make sure it's loadable, you should be able to do this by using:
;; M-x package-install-file RET /path/to/bw.el RET
;; or if you don't use package.el you could use:
;; (add-to-list 'load-path "/path/to/bw/directory")
;; (require 'bw)
;; Once that is done you can set it up for use:
;; (add-to-list 'display-buffer-alist
;; '("^\\*.*\\*$"
;; . ((bw-display-in-bottom-window . nil)))
;; And perhaps even bind a key to it:
;; (global-set-key (kbd "<f11>") 'bw-toggle-bottom-window)
;;; Code:
(defvar bw-last-shown-buffer nil
"The last buffer shown by bw.")
(defadvice quit-window (around delete-window-perhaps activate)
"Delete the bottom window if necessary."
(let* ((win (window-normalize-window (ad-get-arg 2)))
(delp (and (window-parameter win 'bw-bottom)
(string-match-p "^\\*.*\\*$"
(buffer-name (window-buffer win))))))
ad-do-it
(when delp
(delete-window win))))
(defun bw-create-window ()
"Create the bottom window."
(let ((win (split-window (frame-root-window) -20 'below)))
(set-window-parameter win 'bw-bottom t)
;; Don't allow splitting of the bottom window.
(set-window-parameter win 'split-window (lambda (window size side) nil))
;; Don't allow deleting other windows in the bottom window.
(set-window-parameter win 'delete-other-windows (lambda (window) nil))
win))
(defun bw-get-window ()
"Try to get the bottom window."
(let (win)
(mapc
(lambda (w)
(when (window-parameter w 'bw-bottom)
(setq win w)))
(window-list))
win))
;;;###autoload
(defun bw-display-in-bottom-window (buffer alist)
"Show BUFFER in the bottom window, discard ALIST."
(let ((win (or (bw-get-window) (bw-create-window))))
(set-window-buffer win buffer)
(setq bw-last-shown-buffer buffer)
win))
;;;###autoload
(defun bw-display-in-other-window (buffer alist)
"Show BUFFER in any window that is not the bottom window.
Discard ALIST."
(let ((win (get-buffer-window buffer)))
(when (window-parameter win 'bw-bottom)
(setq win (next-window win 'no)))
(set-window-buffer win buffer)))
(add-to-list 'window-persistent-parameters (cons 'bw-bottom t))
(defun bw-find-appropriate-buffer ()
"Find an appropriate buffer for bw."
(let ((buffers (buffer-list))
tmp-buffer buffer)
(while (and (not buffer) buffers)
(setq tmp-buffer (car buffers))
(when (string-match-p "^\\*.*\\*$" (buffer-name tmp-buffer))
(setq buffer tmp-buffer))
(setq buffers (cdr buffers)))
(unless buffer
(setq buffer "*scratch*"))
buffer))
;;;###autoload
(defun bw-toggle-bottom-window ()
"Either show or delete the bottom window."
(interactive)
(let ((win (bw-get-window)))
(if win
(delete-window win)
(setq win (bw-create-window))
(bw-display-in-bottom-window
(or bw-last-shown-buffer (bw-find-appropriate-buffer)) nil)
(select-window win))))
(global-set-key (kbd "<f11>") 'bw-toggle-bottom-window)
(provide 'bw)
;;; bw.el ends here