comparison lisp/modes/rsz-minibuf.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 0293115a14e9
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
1 ;;; rsz-minibuf.el --- dynamically resize minibuffer to display entire contents
2
3 ;;; Copyright (C) 1990 Roland McGrath
4 ;;; Copyright (C) 1993, 1994 Noah S. Friedman
5
6 ;;; Author: Noah Friedman <friedman@prep.ai.mit.edu>
7 ;;; Roland McGrath <roland@prep.ai.mit.edu>
8 ;;; Modified for Lucid Emacs By: Peter Stout <pds@cs.cmu.edu>
9 ;;; Maintainer: friedman@prep.ai.mit.edu
10 ;;; Keywords: minibuffer, window, frames, display
11 ;;; Status: Known to work in FSF GNU Emacs 19.23 and Lucid Emacs 19.9.
12
13 ;;; $Id: rsz-minibuf.el,v 1.1.1.1 1996/12/18 03:30:55 steve Exp $
14
15 ;;; This program is free software; you can redistribute it and/or modify
16 ;;; it under the terms of the GNU General Public License as published by
17 ;;; the Free Software Foundation; either version 2, or (at your option)
18 ;;; any later version.
19 ;;;
20 ;;; This program is distributed in the hope that it will be useful,
21 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 ;;; GNU General Public License for more details.
24 ;;;
25 ;;; You should have received a copy of the GNU General Public License
26 ;;; along with this program; if not, you can either send email to this
27 ;;; program's maintainer or write to: The Free Software Foundation,
28 ;;; Inc.; 675 Massachusetts Avenue; Cambridge, MA 02139, USA.
29
30 ;;; Commentary:
31
32 ;;; This package allows the entire contents (or as much as possible) of the
33 ;;; minibuffer to be visible at once when typing. As the end of a line is
34 ;;; reached, the minibuffer will resize itself. When the user is done
35 ;;; typing, the minibuffer will return to its original size.
36
37 ;;; In window systems where it is possible to have a frame in which the
38 ;;; minibuffer is the only window, the frame itself can be resized. In FSF
39 ;;; GNU Emacs 19.22 and earlier, the frame may not be properly returned to
40 ;;; its original size after it ceases to be active because
41 ;;; `minibuffer-exit-hook' didn't exist until version 19.23.
42
43 ;;; NOTE: The code to resize frames has not been tested under Lucid Emacs,
44 ;;; because detached minibuffers are broken.
45
46 ;;; Note that the minibuffer and echo area are not the same! They simply
47 ;;; happen to occupy roughly the same place on the frame. Messages put in
48 ;;; the echo area will not cause any resizing by this package.
49
50 ;;; This package is considered a minor mode but it doesn't put anything in
51 ;;; minor-mode-alist because this mode is specific to the minibuffer, which
52 ;;; has no modeline.
53
54 ;;; To use this package, put the following in your .emacs:
55 ;;;
56 ;;; (autoload 'resize-minibuffer-mode "rsz-minibuf" nil t)
57 ;;;
58 ;;; Invoking the command `resize-minibuffer-mode' will then enable this mode.
59
60 ;;; Code:
61
62
63 ;;;###autoload
64 (defvar resize-minibuffer-mode nil
65 "*If non-`nil', resize the minibuffer so its entire contents are visible.")
66
67 ;;;###autoload
68 (defvar resize-minibuffer-window-max-height nil
69 "*Maximum size the minibuffer window is allowed to become.
70 If less than 1 or not a number, the limit is the height of the frame in
71 which the active minibuffer window resides.")
72
73 ;;;###autoload
74 (defvar resize-minibuffer-window-exactly t
75 "*If non-`nil', make minibuffer exactly the size needed to display all its contents.
76 Otherwise, the minibuffer window can temporarily increase in size but
77 never get smaller while it is active.")
78
79
80 ;;;###autoload
81 (defvar resize-minibuffer-frame nil
82 "*If non-`nil' and the active minibuffer is the sole window in its frame, allow changing the frame height.")
83
84 ;;;###autoload
85 (defvar resize-minibuffer-frame-max-height nil
86 "*Maximum size the minibuffer frame is allowed to become.
87 If less than 1 or not a number, there is no limit.")
88
89 ;;;###autoload
90 (defvar resize-minibuffer-frame-exactly nil
91 "*If non-`nil', make minibuffer frame exactly the size needed to display all its contents.
92 Otherwise, the minibuffer frame can temporarily increase in size but
93 never get smaller while it is active.")
94
95
96 ;;;###autoload
97 (defun resize-minibuffer-mode (&optional prefix)
98 "Enable or disable resize-minibuffer mode.
99 A negative prefix argument disables this mode. A positive argument or
100 argument of 0 enables it.
101
102 When this minor mode is enabled, the minibuffer is dynamically resized to
103 contain the entire region of text put in it as you type.
104
105 The variable `resize-minibuffer-mode' is set to t or nil depending on
106 whether this mode is active or not.
107
108 The maximum height to which the minibuffer can grow is controlled by the
109 variable `resize-minibuffer-window-max-height'.
110
111 The variable `resize-minibuffer-window-exactly' determines whether the
112 minibuffer window should ever be shrunk to make it no larger than needed to
113 display its contents.
114
115 When using a window system, it is possible for a minibuffer to tbe the sole
116 window in a frame. Since that window is already its maximum size, the only
117 way to make more text visible at once is to increase the size of the frame.
118 The variable `resize-minibuffer-frame' controls whether this should be
119 done. The variables `resize-minibuffer-frame-max-height' and
120 `resize-minibuffer-frame-exactly' are analogous to their window
121 counterparts."
122 (interactive "p")
123 (or prefix (setq prefix 0))
124 (cond
125 ((>= prefix 0)
126 (setq resize-minibuffer-mode t))
127 (t
128 (setq resize-minibuffer-mode nil))))
129
130 ;;; Glue code to make things work in both FSF and Lucid Emacsen.
131 (if (string-match "Lucid" emacs-version)
132 (progn
133 (fset 'resize-frame-parameters 'screen-parameters)
134 (fset 'resize-frame-height 'screen-height)
135 (fset 'resize-frame-width 'screen-width)
136 (fset 'resize-selected-frame 'selected-screen)
137 (fset 'resize-set-frame-size 'set-screen-size)
138 (defun resize-minibuffer-frame-alist ()
139 "Return the frame alist for the minibuffer."
140 minibuffer-alist))
141 (fset 'resize-frame-parameters 'frame-parameters)
142 (fset 'resize-frame-height 'frame-height)
143 (fset 'resize-frame-width 'frame-width)
144 (fset 'resize-selected-frame 'selected-frame)
145 (fset 'resize-set-frame-size 'set-frame-size)
146 (defun resize-minibuffer-frame-alist ()
147 "Return the frame alist for the minibuffer."
148 minibuffer-frame-alist))
149
150 (defun resize-minibuffer-setup ()
151 (cond
152 (resize-minibuffer-mode
153 (cond
154 ((and (not (eq 'tty (console-type)))
155 (eq 'only (cdr (assq 'minibuffer (resize-frame-parameters)))))
156 (and resize-minibuffer-frame
157 (progn
158 (make-local-hook 'minibuffer-exit-hook)
159 (add-hook 'minibuffer-exit-hook 'resize-minibuffer-frame-restore
160 nil t)
161 (make-local-hook 'post-command-hook)
162 (add-hook 'post-command-hook 'resize-minibuffer-frame nil t))))
163 (t
164 (make-local-hook 'post-command-hook)
165 (add-hook 'post-command-hook 'resize-minibuffer-window nil t))))))
166
167 (defun resize-minibuffer-count-window-lines (&optional start end)
168 "Return number of window lines occupied by text in region.
169 The number of window lines may be greater than the number of actual lines
170 in the buffer if any wrap on the display due to their length.
171
172 Optional arguments START and END default to point-min and point-max,
173 respectively."
174 (or start (setq start (point-min)))
175 (or end (setq end (point-max)))
176 (if (= start end)
177 0
178 (save-excursion
179 (save-restriction
180 (widen)
181 (narrow-to-region start end)
182 (goto-char start)
183 (vertical-motion (buffer-size))))))
184
185 ;; Why isn't `min' a subr?
186 ;; Do not pretend this is a real definition of `min'. It suffices for this
187 ;; packages's purposes (and is reasonably fast for a lisp call) but a real
188 ;; min function would be able to take more than 2 arguments.
189 (defun resize-minibuffer-min (x y)
190 "Return the lesser of X or Y."
191 (if (< x y)
192 x
193 y))
194
195
196 ;; Resize the minibuffer window to contain the minibuffer's contents.
197 ;; The minibuffer must be the current window.
198 (defun resize-minibuffer-window ()
199 (let ((height (window-height))
200 (lines (1+ (resize-minibuffer-count-window-lines))))
201 (and (numberp resize-minibuffer-window-max-height)
202 (> resize-minibuffer-window-max-height 0)
203 (setq lines (resize-minibuffer-min
204 lines
205 resize-minibuffer-window-max-height)))
206 (or (if resize-minibuffer-window-exactly
207 (= lines height)
208 (<= lines height))
209 (enlarge-window (- lines height)))))
210
211
212 ;; Resize the minibuffer frame to contain the minibuffer's contents.
213 ;; The minibuffer frame must be the current frame.
214 (defun resize-minibuffer-frame ()
215 (let ((height (resize-frame-height))
216 (lines (1+ (resize-minibuffer-count-window-lines))))
217 (and (numberp resize-minibuffer-frame-max-height)
218 (> resize-minibuffer-frame-max-height 0)
219 (setq lines (resize-minibuffer-min
220 lines
221 resize-minibuffer-frame-max-height)))
222 (cond
223 ((> lines height)
224 (resize-set-frame-size (resize-selected-frame)
225 (resize-frame-width)
226 lines))
227 ((and resize-minibuffer-frame-exactly
228 (> height (cdr (assq 'height (resize-minibuffer-frame-alist))))
229 (< lines height))
230 (resize-set-frame-size (resize-selected-frame)
231 (resize-frame-width)
232 lines)))))
233
234 ;; Restore the original height of the frame.
235 (defun resize-minibuffer-frame-restore ()
236 (resize-set-frame-size (resize-selected-frame)
237 (resize-frame-width)
238 (cdr (assq 'height (resize-minibuffer-frame-alist)))))
239
240
241 (provide 'rsz-minibuf)
242
243 (add-hook 'minibuffer-setup-hook 'resize-minibuffer-setup)
244
245 ;; rsz-minibuf.el ends here