7267
|
1 ;;; rsz-mini.el --- dynamically resize minibuffer to display entire contents
|
|
2
|
23240
|
3 ;; Copyright (C) 1990, 1993-1995, 1997 Free Software Foundation, Inc.
|
7267
|
4
|
23240
|
5 ;; Author: Noah Friedman <friedman@splode.com>
|
|
6 ;; Roland McGrath <roland@gnu.org>
|
|
7 ;; Maintainer: Noah Friedman <friedman@splode.com>
|
11297
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
8 ;; Keywords: minibuffer, window, frame, display
|
7267
|
9
|
24646
|
10 ;; $Id: rsz-mini.el,v 1.25 1999/03/30 21:36:35 kwzh Exp fx $
|
18418
|
11
|
7267
|
12 ;; This file is part of GNU Emacs.
|
|
13
|
|
14 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
15 ;; it under the terms of the GNU General Public License as published by
|
|
16 ;; the Free Software Foundation; either version 2, or (at your option)
|
|
17 ;; any later version.
|
|
18
|
|
19 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
22 ;; GNU General Public License for more details.
|
|
23
|
|
24 ;; You should have received a copy of the GNU General Public License
|
14169
|
25 ;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
26 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
27 ;; Boston, MA 02111-1307, USA.
|
7267
|
28
|
|
29 ;;; Commentary:
|
|
30
|
11297
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
31 ;; This package allows the entire contents (or as much as possible) of the
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
32 ;; minibuffer to be visible at once when typing. As the end of a line is
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
33 ;; reached, the minibuffer will resize itself. When the user is done
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
34 ;; typing, the minibuffer will return to its original size.
|
7267
|
35
|
11297
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
36 ;; In window systems where it is possible to have a frame in which the
|
16741
|
37 ;; minibuffer is the only window, the frame itself can be resized. In
|
|
38 ;; Emacs 19.22 and earlier, the frame may not be properly returned to
|
11297
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
39 ;; its original size after it ceases to be active because
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
40 ;; `minibuffer-exit-hook' didn't exist until version 19.23.
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
41 ;;
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
42 ;; Prior to Emacs 19.26, minibuffer-exit-hook wasn't called after exiting
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
43 ;; from the minibuffer by hitting the quit char. That meant that the
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
44 ;; frame size restoration function wasn't being called in that case. In
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
45 ;; 19.26 or later, minibuffer-exit-hook should be called anyway.
|
7267
|
46
|
11297
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
47 ;; Note that the minibuffer and echo area are not the same! They simply
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
48 ;; happen to occupy roughly the same place on the frame. Messages put in
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
49 ;; the echo area will not cause any resizing by this package.
|
7267
|
50
|
11297
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
51 ;; This package is considered a minor mode but it doesn't put anything in
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
52 ;; minor-mode-alist because this mode is specific to the minibuffer, which
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
53 ;; has no mode line.
|
7267
|
54
|
14123
|
55 ;; To enable or disable this mode, use M-x resize-minibuffer-mode.
|
7267
|
56
|
|
57 ;;; Code:
|
|
58
|
|
59
|
17423
|
60 (defgroup resize-minibuffer nil
|
|
61 "Dynamically resize minibuffer to display entire contents"
|
|
62 :group 'frames)
|
|
63
|
22354
|
64 ;;;###autoload
|
17423
|
65 (defcustom resize-minibuffer-mode nil
|
24545
|
66 "Toggle resizing the minibuffer so its entire contents are visible.
|
24646
|
67 Setting this variable directly does not take effect;
|
|
68 use either \\[customize] or the function `resize-minibuffer-mode'."
|
20581
|
69 :set (lambda (symbol value)
|
|
70 (resize-minibuffer-mode (if value 1 -1)))
|
|
71 :initialize 'custom-initialize-default
|
17423
|
72 :type 'boolean
|
20581
|
73 :group 'resize-minibuffer
|
23238
f99998525810
(resize-minibuffer-mode): remove :version field from defcustom declaration.
Noah Friedman <friedman@splode.com>
diff
changeset
|
74 :require 'rsz-mini)
|
17423
|
75
|
|
76 ;;;###autoload
|
|
77 (defcustom resize-minibuffer-window-max-height nil
|
7267
|
78 "*Maximum size the minibuffer window is allowed to become.
|
|
79 If less than 1 or not a number, the limit is the height of the frame in
|
17423
|
80 which the active minibuffer window resides."
|
|
81 :type '(choice (const nil) integer)
|
|
82 :group 'resize-minibuffer)
|
7267
|
83
|
|
84 ;;;###autoload
|
17423
|
85 (defcustom resize-minibuffer-window-exactly t
|
8012
|
86 "*Allow making minibuffer exactly the size to display all its contents.
|
|
87 If `nil', the minibuffer window can temporarily increase in size but
|
|
88 never get smaller while it is active. Any other value allows exact
|
17423
|
89 resizing."
|
|
90 :type 'boolean
|
|
91 :group 'resize-minibuffer)
|
7267
|
92
|
|
93 ;;;###autoload
|
17423
|
94 (defcustom resize-minibuffer-frame nil
|
8012
|
95 "*Allow changing the frame height of minibuffer frames.
|
|
96 If non-`nil' and the active minibuffer is the sole window in its frame,
|
17423
|
97 allow changing the frame height."
|
|
98 :type 'boolean
|
|
99 :group 'resize-minibuffer)
|
7267
|
100
|
|
101 ;;;###autoload
|
17423
|
102 (defcustom resize-minibuffer-frame-max-height nil
|
7267
|
103 "*Maximum size the minibuffer frame is allowed to become.
|
|
104 If less than 1 or not a number, there is no limit.")
|
|
105
|
|
106 ;;;###autoload
|
17423
|
107 (defcustom resize-minibuffer-frame-exactly t
|
8012
|
108 "*Allow making minibuffer frame exactly the size to display all its contents.
|
|
109 If `nil', the minibuffer frame can temporarily increase in size but
|
|
110 never get smaller while it is active. Any other value allows exact
|
17423
|
111 resizing."
|
|
112 :type 'boolean
|
|
113 :group 'resize-minibuffer)
|
8012
|
114
|
|
115 ;; Variable used to store the height of the minibuffer frame
|
|
116 ;; on entry, so it can be restored on exit. It is made local before it is
|
|
117 ;; modified. Do not use it yourself.
|
|
118 (defvar resize-minibuffer-frame-original-height nil)
|
7267
|
119
|
|
120
|
|
121 ;;;###autoload
|
|
122 (defun resize-minibuffer-mode (&optional prefix)
|
21269
|
123 "Toggle resize-minibuffer mode.
|
|
124 With argument, enable resize-minibuffer mode if and only if argument
|
|
125 is positive.
|
7267
|
126
|
|
127 When this minor mode is enabled, the minibuffer is dynamically resized to
|
|
128 contain the entire region of text put in it as you type.
|
|
129
|
|
130 The variable `resize-minibuffer-mode' is set to t or nil depending on
|
|
131 whether this mode is active or not.
|
|
132
|
|
133 The maximum height to which the minibuffer can grow is controlled by the
|
|
134 variable `resize-minibuffer-window-max-height'.
|
|
135
|
|
136 The variable `resize-minibuffer-window-exactly' determines whether the
|
|
137 minibuffer window should ever be shrunk to make it no larger than needed to
|
|
138 display its contents.
|
|
139
|
7512
|
140 When using a window system, it is possible for a minibuffer to be the sole
|
7267
|
141 window in a frame. Since that window is already its maximum size, the only
|
|
142 way to make more text visible at once is to increase the size of the frame.
|
|
143 The variable `resize-minibuffer-frame' controls whether this should be
|
|
144 done. The variables `resize-minibuffer-frame-max-height' and
|
|
145 `resize-minibuffer-frame-exactly' are analogous to their window
|
|
146 counterparts."
|
21269
|
147 (interactive "P")
|
|
148 (setq resize-minibuffer-mode
|
|
149 (if prefix
|
|
150 (> (prefix-numeric-value prefix) 0)
|
|
151 (not resize-minibuffer-mode)))
|
18418
|
152 (add-hook 'minibuffer-setup-hook 'resize-minibuffer-setup))
|
7267
|
153
|
|
154 (defun resize-minibuffer-setup ()
|
|
155 (cond
|
|
156 (resize-minibuffer-mode
|
|
157 (cond
|
|
158 ((and window-system
|
|
159 (eq 'only (cdr (assq 'minibuffer (frame-parameters)))))
|
8240
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
160 ;; Checking for resize-minibuffer-frame is done outside the cond
|
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
161 ;; predicate because that should always be t if this is a minibuffer
|
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
162 ;; frame; it just shouldn't do anything if this flag is nil.
|
7267
|
163 (and resize-minibuffer-frame
|
|
164 (progn
|
8240
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
165 ;; Can't trust the height stored in minibuffer-frame-alist
|
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
166 ;; since the frame can be resized by the window manager and
|
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
167 ;; that variable isn't updated.
|
8012
|
168 (make-local-variable 'resize-minibuffer-frame-original-height)
|
|
169 (setq resize-minibuffer-frame-original-height (frame-height))
|
8240
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
170
|
12762
|
171 (make-local-hook 'post-command-hook)
|
|
172 (add-hook 'post-command-hook 'resize-minibuffer-frame 'append t)
|
8240
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
173
|
12762
|
174 (make-local-hook 'minibuffer-exit-hook)
|
|
175 (add-hook 'minibuffer-exit-hook 'resize-minibuffer-frame-restore
|
|
176 nil t)
|
8240
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
177
|
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
178 (resize-minibuffer-frame))))
|
7267
|
179 (t
|
|
180 (make-local-variable 'post-command-hook)
|
8240
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
181 ;; Copy this because add-hook modifies the list structure.
|
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
182 (setq post-command-hook (copy-sequence post-command-hook))
|
8012
|
183 (add-hook 'post-command-hook 'resize-minibuffer-window 'append)
|
8240
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
184
|
8012
|
185 (make-local-variable 'minibuffer-exit-hook)
|
8240
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
186 (add-hook 'minibuffer-exit-hook 'resize-minibuffer-window-restore)
|
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
187
|
363f719d47a5
(resize-minibuffer-setup): Copy post-command-hook when handling minibuffer
Noah Friedman <friedman@splode.com>
diff
changeset
|
188 (resize-minibuffer-window))))))
|
7267
|
189
|
|
190 (defun resize-minibuffer-count-window-lines (&optional start end)
|
|
191 "Return number of window lines occupied by text in region.
|
|
192 The number of window lines may be greater than the number of actual lines
|
|
193 in the buffer if any wrap on the display due to their length.
|
|
194
|
|
195 Optional arguments START and END default to point-min and point-max,
|
|
196 respectively."
|
|
197 (or start (setq start (point-min)))
|
|
198 (or end (setq end (point-max)))
|
|
199 (if (= start end)
|
|
200 0
|
|
201 (save-excursion
|
|
202 (save-restriction
|
|
203 (widen)
|
|
204 (narrow-to-region start end)
|
|
205 (goto-char start)
|
|
206 (vertical-motion (buffer-size))))))
|
|
207
|
|
208
|
|
209 ;; Resize the minibuffer window to contain the minibuffer's contents.
|
|
210 (defun resize-minibuffer-window ()
|
11297
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
211 (and (eq (selected-window) (minibuffer-window))
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
212 (let ((height (window-height))
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
213 (lines (1+ (resize-minibuffer-count-window-lines))))
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
214 (and (numberp resize-minibuffer-window-max-height)
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
215 (> resize-minibuffer-window-max-height 0)
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
216 (setq lines (min lines resize-minibuffer-window-max-height)))
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
217 (or (if resize-minibuffer-window-exactly
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
218 (= lines height)
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
219 (<= lines height))
|
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
220 (enlarge-window (- lines height))))))
|
7267
|
221
|
8012
|
222 ;; This resizes the minibuffer back to one line as soon as it is exited
|
|
223 ;; (e.g. when the user hits RET). This way, subsequent messages put in the
|
|
224 ;; echo area aren't cluttered with leftover minibuffer text.
|
|
225 ;; It should be called by minibuffer-exit-hook.
|
|
226 ;;
|
|
227 ;; Note that because it calls sit-for to force a screen update, strange
|
|
228 ;; things may happen in the minibuffer, such as unexpanded partial
|
|
229 ;; completions by complete.el showing their completion.
|
|
230 ;; If this bothers you, just redefine this function to do nothing, in, say,
|
|
231 ;; your after-load-alist. Perhaps there should be an option variable,
|
|
232 ;; but I don't know if there's really any demand for it.
|
|
233 ;; (Clobbering this definition is harmless because eventually emacs restores
|
|
234 ;; its idea of the minibuffer window size when the minibuffer isn't in use
|
|
235 ;; anyway; this is just a kludge because of the timing for that update).
|
|
236 (defun resize-minibuffer-window-restore ()
|
8093
1978838b7b6f
(resize-minibuffer-window-restore): Don't do anything if the window height
Noah Friedman <friedman@splode.com>
diff
changeset
|
237 (cond
|
11297
056c7266a614
(resize-minibuffer-window): Make sure minibuffer window is selected.
Noah Friedman <friedman@splode.com>
diff
changeset
|
238 ((not (eq (minibuffer-window) (selected-window))))
|
8093
1978838b7b6f
(resize-minibuffer-window-restore): Don't do anything if the window height
Noah Friedman <friedman@splode.com>
diff
changeset
|
239 ((> (window-height) 1)
|
1978838b7b6f
(resize-minibuffer-window-restore): Don't do anything if the window height
Noah Friedman <friedman@splode.com>
diff
changeset
|
240 (enlarge-window (- 1 (window-height)))
|
1978838b7b6f
(resize-minibuffer-window-restore): Don't do anything if the window height
Noah Friedman <friedman@splode.com>
diff
changeset
|
241 (sit-for 0))))
|
8012
|
242
|
7267
|
243
|
|
244 ;; Resize the minibuffer frame to contain the minibuffer's contents.
|
|
245 ;; The minibuffer frame must be the current frame.
|
|
246 (defun resize-minibuffer-frame ()
|
|
247 (let ((height (frame-height))
|
|
248 (lines (1+ (resize-minibuffer-count-window-lines))))
|
|
249 (and (numberp resize-minibuffer-frame-max-height)
|
|
250 (> resize-minibuffer-frame-max-height 0)
|
|
251 (setq lines (min lines resize-minibuffer-frame-max-height)))
|
|
252 (cond
|
|
253 ((> lines height)
|
16597
|
254 (set-frame-size (window-frame (minibuffer-window)) (frame-width) lines))
|
7267
|
255 ((and resize-minibuffer-frame-exactly
|
8012
|
256 (> height resize-minibuffer-frame-original-height)
|
7267
|
257 (< lines height))
|
16597
|
258 (set-frame-size (window-frame (minibuffer-window))
|
|
259 (frame-width) lines)))))
|
7267
|
260
|
|
261 ;; Restore the original height of the frame.
|
8012
|
262 ;; resize-minibuffer-frame-original-height is set in
|
|
263 ;; resize-minibuffer-setup.
|
7267
|
264 (defun resize-minibuffer-frame-restore ()
|
16577
|
265 (set-frame-size (window-frame (minibuffer-window))
|
7267
|
266 (frame-width)
|
8012
|
267 resize-minibuffer-frame-original-height))
|
7267
|
268
|
20581
|
269 (if resize-minibuffer-mode
|
|
270 (resize-minibuffer-mode 1))
|
|
271
|
7267
|
272 (provide 'rsz-mini)
|
|
273
|
|
274 ;; rsz-mini.el ends here
|