summaryrefslogtreecommitdiffstats
path: root/bw.el
blob: 0c4844dbc6c65a120dec1bda09015bf2d4abf23c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
;;; 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.

;;; 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))

(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)
    (local-set-key (kbd "C-c C-q") 'delete-window)
    win))

(add-to-list 'display-buffer-alist
             '("^\\*.*\\*$" . ((bw-display-in-bottom-window . nil))))
(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))

(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