aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorPaul Eggert2011-06-10 11:19:35 -0700
committerPaul Eggert2011-06-10 11:19:35 -0700
commite41e9a0e24877b0bc81e08df396f59115f8636da (patch)
treec0cf7e2838761b2c26047aeeac6415bb542bf5a0 /lisp
parent6a54b501af0633c909c96de867c805222fde970c (diff)
parent529a133c390049085db38e7c8f745d650a2626ee (diff)
downloademacs-e41e9a0e24877b0bc81e08df396f59115f8636da.tar.gz
emacs-e41e9a0e24877b0bc81e08df396f59115f8636da.zip
Merge from trunk.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog71
-rw-r--r--lisp/calendar/appt.el92
-rw-r--r--lisp/cus-start.el15
-rw-r--r--lisp/doc-view.el2
-rw-r--r--lisp/files.el8
-rw-r--r--lisp/gnus/ChangeLog21
-rw-r--r--lisp/gnus/gnus-agent.el4
-rw-r--r--lisp/gnus/gnus-group.el32
-rw-r--r--lisp/gnus/gnus-srvr.el6
-rw-r--r--lisp/gnus/gnus-start.el17
-rw-r--r--lisp/gnus/gnus-sum.el23
-rw-r--r--lisp/mail/sendmail.el4
-rw-r--r--lisp/net/ange-ftp.el43
-rw-r--r--lisp/net/soap-client.el2
-rw-r--r--lisp/term/xterm.el192
-rw-r--r--lisp/window.el1365
16 files changed, 1642 insertions, 255 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 2341c0c973a..1ac216dfbe2 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,74 @@
12011-06-10 Martin Rudalics <rudalics@gmx.at>
2
3 * window.el (window-min-height, window-min-width): Move here
4 from window.c. Add defcustoms and rewrite doc-strings.
5 (resize-mini-window, resize-window): New functions.
6 (adjust-window-trailing-edge, enlarge-window, shrink-window):
7 Move here from window.c.
8 (maximize-window, minimize-window): New functions.
9 (delete-window, delete-other-windows, split-window): Move here
10 from window.c.
11 (window-split-min-size): New function.
12 (split-window-keep-point): Mention split-window-above-each-other
13 instead of split-window-vertically.
14 (split-window-above-each-other, split-window-vertically): Rename
15 split-window-vertically to split-window-above-each-other and
16 provide defalias for old definition.
17 (split-window-side-by-side, split-window-horizontally): Rename
18 split-window-horizontally to split-window-side-by-side and provide
19 defalias for the old definition.
20 (ctl-x-map): Move bindings for delete-window,
21 delete-other-windows and enlarge-window here from window.c.
22 Replace bindings for split-window-vertically and
23 split-window-horizontally by bindings for
24 split-window-above-each-other and split-window-side-by-side.
25
26 * cus-start.el (all): Remove entries for window-min-height and
27 window-min-width. Add entries for window-splits and
28 window-nest.
29
302011-06-09 Glenn Morris <rgm@gnu.org>
31
32 * calendar/appt.el (appt-mode-line): New function.
33 (appt-check, appt-disp-window): Use it.
34
35 * files.el (hack-one-local-variable-eval-safep):
36 Allow minor-modes with explicit +/-1 arguments.
37
382011-06-09 Teodor Zlatanov <tzz@lifelogs.com>
39
40 * term/xterm.el (xterm): Add defgroup.
41 (xterm-extra-capabilities): Add defcustom to supply known xterm
42 capabilities, skip querying them, or query them (default).
43 (terminal-init-xterm): Use it.
44 (terminal-init-xterm-modify-other-keys): New function to set up
45 modifyOtherKeys support to simplify `terminal-init-xterm'.
46
472011-06-09 Martin Rudalics <rudalics@gmx.at>
48
49 * window.el (resize-window-reset, resize-window-reset-1)
50 (resize-subwindows-skip-p, resize-subwindows-normal)
51 (resize-subwindows, resize-other-windows, resize-this-window)
52 (resize-root-window, resize-root-window-vertically)
53 (window-deletable-p, window-or-subwindow-p)
54 (frame-root-window-p): New functions.
55
562011-06-09 Glenn Morris <rgm@gnu.org>
57
58 * net/ange-ftp.el (ange-ftp-switches-ok): New function.
59 (ange-ftp-get-files): Use it.
60
612011-06-09 Alexander Klimov <alserkli@inbox.ru> (tiny change)
62
63 * mail/sendmail.el (mail-recover-1, mail-recover):
64 * files.el (recover-file, recover-session):
65 Handle dired-listing-switches not being just a single short option.
66
672011-06-09 Glenn Morris <rgm@gnu.org>
68
69 * calendar/appt.el (appt-display-message, appt-disp-window):
70 Handle lists of appointments.
71
12011-06-08 Martin Rudalics <rudalics@gmx.at> 722011-06-08 Martin Rudalics <rudalics@gmx.at>
2 73
3 * window.el (one-window-p): Move down in code. Rewrite 74 * window.el (one-window-p): Move down in code. Rewrite
diff --git a/lisp/calendar/appt.el b/lisp/calendar/appt.el
index 5089df1d8ed..6148babfd11 100644
--- a/lisp/calendar/appt.el
+++ b/lisp/calendar/appt.el
@@ -214,21 +214,60 @@ If this is non-nil, appointment checking is active.")
214(defun appt-display-message (string mins) 214(defun appt-display-message (string mins)
215 "Display a reminder about an appointment. 215 "Display a reminder about an appointment.
216The string STRING describes the appointment, due in integer MINS minutes. 216The string STRING describes the appointment, due in integer MINS minutes.
217The format of the visible reminder is controlled by `appt-display-format'. 217The arguments may also be lists, where each element relates to a
218The variable `appt-audible' controls the audible reminder." 218separate appointment. The variable `appt-display-format' controls
219the format of the visible reminder. If `appt-audible' is non-nil,
220also calls `beep' for an audible reminder."
219 (if appt-audible (beep 1)) 221 (if appt-audible (beep 1))
222 ;; Backwards compatibility: avoid passing lists to a-d-w-f if not necessary.
223 (and (listp mins)
224 (= (length mins) 1)
225 (setq mins (car mins)
226 string (car string)))
220 (cond ((eq appt-display-format 'window) 227 (cond ((eq appt-display-format 'window)
221 (funcall appt-disp-window-function 228 ;; TODO use calendar-month-abbrev-array rather than %b?
222 (number-to-string mins) 229 (let ((time (format-time-string "%a %b %e " (current-time)))
223 ;; TODO - use calendar-month-abbrev-array rather than %b? 230 err)
224 (format-time-string "%a %b %e " (current-time)) 231 (condition-case err
225 string) 232 (funcall appt-disp-window-function
233 (if (listp mins)
234 (mapcar 'number-to-string mins)
235 (number-to-string mins))
236 time string)
237 (wrong-type-argument
238 (if (not (listp mins))
239 (signal (car err) (cdr err))
240 (message "Argtype error in `appt-disp-window-function' - \
241update it for multiple appts?")
242 ;; Fallback to just displaying the first appt, as we used to.
243 (funcall appt-disp-window-function
244 (number-to-string (car mins)) time
245 (car string))))))
226 (run-at-time (format "%d sec" appt-display-duration) 246 (run-at-time (format "%d sec" appt-display-duration)
227 nil 247 nil
228 appt-delete-window-function)) 248 appt-delete-window-function))
229 ((eq appt-display-format 'echo) 249 ((eq appt-display-format 'echo)
230 (message "%s" string)))) 250 (message "%s" (if (listp string)
231 251 (mapconcat 'identity string "\n")
252 string)))))
253
254(defun appt-mode-line (min-to-app &optional abbrev)
255 "Return an appointment string suitable for use in the mode-line.
256MIN-TO-APP is a list of minutes, as strings.
257If ABBREV is non-nil, abbreviates some text."
258 ;; All this silliness is just to make the formatting slightly nicer.
259 (let* ((multiple (> (length min-to-app) 1))
260 (imin (if (or (not multiple)
261 (not (delete (car min-to-app) min-to-app)))
262 (car min-to-app))))
263 (format "%s%s %s"
264 (if abbrev "App't" "Appointment")
265 (if multiple "s" "")
266 (if (equal imin "0") "now"
267 (format "in %s %s"
268 (or imin (mapconcat 'identity min-to-app ","))
269 (if abbrev "min."
270 (format "minute%s" (if (equal imin "1") "" "s"))))))))
232 271
233(defun appt-check (&optional force) 272(defun appt-check (&optional force)
234 "Check for an appointment and update any reminder display. 273 "Check for an appointment and update any reminder display.
@@ -351,9 +390,8 @@ displayed in a window:
351 (when appt-display-mode-line 390 (when appt-display-mode-line
352 (setq appt-mode-string 391 (setq appt-mode-string
353 (concat " " (propertize 392 (concat " " (propertize
354 (format "App't %s" 393 (appt-mode-line (mapcar 'number-to-string
355 (if (zerop min-to-app) "NOW" 394 (list min-to-app)) t)
356 (format "in %s min." min-to-app)))
357 'face 'mode-line-emphasis)))) 395 'face 'mode-line-emphasis))))
358 ;; When an appointment is reached, delete it from the 396 ;; When an appointment is reached, delete it from the
359 ;; list. Reset the count to 0 in case we display another 397 ;; list. Reset the count to 0 in case we display another
@@ -373,8 +411,10 @@ displayed in a window:
373 411
374(defun appt-disp-window (min-to-app new-time appt-msg) 412(defun appt-disp-window (min-to-app new-time appt-msg)
375 "Display appointment due in MIN-TO-APP (a string) minutes. 413 "Display appointment due in MIN-TO-APP (a string) minutes.
376NEW-TIME is a string giving the date. Displays the appointment 414NEW-TIME is a string giving the current date.
377message APPT-MSG in a separate buffer." 415Displays the appointment message APPT-MSG in a separate buffer.
416The arguments may also be lists, where each element relates to a
417separate appointment."
378 (let ((this-window (selected-window)) 418 (let ((this-window (selected-window))
379 (appt-disp-buf (get-buffer-create appt-buffer-name))) 419 (appt-disp-buf (get-buffer-create appt-buffer-name)))
380 ;; Make sure we're not in the minibuffer before splitting the window. 420 ;; Make sure we're not in the minibuffer before splitting the window.
@@ -395,17 +435,29 @@ message APPT-MSG in a separate buffer."
395 (when (>= (window-height) (* 2 window-min-height)) 435 (when (>= (window-height) (* 2 window-min-height))
396 (select-window (split-window)))) 436 (select-window (split-window))))
397 (switch-to-buffer appt-disp-buf)) 437 (switch-to-buffer appt-disp-buf))
438 (or (listp min-to-app)
439 (setq min-to-app (list min-to-app)
440 appt-msg (list appt-msg)))
441 ;; I don't really see the point of the new-time argument.
442 ;; It repeatedly reminds you of the date?
443 ;; It would make more sense if it was eg the time of the appointment.
444 ;; Let's allow it to be a list or not independent of the other elements.
445 (or (listp new-time)
446 (setq new-time (list new-time)))
398 ;; FIXME Link to diary entry? 447 ;; FIXME Link to diary entry?
399 (calendar-set-mode-line 448 (calendar-set-mode-line
400 (format " Appointment %s. %s " 449 (format " %s. %s" (appt-mode-line min-to-app)
401 (if (string-equal "0" min-to-app) "now" 450 (mapconcat 'identity new-time ", ")))
402 (format "in %s minute%s" min-to-app
403 (if (string-equal "1" min-to-app) "" "s")))
404 new-time))
405 (setq buffer-read-only nil 451 (setq buffer-read-only nil
406 buffer-undo-list t) 452 buffer-undo-list t)
407 (erase-buffer) 453 (erase-buffer)
408 (insert appt-msg) 454 ;; If we have appointments at different times, prepend the times.
455 (if (or (= 1 (length min-to-app))
456 (not (delete (car min-to-app) min-to-app)))
457 (insert (mapconcat 'identity appt-msg "\n"))
458 (dotimes (i (length appt-msg))
459 (insert (format "%s%sm: %s" (if (> i 0) "\n" "")
460 (nth i min-to-app) (nth i appt-msg)))))
409 (shrink-window-if-larger-than-buffer (get-buffer-window appt-disp-buf t)) 461 (shrink-window-if-larger-than-buffer (get-buffer-window appt-disp-buf t))
410 (set-buffer-modified-p nil) 462 (set-buffer-modified-p nil)
411 (setq buffer-read-only t) 463 (setq buffer-read-only t)
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 6113a4321c5..389716b35b9 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -388,19 +388,18 @@ since it could result in memory overflow and make Emacs crash."
388 ;; window.c 388 ;; window.c
389 (temp-buffer-show-function windows (choice (const nil) function)) 389 (temp-buffer-show-function windows (choice (const nil) function))
390 (next-screen-context-lines windows integer) 390 (next-screen-context-lines windows integer)
391 (window-min-height windows integer)
392 (window-min-width windows integer)
393 (scroll-preserve-screen-position 391 (scroll-preserve-screen-position
394 windows (choice 392 windows (choice
395 (const :tag "Off (nil)" :value nil) 393 (const :tag "Off (nil)" :value nil)
396 (const :tag "Full screen (t)" :value t) 394 (const :tag "Full screen (t)" :value t)
397 (other :tag "Always" 1)) "22.1") 395 (other :tag "Always" 1)) "22.1")
398 (recenter-redisplay windows 396 (recenter-redisplay
399 (choice 397 windows (choice
400 (const :tag "Never (nil)" :value nil) 398 (const :tag "Never (nil)" :value nil)
401 (const :tag "Only on ttys" :value tty) 399 (const :tag "Only on ttys" :value tty)
402 (other :tag "Always" t)) 400 (other :tag "Always" t)) "23.1")
403 "23.1") 401 (window-splits windows boolean "24.1")
402 (window-nest windows boolean "24.1")
404 ;; xdisp.c 403 ;; xdisp.c
405 (show-trailing-whitespace whitespace-faces boolean nil 404 (show-trailing-whitespace whitespace-faces boolean nil
406 :safe booleanp) 405 :safe booleanp)
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 06c3b70a3a6..666c6a8b034 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -1550,7 +1550,7 @@ See the command `doc-view-mode' for more information on this mode."
1550(provide 'doc-view) 1550(provide 'doc-view)
1551 1551
1552;; Local Variables: 1552;; Local Variables:
1553;; eval: (outline-minor-mode) 1553;; eval: (outline-minor-mode 1)
1554;; End: 1554;; End:
1555 1555
1556;;; doc-view.el ends here 1556;;; doc-view.el ends here
diff --git a/lisp/files.el b/lisp/files.el
index cc1ad23925d..317153dc9bf 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -2635,7 +2635,7 @@ we don't actually set it to the same mode the buffer already has."
2635 ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*- 2635 ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*-
2636 (let (end done mode modes) 2636 (let (end done mode modes)
2637 ;; Once we drop the deprecated feature where mode: is also allowed to 2637 ;; Once we drop the deprecated feature where mode: is also allowed to
2638 ;; specify minor-modes (ie, there can be more than one "mode:), we can 2638 ;; specify minor-modes (ie, there can be more than one "mode:"), we can
2639 ;; remove this section and just let (hack-local-variables t) handle it. 2639 ;; remove this section and just let (hack-local-variables t) handle it.
2640 ;; Find a -*- mode tag. 2640 ;; Find a -*- mode tag.
2641 (save-excursion 2641 (save-excursion
@@ -3367,7 +3367,7 @@ It is dangerous if either of these conditions are met:
3367 (and (symbolp (car exp)) 3367 (and (symbolp (car exp))
3368 ;; Allow (minor)-modes calls with no arguments. 3368 ;; Allow (minor)-modes calls with no arguments.
3369 ;; This obsoletes the use of "mode:" for such things. (Bug#8613) 3369 ;; This obsoletes the use of "mode:" for such things. (Bug#8613)
3370 (or (and (null (cdr exp)) 3370 (or (and (member (cdr exp) '(nil (1) (-1)))
3371 (string-match "-mode\\'" (symbol-name (car exp)))) 3371 (string-match "-mode\\'" (symbol-name (car exp))))
3372 (let ((prop (get (car exp) 'safe-local-eval-function))) 3372 (let ((prop (get (car exp) 'safe-local-eval-function)))
3373 (cond ((eq prop t) 3373 (cond ((eq prop t)
@@ -5256,7 +5256,7 @@ non-nil, it is called instead of rereading visited file contents."
5256 (save-excursion 5256 (save-excursion
5257 (let ((switches dired-listing-switches)) 5257 (let ((switches dired-listing-switches))
5258 (if (file-symlink-p file) 5258 (if (file-symlink-p file)
5259 (setq switches (concat switches "L"))) 5259 (setq switches (concat switches " -L")))
5260 (set-buffer standard-output) 5260 (set-buffer standard-output)
5261 ;; Use insert-directory-safely, not insert-directory, 5261 ;; Use insert-directory-safely, not insert-directory,
5262 ;; because these files might not exist. In particular, 5262 ;; because these files might not exist. In particular,
@@ -5299,7 +5299,7 @@ Then you'll be asked about a number of files to recover."
5299 (error "No previous sessions to recover"))) 5299 (error "No previous sessions to recover")))
5300 (let ((ls-lisp-support-shell-wildcards t)) 5300 (let ((ls-lisp-support-shell-wildcards t))
5301 (dired (concat auto-save-list-file-prefix "*") 5301 (dired (concat auto-save-list-file-prefix "*")
5302 (concat dired-listing-switches "t"))) 5302 (concat dired-listing-switches " -t")))
5303 (save-excursion 5303 (save-excursion
5304 (goto-char (point-min)) 5304 (goto-char (point-min))
5305 (or (looking-at " Move to the session you want to recover,") 5305 (or (looking-at " Move to the session you want to recover,")
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index ff3eb98bb97..2bfaf32f958 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,24 @@
12011-06-10 Katsumi Yamaoka <yamaoka@jpl.org>
2
3 * gnus-group.el (gnus-group-update-group): Add new argument
4 `info-unchanged' that stops updating dribble buffer.
5
6 * gnus-start.el (gnus-dribble-enter): Add new argument `regexp' that
7 deletes lines matching to it in dribble buffer.
8
9 * gnus-agent.el (gnus-agent-fetch-group-1):
10 * gnus-group.el (gnus-group-update-group-line, gnus-group-make-group):
11 * gnus-srvr.el (gnus-server-update-server, gnus-server-set-info):
12 * gnus-start.el (gnus-group-change-level):
13 * gnus-sum.el (gnus-summary-move-article): Delete old dribble entry.
14
15 * gnus-sum.el (gnus-summary-update-info): Don't update dribble buffer
16 if newsgroup info is not changed.
17
18 * gnus-group.el (gnus-group-get-new-news-this-group):
19 * gnus-sum.el (gnus-summary-read-group-1, gnus-summary-exit-no-update):
20 Don't update dribble buffer.
21
12011-06-01 Teodor Zlatanov <tzz@lifelogs.com> 222011-06-01 Teodor Zlatanov <tzz@lifelogs.com>
2 23
3 * gnus-registry.el (gnus-registry-remove-ignored): New function to 24 * gnus-registry.el (gnus-registry-remove-ignored): New function to
diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el
index b4f0dc38e7e..424c55c40f5 100644
--- a/lisp/gnus/gnus-agent.el
+++ b/lisp/gnus/gnus-agent.el
@@ -2614,7 +2614,9 @@ modified) original contents, they are first saved to their own file."
2614 (gnus-dribble-enter 2614 (gnus-dribble-enter
2615 (concat "(gnus-group-set-info '" 2615 (concat "(gnus-group-set-info '"
2616 (gnus-prin1-to-string info) 2616 (gnus-prin1-to-string info)
2617 ")")))))))))))) 2617 ")")
2618 (concat "^(gnus-group-set-info '(\""
2619 (regexp-quote group) "\""))))))))))))
2618 2620
2619;;; 2621;;;
2620;;; Agent Category Mode 2622;;; Agent Category Mode
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index 4c474b0aa23..518f215a7ba 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -1437,7 +1437,8 @@ if it is a string, only list groups matching REGEXP."
1437 (gnus-dribble-enter 1437 (gnus-dribble-enter
1438 (concat "(gnus-group-set-info '" 1438 (concat "(gnus-group-set-info '"
1439 (gnus-prin1-to-string (nth 2 entry)) 1439 (gnus-prin1-to-string (nth 2 entry))
1440 ")"))) 1440 ")")
1441 (concat "^(gnus-group-set-info '(\"" (regexp-quote group) "\"")))
1441 (setq gnus-group-indentation (gnus-group-group-indentation)) 1442 (setq gnus-group-indentation (gnus-group-group-indentation))
1442 (gnus-delete-line) 1443 (gnus-delete-line)
1443 (gnus-group-insert-group-line-info group) 1444 (gnus-group-insert-group-line-info group)
@@ -1685,10 +1686,11 @@ and ends at END."
1685 (gnus-active group)) 1686 (gnus-active group))
1686 (gnus-group-update-group group)) 1687 (gnus-group-update-group group))
1687 1688
1688(defun gnus-group-update-group (group &optional visible-only) 1689(defun gnus-group-update-group (group &optional visible-only
1690 info-unchanged)
1689 "Update all lines where GROUP appear. 1691 "Update all lines where GROUP appear.
1690If VISIBLE-ONLY is non-nil, the group won't be displayed if it isn't 1692If VISIBLE-ONLY is non-nil, the group won't be displayed if it isn't
1691already." 1693already. If INFO-UNCHANGED is non-nil, dribble buffer is not updated."
1692 (with-current-buffer gnus-group-buffer 1694 (with-current-buffer gnus-group-buffer
1693 (save-excursion 1695 (save-excursion
1694 ;; The buffer may be narrowed. 1696 ;; The buffer may be narrowed.
@@ -1697,14 +1699,17 @@ already."
1697 (let ((ident (gnus-intern-safe group gnus-active-hashtb)) 1699 (let ((ident (gnus-intern-safe group gnus-active-hashtb))
1698 (loc (point-min)) 1700 (loc (point-min))
1699 found buffer-read-only) 1701 found buffer-read-only)
1700 ;; Enter the current status into the dribble buffer. 1702 (unless info-unchanged
1701 (let ((entry (gnus-group-entry group))) 1703 ;; Enter the current status into the dribble buffer.
1702 (when (and entry 1704 (let ((entry (gnus-group-entry group)))
1703 (not (gnus-ephemeral-group-p group))) 1705 (when (and entry
1704 (gnus-dribble-enter 1706 (not (gnus-ephemeral-group-p group)))
1705 (concat "(gnus-group-set-info '" 1707 (gnus-dribble-enter
1706 (gnus-prin1-to-string (nth 2 entry)) 1708 (concat "(gnus-group-set-info '"
1707 ")")))) 1709 (gnus-prin1-to-string (nth 2 entry))
1710 ")")
1711 (concat "^(gnus-group-set-info '(\""
1712 (regexp-quote group) "\"")))))
1708 ;; Find all group instances. If topics are in use, each group 1713 ;; Find all group instances. If topics are in use, each group
1709 ;; may be listed in more than once. 1714 ;; may be listed in more than once.
1710 (while (setq loc (text-property-any 1715 (while (setq loc (text-property-any
@@ -2715,7 +2720,8 @@ server."
2715 (unless (gnus-ephemeral-group-p name) 2720 (unless (gnus-ephemeral-group-p name)
2716 (gnus-dribble-enter 2721 (gnus-dribble-enter
2717 (concat "(gnus-group-set-info '" 2722 (concat "(gnus-group-set-info '"
2718 (gnus-prin1-to-string (cdr info)) ")"))) 2723 (gnus-prin1-to-string (cdr info)) ")")
2724 (concat "^(gnus-group-set-info '(\"" (regexp-quote name) "\"")))
2719 ;; Insert the line. 2725 ;; Insert the line.
2720 (gnus-group-insert-group-line-info nname) 2726 (gnus-group-insert-group-line-info nname)
2721 (forward-line -1) 2727 (forward-line -1)
@@ -4032,7 +4038,7 @@ If DONT-SCAN is non-nil, scan non-activated groups as well."
4032 (when gnus-agent 4038 (when gnus-agent
4033 (gnus-agent-save-group-info 4039 (gnus-agent-save-group-info
4034 method (gnus-group-real-name group) active)) 4040 method (gnus-group-real-name group) active))
4035 (gnus-group-update-group group)) 4041 (gnus-group-update-group group nil t))
4036 (if (eq (gnus-server-status (gnus-find-method-for-group group)) 4042 (if (eq (gnus-server-status (gnus-find-method-for-group group))
4037 'denied) 4043 'denied)
4038 (gnus-error 3 "Server denied access") 4044 (gnus-error 3 "Server denied access")
diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el
index 9bf2d37a3e4..ec98b2ff749 100644
--- a/lisp/gnus/gnus-srvr.el
+++ b/lisp/gnus/gnus-srvr.el
@@ -362,7 +362,8 @@ The following commands are available:
362 (when entry 362 (when entry
363 (gnus-dribble-enter 363 (gnus-dribble-enter
364 (concat "(gnus-server-set-info \"" server "\" '" 364 (concat "(gnus-server-set-info \"" server "\" '"
365 (gnus-prin1-to-string (cdr entry)) ")\n"))) 365 (gnus-prin1-to-string (cdr entry)) ")\n")
366 (concat "^(gnus-server-set-info \"" (regexp-quote server) "\"")))
366 (when (or entry oentry) 367 (when (or entry oentry)
367 ;; Buffer may be narrowed. 368 ;; Buffer may be narrowed.
368 (save-restriction 369 (save-restriction
@@ -381,7 +382,8 @@ The following commands are available:
381 (when (and server info) 382 (when (and server info)
382 (gnus-dribble-enter 383 (gnus-dribble-enter
383 (concat "(gnus-server-set-info \"" server "\" '" 384 (concat "(gnus-server-set-info \"" server "\" '"
384 (gnus-prin1-to-string info) ")")) 385 (gnus-prin1-to-string info) ")")
386 (concat "^(gnus-server-set-info \"" (regexp-quote server) "\""))
385 (let* ((server (nth 1 info)) 387 (let* ((server (nth 1 info))
386 (entry (assoc server gnus-server-alist)) 388 (entry (assoc server gnus-server-alist))
387 (cached (assoc server gnus-server-method-cache))) 389 (cached (assoc server gnus-server-method-cache)))
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 719d0c9e472..aa9af012a1c 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -832,13 +832,22 @@ prompt the user for the name of an NNTP server to use."
832 gnus-current-startup-file) 832 gnus-current-startup-file)
833 "-dribble")) 833 "-dribble"))
834 834
835(defun gnus-dribble-enter (string) 835(defun gnus-dribble-enter (string &optional regexp)
836 "Enter STRING into the dribble buffer." 836 "Enter STRING into the dribble buffer.
837If REGEXP is given, lines that match it will be deleted."
837 (when (and (not gnus-dribble-ignore) 838 (when (and (not gnus-dribble-ignore)
838 gnus-dribble-buffer 839 gnus-dribble-buffer
839 (buffer-name gnus-dribble-buffer)) 840 (buffer-name gnus-dribble-buffer))
840 (let ((obuf (current-buffer))) 841 (let ((obuf (current-buffer)))
841 (set-buffer gnus-dribble-buffer) 842 (set-buffer gnus-dribble-buffer)
843 (when regexp
844 (goto-char (point-min))
845 (let (end)
846 (while (re-search-forward regexp nil t)
847 (unless (bolp) (forward-line 1))
848 (setq end (point))
849 (goto-char (match-beginning 0))
850 (delete-region (point-at-bol) end))))
842 (goto-char (point-max)) 851 (goto-char (point-max))
843 (insert string "\n") 852 (insert string "\n")
844 ;; This has been commented by Josh Huber <huber@alum.wpi.edu> 853 ;; This has been commented by Josh Huber <huber@alum.wpi.edu>
@@ -1354,8 +1363,8 @@ for new groups, and subscribe the new groups as zombies."
1354 (when (cdr entry) 1363 (when (cdr entry)
1355 (setcdr (gnus-group-entry (caadr entry)) entry)) 1364 (setcdr (gnus-group-entry (caadr entry)) entry))
1356 (gnus-dribble-enter 1365 (gnus-dribble-enter
1357 (format 1366 (format "(gnus-group-set-info '%S)" info)
1358 "(gnus-group-set-info '%S)" info))))) 1367 (concat "^(gnus-group-set-info '(\"" (regexp-quote group) "\"")))))
1359 (when gnus-group-change-level-function 1368 (when gnus-group-change-level-function
1360 (funcall gnus-group-change-level-function 1369 (funcall gnus-group-change-level-function
1361 group level oldlevel previous))))) 1370 group level oldlevel previous)))))
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 1c4382b24a6..f974d386acb 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -4098,7 +4098,7 @@ If NO-DISPLAY, don't generate a summary buffer."
4098 (setq gnus-newsgroup-prepared t) 4098 (setq gnus-newsgroup-prepared t)
4099 (gnus-run-hooks 'gnus-summary-prepared-hook) 4099 (gnus-run-hooks 'gnus-summary-prepared-hook)
4100 (unless (gnus-ephemeral-group-p group) 4100 (unless (gnus-ephemeral-group-p group)
4101 (gnus-group-update-group group)) 4101 (gnus-group-update-group group nil t))
4102 t))))) 4102 t)))))
4103 4103
4104(defun gnus-summary-auto-select-subject () 4104(defun gnus-summary-auto-select-subject ()
@@ -7140,7 +7140,12 @@ The prefix argument ALL means to select all articles."
7140 t))) 7140 t)))
7141 (unless (listp (cdr gnus-newsgroup-killed)) 7141 (unless (listp (cdr gnus-newsgroup-killed))
7142 (setq gnus-newsgroup-killed (list gnus-newsgroup-killed))) 7142 (setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
7143 (let ((headers gnus-newsgroup-headers)) 7143 (let ((headers gnus-newsgroup-headers)
7144 (ephemeral-p (gnus-ephemeral-group-p group))
7145 info)
7146 (unless ephemeral-p
7147 (setq info (copy-sequence (gnus-get-info group))
7148 info (delq (gnus-info-params info) info)))
7144 ;; Set the new ranges of read articles. 7149 ;; Set the new ranges of read articles.
7145 (with-current-buffer gnus-group-buffer 7150 (with-current-buffer gnus-group-buffer
7146 (gnus-undo-force-boundary)) 7151 (gnus-undo-force-boundary))
@@ -7160,8 +7165,12 @@ The prefix argument ALL means to select all articles."
7160 (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads)) 7165 (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads))
7161 ;; Do not switch windows but change the buffer to work. 7166 ;; Do not switch windows but change the buffer to work.
7162 (set-buffer gnus-group-buffer) 7167 (set-buffer gnus-group-buffer)
7163 (unless (gnus-ephemeral-group-p group) 7168 (unless ephemeral-p
7164 (gnus-group-update-group group))))))) 7169 (gnus-group-update-group
7170 group nil
7171 (equal info
7172 (setq info (copy-sequence (gnus-get-info group))
7173 info (delq (gnus-info-params info) info))))))))))
7165 7174
7166(defun gnus-summary-save-newsrc (&optional force) 7175(defun gnus-summary-save-newsrc (&optional force)
7167 "Save the current number of read/marked articles in the dribble buffer. 7176 "Save the current number of read/marked articles in the dribble buffer.
@@ -7314,7 +7323,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
7314 ;; Clear the current group name. 7323 ;; Clear the current group name.
7315 (setq gnus-newsgroup-name nil) 7324 (setq gnus-newsgroup-name nil)
7316 (unless (gnus-ephemeral-group-p group) 7325 (unless (gnus-ephemeral-group-p group)
7317 (gnus-group-update-group group)) 7326 (gnus-group-update-group group nil t))
7318 (when (equal (gnus-group-group-name) group) 7327 (when (equal (gnus-group-group-name) group)
7319 (gnus-group-next-unread-group 1)) 7328 (gnus-group-next-unread-group 1))
7320 (when quit-config 7329 (when quit-config
@@ -9994,7 +10003,9 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
9994 (gnus-dribble-enter 10003 (gnus-dribble-enter
9995 (concat "(gnus-group-set-info '" 10004 (concat "(gnus-group-set-info '"
9996 (gnus-prin1-to-string (gnus-get-info to-group)) 10005 (gnus-prin1-to-string (gnus-get-info to-group))
9997 ")")))) 10006 ")")
10007 (concat "^(gnus-group-set-info '(\""
10008 (regexp-quote to-group) "\""))))
9998 10009
9999 ;; Update the Xref header in this article to point to 10010 ;; Update the Xref header in this article to point to
10000 ;; the new crossposted article we have just created. 10011 ;; the new crossposted article we have just created.
diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el
index 2c5fa014a94..f4ef9b91903 100644
--- a/lisp/mail/sendmail.el
+++ b/lisp/mail/sendmail.el
@@ -1801,7 +1801,7 @@ The seventh argument ACTIONS is a list of actions to take
1801 ;; unbound on exit from the let. 1801 ;; unbound on exit from the let.
1802 (require 'dired) 1802 (require 'dired)
1803 (let ((dired-trivial-filenames t)) 1803 (let ((dired-trivial-filenames t))
1804 (dired-other-window wildcard (concat dired-listing-switches "t"))) 1804 (dired-other-window wildcard (concat dired-listing-switches " -t")))
1805 (rename-buffer "*Auto-saved Drafts*" t) 1805 (rename-buffer "*Auto-saved Drafts*" t)
1806 (save-excursion 1806 (save-excursion
1807 (goto-char (point-min)) 1807 (goto-char (point-min))
@@ -1881,7 +1881,7 @@ you can move to one of them and type C-c C-c to recover that one."
1881 ;; `ls' is not a standard program (it will use 1881 ;; `ls' is not a standard program (it will use
1882 ;; ls-lisp instead). 1882 ;; ls-lisp instead).
1883 (dired-noselect file-name 1883 (dired-noselect file-name
1884 (concat dired-listing-switches "t")))) 1884 (concat dired-listing-switches " -t"))))
1885 (save-selected-window 1885 (save-selected-window
1886 (select-window (display-buffer dispbuf t)) 1886 (select-window (display-buffer dispbuf t))
1887 (goto-char (point-min)) 1887 (goto-char (point-min))
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el
index b1d8279e93f..0493ead7bbf 100644
--- a/lisp/net/ange-ftp.el
+++ b/lisp/net/ange-ftp.el
@@ -2806,6 +2806,19 @@ match subdirectories as well.")
2806 (and files (puthash (file-name-as-directory directory) 2806 (and files (puthash (file-name-as-directory directory)
2807 files ange-ftp-files-hashtable))) 2807 files ange-ftp-files-hashtable)))
2808 2808
2809(defun ange-ftp-switches-ok (switches)
2810 "Return SWITCHES (a string) if suitable for our use."
2811 (and (stringp switches)
2812 ;; We allow the A switch, which lists all files except "." and
2813 ;; "..". This is OK because we manually insert these entries
2814 ;; in the hash table.
2815 (string-match
2816 "--\\(almost-\\)?all\\>\\|\\(\\`\\| \\)-[[:alpha:]]*[aA]" switches)
2817 (string-match "\\(\\`\\| \\)-[[:alpha:]]*l" switches)
2818 (not (string-match
2819 "--recursive\\>\\|\\(\\`\\| \\)-[[:alpha:]]*R" switches))
2820 switches))
2821
2809(defun ange-ftp-get-files (directory &optional no-error) 2822(defun ange-ftp-get-files (directory &optional no-error)
2810 "Given a DIRECTORY, return a hashtable of file entries. 2823 "Given a DIRECTORY, return a hashtable of file entries.
2811This will give an error or return nil, depending on the value of 2824This will give an error or return nil, depending on the value of
@@ -2817,30 +2830,12 @@ NO-ERROR, if a listing for DIRECTORY cannot be obtained."
2817 ;; This is an efficiency hack. We try to 2830 ;; This is an efficiency hack. We try to
2818 ;; anticipate what sort of listing dired 2831 ;; anticipate what sort of listing dired
2819 ;; might want, and cache just such a listing. 2832 ;; might want, and cache just such a listing.
2820 (if (and (boundp 'dired-actual-switches) 2833 (or (and (boundp 'dired-actual-switches)
2821 (stringp dired-actual-switches) 2834 (ange-ftp-switches-ok dired-actual-switches))
2822 ;; We allow the A switch, which lists 2835 (and (boundp 'dired-listing-switches)
2823 ;; all files except "." and "..". 2836 (ange-ftp-switches-ok
2824 ;; This is OK because we manually 2837 dired-listing-switches))
2825 ;; insert these entries 2838 "-al")
2826 ;; in the hash table.
2827 (string-match
2828 "[aA]" dired-actual-switches)
2829 (string-match
2830 "l" dired-actual-switches)
2831 (not (string-match
2832 "R" dired-actual-switches)))
2833 dired-actual-switches
2834 (if (and (boundp 'dired-listing-switches)
2835 (stringp dired-listing-switches)
2836 (string-match
2837 "[aA]" dired-listing-switches)
2838 (string-match
2839 "l" dired-listing-switches)
2840 (not (string-match
2841 "R" dired-listing-switches)))
2842 dired-listing-switches
2843 "-al"))
2844 t no-error) 2839 t no-error)
2845 (gethash directory ange-ftp-files-hashtable))))) 2840 (gethash directory ange-ftp-files-hashtable)))))
2846 2841
diff --git a/lisp/net/soap-client.el b/lisp/net/soap-client.el
index 9862332bf3f..b7b0b61f4e1 100644
--- a/lisp/net/soap-client.el
+++ b/lisp/net/soap-client.el
@@ -1745,7 +1745,7 @@ operations in a WSDL document."
1745 1745
1746 1746
1747;;; Local Variables: 1747;;; Local Variables:
1748;;; eval: (outline-minor-mode) 1748;;; eval: (outline-minor-mode 1)
1749;;; outline-regexp: ";;;;+" 1749;;; outline-regexp: ";;;;+"
1750;;; End: 1750;;; End:
1751 1751
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el
index 0db33b5a4de..c2b870bd535 100644
--- a/lisp/term/xterm.el
+++ b/lisp/term/xterm.el
@@ -24,6 +24,23 @@
24 24
25;;; Code: 25;;; Code:
26 26
27(defgroup xterm nil
28 "XTerm support."
29 :version "24.1"
30 :group 'emacs)
31
32(defcustom xterm-extra-capabilities 'check
33 "Set to a list if the XTerm supports modifyOtherKeys or
34reporting the background color. Set to 'check to check for those
35features. Set to nil to skip the checks."
36 :group 'xterm
37 :type '(choice (const :tag "No" nil)
38 (const :tag "Check" check)
39 ;; NOTE: If you add entries here, make sure to update
40 ;; `tocheck-capabilities' in `terminal-init-xterm' as well.
41 (set (const :tag "modifyOtherKeys support" modifyOtherKeys)
42 (const :tag "report background" reportBackground))))
43
27(defvar xterm-function-map 44(defvar xterm-function-map
28 (let ((map (make-sparse-keymap))) 45 (let ((map (make-sparse-keymap)))
29 46
@@ -460,81 +477,116 @@
460 (set-keymap-parent map (keymap-parent input-decode-map)) 477 (set-keymap-parent map (keymap-parent input-decode-map))
461 (set-keymap-parent input-decode-map map))) 478 (set-keymap-parent input-decode-map map)))
462 479
463 (xterm-register-default-colors) 480 (xterm-register-default-colors)
464 (tty-set-up-initial-frame-faces) 481 (tty-set-up-initial-frame-faces)
465 482
466 ;; Try to turn on the modifyOtherKeys feature on modern xterms. 483 ;; Try to turn on the modifyOtherKeys feature on modern xterms.
467 ;; When it is turned on many more key bindings work: things like 484 ;; When it is turned on many more key bindings work: things like
468 ;; C-. C-, etc. 485 ;; C-. C-, etc.
469 ;; To do that we need to find out if the current terminal supports 486 ;; To do that we need to find out if the current terminal supports
470 ;; modifyOtherKeys. At this time only xterm does. 487 ;; modifyOtherKeys. At this time only xterm does.
488 (when xterm-extra-capabilities
471 (let ((coding-system-for-read 'binary) 489 (let ((coding-system-for-read 'binary)
472 (chr nil) 490 (chr nil)
473 (str nil) 491 (str nil)
474 (recompute-faces nil) 492 (background-regex
475 version) 493 "11;rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)")
476 ;; Pending input can be mistakenly returned by the calls to 494 (recompute-faces nil)
477 ;; read-event below. Discard it. 495 ;; If `xterm-extra-capabilities' is 'check, we don't know
478 (discard-input) 496 ;; the capabilities. We need to check for those defined
479 ;; Try to find out the type of terminal by sending a "Secondary 497 ;; as `xterm-extra-capabilities' set options. Otherwise,
480 ;; Device Attributes (DA)" query. 498 ;; we don't need to check for any capabilities because
481 (send-string-to-terminal "\e[>0c") 499 ;; they are given by setting `xterm-extra-capabilities' to
482 500 ;; a list (which could be empty).
483 ;; The reply should be of the form: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c 501 (tocheck-capabilities (when (eq 'check xterm-extra-capabilities)
484 ;; If the timeout is completely removed for read-event, this 502 '(modifyOtherKeys reportBackground)))
485 ;; might hang for terminals that pretend to be xterm, but don't 503 ;; The given capabilities are either the contents of
486 ;; respond to this escape sequence. RMS' opinion was to remove 504 ;; `xterm-extra-capabilities', if it's a list, or an empty
487 ;; it completely. That might be right, but let's first try to 505 ;; list.
488 ;; see if by using a longer timeout we get rid of most issues. 506 (given-capabilities (when (consp xterm-extra-capabilities)
489 (when (equal (read-event nil nil 2) ?\e) 507 xterm-extra-capabilities))
490 (when (equal (read-event nil nil 2) ?\[) 508 version)
491 (while (not (equal (setq chr (read-event nil nil 2)) ?c)) 509
492 (setq str (concat str (string chr)))) 510 ;; Do the following if `xterm-extra-capabilities' is anything but nil.
493 (when (string-match ">0;\\([0-9]+\\);0" str) 511 (when xterm-extra-capabilities
494 (setq version (string-to-number 512 ;; 1. Set `version'
495 (substring str (match-beginning 1) (match-end 1)))) 513
496 ;; xterm version 242 supports reporting the background 514 ;; Pending input can be mistakenly returned by the calls to
497 ;; color, maybe earlier versions do too... 515 ;; read-event below. Discard it.
498 (when (>= version 242) 516 (discard-input)
499 (send-string-to-terminal "\e]11;?\e\\") 517 ;; Try to find out the type of terminal by sending a "Secondary
500 (when (equal (read-event nil nil 2) ?\e) 518 ;; Device Attributes (DA)" query.
501 (when (equal (read-event nil nil 2) ?\]) 519 (send-string-to-terminal "\e[>0c")
502 (setq str "") 520
503 (while (not (equal (setq chr (read-event nil nil 2)) ?\\)) 521 ;; The reply should be: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c
504 (setq str (concat str (string chr)))) 522 ;; If the timeout is completely removed for read-event, this
505 (when (string-match "11;rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)" str) 523 ;; might hang for terminals that pretend to be xterm, but don't
506 (setq recompute-faces 524 ;; respond to this escape sequence. RMS' opinion was to remove
507 (xterm-maybe-set-dark-background-mode 525 ;; it completely. That might be right, but let's first try to
508 (string-to-number (match-string 1 str) 16) 526 ;; see if by using a longer timeout we get rid of most issues.
509 (string-to-number (match-string 2 str) 16) 527 (when (equal (read-event nil nil 2) ?\e)
510 (string-to-number (match-string 3 str) 16))))))) 528 (when (equal (read-event nil nil 2) ?\[)
511 ;; NUMBER2 is the xterm version number, look for something 529 (while (not (equal (setq chr (read-event nil nil 2)) ?c))
512 ;; greater than 216, the version when modifyOtherKeys was 530 (setq str (concat str (string chr))))
513 ;; introduced. 531 (when (string-match ">0;\\([0-9]+\\);0" str)
514 (when (>= version 216) 532 (setq version
515 ;; Make sure that the modifyOtherKeys state is restored when 533 (string-to-number
516 ;; suspending, resuming and exiting. 534 (substring str (match-beginning 1) (match-end 1)))))))
517 (add-hook 'suspend-hook 'xterm-turn-off-modify-other-keys) 535
518 (add-hook 'suspend-resume-hook 'xterm-turn-on-modify-other-keys) 536 ;; 2. If reportBackground is known to be supported, or the
519 (add-hook 'kill-emacs-hook 'xterm-remove-modify-other-keys) 537 ;; version is 242 or higher, assume the xterm supports
520 (add-hook 'delete-terminal-functions 'xterm-remove-modify-other-keys) 538 ;; reporting the background color (TODO: maybe earlier
521 ;; Add the selected frame to the list of frames that 539 ;; versions do too...)
522 ;; need to deal with modify-other-keys. 540 (when (or (memq 'reportBackground given-capabilities)
523 (push (frame-terminal (selected-frame)) 541 (and (memq 'reportBackground tocheck-capabilities)
524 xterm-modify-other-keys-terminal-list) 542 (>= version 242)))
525 (xterm-turn-on-modify-other-keys)) 543 (send-string-to-terminal "\e]11;?\e\\")
526 544 (when (equal (read-event nil nil 2) ?\e)
527 ;; Recompute faces here in case the background mode was 545 (when (equal (read-event nil nil 2) ?\])
528 ;; set to dark. We used to call 546 (setq str "")
529 ;; `tty-set-up-initial-frame-faces' only once, but that 547 (while (not (equal (setq chr (read-event nil nil 2)) ?\\))
530 ;; caused the light background faces to be computed 548 (setq str (concat str (string chr))))
531 ;; incorrectly. See: 549 (when (string-match background-regex str)
532 ;; http://permalink.gmane.org/gmane.emacs.devel/119627 550 (setq recompute-faces
533 (when recompute-faces 551 (xterm-maybe-set-dark-background-mode
534 (tty-set-up-initial-frame-faces)))))) 552 (string-to-number (match-string 1 str) 16)
553 (string-to-number (match-string 2 str) 16)
554 (string-to-number (match-string 3 str) 16)))))))
555
556 ;; 3. If modifyOtherKeys is known to be supported or the
557 ;; version is 216 (the version when modifyOtherKeys was
558 ;; introduced) or higher, initialize the modifyOtherKeys
559 ;; support.
560 (when (or (memq 'modifyOtherKeys given-capabilities)
561 (and (memq 'modifyOtherKeys tocheck-capabilities)
562 (>= version 216)))
563 (terminal-init-xterm-modify-other-keys))
564
565 ;; Recompute faces here in case the background mode was
566 ;; set to dark. We used to call
567 ;; `tty-set-up-initial-frame-faces' only once, but that
568 ;; caused the light background faces to be computed
569 ;; incorrectly. See:
570 ;; http://permalink.gmane.org/gmane.emacs.devel/119627
571 (when recompute-faces
572 (tty-set-up-initial-frame-faces)))))
535 573
536 (run-hooks 'terminal-init-xterm-hook)) 574 (run-hooks 'terminal-init-xterm-hook))
537 575
576(defun terminal-init-xterm-modify-other-keys ()
577 "Terminal initialization for xterm's modifyOtherKeys support."
578 ;; Make sure that the modifyOtherKeys state is restored when
579 ;; suspending, resuming and exiting.
580 (add-hook 'suspend-hook 'xterm-turn-off-modify-other-keys)
581 (add-hook 'suspend-resume-hook 'xterm-turn-on-modify-other-keys)
582 (add-hook 'kill-emacs-hook 'xterm-remove-modify-other-keys)
583 (add-hook 'delete-terminal-functions 'xterm-remove-modify-other-keys)
584 ;; Add the selected frame to the list of frames that
585 ;; need to deal with modify-other-keys.
586 (push (frame-terminal (selected-frame))
587 xterm-modify-other-keys-terminal-list)
588 (xterm-turn-on-modify-other-keys))
589
538;; Set up colors, for those versions of xterm that support it. 590;; Set up colors, for those versions of xterm that support it.
539(defvar xterm-standard-colors 591(defvar xterm-standard-colors
540 ;; The names in the comments taken from XTerm-col.ad in the xterm 592 ;; The names in the comments taken from XTerm-col.ad in the xterm
diff --git a/lisp/window.el b/lisp/window.el
index eafa8a4764a..a88e56be83c 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -161,10 +161,41 @@ these functions to inhibit processing of window parameters.")
161 "The absolut minimum number of lines of a window. 161 "The absolut minimum number of lines of a window.
162Anything less might crash Emacs.") 162Anything less might crash Emacs.")
163 163
164(defcustom window-min-height 4
165 "The minimum number of lines of any window.
166The value has to accomodate a mode- or header-line if present. A
167value less than `window-safe-min-height' is ignored. The value
168of this variable is honored when windows are resized or split.
169
170Applications should never rebind this variable. To resize a
171window to a height less than the one specified here, an
172application should instead call `resize-window' with a non-nil
173IGNORE argument. In order to have `split-window' make a window
174shorter, explictly specify the SIZE argument of that function."
175 :type 'integer
176 :version "24.1"
177 :group 'windows)
178
164(defconst window-safe-min-width 2 179(defconst window-safe-min-width 2
165 "The absolut minimum number of columns of a window. 180 "The absolut minimum number of columns of a window.
166Anything less might crash Emacs.") 181Anything less might crash Emacs.")
167 182
183(defcustom window-min-width 10
184 "The minimum number of columns of any window.
185The value has to accomodate margins, fringes, or scrollbars if
186present. A value less than `window-safe-min-width' is ignored.
187The value of this variable is honored when windows are resized or
188split.
189
190Applications should never rebind this variable. To resize a
191window to a width less than the one specified here, an
192application should instead call `resize-window' with a non-nil
193IGNORE argument. In order to have `split-window' make a window
194narrower, explictly specify the SIZE argument of that function."
195 :type 'integer
196 :version "24.1"
197 :group 'windows)
198
168(defun window-iso-combination-p (&optional window horizontal) 199(defun window-iso-combination-p (&optional window horizontal)
169 "If WINDOW is a vertical combination return WINDOW's first child. 200 "If WINDOW is a vertical combination return WINDOW's first child.
170WINDOW can be any window and defaults to the selected one. 201WINDOW can be any window and defaults to the selected one.
@@ -1312,7 +1343,741 @@ The optional argument MINIBUF specifies whether the minibuffer
1312window shall be counted. See `walk-windows' for the precise 1343window shall be counted. See `walk-windows' for the precise
1313meaning of this argument." 1344meaning of this argument."
1314 (length (window-list-1 nil minibuf))) 1345 (length (window-list-1 nil minibuf)))
1346
1347;;; Resizing windows.
1348(defun resize-window-reset (&optional frame horizontal)
1349 "Reset resize values for all windows on FRAME.
1350FRAME defaults to the selected frame.
1351
1352This function stores the current value of `window-total-size' applied
1353with argument HORIZONTAL in the new total size of all windows on
1354FRAME. It also resets the new normal size of each of these
1355windows."
1356 (resize-window-reset-1
1357 (frame-root-window (normalize-live-frame frame)) horizontal))
1358
1359(defun resize-window-reset-1 (window horizontal)
1360 "Internal function of `resize-window-reset'."
1361 ;; Register old size in the new total size.
1362 (set-window-new-total window (window-total-size window horizontal))
1363 ;; Reset new normal size.
1364 (set-window-new-normal window)
1365 (when (window-child window)
1366 (resize-window-reset-1 (window-child window) horizontal))
1367 (when (window-right window)
1368 (resize-window-reset-1 (window-right window) horizontal)))
1369
1370;; The following routine is used to manually resize the minibuffer
1371;; window and is currently used, for example, by ispell.el.
1372(defun resize-mini-window (window delta)
1373 "Resize minibuffer window WINDOW by DELTA lines.
1374If WINDOW cannot be resized by DELTA lines make it as large \(or
1375as small) as possible but don't signal an error."
1376 (when (window-minibuffer-p window)
1377 (let* ((frame (window-frame window))
1378 (root (frame-root-window frame))
1379 (height (window-total-size window))
1380 (min-delta
1381 (- (window-total-size root)
1382 (window-min-size root))))
1383 ;; Sanitize DELTA.
1384 (cond
1385 ((<= (+ height delta) 0)
1386 (setq delta (- (- height 1))))
1387 ((> delta min-delta)
1388 (setq delta min-delta)))
1389
1390 ;; Resize now.
1391 (resize-window-reset frame)
1392 ;; Ideally we should be able to resize just the last subwindow of
1393 ;; root here. See the comment in `resize-root-window-vertically'
1394 ;; for why we do not do that.
1395 (resize-this-window root (- delta) nil nil t)
1396 (set-window-new-total window (+ height delta))
1397 ;; The following routine catches the case where we want to resize
1398 ;; a minibuffer-only frame.
1399 (resize-mini-window-internal window))))
1400
1401(defun resize-window (window delta &optional horizontal ignore)
1402 "Resize WINDOW vertically by DELTA lines.
1403WINDOW can be an arbitrary window and defaults to the selected
1404one. An attempt to resize the root window of a frame will raise
1405an error though.
1406
1407DELTA a positive number means WINDOW shall be enlarged by DELTA
1408lines. DELTA negative means WINDOW shall be shrunk by -DELTA
1409lines.
1410
1411Optional argument HORIZONTAL non-nil means resize WINDOW
1412horizontally by DELTA columns. In this case a positive DELTA
1413means enlarge WINDOW by DELTA columns. DELTA negative means
1414WINDOW shall be shrunk by -DELTA columns.
1415
1416Optional argument IGNORE non-nil means ignore any restrictions
1417imposed by fixed size windows, `window-min-height' or
1418`window-min-width' settings. IGNORE any window means ignore
1419restrictions for that window only. IGNORE equal `safe' means
1420live windows may get as small as `window-safe-min-height' lines
1421and `window-safe-min-width' columns.
1422
1423This function resizes other windows proportionally and never
1424deletes any windows. If you want to move only the low (right)
1425edge of WINDOW consider using `adjust-window-trailing-edge'
1426instead."
1427 (setq window (normalize-any-window window))
1428 (let* ((frame (window-frame window))
1429 sibling)
1430 (cond
1431 ((eq window (frame-root-window frame))
1432 (error "Cannot resize the root window of a frame"))
1433 ((window-minibuffer-p window)
1434 (resize-mini-window window delta))
1435 ((window-resizable-p window delta horizontal ignore)
1436 (resize-window-reset frame horizontal)
1437 (resize-this-window window delta horizontal ignore t)
1438 (if (and (not (window-splits window))
1439 (window-iso-combined-p window horizontal)
1440 (setq sibling (or (window-right window) (window-left window)))
1441 (window-sizable-p sibling (- delta) horizontal ignore))
1442 ;; If window-splits returns nil for WINDOW, WINDOW is part of
1443 ;; an iso-combination, and WINDOW's neighboring right or left
1444 ;; sibling can be resized as requested, resize that sibling.
1445 (let ((normal-delta
1446 (/ (float delta)
1447 (window-total-size (window-parent window) horizontal))))
1448 (resize-this-window sibling (- delta) horizontal nil t)
1449 (set-window-new-normal
1450 window (+ (window-normal-size window horizontal)
1451 normal-delta))
1452 (set-window-new-normal
1453 sibling (- (window-normal-size sibling horizontal)
1454 normal-delta)))
1455 ;; Otherwise, resize all other windows in the same combination.
1456 (resize-other-windows window delta horizontal ignore))
1457 (resize-window-apply frame horizontal))
1458 (t
1459 (error "Cannot resize window %s" window)))))
1460
1461(defsubst resize-subwindows-skip-p (window)
1462 "Return non-nil if WINDOW shall be skipped by resizing routines."
1463 (memq (window-new-normal window) '(ignore stuck skip)))
1464
1465(defun resize-subwindows-normal (parent horizontal window this-delta &optional trail other-delta)
1466 "Set the new normal height of subwindows of window PARENT.
1467HORIZONTAL non-nil means set the new normal width of these
1468windows. WINDOW specifies a subwindow of PARENT that has been
1469resized by THIS-DELTA lines \(columns).
1470
1471Optional argument TRAIL either 'before or 'after means set values
1472for windows before or after WINDOW only. Optional argument
1473OTHER-DELTA a number specifies that this many lines \(columns)
1474have been obtained from \(or returned to) an ancestor window of
1475PARENT in order to resize WINDOW."
1476 (let* ((delta-normal
1477 (if (and (= (- this-delta) (window-total-size window horizontal))
1478 (zerop other-delta))
1479 ;; When WINDOW gets deleted and we can return its entire
1480 ;; space to its siblings, use WINDOW's normal size as the
1481 ;; normal delta.
1482 (- (window-normal-size window horizontal))
1483 ;; In any other case calculate the normal delta from the
1484 ;; relation of THIS-DELTA to the total size of PARENT.
1485 (/ (float this-delta) (window-total-size parent horizontal))))
1486 (sub (window-child parent))
1487 (parent-normal 0.0)
1488 (skip (eq trail 'after)))
1489
1490 ;; Set parent-normal to the sum of the normal sizes of all
1491 ;; subwindows of PARENT that shall be resized, excluding only WINDOW
1492 ;; and any windows specified by the optional TRAIL argument.
1493 (while sub
1494 (cond
1495 ((eq sub window)
1496 (setq skip (eq trail 'before)))
1497 (skip)
1498 (t
1499 (setq parent-normal
1500 (+ parent-normal (window-normal-size sub horizontal)))))
1501 (setq sub (window-right sub)))
1502
1503 ;; Set the new normal size of all subwindows of PARENT from what
1504 ;; they should have contributed for recovering THIS-DELTA lines
1505 ;; (columns).
1506 (setq sub (window-child parent))
1507 (setq skip (eq trail 'after))
1508 (while sub
1509 (cond
1510 ((eq sub window)
1511 (setq skip (eq trail 'before)))
1512 (skip)
1513 (t
1514 (let ((old-normal (window-normal-size sub horizontal)))
1515 (set-window-new-normal
1516 sub (min 1.0 ; Don't get larger than 1.
1517 (max (- old-normal
1518 (* (/ old-normal parent-normal)
1519 delta-normal))
1520 ;; Don't drop below 0.
1521 0.0))))))
1522 (setq sub (window-right sub)))
1523
1524 (when (numberp other-delta)
1525 ;; Set the new normal size of windows from what they should have
1526 ;; contributed for recovering OTHER-DELTA lines (columns).
1527 (setq delta-normal (/ (float (window-total-size parent horizontal))
1528 (+ (window-total-size parent horizontal)
1529 other-delta)))
1530 (setq sub (window-child parent))
1531 (setq skip (eq trail 'after))
1532 (while sub
1533 (cond
1534 ((eq sub window)
1535 (setq skip (eq trail 'before)))
1536 (skip)
1537 (t
1538 (set-window-new-normal
1539 sub (min 1.0 ; Don't get larger than 1.
1540 (max (* (window-new-normal sub) delta-normal)
1541 ;; Don't drop below 0.
1542 0.0)))))
1543 (setq sub (window-right sub))))
1544
1545 ;; Set the new normal size of WINDOW to what is left by the sum of
1546 ;; the normal sizes of its siblings.
1547 (set-window-new-normal
1548 window
1549 (let ((sum 0))
1550 (setq sub (window-child parent))
1551 (while sub
1552 (cond
1553 ((eq sub window))
1554 ((not (numberp (window-new-normal sub)))
1555 (setq sum (+ sum (window-normal-size sub horizontal))))
1556 (t
1557 (setq sum (+ sum (window-new-normal sub)))))
1558 (setq sub (window-right sub)))
1559 ;; Don't get larger than 1 or smaller than 0.
1560 (min 1.0 (max (- 1.0 sum) 0.0))))))
1561
1562(defun resize-subwindows (parent delta &optional horizontal window ignore trail edge)
1563 "Resize subwindows of window PARENT vertically by DELTA lines.
1564PARENT must be a vertically combined internal window.
1565
1566Optional argument HORIZONTAL non-nil means resize subwindows of
1567PARENT horizontally by DELTA columns. In this case PARENT must
1568be a horizontally combined internal window.
1569
1570WINDOW, if specified, must denote a child window of PARENT that
1571is resized by DELTA lines.
1572
1573Optional argument IGNORE non-nil means ignore any restrictions
1574imposed by fixed size windows, `window-min-height' or
1575`window-min-width' settings. IGNORE equal `safe' means live
1576windows may get as small as `window-safe-min-height' lines and
1577`window-safe-min-width' columns. IGNORE any window means ignore
1578restrictions for that window only.
1579
1580Optional arguments TRAIL and EDGE, when non-nil, restrict the set
1581of windows that shall be resized. If TRAIL equals `before',
1582resize only windows on the left or above EDGE. If TRAIL equals
1583`after', resize only windows on the right or below EDGE. Also,
1584preferably only resize windows adjacent to EDGE.
1585
1586Return the symbol `normalized' if new normal sizes have been
1587already set by this routine."
1588 (let* ((first (window-child parent))
1589 (sub first)
1590 (parent-total (+ (window-total-size parent horizontal) delta))
1591 best-window best-value)
1592
1593 (if (and edge (memq trail '(before after))
1594 (progn
1595 (setq sub first)
1596 (while (and (window-right sub)
1597 (or (and (eq trail 'before)
1598 (not (resize-subwindows-skip-p
1599 (window-right sub))))
1600 (and (eq trail 'after)
1601 (resize-subwindows-skip-p sub))))
1602 (setq sub (window-right sub)))
1603 sub)
1604 (if horizontal
1605 (if (eq trail 'before)
1606 (= (+ (window-left-column sub)
1607 (window-total-size sub t))
1608 edge)
1609 (= (window-left-column sub) edge))
1610 (if (eq trail 'before)
1611 (= (+ (window-top-line sub)
1612 (window-total-size sub))
1613 edge)
1614 (= (window-top-line sub) edge)))
1615 (window-sizable-p sub delta horizontal ignore))
1616 ;; Resize only windows adjacent to EDGE.
1617 (progn
1618 (resize-this-window sub delta horizontal ignore t trail edge)
1619 (if (and window (eq (window-parent sub) parent))
1620 (progn
1621 ;; Assign new normal sizes.
1622 (set-window-new-normal
1623 sub (/ (float (window-new-total sub)) parent-total))
1624 (set-window-new-normal
1625 window (- (window-normal-size window horizontal)
1626 (- (window-new-normal sub)
1627 (window-normal-size sub horizontal)))))
1628 (resize-subwindows-normal parent horizontal sub 0 trail delta))
1629 ;; Return 'normalized to notify `resize-other-windows' that
1630 ;; normal sizes have been already set.
1631 'normalized)
1632 ;; Resize all windows proportionally.
1633 (setq sub first)
1634 (while sub
1635 (cond
1636 ((or (resize-subwindows-skip-p sub)
1637 ;; Ignore windows to skip and fixed-size subwindows - in
1638 ;; the latter case make it a window to skip.
1639 (and (not ignore)
1640 (window-size-fixed-p sub horizontal)
1641 (set-window-new-normal sub 'ignore))))
1642 ((< delta 0)
1643 ;; When shrinking store the number of lines/cols we can get
1644 ;; from this window here together with the total/normal size
1645 ;; factor.
1646 (set-window-new-normal
1647 sub
1648 (cons
1649 ;; We used to call this with NODOWN t, "fixed" 2011-05-11.
1650 (window-min-delta sub horizontal ignore trail t) ; t)
1651 (- (/ (float (window-total-size sub horizontal))
1652 parent-total)
1653 (window-normal-size sub horizontal)))))
1654 ((> delta 0)
1655 ;; When enlarging store the total/normal size factor only
1656 (set-window-new-normal
1657 sub
1658 (- (/ (float (window-total-size sub horizontal))
1659 parent-total)
1660 (window-normal-size sub horizontal)))))
1661
1662 (setq sub (window-right sub)))
1663
1664 (cond
1665 ((< delta 0)
1666 ;; Shrink windows by delta.
1667 (setq best-window t)
1668 (while (and best-window (not (zerop delta)))
1669 (setq sub first)
1670 (setq best-window nil)
1671 (setq best-value most-negative-fixnum)
1672 (while sub
1673 (when (and (consp (window-new-normal sub))
1674 (not (zerop (car (window-new-normal sub))))
1675 (> (cdr (window-new-normal sub)) best-value))
1676 (setq best-window sub)
1677 (setq best-value (cdr (window-new-normal sub))))
1678
1679 (setq sub (window-right sub)))
1680
1681 (when best-window
1682 (setq delta (1+ delta)))
1683 (set-window-new-total best-window -1 t)
1684 (set-window-new-normal
1685 best-window
1686 (if (= (car (window-new-normal best-window)) 1)
1687 'skip ; We can't shrink best-window any further.
1688 (cons (1- (car (window-new-normal best-window)))
1689 (- (/ (float (window-new-total best-window))
1690 parent-total)
1691 (window-normal-size best-window horizontal)))))))
1692 ((> delta 0)
1693 ;; Enlarge windows by delta.
1694 (setq best-window t)
1695 (while (and best-window (not (zerop delta)))
1696 (setq sub first)
1697 (setq best-window nil)
1698 (setq best-value most-positive-fixnum)
1699 (while sub
1700 (when (and (numberp (window-new-normal sub))
1701 (< (window-new-normal sub) best-value))
1702 (setq best-window sub)
1703 (setq best-value (window-new-normal sub)))
1704
1705 (setq sub (window-right sub)))
1706
1707 (when best-window
1708 (setq delta (1- delta)))
1709 (set-window-new-total best-window 1 t)
1710 (set-window-new-normal
1711 best-window
1712 (- (/ (float (window-new-total best-window))
1713 parent-total)
1714 (window-normal-size best-window horizontal))))))
1715
1716 (when best-window
1717 (setq sub first)
1718 (while sub
1719 (when (or (consp (window-new-normal sub))
1720 (numberp (window-new-normal sub)))
1721 ;; Reset new normal size fields so `resize-window-apply'
1722 ;; won't use them to apply new sizes.
1723 (set-window-new-normal sub))
1724
1725 (unless (eq (window-new-normal sub) 'ignore)
1726 ;; Resize this subwindow's subwindows (back-engineering
1727 ;; delta from sub's old and new total sizes).
1728 (let ((delta (- (window-new-total sub)
1729 (window-total-size sub horizontal))))
1730 (unless (and (zerop delta) (not trail))
1731 ;; For the TRAIL non-nil case we have to resize SUB
1732 ;; recursively even if it's size does not change.
1733 (resize-this-window
1734 sub delta horizontal ignore nil trail edge))))
1735 (setq sub (window-right sub)))))))
1736
1737(defun resize-other-windows (window delta &optional horizontal ignore trail edge)
1738 "Resize other windows when WINDOW is resized vertically by DELTA lines.
1739Optional argument HORIZONTAL non-nil means resize other windows
1740when WINDOW is resized horizontally by DELTA columns. WINDOW
1741itself is not resized by this function.
1315 1742
1743Optional argument IGNORE non-nil means ignore any restrictions
1744imposed by fixed size windows, `window-min-height' or
1745`window-min-width' settings. IGNORE equal `safe' means live
1746windows may get as small as `window-safe-min-height' lines and
1747`window-safe-min-width' columns. IGNORE any window means ignore
1748restrictions for that window only.
1749
1750Optional arguments TRAIL and EDGE, when non-nil, refine the set
1751of windows that shall be resized. If TRAIL equals `before',
1752resize only windows on the left or above EDGE. If TRAIL equals
1753`after', resize only windows on the right or below EDGE. Also,
1754preferably only resize windows adjacent to EDGE."
1755 (when (window-parent window)
1756 (let* ((parent (window-parent window))
1757 (sub (window-child parent)))
1758 (if (window-iso-combined-p sub horizontal)
1759 ;; In an iso-combination try to extract DELTA from WINDOW's
1760 ;; siblings.
1761 (let ((first sub)
1762 (skip (eq trail 'after))
1763 this-delta other-delta)
1764 ;; Decide which windows shall be left alone.
1765 (while sub
1766 (cond
1767 ((eq sub window)
1768 ;; Make sure WINDOW is left alone when
1769 ;; resizing its siblings.
1770 (set-window-new-normal sub 'ignore)
1771 (setq skip (eq trail 'before)))
1772 (skip
1773 ;; Make sure this sibling is left alone when
1774 ;; resizing its siblings.
1775 (set-window-new-normal sub 'ignore))
1776 ((or (window-size-ignore sub ignore)
1777 (not (window-size-fixed-p sub horizontal)))
1778 ;; Set this-delta to t to signal that we found a sibling
1779 ;; of WINDOW whose size is not fixed.
1780 (setq this-delta t)))
1781
1782 (setq sub (window-right sub)))
1783
1784 ;; Set this-delta to what we can get from WINDOW's siblings.
1785 (if (= (- delta) (window-total-size window horizontal))
1786 ;; A deletion, presumably. We must handle this case
1787 ;; specially since `window-resizable' can't be used.
1788 (if this-delta
1789 ;; There's at least one resizable sibling we can
1790 ;; give WINDOW's size to.
1791 (setq this-delta delta)
1792 ;; No resizable sibling exists.
1793 (setq this-delta 0))
1794 ;; Any other form of resizing.
1795 (setq this-delta
1796 (window-resizable window delta horizontal ignore trail t)))
1797
1798 ;; Set other-delta to what we still have to get from
1799 ;; ancestor windows of parent.
1800 (setq other-delta (- delta this-delta))
1801 (unless (zerop other-delta)
1802 ;; Unless we got everything from WINDOW's siblings, PARENT
1803 ;; must be resized by other-delta lines or columns.
1804 (set-window-new-total parent other-delta 'add))
1805
1806 (if (zerop this-delta)
1807 ;; We haven't got anything from WINDOW's siblings but we
1808 ;; must update the normal sizes to respect other-delta.
1809 (resize-subwindows-normal
1810 parent horizontal window this-delta trail other-delta)
1811 ;; We did get something from WINDOW's siblings which means
1812 ;; we have to resize their subwindows.
1813 (unless (eq (resize-subwindows parent (- this-delta) horizontal
1814 window ignore trail edge)
1815 ;; `resize-subwindows' returning 'normalized,
1816 ;; means it has set the normal sizes already.
1817 'normalized)
1818 ;; Set the normal sizes.
1819 (resize-subwindows-normal
1820 parent horizontal window this-delta trail other-delta))
1821 ;; Set DELTA to what we still have to get from ancestor
1822 ;; windows.
1823 (setq delta other-delta)))
1824
1825 ;; In an ortho-combination all siblings of WINDOW must be
1826 ;; resized by DELTA.
1827 (set-window-new-total parent delta 'add)
1828 (while sub
1829 (unless (eq sub window)
1830 (resize-this-window sub delta horizontal ignore t))
1831 (setq sub (window-right sub))))
1832
1833 (unless (zerop delta)
1834 ;; "Go up."
1835 (resize-other-windows parent delta horizontal ignore trail edge)))))
1836
1837(defun resize-this-window (window delta &optional horizontal ignore add trail edge)
1838 "Resize WINDOW vertically by DELTA lines.
1839Optional argument HORIZONTAL non-nil means resize WINDOW
1840horizontally by DELTA columns.
1841
1842Optional argument IGNORE non-nil means ignore any restrictions
1843imposed by fixed size windows, `window-min-height' or
1844`window-min-width' settings. IGNORE equal `safe' means live
1845windows may get as small as `window-safe-min-height' lines and
1846`window-safe-min-width' columns. IGNORE any window means ignore
1847restrictions for that window only.
1848
1849Optional argument ADD non-nil means add DELTA to the new total
1850size of WINDOW.
1851
1852Optional arguments TRAIL and EDGE, when non-nil, refine the set
1853of windows that shall be resized. If TRAIL equals `before',
1854resize only windows on the left or above EDGE. If TRAIL equals
1855`after', resize only windows on the right or below EDGE. Also,
1856preferably only resize windows adjacent to EDGE.
1857
1858This function recursively resizes WINDOW's subwindows to fit the
1859new size. Make sure that WINDOW is `window-resizable' before
1860calling this function. Note that this function does not resize
1861siblings of WINDOW or WINDOW's parent window. You have to
1862eventually call `resize-window-apply' in order to make resizing
1863actually take effect."
1864 (when add
1865 ;; Add DELTA to the new total size of WINDOW.
1866 (set-window-new-total window delta t))
1867
1868 (let ((sub (window-child window)))
1869 (cond
1870 ((not sub))
1871 ((window-iso-combined-p sub horizontal)
1872 ;; In an iso-combination resize subwindows according to their
1873 ;; normal sizes.
1874 (resize-subwindows window delta horizontal nil ignore trail edge))
1875 ;; In an ortho-combination resize each subwindow by DELTA.
1876 (t
1877 (while sub
1878 (resize-this-window sub delta horizontal ignore t trail edge)
1879 (setq sub (window-right sub)))))))
1880
1881(defun resize-root-window (window delta horizontal ignore)
1882 "Resize root window WINDOW vertically by DELTA lines.
1883HORIZONTAL non-nil means resize root window WINDOW horizontally
1884by DELTA columns.
1885
1886IGNORE non-nil means ignore any restrictions imposed by fixed
1887size windows, `window-min-height' or `window-min-width' settings.
1888
1889This function is only called by the frame resizing routines. It
1890resizes windows proportionally and never deletes any windows."
1891 (when (and (windowp window) (numberp delta)
1892 (window-sizable-p window delta horizontal ignore))
1893 (resize-window-reset (window-frame window) horizontal)
1894 (resize-this-window window delta horizontal ignore t)))
1895
1896(defun resize-root-window-vertically (window delta)
1897 "Resize root window WINDOW vertically by DELTA lines.
1898If DELTA is less than zero and we can't shrink WINDOW by DELTA
1899lines, shrink it as much as possible. If DELTA is greater than
1900zero, this function can resize fixed-size subwindows in order to
1901recover the necessary lines.
1902
1903Return the number of lines that were recovered.
1904
1905This function is only called by the minibuffer window resizing
1906routines. It resizes windows proportionally and never deletes
1907any windows."
1908 (when (numberp delta)
1909 (let (ignore)
1910 (cond
1911 ((< delta 0)
1912 (setq delta (window-sizable window delta)))
1913 ((> delta 0)
1914 (unless (window-sizable window delta)
1915 (setq ignore t))))
1916
1917 (resize-window-reset (window-frame window))
1918 ;; Ideally, we would resize just the last window in a combination
1919 ;; but that's not feasible for the following reason: If we grow
1920 ;; the minibuffer window and the last window cannot be shrunk any
1921 ;; more, we shrink another window instead. But if we then shrink
1922 ;; the minibuffer window again, the last window might get enlarged
1923 ;; and the state after shrinking is not the state before growing.
1924 ;; So, in practice, we'd need a history variable to record how to
1925 ;; proceed. But I'm not sure how such a variable could work with
1926 ;; repeated minibuffer window growing steps.
1927 (resize-this-window window delta nil ignore t)
1928 delta)))
1929
1930(defun adjust-window-trailing-edge (window delta &optional horizontal)
1931 "Move WINDOW's bottom edge by DELTA lines.
1932Optional argument HORIZONTAL non-nil means move WINDOW's right
1933edge by DELTA columns. WINDOW defaults to the selected window.
1934
1935If DELTA is greater zero, then move the edge downwards or to the
1936right. If DELTA is less than zero, move the edge upwards or to
1937the left. If the edge can't be moved by DELTA lines or columns,
1938move it as far as possible in the desired direction."
1939 (setq window (normalize-any-window window))
1940 (let ((frame (window-frame window))
1941 (right window)
1942 left this-delta min-delta max-delta failed)
1943 ;; Find the edge we want to move.
1944 (while (and (or (not (window-iso-combined-p right horizontal))
1945 (not (window-right right)))
1946 (setq right (window-parent right))))
1947 (cond
1948 ((and (not right) (not horizontal) (not resize-mini-windows)
1949 (eq (window-frame (minibuffer-window frame)) frame))
1950 (resize-mini-window (minibuffer-window frame) (- delta)))
1951 ((or (not (setq left right)) (not (setq right (window-right right))))
1952 (if horizontal
1953 (error "No window on the right of this one")
1954 (error "No window below this one")))
1955 (t
1956 ;; Set LEFT to the first resizable window on the left. This step is
1957 ;; needed to handle fixed-size windows.
1958 (while (and left (window-size-fixed-p left horizontal))
1959 (setq left
1960 (or (window-left left)
1961 (progn
1962 (while (and (setq left (window-parent left))
1963 (not (window-iso-combined-p left horizontal))))
1964 (window-left left)))))
1965 (unless left
1966 (if horizontal
1967 (error "No resizable window on the left of this one")
1968 (error "No resizable window above this one")))
1969
1970 ;; Set RIGHT to the first resizable window on the right. This step
1971 ;; is needed to handle fixed-size windows.
1972 (while (and right (window-size-fixed-p right horizontal))
1973 (setq right
1974 (or (window-right right)
1975 (progn
1976 (while (and (setq right (window-parent right))
1977 (not (window-iso-combined-p right horizontal))))
1978 (window-right right)))))
1979 (unless right
1980 (if horizontal
1981 (error "No resizable window on the right of this one")
1982 (error "No resizable window below this one")))
1983
1984 ;; LEFT and RIGHT (which might be both internal windows) are now the
1985 ;; two windows we want to resize.
1986 (cond
1987 ((> delta 0)
1988 (setq max-delta (window-max-delta-1 left 0 horizontal nil 'after))
1989 (setq min-delta (window-min-delta-1 right (- delta) horizontal nil 'before))
1990 (when (or (< max-delta delta) (> min-delta (- delta)))
1991 ;; We can't get the whole DELTA - move as far as possible.
1992 (setq delta (min max-delta (- min-delta))))
1993 (unless (zerop delta)
1994 ;; Start resizing.
1995 (resize-window-reset frame horizontal)
1996 ;; Try to enlarge LEFT first.
1997 (setq this-delta (window-resizable left delta horizontal))
1998 (unless (zerop this-delta)
1999 (resize-this-window
2000 left this-delta horizontal nil t 'before
2001 (if horizontal
2002 (+ (window-left-column left) (window-total-size left t))
2003 (+ (window-top-line left) (window-total-size left)))))
2004 ;; Shrink windows on right of LEFT.
2005 (resize-other-windows
2006 left delta horizontal nil 'after
2007 (if horizontal
2008 (window-left-column right)
2009 (window-top-line right)))))
2010 ((< delta 0)
2011 (setq max-delta (window-max-delta-1 right 0 horizontal nil 'before))
2012 (setq min-delta (window-min-delta-1 left delta horizontal nil 'after))
2013 (when (or (< max-delta (- delta)) (> min-delta delta))
2014 ;; We can't get the whole DELTA - move as far as possible.
2015 (setq delta (max (- max-delta) min-delta)))
2016 (unless (zerop delta)
2017 ;; Start resizing.
2018 (resize-window-reset frame horizontal)
2019 ;; Try to enlarge RIGHT.
2020 (setq this-delta (window-resizable right (- delta) horizontal))
2021 (unless (zerop this-delta)
2022 (resize-this-window
2023 right this-delta horizontal nil t 'after
2024 (if horizontal
2025 (window-left-column right)
2026 (window-top-line right))))
2027 ;; Shrink windows on left of RIGHT.
2028 (resize-other-windows
2029 right (- delta) horizontal nil 'before
2030 (if horizontal
2031 (+ (window-left-column left) (window-total-size left t))
2032 (+ (window-top-line left) (window-total-size left)))))))
2033 (unless (zerop delta)
2034 ;; Don't report an error in the standard case.
2035 (unless (resize-window-apply frame horizontal)
2036 ;; But do report an error if applying the changes fails.
2037 (error "Failed adjusting window %s" window)))))))
2038
2039(defun enlarge-window (delta &optional horizontal)
2040 "Make selected window DELTA lines taller.
2041Interactively, if no argument is given, make the selected window
2042one line taller. If optional argument HORIZONTAL is non-nil,
2043make selected window wider by DELTA columns. If DELTA is
2044negative, shrink selected window by -DELTA lines or columns.
2045Return nil."
2046 (interactive "p")
2047 (resize-window (selected-window) delta horizontal))
2048
2049(defun shrink-window (delta &optional horizontal)
2050 "Make selected window DELTA lines smaller.
2051Interactively, if no argument is given, make the selected window
2052one line smaller. If optional argument HORIZONTAL is non-nil,
2053make selected window narrower by DELTA columns. If DELTA is
2054negative, enlarge selected window by -DELTA lines or columns.
2055Return nil."
2056 (interactive "p")
2057 (resize-window (selected-window) (- delta) horizontal))
2058
2059(defun maximize-window (&optional window)
2060 "Maximize WINDOW.
2061Make WINDOW as large as possible without deleting any windows.
2062WINDOW can be any window and defaults to the selected window."
2063 (interactive)
2064 (setq window (normalize-any-window window))
2065 (resize-window window (window-max-delta window))
2066 (resize-window window (window-max-delta window t) t))
2067
2068(defun minimize-window (&optional window)
2069 "Minimize WINDOW.
2070Make WINDOW as small as possible without deleting any windows.
2071WINDOW can be any window and defaults to the selected window."
2072 (interactive)
2073 (setq window (normalize-any-window window))
2074 (resize-window window (- (window-min-delta window)))
2075 (resize-window window (- (window-min-delta window t)) t))
2076
2077(defsubst frame-root-window-p (window)
2078 "Return non-nil if WINDOW is the root window of its frame."
2079 (eq window (frame-root-window window)))
2080
1316;; This should probably return non-nil when the selected window is part 2081;; This should probably return non-nil when the selected window is part
1317;; of an atomic window whose root is the frame's root window. 2082;; of an atomic window whose root is the frame's root window.
1318(defun one-window-p (&optional nomini all-frames) 2083(defun one-window-p (&optional nomini all-frames)
@@ -1347,6 +2112,501 @@ and no others."
1347 (eq base-window 2112 (eq base-window
1348 (next-window base-window (if nomini 'arg) all-frames)))) 2113 (next-window base-window (if nomini 'arg) all-frames))))
1349 2114
2115;;; Deleting windows.
2116(defun window-deletable-p (&optional window)
2117 "Return t if WINDOW can be safely deleted from its frame.
2118Return `frame' if deleting WINDOW should delete its frame
2119instead."
2120 (setq window (normalize-any-window window))
2121 (unless ignore-window-parameters
2122 ;; Handle atomicity.
2123 (when (window-parameter window 'window-atom)
2124 (setq window (window-atom-root window))))
2125 (let ((parent (window-parent window))
2126 (frame (window-frame window))
2127 (dedicated (and (window-buffer window) (window-dedicated-p window)))
2128 (quit-restore (window-parameter window 'quit-restore)))
2129 (cond
2130 ((frame-root-window-p window)
2131 (when (and (or dedicated
2132 (and (eq (car-safe quit-restore) 'new-frame)
2133 (eq (nth 1 quit-restore) (window-buffer window))))
2134 (other-visible-frames-p frame))
2135 ;; WINDOW is the root window of its frame. Return `frame' but
2136 ;; only if WINDOW is (1) either dedicated or quit-restore's car
2137 ;; is new-frame and the window still displays the same buffer
2138 ;; and (2) there are other frames left.
2139 'frame))
2140 ((and (not ignore-window-parameters)
2141 (eq (window-parameter window 'window-side) 'none)
2142 (or (not parent)
2143 (not (eq (window-parameter parent 'window-side) 'none))))
2144 ;; Can't delete last main window.
2145 nil)
2146 (t))))
2147
2148(defun window-or-subwindow-p (subwindow window)
2149 "Return t if SUBWINDOW is either WINDOW or a subwindow of WINDOW."
2150 (or (eq subwindow window)
2151 (let ((parent (window-parent subwindow)))
2152 (catch 'done
2153 (while parent
2154 (if (eq parent window)
2155 (throw 'done t)
2156 (setq parent (window-parent parent))))))))
2157
2158(defun delete-window (&optional window)
2159 "Delete WINDOW.
2160WINDOW can be an arbitrary window and defaults to the selected
2161one. Return nil.
2162
2163If the variable `ignore-window-parameters' is non-nil or the
2164`delete-window' parameter of WINDOW equals t, do not process any
2165parameters of WINDOW. Otherwise, if the `delete-window'
2166parameter of WINDOW specifies a function, call that function with
2167WINDOW as its sole argument and return the value returned by that
2168function.
2169
2170Otherwise, if WINDOW is part of an atomic window, call
2171`delete-window' with the root of the atomic window as its
2172argument. If WINDOW is the only window on its frame or the last
2173non-side window, signal an error."
2174 (interactive)
2175 (setq window (normalize-any-window window))
2176 (let* ((frame (window-frame window))
2177 (function (window-parameter window 'delete-window))
2178 (parent (window-parent window))
2179 atom-root)
2180 (window-check frame)
2181 (catch 'done
2182 ;; Handle window parameters.
2183 (cond
2184 ;; Ignore window parameters if `ignore-window-parameters' tells
2185 ;; us so or `delete-window' equals t.
2186 ((or ignore-window-parameters (eq function t)))
2187 ((functionp function)
2188 ;; The `delete-window' parameter specifies the function to call.
2189 ;; If that function is `ignore' nothing is done. It's up to the
2190 ;; function called here to avoid infinite recursion.
2191 (throw 'done (funcall function window)))
2192 ((and (window-parameter window 'window-atom)
2193 (setq atom-root (window-atom-root window))
2194 (not (eq atom-root window)))
2195 (throw 'done (delete-window atom-root)))
2196 ((and (eq (window-parameter window 'window-side) 'none)
2197 (or (not parent)
2198 (not (eq (window-parameter parent 'window-side) 'none))))
2199 (error "Attempt to delete last non-side window"))
2200 ((not parent)
2201 (error "Attempt to delete minibuffer or sole ordinary window")))
2202
2203 (let* ((horizontal (window-hchild parent))
2204 (size (window-total-size window horizontal))
2205 (frame-selected
2206 (window-or-subwindow-p (frame-selected-window frame) window))
2207 ;; Emacs 23 preferably gives WINDOW's space to its left
2208 ;; sibling.
2209 (sibling (or (window-left window) (window-right window))))
2210 (resize-window-reset frame horizontal)
2211 (cond
2212 ((and (not (window-splits window))
2213 sibling (window-sizable-p sibling size))
2214 ;; Resize WINDOW's sibling.
2215 (resize-this-window sibling size horizontal nil t)
2216 (set-window-new-normal
2217 sibling (+ (window-normal-size sibling horizontal)
2218 (window-normal-size window horizontal))))
2219 ((window-resizable-p window (- size) horizontal nil nil nil t)
2220 ;; Can do without resizing fixed-size windows.
2221 (resize-other-windows window (- size) horizontal))
2222 (t
2223 ;; Can't do without resizing fixed-size windows.
2224 (resize-other-windows window (- size) horizontal t)))
2225 ;; Actually delete WINDOW.
2226 (delete-window-internal window)
2227 (when (and frame-selected
2228 (window-parameter
2229 (frame-selected-window frame) 'no-other-window))
2230 ;; `delete-window-internal' has selected a window that should
2231 ;; not be selected, fix this here.
2232 (other-window -1 frame))
2233 (run-window-configuration-change-hook frame)
2234 (window-check frame)
2235 ;; Always return nil.
2236 nil))))
2237
2238(defun delete-other-windows (&optional window)
2239 "Make WINDOW fill its frame.
2240WINDOW may be any window and defaults to the selected one.
2241Return nil.
2242
2243If the variable `ignore-window-parameters' is non-nil or the
2244`delete-other-windows' parameter of WINDOW equals t, do not
2245process any parameters of WINDOW. Otherwise, if the
2246`delete-other-windows' parameter of WINDOW specifies a function,
2247call that function with WINDOW as its sole argument and return
2248the value returned by that function.
2249
2250Otherwise, if WINDOW is part of an atomic window, call this
2251function with the root of the atomic window as its argument. If
2252WINDOW is a non-side window, make WINDOW the only non-side window
2253on the frame. Side windows are not deleted. If WINDOW is a side
2254window signal an error."
2255 (interactive)
2256 (setq window (normalize-any-window window))
2257 (let* ((frame (window-frame window))
2258 (function (window-parameter window 'delete-other-windows))
2259 (window-side (window-parameter window 'window-side))
2260 atom-root side-main)
2261 (window-check frame)
2262 (catch 'done
2263 (cond
2264 ;; Ignore window parameters if `ignore-window-parameters' is t or
2265 ;; `delete-other-windows' is t.
2266 ((or ignore-window-parameters (eq function t)))
2267 ((functionp function)
2268 ;; The `delete-other-windows' parameter specifies the function
2269 ;; to call. If the function is `ignore' no windows are deleted.
2270 ;; It's up to the function called to avoid infinite recursion.
2271 (throw 'done (funcall function window)))
2272 ((and (window-parameter window 'window-atom)
2273 (setq atom-root (window-atom-root window))
2274 (not (eq atom-root window)))
2275 (throw 'done (delete-other-windows atom-root)))
2276 ((eq window-side 'none)
2277 ;; Set side-main to the major non-side window.
2278 (setq side-main (window-with-parameter 'window-side 'none nil t)))
2279 ((memq window-side window-sides)
2280 (error "Cannot make side window the only window")))
2281 ;; If WINDOW is the main non-side window, do nothing.
2282 (unless (eq window side-main)
2283 (delete-other-windows-internal window side-main)
2284 (run-window-configuration-change-hook frame)
2285 (window-check frame))
2286 ;; Always return nil.
2287 nil)))
2288
2289;;; Splitting windows.
2290(defsubst window-split-min-size (&optional horizontal)
2291 "Return minimum height of any window when splitting windows.
2292Optional argument HORIZONTAL non-nil means return minimum width."
2293 (if horizontal
2294 (max window-min-width window-safe-min-width)
2295 (max window-min-height window-safe-min-height)))
2296
2297(defun split-window (&optional window size side)
2298 "Make a new window adjacent to WINDOW.
2299WINDOW can be any window and defaults to the selected one.
2300Return the new window which is always a live window.
2301
2302Optional argument SIZE a positive number means make WINDOW SIZE
2303lines or columns tall. If SIZE is negative, make the new window
2304-SIZE lines or columns tall. If and only if SIZE is non-nil, its
2305absolute value can be less than `window-min-height' or
2306`window-min-width'; so this command can make a new window as
2307small as one line or two columns. SIZE defaults to half of
2308WINDOW's size. Interactively, SIZE is the prefix argument.
2309
2310Optional third argument SIDE nil (or `below') specifies that the
2311new window shall be located below WINDOW. SIDE `above' means the
2312new window shall be located above WINDOW. In both cases SIZE
2313specifies the new number of lines for WINDOW \(or the new window
2314if SIZE is negative) including space reserved for the mode and/or
2315header line.
2316
2317SIDE t (or `right') specifies that the new window shall be
2318located on the right side of WINDOW. SIDE `left' means the new
2319window shall be located on the left of WINDOW. In both cases
2320SIZE specifies the new number of columns for WINDOW \(or the new
2321window provided SIZE is negative) including space reserved for
2322fringes and the scrollbar or a divider column. Any other non-nil
2323value for SIDE is currently handled like t (or `right').
2324
2325If the variable `ignore-window-parameters' is non-nil or the
2326`split-window' parameter of WINDOW equals t, do not process any
2327parameters of WINDOW. Otherwise, if the `split-window' parameter
2328of WINDOW specifies a function, call that function with all three
2329arguments and return the value returned by that function.
2330
2331Otherwise, if WINDOW is part of an atomic window, \"split\" the
2332root of that atomic window. The new window does not become a
2333member of that atomic window.
2334
2335If WINDOW is live, properties of the new window like margins and
2336scrollbars are inherited from WINDOW. If WINDOW is an internal
2337window, these properties as well as the buffer displayed in the
2338new window are inherited from the window selected on WINDOW's
2339frame. The selected window is not changed by this function."
2340 (interactive "i")
2341 (setq window (normalize-any-window window))
2342 (let* ((horizontal (not (memq side '(nil below above))))
2343 (frame (window-frame window))
2344 (parent (window-parent window))
2345 (function (window-parameter window 'split-window))
2346 (window-side (window-parameter window 'window-side))
2347 ;; Rebind `window-nest' since in some cases we may have to
2348 ;; override its value.
2349 (window-nest window-nest)
2350 atom-root)
2351
2352 (window-check frame)
2353 (catch 'done
2354 (cond
2355 ;; Ignore window parameters if either `ignore-window-parameters'
2356 ;; is t or the `split-window' parameter equals t.
2357 ((or ignore-window-parameters (eq function t)))
2358 ((functionp function)
2359 ;; The `split-window' parameter specifies the function to call.
2360 ;; If that function is `ignore', do nothing.
2361 (throw 'done (funcall function window size side)))
2362 ;; If WINDOW is a subwindow of an atomic window, split the root
2363 ;; window of that atomic window instead.
2364 ((and (window-parameter window 'window-atom)
2365 (setq atom-root (window-atom-root window))
2366 (not (eq atom-root window)))
2367 (throw 'done (split-window atom-root size side))))
2368
2369 (when (and window-side
2370 (or (not parent)
2371 (not (window-parameter parent 'window-side))))
2372 ;; WINDOW is a side root window. To make sure that a new parent
2373 ;; window gets created set `window-nest' to t.
2374 (setq window-nest t))
2375
2376 (when (and window-splits size (> size 0))
2377 ;; If `window-splits' is non-nil and SIZE is a non-negative
2378 ;; integer, we cannot reasonably resize other windows. Rather
2379 ;; bind `window-nest' to t to make sure that subsequent window
2380 ;; deletions are handled correctly.
2381 (setq window-nest t))
2382
2383 (let* ((parent-size
2384 ;; `parent-size' is the size of WINDOW's parent, provided
2385 ;; it has one.
2386 (when parent (window-total-size parent horizontal)))
2387 ;; `resize' non-nil means we are supposed to resize other
2388 ;; windows in WINDOW's combination.
2389 (resize
2390 (and window-splits (not window-nest)
2391 ;; Resize makes sense in iso-combinations only.
2392 (window-iso-combined-p window horizontal)))
2393 ;; `old-size' is the current size of WINDOW.
2394 (old-size (window-total-size window horizontal))
2395 ;; `new-size' is the specified or calculated size of the
2396 ;; new window.
2397 (new-size
2398 (cond
2399 ((not size)
2400 (max (window-split-min-size horizontal)
2401 (if resize
2402 ;; When resizing try to give the new window the
2403 ;; average size of a window in its combination.
2404 (min (- parent-size
2405 (window-min-size parent horizontal))
2406 (/ parent-size
2407 (1+ (window-iso-combinations
2408 parent horizontal))))
2409 ;; Else try to give the new window half the size
2410 ;; of WINDOW (plus an eventual odd line).
2411 (+ (/ old-size 2) (% old-size 2)))))
2412 ((>= size 0)
2413 ;; SIZE non-negative specifies the new size of WINDOW.
2414
2415 ;; Note: Specifying a non-negative SIZE is practically
2416 ;; always done as workaround for making the new window
2417 ;; appear above or on the left of the new window (the
2418 ;; ispell window is a typical example of that). In all
2419 ;; these cases the SIDE argument should be set to 'above
2420 ;; or 'left in order to support the 'resize option.
2421 ;; Here we have to nest the windows instead, see above.
2422 (- old-size size))
2423 (t
2424 ;; SIZE negative specifies the size of the new window.
2425 (- size))))
2426 new-parent new-normal)
2427
2428 ;; Check SIZE.
2429 (cond
2430 ((not size)
2431 (cond
2432 (resize
2433 ;; SIZE unspecified, resizing.
2434 (when (and (not (window-sizable-p parent (- new-size) horizontal))
2435 ;; Try again with minimum split size.
2436 (setq new-size
2437 (max new-size (window-split-min-size horizontal)))
2438 (not (window-sizable-p parent (- new-size) horizontal)))
2439 (error "Window %s too small for splitting" parent)))
2440 ((> (+ new-size (window-min-size window horizontal)) old-size)
2441 ;; SIZE unspecified, no resizing.
2442 (error "Window %s too small for splitting" window))))
2443 ((and (>= size 0)
2444 (or (>= size old-size)
2445 (< new-size (if horizontal
2446 window-safe-min-width
2447 window-safe-min-width))))
2448 ;; SIZE specified as new size of old window. If the new size
2449 ;; is larger than the old size or the size of the new window
2450 ;; would be less than the safe minimum, signal an error.
2451 (error "Window %s too small for splitting" window))
2452 (resize
2453 ;; SIZE specified, resizing.
2454 (unless (window-sizable-p parent (- new-size) horizontal)
2455 ;; If we cannot resize the parent give up.
2456 (error "Window %s too small for splitting" parent)))
2457 ((or (< new-size
2458 (if horizontal window-safe-min-width window-safe-min-height))
2459 (< (- old-size new-size)
2460 (if horizontal window-safe-min-width window-safe-min-height)))
2461 ;; SIZE specification violates minimum size restrictions.
2462 (error "Window %s too small for splitting" window)))
2463
2464 (resize-window-reset frame horizontal)
2465
2466 (setq new-parent
2467 ;; Make new-parent non-nil if we need a new parent window;
2468 ;; either because we want to nest or because WINDOW is not
2469 ;; iso-combined.
2470 (or window-nest (not (window-iso-combined-p window horizontal))))
2471 (setq new-normal
2472 ;; Make new-normal the normal size of the new window.
2473 (cond
2474 (size (/ (float new-size) (if new-parent old-size parent-size)))
2475 (new-parent 0.5)
2476 (resize (/ 1.0 (1+ (window-iso-combinations parent horizontal))))
2477 (t (/ (window-normal-size window horizontal) 2.0))))
2478
2479 (if resize
2480 ;; Try to get space from OLD's siblings. We could go "up" and
2481 ;; try getting additional space from surrounding windows but
2482 ;; we won't be able to return space to those windows when we
2483 ;; delete the one we create here. Hence we do not go up.
2484 (progn
2485 (resize-subwindows parent (- new-size) horizontal)
2486 (let* ((normal (- 1.0 new-normal))
2487 (sub (window-child parent)))
2488 (while sub
2489 (set-window-new-normal
2490 sub (* (window-normal-size sub horizontal) normal))
2491 (setq sub (window-right sub)))))
2492 ;; Get entire space from WINDOW.
2493 (set-window-new-total window (- old-size new-size))
2494 (resize-this-window window (- new-size) horizontal)
2495 (set-window-new-normal
2496 window (- (if new-parent 1.0 (window-normal-size window horizontal))
2497 new-normal)))
2498
2499 (let* ((new (split-window-internal window new-size side new-normal)))
2500 ;; Inherit window-side parameters, if any.
2501 (when (and window-side new-parent)
2502 (set-window-parameter (window-parent new) 'window-side window-side)
2503 (set-window-parameter new 'window-side window-side))
2504
2505 (run-window-configuration-change-hook frame)
2506 (window-check frame)
2507 ;; Always return the new window.
2508 new)))))
2509
2510;; I think this should be the default; I think people will prefer it--rms.
2511(defcustom split-window-keep-point t
2512 "If non-nil, \\[split-window-above-each-other] keeps the original point \
2513in both children.
2514This is often more convenient for editing.
2515If nil, adjust point in each of the two windows to minimize redisplay.
2516This is convenient on slow terminals, but point can move strangely.
2517
2518This option applies only to `split-window-above-each-other' and
2519functions that call it. `split-window' always keeps the original
2520point in both children."
2521 :type 'boolean
2522 :group 'windows)
2523
2524(defun split-window-above-each-other (&optional size)
2525 "Split selected window into two windows, one above the other.
2526The upper window gets SIZE lines and the lower one gets the rest.
2527SIZE negative means the lower window gets -SIZE lines and the
2528upper one the rest. With no argument, split windows equally or
2529close to it. Both windows display the same buffer, now current.
2530
2531If the variable `split-window-keep-point' is non-nil, both new
2532windows will get the same value of point as the selected window.
2533This is often more convenient for editing. The upper window is
2534the selected window.
2535
2536Otherwise, we choose window starts so as to minimize the amount of
2537redisplay; this is convenient on slow terminals. The new selected
2538window is the one that the current value of point appears in. The
2539value of point can change if the text around point is hidden by the
2540new mode line.
2541
2542Regardless of the value of `split-window-keep-point', the upper
2543window is the original one and the return value is the new, lower
2544window."
2545 (interactive "P")
2546 (let ((old-window (selected-window))
2547 (old-point (point))
2548 (size (and size (prefix-numeric-value size)))
2549 moved-by-window-height moved new-window bottom)
2550 (when (and size (< size 0) (< (- size) window-min-height))
2551 ;; `split-window' would not signal an error here.
2552 (error "Size of new window too small"))
2553 (setq new-window (split-window nil size))
2554 (unless split-window-keep-point
2555 (with-current-buffer (window-buffer)
2556 (goto-char (window-start))
2557 (setq moved (vertical-motion (window-height)))
2558 (set-window-start new-window (point))
2559 (when (> (point) (window-point new-window))
2560 (set-window-point new-window (point)))
2561 (when (= moved (window-height))
2562 (setq moved-by-window-height t)
2563 (vertical-motion -1))
2564 (setq bottom (point)))
2565 (and moved-by-window-height
2566 (<= bottom (point))
2567 (set-window-point old-window (1- bottom)))
2568 (and moved-by-window-height
2569 (<= (window-start new-window) old-point)
2570 (set-window-point new-window old-point)
2571 (select-window new-window)))
2572 (split-window-save-restore-data new-window old-window)))
2573
2574(defalias 'split-window-vertically 'split-window-above-each-other)
2575
2576;; This is to avoid compiler warnings.
2577(defvar view-return-to-alist)
2578
2579(defun split-window-save-restore-data (new-window old-window)
2580 (with-current-buffer (window-buffer)
2581 (when view-mode
2582 (let ((old-info (assq old-window view-return-to-alist)))
2583 (when old-info
2584 (push (cons new-window (cons (car (cdr old-info)) t))
2585 view-return-to-alist))))
2586 new-window))
2587
2588(defun split-window-side-by-side (&optional size)
2589 "Split selected window into two windows side by side.
2590The selected window becomes the left one and gets SIZE columns.
2591SIZE negative means the right window gets -SIZE lines.
2592
2593SIZE includes the width of the window's scroll bar; if there are
2594no scroll bars, it includes the width of the divider column to
2595the window's right, if any. SIZE omitted or nil means split
2596window equally.
2597
2598The selected window remains selected. Return the new window."
2599 (interactive "P")
2600 (let ((old-window (selected-window))
2601 (size (and size (prefix-numeric-value size)))
2602 new-window)
2603 (when (and size (< size 0) (< (- size) window-min-width))
2604 ;; `split-window' would not signal an error here.
2605 (error "Size of new window too small"))
2606 (split-window-save-restore-data (split-window nil size t) old-window)))
2607
2608(defalias 'split-window-horizontally 'split-window-side-by-side)
2609
1350;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2610;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1351;;; `balance-windows' subroutines using `window-tree' 2611;;; `balance-windows' subroutines using `window-tree'
1352 2612
@@ -2327,102 +3587,6 @@ at the front of the list of recently selected ones."
2327 ;; input focus and is risen. 3587 ;; input focus and is risen.
2328 (select-frame-set-input-focus new-frame)) 3588 (select-frame-set-input-focus new-frame))
2329 buffer)) 3589 buffer))
2330
2331;; I think this should be the default; I think people will prefer it--rms.
2332(defcustom split-window-keep-point t
2333 "If non-nil, \\[split-window-vertically] keeps the original point \
2334in both children.
2335This is often more convenient for editing.
2336If nil, adjust point in each of the two windows to minimize redisplay.
2337This is convenient on slow terminals, but point can move strangely.
2338
2339This option applies only to `split-window-vertically' and
2340functions that call it. `split-window' always keeps the original
2341point in both children."
2342 :type 'boolean
2343 :group 'windows)
2344
2345(defun split-window-vertically (&optional size)
2346 "Split selected window into two windows, one above the other.
2347The upper window gets SIZE lines and the lower one gets the rest.
2348SIZE negative means the lower window gets -SIZE lines and the
2349upper one the rest. With no argument, split windows equally or
2350close to it. Both windows display the same buffer, now current.
2351
2352If the variable `split-window-keep-point' is non-nil, both new
2353windows will get the same value of point as the selected window.
2354This is often more convenient for editing. The upper window is
2355the selected window.
2356
2357Otherwise, we choose window starts so as to minimize the amount of
2358redisplay; this is convenient on slow terminals. The new selected
2359window is the one that the current value of point appears in. The
2360value of point can change if the text around point is hidden by the
2361new mode line.
2362
2363Regardless of the value of `split-window-keep-point', the upper
2364window is the original one and the return value is the new, lower
2365window."
2366 (interactive "P")
2367 (let ((old-window (selected-window))
2368 (old-point (point))
2369 (size (and size (prefix-numeric-value size)))
2370 moved-by-window-height moved new-window bottom)
2371 (and size (< size 0)
2372 ;; Handle negative SIZE value.
2373 (setq size (+ (window-height) size)))
2374 (setq new-window (split-window nil size))
2375 (unless split-window-keep-point
2376 (with-current-buffer (window-buffer)
2377 (goto-char (window-start))
2378 (setq moved (vertical-motion (window-height)))
2379 (set-window-start new-window (point))
2380 (when (> (point) (window-point new-window))
2381 (set-window-point new-window (point)))
2382 (when (= moved (window-height))
2383 (setq moved-by-window-height t)
2384 (vertical-motion -1))
2385 (setq bottom (point)))
2386 (and moved-by-window-height
2387 (<= bottom (point))
2388 (set-window-point old-window (1- bottom)))
2389 (and moved-by-window-height
2390 (<= (window-start new-window) old-point)
2391 (set-window-point new-window old-point)
2392 (select-window new-window)))
2393 (split-window-save-restore-data new-window old-window)))
2394
2395;; This is to avoid compiler warnings.
2396(defvar view-return-to-alist)
2397
2398(defun split-window-save-restore-data (new-window old-window)
2399 (with-current-buffer (window-buffer)
2400 (when view-mode
2401 (let ((old-info (assq old-window view-return-to-alist)))
2402 (when old-info
2403 (push (cons new-window (cons (car (cdr old-info)) t))
2404 view-return-to-alist))))
2405 new-window))
2406
2407(defun split-window-horizontally (&optional size)
2408 "Split selected window into two windows side by side.
2409The selected window becomes the left one and gets SIZE columns.
2410SIZE negative means the right window gets -SIZE lines.
2411
2412SIZE includes the width of the window's scroll bar; if there are
2413no scroll bars, it includes the width of the divider column to
2414the window's right, if any. SIZE omitted or nil means split
2415window equally.
2416
2417The selected window remains selected. Return the new window."
2418 (interactive "P")
2419 (let ((old-window (selected-window))
2420 (size (and size (prefix-numeric-value size))))
2421 (and size (< size 0)
2422 ;; Handle negative SIZE value.
2423 (setq size (+ (window-width) size)))
2424 (split-window-save-restore-data (split-window nil size t) old-window)))
2425
2426 3590
2427(defun set-window-text-height (window height) 3591(defun set-window-text-height (window height)
2428 "Set the height in lines of the text display area of WINDOW to HEIGHT. 3592 "Set the height in lines of the text display area of WINDOW to HEIGHT.
@@ -3124,9 +4288,12 @@ Otherwise, consult the value of `truncate-partial-width-windows'
3124 (if (integerp t-p-w-w) 4288 (if (integerp t-p-w-w)
3125 (< (window-width window) t-p-w-w) 4289 (< (window-width window) t-p-w-w)
3126 t-p-w-w)))) 4290 t-p-w-w))))
3127 4291
3128(define-key ctl-x-map "2" 'split-window-vertically) 4292(define-key ctl-x-map "0" 'delete-window)
3129(define-key ctl-x-map "3" 'split-window-horizontally) 4293(define-key ctl-x-map "1" 'delete-other-windows)
4294(define-key ctl-x-map "2" 'split-window-above-each-other)
4295(define-key ctl-x-map "3" 'split-window-side-by-side)
4296(define-key ctl-x-map "^" 'enlarge-window)
3130(define-key ctl-x-map "}" 'enlarge-window-horizontally) 4297(define-key ctl-x-map "}" 'enlarge-window-horizontally)
3131(define-key ctl-x-map "{" 'shrink-window-horizontally) 4298(define-key ctl-x-map "{" 'shrink-window-horizontally)
3132(define-key ctl-x-map "-" 'shrink-window-if-larger-than-buffer) 4299(define-key ctl-x-map "-" 'shrink-window-if-larger-than-buffer)