1 /* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay.
3 Copyright (C) 1985, 1986, 1987, 1993, 1994 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
32 Lisp_Object Qwindowp
, Qwindow_live_p
;
34 Lisp_Object
Fnext_window (), Fdelete_window (), Fselect_window ();
35 Lisp_Object
Fset_window_buffer (), Fsplit_window (), Frecenter ();
37 void delete_all_subwindows ();
38 static struct window
*decode_window();
40 /* This is the window in which the terminal's cursor should
41 be left when nothing is being done with it. This must
42 always be a leaf window, and its buffer is selected by
43 the top level editing loop at the end of each command.
45 This value is always the same as
46 FRAME_SELECTED_WINDOW (selected_frame). */
48 Lisp_Object selected_window
;
50 /* The minibuffer window of the selected frame.
51 Note that you cannot test for minibufferness of an arbitrary window
52 by comparing against this; but you can test for minibufferness of
53 the selected window. */
54 Lisp_Object minibuf_window
;
56 /* Non-nil means it is the window for C-M-v to scroll
57 when the minibuffer is selected. */
58 Lisp_Object Vminibuf_scroll_window
;
60 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
61 Lisp_Object Vother_window_scroll_buffer
;
63 /* Non-nil means it's function to call to display temp buffers. */
64 Lisp_Object Vtemp_buffer_show_function
;
66 /* If a window gets smaller than either of these, it is removed. */
67 int window_min_height
;
70 /* Nonzero implies Fdisplay_buffer should create windows. */
73 /* Nonzero implies make new frames for Fdisplay_buffer. */
76 /* Non-nil means use this function instead of default */
77 Lisp_Object Vpop_up_frame_function
;
79 /* Function to call to handle Fdisplay_buffer. */
80 Lisp_Object Vdisplay_buffer_function
;
82 /* Fdisplay_buffer always splits the largest window
83 if that window is more than this high. */
84 int split_height_threshold
;
86 /* Number of lines of continuity in scrolling by screenfuls. */
87 int next_screen_context_lines
;
89 /* Incremented for each window created. */
90 static int sequence_number
;
92 #define min(a, b) ((a) < (b) ? (a) : (b))
94 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
95 "Returns t if OBJ is a window.")
99 return XTYPE (obj
) == Lisp_Window
? Qt
: Qnil
;
102 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
103 "Returns t if OBJ is a window which is currently visible.")
107 return ((XTYPE (obj
) == Lisp_Window
108 && ! NILP (XWINDOW (obj
)->buffer
))
115 register Lisp_Object val
;
116 register struct window
*p
;
118 /* Add sizeof (Lisp_Object) here because sizeof (struct Lisp_Vector)
119 includes the first element. */
121 make_number ((sizeof (struct window
) - sizeof (struct Lisp_Vector
)
122 + sizeof (Lisp_Object
))
123 / sizeof (Lisp_Object
)),
125 XSETTYPE (val
, Lisp_Window
);
127 XFASTINT (p
->sequence_number
) = ++sequence_number
;
128 XFASTINT (p
->left
) = XFASTINT (p
->top
)
129 = XFASTINT (p
->height
) = XFASTINT (p
->width
)
130 = XFASTINT (p
->hscroll
) = 0;
131 XFASTINT (p
->last_point_x
) = XFASTINT (p
->last_point_y
) = 0;
132 p
->start
= Fmake_marker ();
133 p
->pointm
= Fmake_marker ();
134 XFASTINT (p
->use_time
) = 0;
136 p
->display_table
= Qnil
;
141 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
142 "Return the window that the cursor now appears in and commands apply to.")
145 return selected_window
;
148 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
149 "Return the window used now for minibuffers.\n\
150 If the optional argument FRAME is specified, return the minibuffer window\n\
151 used by that frame.")
157 XSET (frame
, Lisp_Frame
, selected_frame
);
159 CHECK_LIVE_FRAME (frame
, 0);
162 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
165 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
166 "Returns non-nil if WINDOW is a minibuffer window.")
170 struct window
*w
= decode_window (window
);
171 return (MINI_WINDOW_P (w
) ? Qt
: Qnil
);
174 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
175 Spos_visible_in_window_p
, 0, 2, 0,
176 "Return t if position POS is currently on the frame in WINDOW.\n\
177 Returns nil if that position is scrolled vertically out of view.\n\
178 POS defaults to point; WINDOW, to the selected window.")
180 Lisp_Object pos
, window
;
182 register struct window
*w
;
186 register struct buffer
*buf
;
187 struct position posval
;
194 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
198 w
= decode_window (window
);
199 top
= marker_position (w
->start
);
200 hscroll
= XINT (w
->hscroll
);
205 height
= XFASTINT (w
->height
) - ! MINI_WINDOW_P (w
);
207 buf
= XBUFFER (w
->buffer
);
208 if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
))
210 /* If frame is up to date,
211 use the info recorded about how much text fit on it. */
212 if (posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
)
213 || (XFASTINT (w
->window_end_vpos
) < height
))
219 if (posint
> BUF_ZV (buf
))
222 /* If that info is not correct, calculate afresh */
223 posval
= *compute_motion (top
, 0, (hscroll
? 1 - hscroll
: 0),
225 window_internal_width (w
) - 1,
228 return posval
.vpos
< height
? Qt
: Qnil
;
232 static struct window
*
233 decode_window (window
)
234 register Lisp_Object window
;
237 return XWINDOW (selected_window
);
239 CHECK_LIVE_WINDOW (window
, 0);
240 return XWINDOW (window
);
243 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
244 "Return the buffer that WINDOW is displaying.")
248 return decode_window (window
)->buffer
;
251 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
252 "Return the number of lines in WINDOW (including its mode line).")
256 return decode_window (window
)->height
;
259 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
260 "Return the number of display columns in WINDOW.\n\
261 This is the width that is usable columns available for text in WINDOW.\n\
262 If you want to find out how many columns WINDOW takes up,\n\
263 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).")
267 return make_number (window_internal_width (decode_window (window
)));
270 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
271 "Return the number of columns by which WINDOW is scrolled from left margin.")
275 return decode_window (window
)->hscroll
;
278 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
279 "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\
280 NCOL should be zero or positive.")
282 register Lisp_Object window
, ncol
;
284 register struct window
*w
;
286 CHECK_NUMBER (ncol
, 1);
287 if (XINT (ncol
) < 0) XFASTINT (ncol
) = 0;
288 if (XFASTINT (ncol
) >= (1 << (SHORTBITS
- 1)))
289 args_out_of_range (ncol
, Qnil
);
290 w
= decode_window (window
);
291 if (XINT (w
->hscroll
) != XINT (ncol
))
292 clip_changed
= 1; /* Prevent redisplay shortcuts */
297 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
298 "Return a list of the edge coordinates of WINDOW.\n\
299 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.\n\
300 RIGHT is one more than the rightmost column used by WINDOW,\n\
301 and BOTTOM is one more than the bottommost row used by WINDOW\n\
306 register struct window
*w
= decode_window (window
);
308 return Fcons (w
->left
, Fcons (w
->top
,
309 Fcons (make_number (XFASTINT (w
->left
) + XFASTINT (w
->width
)),
310 Fcons (make_number (XFASTINT (w
->top
)
311 + XFASTINT (w
->height
)),
315 /* Test if the character at column *x, row *y is within window *w.
316 If it is not, return 0;
317 if it is in the window's text area,
318 set *x and *y to its location relative to the upper left corner
321 if it is on the window's modeline, return 2;
322 if it is on the border between the window and its right sibling,
325 coordinates_in_window (w
, x
, y
)
326 register struct window
*w
;
329 register int left
= XINT (w
->left
);
330 register int width
= XINT (w
->width
);
331 register int window_height
= XINT (w
->height
);
332 register int top
= XFASTINT (w
->top
);
334 if ( *x
< left
|| *x
>= left
+ width
335 || *y
< top
|| *y
>= top
+ window_height
)
338 /* Is the character is the mode line? */
339 if (*y
== top
+ window_height
- 1
340 && ! MINI_WINDOW_P (w
))
343 /* Is the character in the right border? */
344 if (*x
== left
+ width
- 1
345 && left
+ width
!= FRAME_WIDTH (XFRAME (w
->frame
)))
353 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
354 Scoordinates_in_window_p
, 2, 2, 0,
355 "Return non-nil if COORDINATES are in WINDOW.\n\
356 COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
357 measured in characters from the upper-left corner of the frame.\n\
358 (0 . 0) denotes the character in the upper left corner of the\n\
360 If COORDINATES are in the text portion of WINDOW,\n\
361 the coordinates relative to the window are returned.\n\
362 If they are in the mode line of WINDOW, `mode-line' is returned.\n\
363 If they are on the border between WINDOW and its right sibling,\n\
364 `vertical-line' is returned.")
365 (coordinates
, window
)
366 register Lisp_Object coordinates
, window
;
370 CHECK_LIVE_WINDOW (window
, 0);
371 CHECK_CONS (coordinates
, 1);
372 x
= XINT (Fcar (coordinates
));
373 y
= XINT (Fcdr (coordinates
));
375 switch (coordinates_in_window (XWINDOW (window
), &x
, &y
))
377 case 0: /* NOT in window at all. */
380 case 1: /* In text part of window. */
383 case 2: /* In mode line of window. */
386 case 3: /* On right border of window. */
387 return Qvertical_line
;
394 /* Find the window containing column x, row y, and return it as a
395 Lisp_Object. If x, y is on the window's modeline, set *part
396 to 1; if it is on the separating line between the window and its
397 right sibling, set it to 2; otherwise set it to 0. If there is no
398 window under x, y return nil and leave *part unmodified. */
400 window_from_coordinates (frame
, x
, y
, part
)
405 register Lisp_Object tem
, first
;
407 tem
= first
= FRAME_SELECTED_WINDOW (frame
);
411 int found
= coordinates_in_window (XWINDOW (tem
), &x
, &y
);
419 tem
= Fnext_window (tem
, Qt
, Qlambda
);
421 while (! EQ (tem
, first
));
426 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
427 "Return window containing coordinates X and Y on FRAME.\n\
428 If omitted, FRAME defaults to the currently selected frame.\n\
429 The top left corner of the frame is considered to be row 0,\n\
432 Lisp_Object x
, y
, frame
;
438 XSET (frame
, Lisp_Frame
, selected_frame
);
440 CHECK_LIVE_FRAME (frame
, 2);
445 return window_from_coordinates (XFRAME (frame
),
450 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
451 "Return current value of point in WINDOW.\n\
452 For a nonselected window, this is the value point would have\n\
453 if that window were selected.\n\
455 Note that, when WINDOW is the selected window and its buffer\n\
456 is also currently selected, the value returned is the same as (point).\n\
457 It would be more strictly correct to return the `top-level' value\n\
458 of point, outside of any save-excursion forms.\n\
459 But that is hard to define.")
463 register struct window
*w
= decode_window (window
);
465 if (w
== XWINDOW (selected_window
)
466 && current_buffer
== XBUFFER (w
->buffer
))
468 return Fmarker_position (w
->pointm
);
471 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
472 "Return position at which display currently starts in WINDOW.")
476 return Fmarker_position (decode_window (window
)->start
);
479 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 1, 0,
480 "Return position at which display currently ends in WINDOW.")
485 struct window
*w
= decode_window (window
);
489 CHECK_BUFFER (buf
, 0);
491 XSET (value
, Lisp_Int
,
492 BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
497 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
498 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
500 Lisp_Object window
, pos
;
502 register struct window
*w
= decode_window (window
);
504 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
505 if (w
== XWINDOW (selected_window
))
508 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
513 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
514 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
515 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
516 from overriding motion of point in order to display at this exact start.")
517 (window
, pos
, noforce
)
518 Lisp_Object window
, pos
, noforce
;
520 register struct window
*w
= decode_window (window
);
522 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
523 set_marker_restricted (w
->start
, pos
, w
->buffer
);
524 /* this is not right, but much easier than doing what is right. */
525 w
->start_at_line_beg
= Qnil
;
528 w
->update_mode_line
= Qt
;
529 XFASTINT (w
->last_modified
) = 0;
530 if (!EQ (window
, selected_window
))
531 windows_or_buffers_changed
++;
535 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
537 "Return WINDOW's dedicated object, usually t or nil.\n\
538 See also `set-window-dedicated-p'.")
542 return decode_window (window
)->dedicated
;
545 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
546 Sset_window_dedicated_p
, 2, 2, 0,
547 "Control whether WINDOW is dedicated to the buffer it displays.\n\
548 If it is dedicated, Emacs will not automatically change\n\
549 which buffer appears in it.\n\
550 The second argument is the new value for the dedication flag;\n\
553 Lisp_Object window
, arg
;
555 register struct window
*w
= decode_window (window
);
565 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
567 "Return the display-table that WINDOW is using.")
571 return decode_window (window
)->display_table
;
574 /* Get the display table for use currently on window W.
575 This is either W's display table or W's buffer's display table.
576 Ignore the specified tables if they are not valid;
577 if no valid table is specified, return 0. */
580 window_display_table (w
)
584 tem
= w
->display_table
;
585 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
586 return XVECTOR (tem
);
587 tem
= XBUFFER (w
->buffer
)->display_table
;
588 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
589 return XVECTOR (tem
);
590 tem
= Vstandard_display_table
;
591 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
592 return XVECTOR (tem
);
596 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
597 "Set WINDOW's display-table to TABLE.")
599 register Lisp_Object window
, table
;
601 register struct window
*w
;
602 register Lisp_Object z
; /* Return value. */
604 w
= decode_window (window
);
605 w
->display_table
= table
;
609 /* Record info on buffer window w is displaying
610 when it is about to cease to display that buffer. */
613 register struct window
*w
;
618 if (XBUFFER (buf
) != XMARKER (w
->pointm
)->buffer
)
622 if (w
== XWINDOW (selected_window
)
623 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
624 /* Do this except when the selected window's buffer
625 is being removed from some other window. */
627 /* last_window_start records the start position that this buffer
628 had in the last window to be disconnected from it.
629 Now that this statement is unconditional,
630 it is possible for the buffer to be displayed in the
631 selected window, while last_window_start reflects another
632 window which was recently showing the same buffer.
633 Some people might say that might be a good thing. Let's see. */
634 XBUFFER (buf
)->last_window_start
= marker_position (w
->start
);
636 /* Point in the selected window's buffer
637 is actually stored in that buffer, and the window's pointm isn't used.
638 So don't clobber point in that buffer. */
639 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
))
640 BUF_PT (XBUFFER (buf
))
641 = clip_to_bounds (BUF_BEGV (XBUFFER (buf
)),
642 marker_position (w
->pointm
),
643 BUF_ZV (XBUFFER (buf
)));
646 /* Put replacement into the window structure in place of old. */
648 replace_window (old
, replacement
)
649 Lisp_Object old
, replacement
;
651 register Lisp_Object tem
;
652 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
654 /* If OLD is its frame's root_window, then replacement is the new
655 root_window for that frame. */
657 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
658 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
663 p
->height
= o
->height
;
665 p
->next
= tem
= o
->next
;
667 XWINDOW (tem
)->prev
= replacement
;
669 p
->prev
= tem
= o
->prev
;
671 XWINDOW (tem
)->next
= replacement
;
673 p
->parent
= tem
= o
->parent
;
676 if (EQ (XWINDOW (tem
)->vchild
, old
))
677 XWINDOW (tem
)->vchild
= replacement
;
678 if (EQ (XWINDOW (tem
)->hchild
, old
))
679 XWINDOW (tem
)->hchild
= replacement
;
682 /*** Here, if replacement is a vertical combination
683 and so is its new parent, we should make replacement's
684 children be children of that parent instead. ***/
687 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
688 "Remove WINDOW from the display. Default is selected window.")
690 register Lisp_Object window
;
692 register Lisp_Object tem
, parent
, sib
;
693 register struct window
*p
;
694 register struct window
*par
;
696 /* Because this function is called by other C code on non-leaf
697 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
698 so we can't decode_window here. */
700 window
= selected_window
;
702 CHECK_WINDOW (window
, 0);
703 p
= XWINDOW (window
);
705 /* It's okay to delete an already-deleted window. */
713 error ("Attempt to delete minibuffer or sole ordinary window");
714 par
= XWINDOW (parent
);
716 windows_or_buffers_changed
++;
718 /* Are we trying to delete any frame's selected window? */
720 Lisp_Object frame
, pwindow
;
722 /* See if the frame's selected window is either WINDOW
723 or any subwindow of it, by finding all that window's parents
724 and comparing each one with WINDOW. */
725 frame
= WINDOW_FRAME (XWINDOW (window
));
726 pwindow
= FRAME_SELECTED_WINDOW (XFRAME (frame
));
728 while (!NILP (pwindow
))
730 if (EQ (window
, pwindow
))
732 pwindow
= XWINDOW (pwindow
)->parent
;
735 if (EQ (window
, pwindow
))
737 Lisp_Object alternative
;
738 alternative
= Fnext_window (window
, Qlambda
, Qnil
);
740 /* If we're about to delete the selected window on the
741 selected frame, then we should use Fselect_window to select
742 the new window. On the other hand, if we're about to
743 delete the selected window on any other frame, we shouldn't do
744 anything but set the frame's selected_window slot. */
745 if (EQ (window
, selected_window
))
746 Fselect_window (alternative
);
748 FRAME_SELECTED_WINDOW (XFRAME (frame
)) = alternative
;
753 /* tem is null for dummy parent windows
754 (which have inferiors but not any contents themselves) */
758 unchain_marker (p
->pointm
);
759 unchain_marker (p
->start
);
764 XWINDOW (tem
)->prev
= p
->prev
;
768 XWINDOW (tem
)->next
= p
->next
;
770 if (EQ (window
, par
->hchild
))
771 par
->hchild
= p
->next
;
772 if (EQ (window
, par
->vchild
))
773 par
->vchild
= p
->next
;
775 /* Find one of our siblings to give our space to. */
779 /* If p gives its space to its next sibling, that sibling needs
780 to have its top/left side pulled back to where p's is.
781 set_window_{height,width} will re-position the sibling's
784 XWINDOW (sib
)->top
= p
->top
;
785 XWINDOW (sib
)->left
= p
->left
;
788 /* Stretch that sibling. */
789 if (!NILP (par
->vchild
))
790 set_window_height (sib
,
791 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
793 if (!NILP (par
->hchild
))
794 set_window_width (sib
,
795 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
798 /* If parent now has only one child,
799 put the child into the parent's place. */
803 if (NILP (XWINDOW (tem
)->next
))
804 replace_window (parent
, tem
);
806 /* Since we may be deleting combination windows, we must make sure that
807 not only p but all its children have been marked as deleted. */
808 if (! NILP (p
->hchild
))
809 delete_all_subwindows (XWINDOW (p
->hchild
));
810 else if (! NILP (p
->vchild
))
811 delete_all_subwindows (XWINDOW (p
->vchild
));
813 /* Mark this window as deleted. */
814 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
820 extern Lisp_Object
next_frame (), prev_frame ();
822 /* This comment supplies the doc string for `next-window',
823 for make-docfile to see. We cannot put this in the real DEFUN
824 due to limits in the Unix cpp.
826 DEFUN ("next-window", Ffoo, Sfoo, 0, 3, 0,
827 "Return next window after WINDOW in canonical ordering of windows.\n\
828 If omitted, WINDOW defaults to the selected window.\n\
830 Optional second arg MINIBUF t means count the minibuffer window even\n\
831 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
832 it is active. MINIBUF neither t nor nil means not to count the\n\
833 minibuffer even if it is active.\n\
835 Several frames may share a single minibuffer; if the minibuffer\n\
836 counts, all windows on all frames that share that minibuffer count\n\
837 too. This means that next-window may be used to iterate through the\n\
838 set of windows even when the minibuffer is on another frame. If the\n\
839 minibuffer does not count, only windows from WINDOW's frame count.\n\
841 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
842 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
843 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
844 Anything else means restrict to WINDOW's frame.\n\
846 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
847 `next-window' to iterate through the entire cycle of acceptable\n\
848 windows, eventually ending up back at the window you started with.\n\
849 `previous-window' traverses the same cycle, in the reverse order.")
850 (window, minibuf, all_frames) */
852 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
854 (window
, minibuf
, all_frames
)
855 register Lisp_Object window
, minibuf
, all_frames
;
857 register Lisp_Object tem
;
858 Lisp_Object start_window
;
861 window
= selected_window
;
863 CHECK_LIVE_WINDOW (window
, 0);
865 start_window
= window
;
867 /* minibuf == nil may or may not include minibuffers.
868 Decide if it does. */
870 minibuf
= (minibuf_level
? Qt
: Qlambda
);
873 /* all_frames == nil doesn't specify which frames to include.
874 Decide which frames it includes. */
875 if (NILP (all_frames
))
876 all_frames
= (EQ (minibuf
, Qt
)
877 ? (FRAME_MINIBUF_WINDOW
880 (XWINDOW (window
)))))
882 else if (EQ (all_frames
, Qvisible
))
884 else if (! EQ (all_frames
, Qt
))
886 /* Now all_frames is t meaning search all frames,
887 nil meaning search just current frame,
888 or a window, meaning search the frame that window belongs to. */
891 /* Do this loop at least once, to get the next window, and perhaps
892 again, if we hit the minibuffer and that is not acceptable. */
895 /* Find a window that actually has a next one. This loop
896 climbs up the tree. */
897 while (tem
= XWINDOW (window
)->next
, NILP (tem
))
898 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
902 /* We've reached the end of this frame.
903 Which other frames are acceptable? */
904 tem
= WINDOW_FRAME (XWINDOW (window
));
906 if (! NILP (all_frames
))
907 tem
= next_frame (tem
, all_frames
);
909 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
916 /* If we're in a combination window, find its first child and
917 recurse on that. Otherwise, we've found the window we want. */
920 if (!NILP (XWINDOW (window
)->hchild
))
921 window
= XWINDOW (window
)->hchild
;
922 else if (!NILP (XWINDOW (window
)->vchild
))
923 window
= XWINDOW (window
)->vchild
;
927 /* Which windows are acceptible?
928 Exit the loop and accept this window if
929 this isn't a minibuffer window, or
930 we're accepting minibuffer windows, or
931 we've come all the way around and we're back at the original window. */
932 while (MINI_WINDOW_P (XWINDOW (window
))
933 && ! EQ (minibuf
, Qt
)
934 && ! EQ (window
, start_window
));
939 /* This comment supplies the doc string for `previous-window',
940 for make-docfile to see. We cannot put this in the real DEFUN
941 due to limits in the Unix cpp.
943 DEFUN ("previous-window", Ffoo, Sfoo, 0, 3, 0,
944 "Return the window preceeding WINDOW in canonical ordering of windows.\n\
945 If omitted, WINDOW defaults to the selected window.\n\
947 Optional second arg MINIBUF t means count the minibuffer window even\n\
948 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
949 it is active. MINIBUF neither t nor nil means not to count the\n\
950 minibuffer even if it is active.\n\
952 Several frames may share a single minibuffer; if the minibuffer\n\
953 counts, all windows on all frames that share that minibuffer count\n\
954 too. This means that previous-window may be used to iterate through\n\
955 the set of windows even when the minibuffer is on another frame. If\n\
956 the minibuffer does not count, only windows from WINDOW's frame\n\
959 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
960 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
961 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
962 Anything else means restrict to WINDOW's frame.\n\
964 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
965 `previous-window' to iterate through the entire cycle of acceptable\n\
966 windows, eventually ending up back at the window you started with.\n\
967 `next-window' traverses the same cycle, in the reverse order.")
968 (window, minibuf, all_frames) */
971 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
973 (window
, minibuf
, all_frames
)
974 register Lisp_Object window
, minibuf
, all_frames
;
976 register Lisp_Object tem
;
977 Lisp_Object start_window
;
980 window
= selected_window
;
982 CHECK_LIVE_WINDOW (window
, 0);
984 start_window
= window
;
986 /* minibuf == nil may or may not include minibuffers.
987 Decide if it does. */
989 minibuf
= (minibuf_level
? Qt
: Qlambda
);
992 /* all_frames == nil doesn't specify which frames to include.
993 Decide which frames it includes. */
994 if (NILP (all_frames
))
995 all_frames
= (EQ (minibuf
, Qt
)
996 ? (FRAME_MINIBUF_WINDOW
999 (XWINDOW (window
)))))
1001 else if (EQ (all_frames
, Qvisible
))
1003 else if (! EQ (all_frames
, Qt
))
1005 /* Now all_frames is t meaning search all frames,
1006 nil meaning search just current frame,
1007 or a window, meaning search the frame that window belongs to. */
1010 /* Do this loop at least once, to get the previous window, and perhaps
1011 again, if we hit the minibuffer and that is not acceptable. */
1014 /* Find a window that actually has a previous one. This loop
1015 climbs up the tree. */
1016 while (tem
= XWINDOW (window
)->prev
, NILP (tem
))
1017 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
1021 /* We have found the top window on the frame.
1022 Which frames are acceptable? */
1023 tem
= WINDOW_FRAME (XWINDOW (window
));
1025 if (! NILP (all_frames
))
1026 /* It's actually important that we use prev_frame here,
1027 rather than next_frame. All the windows acceptable
1028 according to the given parameters should form a ring;
1029 Fnext_window and Fprevious_window should go back and
1030 forth around the ring. If we use next_frame here,
1031 then Fnext_window and Fprevious_window take different
1032 paths through the set of acceptable windows.
1033 window_loop assumes that these `ring' requirement are
1035 tem
= prev_frame (tem
, all_frames
);
1037 /* If this frame has a minibuffer, find that window first,
1038 because it is conceptually the last window in that frame. */
1039 if (FRAME_HAS_MINIBUF_P (XFRAME (tem
)))
1040 tem
= FRAME_MINIBUF_WINDOW (XFRAME (tem
));
1042 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
1048 /* If we're in a combination window, find its last child and
1049 recurse on that. Otherwise, we've found the window we want. */
1052 if (!NILP (XWINDOW (window
)->hchild
))
1053 window
= XWINDOW (window
)->hchild
;
1054 else if (!NILP (XWINDOW (window
)->vchild
))
1055 window
= XWINDOW (window
)->vchild
;
1057 while (tem
= XWINDOW (window
)->next
, !NILP (tem
))
1061 /* Which windows are acceptable?
1062 Exit the loop and accept this window if
1063 this isn't a minibuffer window, or
1064 we're accepting minibuffer windows, or
1065 we've come all the way around and we're back at the original window. */
1066 while (MINI_WINDOW_P (XWINDOW (window
))
1067 && !EQ (minibuf
, Qt
)
1068 && !EQ (window
, start_window
));
1073 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1074 "Select the ARG'th different window on this frame.\n\
1075 All windows on current frame are arranged in a cyclic order.\n\
1076 This command selects the window ARG steps away in that order.\n\
1077 A negative ARG moves in the opposite order. If the optional second\n\
1078 argument ALL_FRAMES is non-nil, cycle through all frames.")
1080 register Lisp_Object n
, all_frames
;
1083 register Lisp_Object w
;
1085 CHECK_NUMBER (n
, 0);
1086 w
= selected_window
;
1091 w
= Fnext_window (w
, Qnil
, all_frames
);
1096 w
= Fprevious_window (w
, Qnil
, all_frames
);
1103 /* Look at all windows, performing an operation specified by TYPE
1105 If FRAMES is Qt, look at all frames;
1106 Qnil, look at just the selected frame;
1107 Qvisible, look at visible frames;
1108 a frame, just look at windows on that frame.
1109 If MINI is non-zero, perform the operation on minibuffer windows too.
1115 GET_BUFFER_WINDOW
, /* Arg is buffer */
1116 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1117 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1118 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1120 UNSHOW_BUFFER
/* Arg is buffer */
1124 window_loop (type
, obj
, mini
, frames
)
1125 enum window_loop type
;
1126 register Lisp_Object obj
, frames
;
1129 register Lisp_Object w
;
1130 register Lisp_Object best_window
;
1131 register Lisp_Object next_window
;
1132 register Lisp_Object last_window
;
1134 Lisp_Object frame_arg
;
1138 /* If we're only looping through windows on a particular frame,
1139 frame points to that frame. If we're looping through windows
1140 on all frames, frame is 0. */
1141 if (FRAMEP (frames
))
1142 frame
= XFRAME (frames
);
1143 else if (NILP (frames
))
1144 frame
= selected_frame
;
1148 frame_arg
= Qlambda
;
1149 else if (EQ (frames
, Qvisible
))
1155 /* frame_arg is Qlambda to stick to one frame,
1156 Qvisible to consider all visible frames,
1159 /* Pick a window to start with. */
1160 if (XTYPE (obj
) == Lisp_Window
)
1163 w
= FRAME_SELECTED_WINDOW (frame
);
1165 w
= FRAME_SELECTED_WINDOW (selected_frame
);
1167 /* Figure out the last window we're going to mess with. Since
1168 Fnext_window, given the same options, is guaranteed to go in a
1169 ring, we can just use Fprevious_window to find the last one.
1171 We can't just wait until we hit the first window again, because
1172 it might be deleted. */
1174 last_window
= Fprevious_window (w
, mini
? Qt
: Qnil
, frame_arg
);
1179 FRAME_PTR w_frame
= XFRAME (WINDOW_FRAME (XWINDOW (w
)));
1181 /* Pick the next window now, since some operations will delete
1182 the current window. */
1183 next_window
= Fnext_window (w
, mini
? Qt
: Qnil
, frame_arg
);
1185 /* Note that we do not pay attention here to whether
1186 the frame is visible, since Fnext_window skips non-visible frames
1187 if that is desired, under the control of frame_arg. */
1188 if (! MINI_WINDOW_P (XWINDOW (w
))
1189 || (mini
&& minibuf_level
> 0))
1192 case GET_BUFFER_WINDOW
:
1193 if (XBUFFER (XWINDOW (w
)->buffer
) == XBUFFER (obj
))
1197 case GET_LRU_WINDOW
:
1198 /* t as arg means consider only full-width windows */
1199 if (!NILP (obj
) && XFASTINT (XWINDOW (w
)->width
)
1200 != FRAME_WIDTH (XFRAME (WINDOW_FRAME (XWINDOW (w
)))))
1202 /* Ignore dedicated windows and minibuffers. */
1203 if (MINI_WINDOW_P (XWINDOW (w
))
1204 || !NILP (XWINDOW (w
)->dedicated
))
1206 if (NILP (best_window
)
1207 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1208 > XFASTINT (XWINDOW (w
)->use_time
)))
1212 case DELETE_OTHER_WINDOWS
:
1213 if (XWINDOW (w
) != XWINDOW (obj
))
1217 case DELETE_BUFFER_WINDOWS
:
1218 if (EQ (XWINDOW (w
)->buffer
, obj
))
1220 /* If we're deleting the buffer displayed in the only window
1221 on the frame, find a new buffer to display there. */
1222 if (NILP (XWINDOW (w
)->parent
))
1224 Lisp_Object new_buffer
;
1225 new_buffer
= Fother_buffer (obj
, Qnil
);
1226 if (NILP (new_buffer
))
1228 = Fget_buffer_create (build_string ("*scratch*"));
1229 Fset_window_buffer (w
, new_buffer
);
1230 if (EQ (w
, selected_window
))
1231 Fset_buffer (XWINDOW (w
)->buffer
);
1238 case GET_LARGEST_WINDOW
:
1239 /* Ignore dedicated windows and minibuffers. */
1240 if (MINI_WINDOW_P (XWINDOW (w
))
1241 || !NILP (XWINDOW (w
)->dedicated
))
1244 struct window
*best_window_ptr
= XWINDOW (best_window
);
1245 struct window
*w_ptr
= XWINDOW (w
);
1246 if (NILP (best_window
) ||
1247 (XFASTINT (w_ptr
->height
) * XFASTINT (w_ptr
->width
))
1248 > (XFASTINT (best_window_ptr
->height
)
1249 * XFASTINT (best_window_ptr
->width
)))
1255 if (EQ (XWINDOW (w
)->buffer
, obj
))
1257 /* Find another buffer to show in this window. */
1258 Lisp_Object another_buffer
;
1259 another_buffer
= Fother_buffer (obj
, Qnil
);
1260 if (NILP (another_buffer
))
1262 = Fget_buffer_create (build_string ("*scratch*"));
1263 Fset_window_buffer (w
, another_buffer
);
1264 if (EQ (w
, selected_window
))
1265 Fset_buffer (XWINDOW (w
)->buffer
);
1270 if (EQ (w
, last_window
))
1279 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1280 "Return the window least recently selected or used for display.\n\
1281 If optional argument FRAME is `visible', search all visible frames.\n\
1282 If FRAME is t, search all frames.\n\
1283 If FRAME is nil, search only the selected frame.\n\
1284 If FRAME is a frame, search only that frame.")
1288 register Lisp_Object w
;
1289 /* First try for a window that is full-width */
1290 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1291 if (!NILP (w
) && !EQ (w
, selected_window
))
1293 /* If none of them, try the rest */
1294 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1297 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1298 "Return the largest window in area.\n\
1299 If optional argument FRAME is `visible', search all visible frames.\n\
1300 If FRAME is t, search all frames.\n\
1301 If FRAME is nil, search only the selected frame.\n\
1302 If FRAME is a frame, search only that frame.")
1306 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1310 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1311 "Return a window currently displaying BUFFER, or nil if none.\n\
1312 If optional argument FRAME is `visible', search all visible frames.\n\
1313 If FRAME is t, search all frames.\n\
1314 If FRAME is nil, search only the selected frame.\n\
1315 If FRAME is a frame, search only that frame.")
1317 Lisp_Object buffer
, frame
;
1319 buffer
= Fget_buffer (buffer
);
1320 if (XTYPE (buffer
) == Lisp_Buffer
)
1321 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1326 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1328 "Make WINDOW (or the selected window) fill its frame.\n\
1329 Only the frame WINDOW is on is affected.\n\
1330 This function tries to reduce display jumps\n\
1331 by keeping the text previously visible in WINDOW\n\
1332 in the same place on the frame. Doing this depends on\n\
1333 the value of (window-start WINDOW), so if calling this function\n\
1334 in a program gives strange scrolling, make sure the window-start\n\
1335 value is reasonable when this function is called.")
1340 struct buffer
*obuf
= current_buffer
;
1345 window
= selected_window
;
1347 CHECK_LIVE_WINDOW (window
, 0);
1349 w
= XWINDOW (window
);
1350 top
= XFASTINT (w
->top
);
1352 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
1354 Fset_buffer (w
->buffer
);
1356 SET_PT (marker_position (w
->start
));
1357 /* Like Frecenter but avoid setting w->force_start. */
1358 Fvertical_motion (make_number (- (top
- FRAME_MENU_BAR_LINES (XFRAME (WINDOW_FRAME (w
))))),
1360 Fset_marker (w
->start
, make_number (PT
), w
->buffer
);
1361 w
->start_at_line_beg
= Fbolp ();
1364 set_buffer_internal (obuf
);
1368 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1369 1, 2, "bDelete windows on (buffer): ",
1370 "Delete all windows showing BUFFER.\n\
1371 Optional second argument FRAME controls which frames are affected.\n\
1372 If nil or omitted, delete all windows showing BUFFER in any frame.\n\
1373 If t, delete only windows showing BUFFER in the selected frame.\n\
1374 If `visible', delete all windows showing BUFFER in any visible frame.\n\
1375 If a frame, delete only windows showing BUFFER in that frame.")
1377 Lisp_Object buffer
, frame
;
1380 /* FRAME uses t and nil to mean the opposite of what window_loop
1382 if (! FRAMEP (frame
))
1383 frame
= NILP (frame
) ? Qt
: Qnil
;
1390 buffer
= Fget_buffer (buffer
);
1391 CHECK_BUFFER (buffer
, 0);
1392 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
1397 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1398 Sreplace_buffer_in_windows
,
1399 1, 1, "bReplace buffer in windows: ",
1400 "Replace BUFFER with some other buffer in all windows showing it.")
1406 buffer
= Fget_buffer (buffer
);
1407 CHECK_BUFFER (buffer
, 0);
1408 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
1413 /* Set the height of WINDOW and all its inferiors. */
1415 /* The smallest acceptable dimensions for a window. Anything smaller
1416 might crash Emacs. */
1417 #define MIN_SAFE_WINDOW_WIDTH (2)
1418 #define MIN_SAFE_WINDOW_HEIGHT (2)
1420 /* Make sure that window_min_height and window_min_width are
1421 not too small; if they are, set them to safe minima. */
1424 check_min_window_sizes ()
1426 /* Smaller values might permit a crash. */
1427 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
1428 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
1429 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
1430 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
1433 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
1434 minimum allowable size. */
1436 check_frame_size (frame
, rows
, cols
)
1440 /* For height, we have to see:
1441 whether the frame has a minibuffer,
1442 whether it wants a mode line, and
1443 whether it has a menu bar. */
1445 (FRAME_MINIBUF_ONLY_P (frame
) ? MIN_SAFE_WINDOW_HEIGHT
- 1
1446 : (! FRAME_HAS_MINIBUF_P (frame
)) ? MIN_SAFE_WINDOW_HEIGHT
1447 : 2 * MIN_SAFE_WINDOW_HEIGHT
- 1);
1448 if (FRAME_MENU_BAR_LINES (frame
) > 0)
1449 min_height
+= FRAME_MENU_BAR_LINES (frame
);
1451 if (*rows
< min_height
)
1453 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
1454 *cols
= MIN_SAFE_WINDOW_WIDTH
;
1457 /* Normally the window is deleted if it gets too small.
1458 nodelete nonzero means do not do this.
1459 (The caller should check later and do so if appropriate) */
1461 set_window_height (window
, height
, nodelete
)
1466 register struct window
*w
= XWINDOW (window
);
1467 register struct window
*c
;
1468 int oheight
= XFASTINT (w
->height
);
1469 int top
, pos
, lastbot
, opos
, lastobot
;
1472 check_min_window_sizes ();
1475 && ! NILP (w
->parent
)
1476 && height
< window_min_height
)
1478 Fdelete_window (window
);
1482 XFASTINT (w
->last_modified
) = 0;
1483 windows_or_buffers_changed
++;
1484 XFASTINT (w
->height
) = height
;
1485 if (!NILP (w
->hchild
))
1487 for (child
= w
->hchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1489 XWINDOW (child
)->top
= w
->top
;
1490 set_window_height (child
, height
, nodelete
);
1493 else if (!NILP (w
->vchild
))
1495 lastbot
= top
= XFASTINT (w
->top
);
1497 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
1499 c
= XWINDOW (child
);
1501 opos
= lastobot
+ XFASTINT (c
->height
);
1503 XFASTINT (c
->top
) = lastbot
;
1505 pos
= (((opos
* height
) << 1) + oheight
) / (oheight
<< 1);
1507 /* Avoid confusion: inhibit deletion of child if becomes too small */
1508 set_window_height (child
, pos
+ top
- lastbot
, 1);
1510 /* Now advance child to next window,
1511 and set lastbot if child was not just deleted. */
1512 lastbot
= pos
+ top
;
1515 /* Now delete any children that became too small. */
1517 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1519 set_window_height (child
, XINT (XWINDOW (child
)->height
), 0);
1524 /* Recursively set width of WINDOW and its inferiors. */
1526 set_window_width (window
, width
, nodelete
)
1531 register struct window
*w
= XWINDOW (window
);
1532 register struct window
*c
;
1533 int owidth
= XFASTINT (w
->width
);
1534 int left
, pos
, lastright
, opos
, lastoright
;
1537 if (!nodelete
&& width
< window_min_width
&& !NILP (w
->parent
))
1539 Fdelete_window (window
);
1543 XFASTINT (w
->last_modified
) = 0;
1544 windows_or_buffers_changed
++;
1545 XFASTINT (w
->width
) = width
;
1546 if (!NILP (w
->vchild
))
1548 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1550 XWINDOW (child
)->left
= w
->left
;
1551 set_window_width (child
, width
, nodelete
);
1554 else if (!NILP (w
->hchild
))
1556 lastright
= left
= XFASTINT (w
->left
);
1558 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
1560 c
= XWINDOW (child
);
1562 opos
= lastoright
+ XFASTINT (c
->width
);
1564 XFASTINT (c
->left
) = lastright
;
1566 pos
= (((opos
* width
) << 1) + owidth
) / (owidth
<< 1);
1568 /* Inhibit deletion for becoming too small */
1569 set_window_width (child
, pos
+ left
- lastright
, 1);
1571 /* Now advance child to next window,
1572 and set lastright if child was not just deleted. */
1573 lastright
= pos
+ left
, lastoright
= opos
;
1575 /* Delete children that became too small */
1577 for (child
= w
->hchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1579 set_window_width (child
, XINT (XWINDOW (child
)->width
), 0);
1584 int window_select_count
;
1586 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
1587 "Make WINDOW display BUFFER as its contents.\n\
1588 BUFFER can be a buffer or buffer name.")
1590 register Lisp_Object window
, buffer
;
1592 register Lisp_Object tem
;
1593 register struct window
*w
= decode_window (window
);
1595 buffer
= Fget_buffer (buffer
);
1596 CHECK_BUFFER (buffer
, 1);
1598 if (NILP (XBUFFER (buffer
)->name
))
1599 error ("Attempt to display deleted buffer");
1603 error ("Window is deleted");
1604 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
1605 is first being set up. */
1607 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
1608 error ("Window is dedicated to %s\n", tem
);
1614 w
->window_end_pos
= 0;
1615 w
->window_end_valid
= Qnil
;
1617 Fset_marker (w
->pointm
,
1618 make_number (BUF_PT (XBUFFER (buffer
))),
1620 set_marker_restricted (w
->start
,
1621 make_number (XBUFFER (buffer
)->last_window_start
),
1623 w
->start_at_line_beg
= Qnil
;
1624 w
->force_start
= Qnil
;
1625 XFASTINT (w
->last_modified
) = 0;
1626 windows_or_buffers_changed
++;
1627 if (EQ (window
, selected_window
))
1628 Fset_buffer (buffer
);
1633 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
1634 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
1635 The main editor command loop selects the buffer of the selected window\n\
1636 before each command.")
1638 register Lisp_Object window
;
1640 register struct window
*w
;
1641 register struct window
*ow
= XWINDOW (selected_window
);
1643 CHECK_LIVE_WINDOW (window
, 0);
1645 w
= XWINDOW (window
);
1647 if (NILP (w
->buffer
))
1648 error ("Trying to select deleted window or non-leaf window");
1650 XFASTINT (w
->use_time
) = ++window_select_count
;
1651 if (EQ (window
, selected_window
))
1654 Fset_marker (ow
->pointm
, make_number (BUF_PT (XBUFFER (ow
->buffer
))),
1657 selected_window
= window
;
1659 if (XFRAME (WINDOW_FRAME (w
)) != selected_frame
)
1661 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
1662 Fhandle_switch_frame (WINDOW_FRAME (w
), Qnil
);
1665 selected_frame
->selected_window
= window
;
1668 record_buffer (w
->buffer
);
1669 Fset_buffer (w
->buffer
);
1671 /* Go to the point recorded in the window.
1672 This is important when the buffer is in more
1673 than one window. It also matters when
1674 redisplay_window has altered point after scrolling,
1675 because it makes the change only in the window. */
1677 register int new_point
= marker_position (w
->pointm
);
1678 if (new_point
< BEGV
)
1686 windows_or_buffers_changed
++;
1690 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 2,
1691 "BDisplay buffer: \nP",
1692 "Make BUFFER appear in some window but don't select it.\n\
1693 BUFFER can be a buffer or a buffer name.\n\
1694 If BUFFER is shown already in some window, just use that one,\n\
1695 unless the window is the selected window and the optional second\n\
1696 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).\n\
1697 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.\n\
1698 Returns the window displaying BUFFER.")
1699 (buffer
, not_this_window
)
1700 register Lisp_Object buffer
, not_this_window
;
1702 register Lisp_Object window
;
1704 buffer
= Fget_buffer (buffer
);
1705 CHECK_BUFFER (buffer
, 0);
1707 if (!NILP (Vdisplay_buffer_function
))
1708 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
1710 if (NILP (not_this_window
)
1711 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
1712 return selected_window
;
1715 /* If pop_up_frames,
1716 look for a window showing BUFFER on any visible frame. */
1717 window
= Fget_buffer_window (buffer
, pop_up_frames
? Qvisible
: Qnil
);
1719 window
= Fget_buffer_window (buffer
, Qnil
);
1722 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
1726 /* If there are no frames open that have more than a minibuffer,
1727 we need to create a new frame. */
1728 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
1731 = Fframe_selected_window (call0 (Vpop_up_frame_function
));
1732 Fset_window_buffer (window
, buffer
);
1734 Fhandle_switch_frame (XWINDOW (window
)->frame
, Qnil
);
1738 #endif /* MULTI_FRAME */
1742 || FRAME_MINIBUF_ONLY_P (selected_frame
)
1750 if (FRAME_MINIBUF_ONLY_P (selected_frame
))
1751 XSET (frames
, Lisp_Frame
, last_nonminibuf_frame
);
1753 /* Don't try to create a window if would get an error */
1754 if (split_height_threshold
< window_min_height
<< 1)
1755 split_height_threshold
= window_min_height
<< 1;
1757 window
= Fget_largest_window (frames
);
1760 && window_height (window
) >= split_height_threshold
1761 && (XFASTINT (XWINDOW (window
)->width
)
1762 == FRAME_WIDTH (XFRAME (WINDOW_FRAME (XWINDOW (window
))))))
1763 window
= Fsplit_window (window
, Qnil
, Qnil
);
1766 window
= Fget_lru_window (frames
);
1767 if ((EQ (window
, selected_window
)
1768 || EQ (XWINDOW (window
)->parent
, Qnil
))
1769 && window_height (window
) >= window_min_height
<< 1)
1770 window
= Fsplit_window (window
, Qnil
, Qnil
);
1774 window
= Fget_lru_window (Qnil
);
1776 Fset_window_buffer (window
, buffer
);
1781 temp_output_buffer_show (buf
)
1782 register Lisp_Object buf
;
1784 register struct buffer
*old
= current_buffer
;
1785 register Lisp_Object window
;
1786 register struct window
*w
;
1789 XBUFFER (buf
)->save_modified
= MODIFF
;
1794 set_buffer_internal (old
);
1796 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
1797 call1 (Vtemp_buffer_show_function
, buf
);
1800 window
= Fdisplay_buffer (buf
, Qnil
);
1803 if (XFRAME (XWINDOW (window
)->frame
) != selected_frame
)
1804 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
1805 #endif /* MULTI_FRAME */
1806 Vminibuf_scroll_window
= window
;
1807 w
= XWINDOW (window
);
1808 XFASTINT (w
->hscroll
) = 0;
1809 set_marker_restricted (w
->start
, make_number (1), buf
);
1810 set_marker_restricted (w
->pointm
, make_number (1), buf
);
1815 make_dummy_parent (window
)
1818 register Lisp_Object old
, new;
1819 register struct window
*o
, *p
;
1822 XSETTYPE (old
, Lisp_Vector
);
1823 new = Fcopy_sequence (old
);
1824 XSETTYPE (new, Lisp_Window
);
1828 XFASTINT (p
->sequence_number
) = ++sequence_number
;
1830 /* Put new into window structure in place of window */
1831 replace_window (window
, new);
1844 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
1845 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
1846 WINDOW defaults to selected one and SIZE to half its size.\n\
1847 If optional third arg HOR-FLAG is non-nil, split side by side\n\
1848 and put SIZE columns in the first of the pair.")
1849 (window
, chsize
, horflag
)
1850 Lisp_Object window
, chsize
, horflag
;
1852 register Lisp_Object
new;
1853 register struct window
*o
, *p
;
1857 window
= selected_window
;
1859 CHECK_LIVE_WINDOW (window
, 0);
1861 o
= XWINDOW (window
);
1865 if (!NILP (horflag
))
1866 /* Round odd size up, since this is for the left-hand window,
1867 and it will lose a column for the separators. */
1868 size
= ((XFASTINT (o
->width
) + 1) & -2) >> 1;
1870 size
= XFASTINT (o
->height
) >> 1;
1874 CHECK_NUMBER (chsize
, 1);
1875 size
= XINT (chsize
);
1878 if (MINI_WINDOW_P (o
))
1879 error ("Attempt to split minibuffer window");
1880 else if (FRAME_NO_SPLIT_P (XFRAME (WINDOW_FRAME (o
))))
1881 error ("Attempt to split unsplittable frame");
1883 check_min_window_sizes ();
1887 if (size
< window_min_height
1888 || size
+ window_min_height
> XFASTINT (o
->height
))
1889 args_out_of_range_3 (window
, chsize
, horflag
);
1890 if (NILP (o
->parent
)
1891 || NILP (XWINDOW (o
->parent
)->vchild
))
1893 make_dummy_parent (window
);
1895 XWINDOW (new)->vchild
= window
;
1900 if (size
< window_min_width
1901 || size
+ window_min_width
> XFASTINT (o
->width
))
1902 args_out_of_range_3 (window
, chsize
, horflag
);
1903 if (NILP (o
->parent
)
1904 || NILP (XWINDOW (o
->parent
)->hchild
))
1906 make_dummy_parent (window
);
1908 XWINDOW (new)->hchild
= window
;
1912 /* Now we know that window's parent is a vertical combination
1913 if we are dividing vertically, or a horizontal combination
1914 if we are making side-by-side windows */
1916 windows_or_buffers_changed
++;
1917 new = make_window ();
1920 p
->frame
= o
->frame
;
1922 if (!NILP (p
->next
))
1923 XWINDOW (p
->next
)->prev
= new;
1926 p
->parent
= o
->parent
;
1929 Fset_window_buffer (new, o
->buffer
);
1931 /* Apportion the available frame space among the two new windows */
1933 if (!NILP (horflag
))
1935 p
->height
= o
->height
;
1937 XFASTINT (p
->width
) = XFASTINT (o
->width
) - size
;
1938 XFASTINT (o
->width
) = size
;
1939 XFASTINT (p
->left
) = XFASTINT (o
->left
) + size
;
1944 p
->width
= o
->width
;
1945 XFASTINT (p
->height
) = XFASTINT (o
->height
) - size
;
1946 XFASTINT (o
->height
) = size
;
1947 XFASTINT (p
->top
) = XFASTINT (o
->top
) + size
;
1953 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
1954 "Make current window ARG lines bigger.\n\
1955 From program, optional second arg non-nil means grow sideways ARG columns.")
1957 register Lisp_Object n
, side
;
1959 CHECK_NUMBER (n
, 0);
1960 change_window_height (XINT (n
), !NILP (side
));
1964 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
1965 "Make current window ARG lines smaller.\n\
1966 From program, optional second arg non-nil means shrink sideways ARG columns.")
1968 register Lisp_Object n
, side
;
1970 CHECK_NUMBER (n
, 0);
1971 change_window_height (-XINT (n
), !NILP (side
));
1976 window_height (window
)
1979 register struct window
*p
= XWINDOW (window
);
1980 return XFASTINT (p
->height
);
1984 window_width (window
)
1987 register struct window
*p
= XWINDOW (window
);
1988 return XFASTINT (p
->width
);
1991 #define MINSIZE(w) \
1993 ? window_min_width \
1994 : (MINI_WINDOW_P (XWINDOW (w)) ? 1 : window_min_height))
1997 *(widthflag ? (int *) &(XWINDOW (w)->left) : (int *) &(XWINDOW (w)->top))
1999 #define CURSIZE(w) \
2000 *(widthflag ? (int *) &(XWINDOW (w)->width) : (int *) &(XWINDOW (w)->height))
2002 /* Unlike set_window_height, this function
2003 also changes the heights of the siblings so as to
2004 keep everything consistent. */
2006 change_window_height (delta
, widthflag
)
2010 register Lisp_Object parent
;
2012 register struct window
*p
;
2014 int (*sizefun
) () = widthflag
? window_width
: window_height
;
2015 register int (*setsizefun
) () = (widthflag
2017 : set_window_height
);
2019 check_min_window_sizes ();
2021 window
= selected_window
;
2024 p
= XWINDOW (window
);
2029 error ("No other window to side of this one");
2032 if (widthflag
? !NILP (XWINDOW (parent
)->hchild
)
2033 : !NILP (XWINDOW (parent
)->vchild
))
2038 sizep
= &CURSIZE (window
);
2040 if (*sizep
+ delta
< MINSIZE (window
))
2042 Fdelete_window (window
);
2047 register int maxdelta
;
2049 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - *sizep
2050 : !NILP (p
->next
) ? (*sizefun
) (p
->next
) - MINSIZE (p
->next
)
2051 : !NILP (p
->prev
) ? (*sizefun
) (p
->prev
) - MINSIZE (p
->prev
)
2052 /* This is a frame with only one window, a minibuffer-only
2053 or a minibufferless frame. */
2056 if (delta
> maxdelta
)
2057 /* This case traps trying to make the minibuffer
2058 the full frame, or make the only window aside from the
2059 minibuffer the full frame. */
2066 if (!NILP (p
->next
) &&
2067 (*sizefun
) (p
->next
) - delta
>= MINSIZE (p
->next
))
2069 (*setsizefun
) (p
->next
, (*sizefun
) (p
->next
) - delta
, 0);
2070 (*setsizefun
) (window
, *sizep
+ delta
, 0);
2071 CURBEG (p
->next
) += delta
;
2072 /* This does not change size of p->next,
2073 but it propagates the new top edge to its children */
2074 (*setsizefun
) (p
->next
, (*sizefun
) (p
->next
), 0);
2076 else if (!NILP (p
->prev
) &&
2077 (*sizefun
) (p
->prev
) - delta
>= MINSIZE (p
->prev
))
2079 (*setsizefun
) (p
->prev
, (*sizefun
) (p
->prev
) - delta
, 0);
2080 CURBEG (window
) -= delta
;
2081 (*setsizefun
) (window
, *sizep
+ delta
, 0);
2085 register int delta1
;
2086 register int opht
= (*sizefun
) (parent
);
2088 /* If trying to grow this window to or beyond size of the parent,
2089 make delta1 so big that, on shrinking back down,
2090 all the siblings end up with less than one line and are deleted. */
2091 if (opht
<= *sizep
+ delta
)
2092 delta1
= opht
* opht
* 2;
2093 /* Otherwise, make delta1 just right so that if we add delta1
2094 lines to this window and to the parent, and then shrink
2095 the parent back to its original size, the new proportional
2096 size of this window will increase by delta. */
2098 delta1
= (delta
* opht
* 100) / ((opht
- *sizep
- delta
) * 100);
2100 /* Add delta1 lines or columns to this window, and to the parent,
2101 keeping things consistent while not affecting siblings. */
2102 CURSIZE (parent
) = opht
+ delta1
;
2103 (*setsizefun
) (window
, *sizep
+ delta1
, 0);
2105 /* Squeeze out delta1 lines or columns from our parent,
2106 shriking this window and siblings proportionately.
2107 This brings parent back to correct size.
2108 Delta1 was calculated so this makes this window the desired size,
2109 taking it all out of the siblings. */
2110 (*setsizefun
) (parent
, opht
, 0);
2113 XFASTINT (p
->last_modified
) = 0;
2120 /* Return number of lines of text (not counting mode line) in W. */
2123 window_internal_height (w
)
2126 int ht
= XFASTINT (w
->height
);
2128 if (MINI_WINDOW_P (w
))
2131 if (!NILP (w
->parent
) || !NILP (w
->vchild
) || !NILP (w
->hchild
)
2132 || !NILP (w
->next
) || !NILP (w
->prev
)
2133 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w
))))
2140 /* Return the number of columns in W.
2141 Don't count columns occupied by scroll bars or the vertical bar
2142 separating W from the sibling to its right. */
2144 window_internal_width (w
)
2147 FRAME_PTR f
= XFRAME (WINDOW_FRAME (w
));
2148 int left
= XINT (w
->left
);
2149 int width
= XINT (w
->width
);
2151 /* If this window is flush against the right edge of the frame, its
2152 internal width is its full width. */
2153 if (left
+ width
>= FRAME_WIDTH (f
))
2156 /* If we are not flush right, then our rightmost columns are
2157 occupied by some sort of separator. */
2159 /* Scroll bars occupy a few columns. */
2160 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
2161 return width
- VERTICAL_SCROLL_BAR_WIDTH
;
2163 /* The column of `|' characters separating side-by-side windows
2164 occupies one column only. */
2169 /* Scroll contents of window WINDOW up N lines. */
2172 window_scroll (window
, n
, noerror
)
2177 register struct window
*w
= XWINDOW (window
);
2178 register int opoint
= point
;
2180 register int ht
= window_internal_height (w
);
2181 register Lisp_Object tem
;
2183 Lisp_Object bolp
, nmoved
;
2185 XFASTINT (tem
) = point
;
2186 tem
= Fpos_visible_in_window_p (tem
, window
);
2190 Fvertical_motion (make_number (- (ht
/ 2)), window
);
2191 XFASTINT (tem
) = point
;
2192 Fset_marker (w
->start
, tem
, w
->buffer
);
2193 w
->force_start
= Qt
;
2196 SET_PT (marker_position (w
->start
));
2197 lose
= n
< 0 && point
== BEGV
;
2198 Fvertical_motion (make_number (n
), window
);
2208 Fsignal (Qbeginning_of_buffer
, Qnil
);
2213 set_marker_restricted (w
->start
, make_number (pos
), w
->buffer
);
2214 w
->start_at_line_beg
= bolp
;
2215 w
->update_mode_line
= Qt
;
2216 XFASTINT (w
->last_modified
) = 0;
2222 tem
= Fvertical_motion (make_number (ht
), window
);
2223 if (point
> opoint
|| XFASTINT (tem
) < ht
)
2226 Fvertical_motion (make_number (-1), window
);
2234 Fsignal (Qend_of_buffer
, Qnil
);
2238 /* This is the guts of Fscroll_up and Fscroll_down. */
2241 scroll_command (n
, direction
)
2242 register Lisp_Object n
;
2245 register int defalt
;
2246 int count
= specpdl_ptr
- specpdl
;
2248 /* If selected window's buffer isn't current, make it current for the moment.
2249 But don't screw up if window_scroll gets an error. */
2250 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
2252 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
2253 Fset_buffer (XWINDOW (selected_window
)->buffer
);
2256 defalt
= (window_internal_height (XWINDOW (selected_window
))
2257 - next_screen_context_lines
);
2258 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
2261 window_scroll (selected_window
, defalt
, 0);
2262 else if (EQ (n
, Qminus
))
2263 window_scroll (selected_window
, - defalt
, 0);
2266 n
= Fprefix_numeric_value (n
);
2267 window_scroll (selected_window
, XINT (n
) * direction
, 0);
2270 unbind_to (count
, Qnil
);
2273 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
2274 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
2275 A near full screen is `next-screen-context-lines' less than a full screen.\n\
2276 Negative ARG means scroll downward.\n\
2277 When calling from a program, supply a number as argument or nil.")
2281 scroll_command (n
, 1);
2285 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
2286 "Scroll text of current window downward ARG lines; or near full screen if no ARG.\n\
2287 A near full screen is `next-screen-context-lines' less than a full screen.\n\
2288 Negative ARG means scroll upward.\n\
2289 When calling from a program, supply a number as argument or nil.")
2293 scroll_command (n
, -1);
2297 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
2298 "Scroll next window upward ARG lines; or near full screen if no ARG.\n\
2299 The next window is the one below the current one; or the one at the top\n\
2300 if the current one is at the bottom. Negative ARG means scroll downward.\n\
2301 When calling from a program, supply a number as argument or nil.\n\
2303 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
2304 specifies the window to scroll.\n\
2305 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
2306 showing that buffer, popping the buffer up if necessary.")
2308 register Lisp_Object n
;
2310 register Lisp_Object window
;
2312 register struct window
*w
;
2313 register int count
= specpdl_ptr
- specpdl
;
2315 if (MINI_WINDOW_P (XWINDOW (selected_window
))
2316 && !NILP (Vminibuf_scroll_window
))
2317 window
= Vminibuf_scroll_window
;
2318 /* If buffer is specified, scroll that buffer. */
2319 else if (!NILP (Vother_window_scroll_buffer
))
2321 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
2323 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
);
2327 /* Nothing specified; look for a neighboring window on the same
2329 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
2331 if (EQ (window
, selected_window
))
2332 /* That didn't get us anywhere; look for a window on another
2335 window
= Fnext_window (window
, Qnil
, Qt
);
2336 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
2337 && ! EQ (window
, selected_window
));
2340 CHECK_LIVE_WINDOW (window
, 0);
2342 if (EQ (window
, selected_window
))
2343 error ("There is no other window");
2345 w
= XWINDOW (window
);
2346 ht
= window_internal_height (w
);
2348 /* Don't screw up if window_scroll gets an error. */
2349 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
2351 Fset_buffer (w
->buffer
);
2352 SET_PT (marker_position (w
->pointm
));
2355 window_scroll (window
, ht
- next_screen_context_lines
, 1);
2356 else if (EQ (n
, Qminus
))
2357 window_scroll (window
, next_screen_context_lines
- ht
, 1);
2360 if (XTYPE (n
) == Lisp_Cons
)
2362 CHECK_NUMBER (n
, 0);
2363 window_scroll (window
, XINT (n
), 1);
2366 Fset_marker (w
->pointm
, make_number (point
), Qnil
);
2367 unbind_to (count
, Qnil
);
2372 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
2373 "Scroll selected window display ARG columns left.\n\
2374 Default for ARG is window width minus 2.")
2376 register Lisp_Object arg
;
2380 XFASTINT (arg
) = window_internal_width (XWINDOW (selected_window
)) - 2;
2382 arg
= Fprefix_numeric_value (arg
);
2385 Fset_window_hscroll (selected_window
,
2386 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
2390 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
2391 "Scroll selected window display ARG columns right.\n\
2392 Default for ARG is window width minus 2.")
2394 register Lisp_Object arg
;
2397 XFASTINT (arg
) = window_internal_width (XWINDOW (selected_window
)) - 2;
2399 arg
= Fprefix_numeric_value (arg
);
2402 Fset_window_hscroll (selected_window
,
2403 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
2407 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
2408 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
2409 The desired position of point is always relative to the current window.\n\
2410 Just C-u as prefix means put point in the center of the window.\n\
2411 No arg (i.e., it is nil) erases the entire frame and then\n\
2412 redraws with point in the center of the current window.")
2414 register Lisp_Object n
;
2416 register struct window
*w
= XWINDOW (selected_window
);
2417 register int ht
= window_internal_height (w
);
2418 register int opoint
= point
;
2423 extern int frame_garbaged
;
2425 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
2426 XFASTINT (n
) = ht
/ 2;
2428 else if (XTYPE (n
) == Lisp_Cons
) /* Just C-u. */
2430 XFASTINT (n
) = ht
/ 2;
2434 n
= Fprefix_numeric_value (n
);
2435 CHECK_NUMBER (n
, 0);
2439 XSETINT (n
, XINT (n
) + ht
);
2441 XSETINT (n
, - XINT (n
));
2443 XSET (window
, Lisp_Window
, w
);
2444 Fvertical_motion (n
, window
);
2445 Fset_marker (w
->start
, make_number (point
), w
->buffer
);
2446 w
->start_at_line_beg
= Fbolp ();
2449 w
->force_start
= Qt
;
2454 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
2456 "Position point relative to window.\n\
2457 With no argument, position text at center of window.\n\
2458 An argument specifies frame line; zero means top of window,\n\
2459 negative means relative to bottom of window.")
2461 register Lisp_Object arg
;
2463 register struct window
*w
= XWINDOW (selected_window
);
2464 register int height
= window_internal_height (w
);
2469 XFASTINT (arg
) = height
/ 2;
2472 arg
= Fprefix_numeric_value (arg
);
2474 XSETINT (arg
, XINT (arg
) + height
);
2477 start
= marker_position (w
->start
);
2478 XSET (window
, Lisp_Window
, w
);
2479 if (start
< BEGV
|| start
> ZV
)
2481 Fvertical_motion (make_number (- (height
/ 2)), window
);
2482 Fset_marker (w
->start
, make_number (point
), w
->buffer
);
2483 w
->start_at_line_beg
= Fbolp ();
2484 w
->force_start
= Qt
;
2489 return Fvertical_motion (arg
, window
);
2492 struct save_window_data
2494 int size_from_Lisp_Vector_struct
;
2495 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
2496 Lisp_Object frame_width
, frame_height
, frame_menu_bar_lines
;
2497 Lisp_Object selected_frame
;
2498 Lisp_Object current_window
;
2499 Lisp_Object current_buffer
;
2500 Lisp_Object minibuf_scroll_window
;
2501 Lisp_Object root_window
;
2502 Lisp_Object focus_frame
;
2503 /* A vector, interpreted as a struct saved_window */
2504 Lisp_Object saved_windows
;
2507 /* Arg to Fmake_vector */
2508 #define SAVE_WINDOW_DATA_SIZE \
2509 ((sizeof (struct save_window_data) \
2510 - (sizeof (struct Lisp_Vector) \
2511 /* Don't count the contents member of the struct Lisp_Vector */ \
2512 - sizeof (Lisp_Object))) \
2513 / sizeof (Lisp_Object))
2515 /* This is saved as a Lisp_Vector */
2518 /* these first two must agree with struct Lisp_Vector in lisp.h */
2519 int size_from_Lisp_Vector_struct
;
2520 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
2523 Lisp_Object buffer
, start
, pointm
, mark
;
2524 Lisp_Object left
, top
, width
, height
, hscroll
;
2525 Lisp_Object parent
, prev
;
2526 Lisp_Object start_at_line_beg
;
2527 Lisp_Object display_table
;
2529 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
2531 #define SAVED_WINDOW_N(swv,n) \
2532 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
2534 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
2535 "T if OBJECT is a window-configration object.")
2539 if (XTYPE (obj
) == Lisp_Window_Configuration
)
2545 DEFUN ("set-window-configuration", Fset_window_configuration
,
2546 Sset_window_configuration
, 1, 1, 0,
2547 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
2548 CONFIGURATION must be a value previously returned\n\
2549 by `current-window-configuration' (which see).")
2551 Lisp_Object configuration
;
2553 register struct save_window_data
*data
;
2554 struct Lisp_Vector
*saved_windows
;
2555 Lisp_Object new_current_buffer
;
2559 while (XTYPE (configuration
) != Lisp_Window_Configuration
)
2561 configuration
= wrong_type_argument (intern ("window-configuration-p"),
2565 data
= (struct save_window_data
*) XVECTOR (configuration
);
2566 saved_windows
= XVECTOR (data
->saved_windows
);
2568 new_current_buffer
= data
->current_buffer
;
2569 if (NILP (XBUFFER (new_current_buffer
)->name
))
2570 new_current_buffer
= Qnil
;
2572 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
2575 /* If f is a dead frame, don't bother rebuilding its window tree.
2576 However, there is other stuff we should still try to do below. */
2577 if (FRAME_LIVE_P (f
))
2579 register struct window
*w
;
2580 register struct saved_window
*p
;
2583 /* If the frame has been resized since this window configuration was
2584 made, we change the frame to the size specified in the
2585 configuration, restore the configuration, and then resize it
2586 back. We keep track of the prevailing height in these variables. */
2587 int previous_frame_height
= FRAME_HEIGHT (f
);
2588 int previous_frame_width
= FRAME_WIDTH (f
);
2589 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
2591 if (XFASTINT (data
->frame_height
) != previous_frame_height
2592 || XFASTINT (data
->frame_width
) != previous_frame_width
)
2593 change_frame_size (f
, data
->frame_height
, data
->frame_width
, 0, 0);
2594 #ifdef HAVE_X_WINDOWS
2595 if (XFASTINT (data
->frame_menu_bar_lines
)
2596 != previous_frame_menu_bar_lines
)
2597 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, 0);
2600 windows_or_buffers_changed
++;
2603 Mark all windows now on frame as "deleted".
2604 Restoring the new configuration "undeletes" any that are in it.
2606 Save their current buffers in their height fields, since we may
2607 need it later, if a buffer saved in the configuration is now
2609 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
2611 for (k
= 0; k
< saved_windows
->size
; k
++)
2613 p
= SAVED_WINDOW_N (saved_windows
, k
);
2614 w
= XWINDOW (p
->window
);
2617 if (!NILP (p
->parent
))
2618 w
->parent
= SAVED_WINDOW_N (saved_windows
,
2619 XFASTINT (p
->parent
))->window
;
2623 if (!NILP (p
->prev
))
2625 w
->prev
= SAVED_WINDOW_N (saved_windows
,
2626 XFASTINT (p
->prev
))->window
;
2627 XWINDOW (w
->prev
)->next
= p
->window
;
2632 if (!NILP (w
->parent
))
2634 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
2636 XWINDOW (w
->parent
)->vchild
= p
->window
;
2637 XWINDOW (w
->parent
)->hchild
= Qnil
;
2641 XWINDOW (w
->parent
)->hchild
= p
->window
;
2642 XWINDOW (w
->parent
)->vchild
= Qnil
;
2647 /* If we squirreled away the buffer in the window's height,
2649 if (XTYPE (w
->height
) == Lisp_Buffer
)
2650 w
->buffer
= w
->height
;
2653 w
->width
= p
->width
;
2654 w
->height
= p
->height
;
2655 w
->hscroll
= p
->hscroll
;
2656 w
->display_table
= p
->display_table
;
2657 XFASTINT (w
->last_modified
) = 0;
2659 /* Reinstall the saved buffer and pointers into it. */
2660 if (NILP (p
->buffer
))
2661 w
->buffer
= p
->buffer
;
2664 if (!NILP (XBUFFER (p
->buffer
)->name
))
2665 /* If saved buffer is alive, install it. */
2667 w
->buffer
= p
->buffer
;
2668 w
->start_at_line_beg
= p
->start_at_line_beg
;
2669 set_marker_restricted (w
->start
,
2670 Fmarker_position (p
->start
),
2672 set_marker_restricted (w
->pointm
,
2673 Fmarker_position (p
->pointm
),
2675 Fset_marker (XBUFFER (w
->buffer
)->mark
,
2676 Fmarker_position (p
->mark
), w
->buffer
);
2678 /* As documented in Fcurrent_window_configuration, don't
2679 save the location of point in the buffer which was current
2680 when the window configuration was recorded. */
2681 if (!EQ (p
->buffer
, new_current_buffer
) &&
2682 XBUFFER (p
->buffer
) == current_buffer
)
2683 Fgoto_char (w
->pointm
);
2685 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
2686 /* Else unless window has a live buffer, get one. */
2688 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
2689 /* This will set the markers to beginning of visible
2691 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
2692 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
2693 w
->start_at_line_beg
= Qt
;
2696 /* Keeping window's old buffer; make sure the markers
2699 /* Set window markers at start of visible range. */
2700 if (XMARKER (w
->start
)->buffer
== 0)
2701 set_marker_restricted (w
->start
, make_number (0),
2703 if (XMARKER (w
->pointm
)->buffer
== 0)
2704 set_marker_restricted (w
->pointm
,
2706 (BUF_PT (XBUFFER (w
->buffer
)))),
2708 w
->start_at_line_beg
= Qt
;
2713 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
2714 Fselect_window (data
->current_window
);
2717 if (NILP (data
->focus_frame
)
2718 || (XTYPE (data
->focus_frame
) == Lisp_Frame
2719 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
2720 Fredirect_frame_focus (frame
, data
->focus_frame
);
2723 #if 0 /* I don't understand why this is needed, and it causes problems
2724 when the frame's old selected window has been deleted. */
2726 if (f
!= selected_frame
&& ! FRAME_TERMCAP_P (f
))
2727 Fhandle_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)), Qnil
);
2731 /* Set the screen height to the value it had before this function. */
2732 if (previous_frame_height
!= FRAME_HEIGHT (f
)
2733 || previous_frame_width
!= FRAME_WIDTH (f
))
2734 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
2736 #ifdef HAVE_X_WINDOWS
2737 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
2738 x_set_menu_bar_lines (f
, previous_frame_menu_bar_lines
, 0);
2743 /* Fselect_window will have made f the selected frame, so we
2744 reselect the proper frame here. Fhandle_switch_frame will change the
2745 selected window too, but that doesn't make the call to
2746 Fselect_window above totally superfluous; it still sets f's
2748 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
2749 Fhandle_switch_frame (data
->selected_frame
, Qnil
);
2752 if (!NILP (new_current_buffer
))
2753 Fset_buffer (new_current_buffer
);
2755 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
2759 /* Mark all windows now on frame as deleted
2760 by setting their buffers to nil. */
2763 delete_all_subwindows (w
)
2764 register struct window
*w
;
2766 if (!NILP (w
->next
))
2767 delete_all_subwindows (XWINDOW (w
->next
));
2768 if (!NILP (w
->vchild
))
2769 delete_all_subwindows (XWINDOW (w
->vchild
));
2770 if (!NILP (w
->hchild
))
2771 delete_all_subwindows (XWINDOW (w
->hchild
));
2773 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
2775 /* We set all three of these fields to nil, to make sure that we can
2776 distinguish this dead window from any live window. Live leaf
2777 windows will have buffer set, and combination windows will have
2778 vchild or hchild set. */
2785 count_windows (window
)
2786 register struct window
*window
;
2788 register int count
= 1;
2789 if (!NILP (window
->next
))
2790 count
+= count_windows (XWINDOW (window
->next
));
2791 if (!NILP (window
->vchild
))
2792 count
+= count_windows (XWINDOW (window
->vchild
));
2793 if (!NILP (window
->hchild
))
2794 count
+= count_windows (XWINDOW (window
->hchild
));
2799 save_window_save (window
, vector
, i
)
2801 struct Lisp_Vector
*vector
;
2804 register struct saved_window
*p
;
2805 register struct window
*w
;
2806 register Lisp_Object tem
;
2808 for (;!NILP (window
); window
= w
->next
)
2810 p
= SAVED_WINDOW_N (vector
, i
);
2811 w
= XWINDOW (window
);
2813 XFASTINT (w
->temslot
) = i
++;
2815 p
->buffer
= w
->buffer
;
2818 p
->width
= w
->width
;
2819 p
->height
= w
->height
;
2820 p
->hscroll
= w
->hscroll
;
2821 p
->display_table
= w
->display_table
;
2822 if (!NILP (w
->buffer
))
2824 /* Save w's value of point in the window configuration.
2825 If w is the selected window, then get the value of point
2826 from the buffer; pointm is garbage in the selected window. */
2827 if (EQ (window
, selected_window
))
2829 p
->pointm
= Fmake_marker ();
2830 Fset_marker (p
->pointm
, BUF_PT (XBUFFER (w
->buffer
)),
2834 p
->pointm
= Fcopy_marker (w
->pointm
);
2836 p
->start
= Fcopy_marker (w
->start
);
2837 p
->start_at_line_beg
= w
->start_at_line_beg
;
2839 tem
= XBUFFER (w
->buffer
)->mark
;
2840 p
->mark
= Fcopy_marker (tem
);
2847 p
->start_at_line_beg
= Qnil
;
2850 if (NILP (w
->parent
))
2853 p
->parent
= XWINDOW (w
->parent
)->temslot
;
2858 p
->prev
= XWINDOW (w
->prev
)->temslot
;
2860 if (!NILP (w
->vchild
))
2861 i
= save_window_save (w
->vchild
, vector
, i
);
2862 if (!NILP (w
->hchild
))
2863 i
= save_window_save (w
->hchild
, vector
, i
);
2869 DEFUN ("current-window-configuration",
2870 Fcurrent_window_configuration
, Scurrent_window_configuration
, 0, 1, 0,
2871 "Return an object representing the current window configuration of FRAME.\n\
2872 If FRAME is nil or omitted, use the selected frame.\n\
2873 This describes the number of windows, their sizes and current buffers,\n\
2874 and for each displayed buffer, where display starts, and the positions of\n\
2875 point and mark. An exception is made for point in the current buffer:\n\
2876 its value is -not- saved.\n\
2877 This also records the currently selected frame, and FRAME's focus\n\
2878 redirection (see `redirect-frame-focus').")
2882 register Lisp_Object tem
;
2883 register int n_windows
;
2884 register struct save_window_data
*data
;
2892 CHECK_LIVE_FRAME (frame
, 0);
2896 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
2897 data
= (struct save_window_data
*)
2898 XVECTOR (Fmake_vector (make_number (SAVE_WINDOW_DATA_SIZE
),
2900 XFASTINT (data
->frame_width
) = FRAME_WIDTH (f
);
2901 XFASTINT (data
->frame_height
) = FRAME_HEIGHT (f
);
2902 XFASTINT (data
->frame_menu_bar_lines
) = FRAME_MENU_BAR_LINES (f
);
2904 XSET (data
->selected_frame
, Lisp_Frame
, selected_frame
);
2906 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
2907 XSET (data
->current_buffer
, Lisp_Buffer
, current_buffer
);
2908 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
2909 data
->root_window
= FRAME_ROOT_WINDOW (f
);
2910 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
2911 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
2912 data
->saved_windows
= tem
;
2913 for (i
= 0; i
< n_windows
; i
++)
2914 XVECTOR (tem
)->contents
[i
]
2915 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
2916 save_window_save (FRAME_ROOT_WINDOW (f
),
2918 XSET (tem
, Lisp_Window_Configuration
, data
);
2922 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
2924 "Execute body, preserving window sizes and contents.\n\
2925 Restores which buffer appears in which window, where display starts,\n\
2926 as well as the current buffer.\n\
2927 Does not restore the value of point in current buffer.")
2931 register Lisp_Object val
;
2932 register int count
= specpdl_ptr
- specpdl
;
2934 record_unwind_protect (Fset_window_configuration
,
2935 Fcurrent_window_configuration (Qnil
));
2936 val
= Fprogn (args
);
2937 return unbind_to (count
, val
);
2943 selected_frame
= make_terminal_frame ();
2944 minibuf_window
= selected_frame
->minibuffer_window
;
2945 selected_window
= selected_frame
->selected_window
;
2946 last_nonminibuf_frame
= selected_frame
;
2947 #else /* not MULTI_FRAME */
2948 extern Lisp_Object
get_minibuffer ();
2950 minibuf_window
= make_window ();
2951 FRAME_ROOT_WINDOW (selected_frame
) = make_window ();
2953 XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->next
= minibuf_window
;
2954 XWINDOW (minibuf_window
)->prev
= FRAME_ROOT_WINDOW (selected_frame
);
2955 XWINDOW (minibuf_window
)->mini_p
= Qt
;
2957 /* These values 9 and 10 are arbitrary,
2958 just so that there is "something there."
2959 Correct values are put in in init_xdisp */
2961 XFASTINT (XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->width
) = 10;
2962 XFASTINT (XWINDOW (minibuf_window
)->width
) = 10;
2964 XFASTINT (XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->height
) = 9;
2965 XFASTINT (XWINDOW (minibuf_window
)->top
) = 9;
2966 XFASTINT (XWINDOW (minibuf_window
)->height
) = 1;
2968 /* Prevent error in Fset_window_buffer. */
2969 XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->buffer
= Qt
;
2970 XWINDOW (minibuf_window
)->buffer
= Qt
;
2972 /* Now set them up for real. */
2973 Fset_window_buffer (FRAME_ROOT_WINDOW (selected_frame
),
2974 Fcurrent_buffer ());
2975 Fset_window_buffer (minibuf_window
, get_minibuffer (0));
2977 selected_window
= FRAME_ROOT_WINDOW (selected_frame
);
2978 /* Make sure this window seems more recently used than
2979 a newly-created, never-selected window. Increment
2980 window_select_count so the first selection ever will get
2981 something newer than this. */
2982 XFASTINT (XWINDOW (selected_window
)->use_time
) = ++window_select_count
;
2983 #endif /* not MULTI_FRAME */
2988 Qwindowp
= intern ("windowp");
2989 staticpro (&Qwindowp
);
2991 Qwindow_live_p
= intern ("window-live-p");
2992 staticpro (&Qwindow_live_p
);
2995 /* Make sure all windows get marked */
2996 staticpro (&minibuf_window
);
2999 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
3000 "Non-nil means call as function to display a help buffer.\n\
3001 Used by `with-output-to-temp-buffer'.");
3002 Vtemp_buffer_show_function
= Qnil
;
3004 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
3005 "If non-nil, function to call to handle `display-buffer'.\n\
3006 It will receive two args, the buffer and a flag which if non-nil means\n\
3007 that the currently selected window is not acceptable.\n\
3008 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
3009 work using this function.");
3010 Vdisplay_buffer_function
= Qnil
;
3012 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
3013 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
3014 Vminibuf_scroll_window
= Qnil
;
3016 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
3017 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
3018 Vother_window_scroll_buffer
= Qnil
;
3020 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
3021 "*Non-nil means `display-buffer' should make a separate frame.");
3024 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
3025 "*If non-nil, function to call to handle automatic new frame creation.\n\
3026 It is called with no arguments and should return a newly created frame.\n\
3028 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
3029 where `pop-up-frame-alist' would hold the default frame parameters.");
3030 Vpop_up_frame_function
= Qnil
;
3032 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
3033 "*Non-nil means display-buffer should make new windows.");
3036 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
3037 "*Number of lines of continuity when scrolling by screenfuls.");
3038 next_screen_context_lines
= 2;
3040 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
3041 "*display-buffer would prefer to split the largest window if this large.\n\
3042 If there is only one window, it is split regardless of this value.");
3043 split_height_threshold
= 500;
3045 DEFVAR_INT ("window-min-height", &window_min_height
,
3046 "*Delete any window less than this tall (including its mode line).");
3047 window_min_height
= 4;
3049 DEFVAR_INT ("window-min-width", &window_min_width
,
3050 "*Delete any window less than this wide.");
3051 window_min_width
= 10;
3053 defsubr (&Sselected_window
);
3054 defsubr (&Sminibuffer_window
);
3055 defsubr (&Swindow_minibuffer_p
);
3056 defsubr (&Swindowp
);
3057 defsubr (&Swindow_live_p
);
3058 defsubr (&Spos_visible_in_window_p
);
3059 defsubr (&Swindow_buffer
);
3060 defsubr (&Swindow_height
);
3061 defsubr (&Swindow_width
);
3062 defsubr (&Swindow_hscroll
);
3063 defsubr (&Sset_window_hscroll
);
3064 defsubr (&Swindow_edges
);
3065 defsubr (&Scoordinates_in_window_p
);
3066 defsubr (&Swindow_at
);
3067 defsubr (&Swindow_point
);
3068 defsubr (&Swindow_start
);
3069 defsubr (&Swindow_end
);
3070 defsubr (&Sset_window_point
);
3071 defsubr (&Sset_window_start
);
3072 defsubr (&Swindow_dedicated_p
);
3073 defsubr (&Sset_window_dedicated_p
);
3074 defsubr (&Swindow_display_table
);
3075 defsubr (&Sset_window_display_table
);
3076 defsubr (&Snext_window
);
3077 defsubr (&Sprevious_window
);
3078 defsubr (&Sother_window
);
3079 defsubr (&Sget_lru_window
);
3080 defsubr (&Sget_largest_window
);
3081 defsubr (&Sget_buffer_window
);
3082 defsubr (&Sdelete_other_windows
);
3083 defsubr (&Sdelete_windows_on
);
3084 defsubr (&Sreplace_buffer_in_windows
);
3085 defsubr (&Sdelete_window
);
3086 defsubr (&Sset_window_buffer
);
3087 defsubr (&Sselect_window
);
3088 defsubr (&Sdisplay_buffer
);
3089 defsubr (&Ssplit_window
);
3090 defsubr (&Senlarge_window
);
3091 defsubr (&Sshrink_window
);
3092 defsubr (&Sscroll_up
);
3093 defsubr (&Sscroll_down
);
3094 defsubr (&Sscroll_left
);
3095 defsubr (&Sscroll_right
);
3096 defsubr (&Sscroll_other_window
);
3097 defsubr (&Srecenter
);
3098 defsubr (&Smove_to_window_line
);
3099 defsubr (&Swindow_configuration_p
);
3100 defsubr (&Sset_window_configuration
);
3101 defsubr (&Scurrent_window_configuration
);
3102 defsubr (&Ssave_window_excursion
);
3107 initial_define_key (control_x_map
, '1', "delete-other-windows");
3108 initial_define_key (control_x_map
, '2', "split-window");
3109 initial_define_key (control_x_map
, '0', "delete-window");
3110 initial_define_key (control_x_map
, 'o', "other-window");
3111 initial_define_key (control_x_map
, '^', "enlarge-window");
3112 initial_define_key (control_x_map
, '<', "scroll-left");
3113 initial_define_key (control_x_map
, '>', "scroll-right");
3115 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
3116 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
3117 initial_define_key (meta_map
, 'v', "scroll-down");
3119 initial_define_key (global_map
, Ctl('L'), "recenter");
3120 initial_define_key (meta_map
, 'r', "move-to-window-line");