Annotation of 43BSD/contrib/emacs/src/window.c, revision 1.1.1.1

1.1       root        1: /* Window creation, deletion and examination for GNU Emacs.
                      2:    Does not include redisplay.
                      3:    Copyright (C) 1985 Richard M. Stallman.
                      4: 
                      5: This file is part of GNU Emacs.
                      6: 
                      7: GNU Emacs is distributed in the hope that it will be useful,
                      8: but WITHOUT ANY WARRANTY.  No author or distributor
                      9: accepts responsibility to anyone for the consequences of using it
                     10: or for whether it serves any particular purpose or works at all,
                     11: unless he says so in writing.  Refer to the GNU Emacs General Public
                     12: License for full details.
                     13: 
                     14: Everyone is granted permission to copy, modify and redistribute
                     15: GNU Emacs, but only under the conditions described in the
                     16: GNU Emacs General Public License.   A copy of this license is
                     17: supposed to have been given to you along with GNU Emacs so you
                     18: can know your rights and responsibilities.  It should be in a
                     19: file named COPYING.  Among other things, the copyright notice
                     20: and this notice must be preserved on all copies.  */
                     21: 
                     22: 
                     23: #include "config.h"
                     24: #include "lisp.h"
                     25: #include "buffer.h"
                     26: #include "window.h"
                     27: #include "commands.h"
                     28: #include "indent.h"
                     29: #include "termchar.h"
                     30: 
                     31: Lisp_Object Qwindowp;
                     32: 
                     33: Lisp_Object Fnext_window (), Fdelete_window (), Fselect_window ();
                     34: Lisp_Object Fshow_buffer (), Fsplit_window (), Frecenter ();
                     35: 
                     36: /* This is the window which displays the minibuffer.
                     37: It is always the same window.  */
                     38: 
                     39: Lisp_Object minibuf_window;
                     40: 
                     41: /* This is the window in which the terminal's cursor should
                     42:  be left when nothing is being done with it.  This must
                     43:  always be a leaf window, and its buffer is selected by
                     44:  the top level editing loop at the end of each command.  */
                     45: 
                     46: Lisp_Object selected_window;
                     47: 
                     48: /* If a window gets smaller than either of these, it is removed. */
                     49: 
                     50: int window_min_height;
                     51: int window_min_width;
                     52: 
                     53: /* Nonzero implies pop_to_buffer should create windows. */
                     54: 
                     55: int pop_up_windows;
                     56: 
                     57: /* display-buffer always splits the largest window 
                     58:  if that window is more than this high */
                     59: 
                     60: int split_height_threshold;
                     61: 
                     62: /* Number of lines of continuity in scrolling by screenfuls.  */
                     63: 
                     64: int next_screen_context_lines;
                     65: 
                     66: /* Incremented for each window created.  */
                     67: 
                     68: static int sequence_number;
                     69: 
                     70: DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
                     71:   "Returns t if OBJ is a window.")
                     72:   (obj)
                     73:      Lisp_Object obj;
                     74: {
                     75:   return XTYPE (obj) == Lisp_Window ? Qt : Qnil;
                     76: }
                     77: 
                     78: Lisp_Object
                     79: make_window ()
                     80: {
                     81:   Lisp_Object val;
                     82:   register struct window *p;
                     83: 
                     84:   val = Fmake_vector (
                     85:     make_number ((sizeof (struct window) - sizeof (struct Lisp_Vector))
                     86:                 / sizeof (Lisp_Object)),
                     87:     Qnil);
                     88:   XSETTYPE (val, Lisp_Window);
                     89:   p = XWINDOW (val);
                     90:   XFASTINT (p->left) = XFASTINT (p->top)
                     91:     = XFASTINT (p->height) = XFASTINT (p->width)
                     92:       = XFASTINT (p->hscroll) = 0;
                     93:   XFASTINT (p->last_point_x) = XFASTINT (p->last_point_y) = 0;
                     94:   p->start = Fmake_marker ();
                     95:   p->pointm = Fmake_marker ();
                     96:   XFASTINT (p->sequence_number) = ++sequence_number;
                     97:   XFASTINT (p->use_time) = 0;
                     98:   return val;
                     99: }
                    100: 
                    101: DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0,
                    102:   "Return the window that the cursor appears in and commands apply to.")
                    103:   ()
                    104: {
                    105:   return selected_window;
                    106: }
                    107: 
                    108: DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p,
                    109:   Spos_visible_in_window_p, 0, 2, 0,
                    110:   "Return t if position POS is currently on the screen in WINDOW.\n\
                    111: Returns nil if that position is scrolled vertically out of view.\n\
                    112: POS defaults to point; WINDOW, to the selected window.")
                    113:   (pos, window)
                    114:      Lisp_Object pos, window;
                    115: {
                    116:   register struct window *w;
                    117:   register int top;
                    118:   register int height;
                    119:   register int posint;
                    120:   register struct buffer_text *text;
                    121:   struct position posval;
                    122: 
                    123:   if (NULL (pos))
                    124:     posint = point;
                    125:   else
                    126:     {
                    127:       CHECK_NUMBER_COERCE_MARKER (pos, 0);
                    128:       posint = XINT (pos);
                    129:     }
                    130: 
                    131:   if (NULL (window))
                    132:     window = selected_window;
                    133:   else
                    134:     CHECK_WINDOW (window, 1);
                    135:   w = XWINDOW (window);
                    136:   top = marker_position (w->start);
                    137: 
                    138:   if (posint < top)
                    139:     return Qnil;
                    140: 
                    141:   height = XFASTINT (w->height) - !EQ (window, minibuf_window);
                    142: 
                    143:   bf_cur->text = bf_text;
                    144:   text = &XBUFFER (w->buffer)->text;
                    145:   if (XFASTINT (w->last_modified) >= text->modified)
                    146:     {
                    147:       /* If screen is up to date,
                    148:         use the info recorded about how much text fit on it. */
                    149:       if (posint < text->size1 + text->size2 + 1 - XFASTINT (w->window_end_pos)
                    150:          || (XFASTINT (w->window_end_vpos) < height))
                    151:        return Qt;
                    152:       return Qnil;
                    153:     }
                    154:   else
                    155:     {
                    156:       if (posint > text->size1 + text->size2 + 1)
                    157:        return Qnil;
                    158:       /* If that info is not correct, calculate afresh */
                    159:       posval = *compute_motion (top, 0, 0,
                    160:                               posint, height, 0,
                    161:                               XFASTINT (w->width) - 1
                    162:                               - (XFASTINT (w->width) + XFASTINT (w->left) != XFASTINT (XWINDOW (minibuf_window)->width)),
                    163: 
                    164:                               XINT (w->hscroll), 0);
                    165:       return posval.vpos < height ? Qt : Qnil;
                    166:     }
                    167: }
                    168: 
                    169: struct window *
                    170: decode_window (window)
                    171:      Lisp_Object window;
                    172: {
                    173:   if (NULL (window))
                    174:     return XWINDOW (selected_window);
                    175: 
                    176:   CHECK_WINDOW (window, 0);
                    177:   return XWINDOW (window);
                    178: }
                    179: 
                    180: DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0,
                    181:   "Return the buffer that WINDOW is displaying.")
                    182:   (window)
                    183:      Lisp_Object window;
                    184: {
                    185:   return decode_window (window)->buffer;
                    186: }
                    187: 
                    188: DEFUN ("window-height", Fwindow_height, Swindow_height, 0, 1, 0,
                    189:   "Return the number of lines in WINDOW (including its mode line).")
                    190:   (window)
                    191:      Lisp_Object window;
                    192: {
                    193:   return decode_window (window)->height;
                    194: }
                    195: 
                    196: DEFUN ("window-width", Fwindow_width, Swindow_width, 0, 1, 0,
                    197:   "Return the number of columns in WINDOW.")
                    198:   (window)
                    199:      Lisp_Object window;
                    200: {
                    201:   return decode_window (window)->width;
                    202: }
                    203: 
                    204: DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
                    205:   "Return the number of columns by which WINDOW is scrolled from left margin.")
                    206:   (window)
                    207:      Lisp_Object window;
                    208: {
                    209:   return decode_window (window)->hscroll;
                    210: }
                    211: 
                    212: DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
                    213:   "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\
                    214: NCOL should be zero or positive.")
                    215:   (window, ncol)
                    216:      Lisp_Object window, ncol;
                    217: {
                    218:   CHECK_NUMBER (ncol, 1);
                    219:   if (XINT (ncol) < 0) XFASTINT (ncol) = 0;
                    220:   if (XFASTINT (ncol) >= (1 << (SHORTBITS - 1)))
                    221:     args_out_of_range (ncol, Qnil);
                    222: 
                    223:   clip_changed = 1;            /* Prevent redisplay shortcuts */
                    224:   decode_window (window)->hscroll = ncol;
                    225:   return ncol;
                    226: }
                    227: 
                    228: DEFUN ("window-edges", Fwindow_edges, Swindow_edges, 0, 1, 0,
                    229:   "Return a list of the edge coordinates of WINDOW.\n\
                    230: \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of screen.")
                    231:   (window)
                    232:      Lisp_Object window;
                    233: {
                    234:   register struct window *w = decode_window (window);
                    235: 
                    236:   return Fcons (w->left, Fcons (w->top,
                    237:            Fcons (make_number (XFASTINT (w->left) + XFASTINT (w->width)),
                    238:                  Fcons (make_number (XFASTINT (w->top)
                    239:                                      + XFASTINT (w->height)),
                    240:                         Qnil))));
                    241: }
                    242: 
                    243: DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0,
                    244:   "Return current value of point in WINDOW.")
                    245:   (window)
                    246:      Lisp_Object window;
                    247: {
                    248:   return Fmarker_position (decode_window (window)->pointm);
                    249: }
                    250: 
                    251: DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0,
                    252:   "Return position at which display currently starts in WINDOW.")
                    253:   (window)
                    254:      Lisp_Object window;
                    255: {
                    256:   return Fmarker_position (decode_window (window)->start);
                    257: }
                    258: 
                    259: DEFUN ("set-window-point", Fset_window_point, Sset_window_point, 2, 2, 0,
                    260:   "Make point value in WINDOW be at position POS in WINDOW's buffer.")
                    261:   (window, pos)
                    262:      Lisp_Object window, pos;
                    263: {
                    264:   struct window *w = decode_window (window);
                    265:   CHECK_NUMBER_COERCE_MARKER (pos, 1);
                    266:   Fset_marker (w->pointm, pos, w->buffer);
                    267:   return pos;
                    268: }
                    269: 
                    270: DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0,
                    271:   "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
                    272: Optional third arg NOFORCE non-nil inhibits next redisplay\n\
                    273: from overriding motion of point in order to display at this exact start.")
                    274:   (window, pos, noforce)
                    275:      Lisp_Object window, pos, noforce;
                    276: {
                    277:   struct window *w = decode_window (window);
                    278:   CHECK_NUMBER_COERCE_MARKER (pos, 1);
                    279:   Fset_marker (w->start, pos, w->buffer);
                    280:   if (NULL (noforce))
                    281:     w->force_start = Qt;
                    282:   w->redo_mode_line = Qt;
                    283:   XFASTINT (w->last_modified) = 0;
                    284:   return pos;
                    285: }
                    286: 
                    287: DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
                    288:   "Remove WINDOW from the display.  Default is selected window.")
                    289:   (window)
                    290:      Lisp_Object window;
                    291: {
                    292:   int osize;
                    293:   Lisp_Object tem, parent;
                    294:   register struct window *p;
                    295: 
                    296:   if (NULL (window))
                    297:     window = selected_window;
                    298:   else
                    299:     CHECK_WINDOW (window, 0);
                    300: 
                    301:   p = XWINDOW (window);
                    302:   parent = p->parent;
                    303:   if (NULL (parent))
                    304:     error ("Attempt to delete minibuffer or sole ordinary window");
                    305: 
                    306:   windows_or_buffers_changed++;
                    307: 
                    308:   if (EQ (window, selected_window))
                    309:     Fselect_window (Fnext_window (window, Qnil));
                    310: 
                    311:   tem = p->buffer;
                    312:   /* tem is null for dummy parent windows
                    313:      (which have inferiors but not any contents themselves) */
                    314:   if (!NULL (tem))
                    315:     {
                    316:       unshow_buffer (p);
                    317:       unchain_marker (p->pointm);
                    318:       unchain_marker (p->start);
                    319:     }
                    320: 
                    321:   tem = p->next;
                    322:   if (!NULL (tem))
                    323:     XWINDOW (tem)->prev = p->prev;
                    324: 
                    325:   tem = p->prev;
                    326:   if (!NULL (tem))
                    327:     XWINDOW (tem)->next = p->next;
                    328: 
                    329:   if (EQ (window, XWINDOW (parent)->hchild))
                    330:     XWINDOW (parent)->hchild = p->next;
                    331:   if (EQ (window, XWINDOW (parent)->vchild))
                    332:     XWINDOW (parent)->vchild = p->next;
                    333: 
                    334:   /* Stretch the siblings to use all the available space */
                    335:   if (!NULL (XWINDOW (parent)->vchild))
                    336:     {
                    337:       /* It's a vertical combination */
                    338:       osize = XFASTINT (XWINDOW (parent)->height);
                    339:       XFASTINT (XWINDOW (parent)->height)
                    340:        -= XFASTINT (p->height);
                    341:       set_window_height (parent, osize, 1);
                    342:     }
                    343:   if (!NULL (XWINDOW (parent)->hchild))
                    344:     {
                    345:       /* It's a horizontal combination */
                    346:       osize = XFASTINT (XWINDOW (parent)->width);
                    347:       XFASTINT (XWINDOW (parent)->width)
                    348:        -= XFASTINT (p->width);
                    349:       set_window_width (parent, osize, 1);
                    350:     }
                    351: 
                    352:   /* If parent now has only one child,
                    353:      put the child into the parent's place.  */
                    354: 
                    355:   tem = XWINDOW (parent)->hchild;
                    356:   if (NULL (tem))
                    357:     tem = XWINDOW (parent)->vchild;
                    358:   if (NULL (XWINDOW (tem)->next))
                    359:     replace_window (parent, tem);
                    360:   return Qnil;
                    361: }
                    362: 
                    363: /* Put replacement into the window structure in place of old. */
                    364: 
                    365: replace_window (old, replacement)
                    366:      Lisp_Object old, replacement;
                    367: {
                    368:   Lisp_Object tem;
                    369:   register struct window *o = XWINDOW (old), *p = XWINDOW (replacement);
                    370: 
                    371:   p->left = o->left;
                    372:   p->top = o->top;
                    373:   p->width = o->width;
                    374:   p->height = o->height;
                    375: 
                    376:   p->next = tem = o->next;
                    377:   if (!NULL (tem))
                    378:     XWINDOW (tem)->prev = replacement;
                    379: 
                    380:   p->prev = tem = o->prev;
                    381:   if (!NULL (tem))
                    382:     XWINDOW (tem)->next = replacement;
                    383: 
                    384:   p->parent = tem = o->parent;
                    385:   if (!NULL (tem))
                    386:     {
                    387:       if (EQ (XWINDOW (tem)->vchild, old))
                    388:        XWINDOW (tem)->vchild = replacement;
                    389:       if (EQ (XWINDOW (tem)->hchild, old))
                    390:        XWINDOW (tem)->hchild = replacement;
                    391:     }
                    392: 
                    393: /*** Here, if replacement is a vertical combination
                    394: and so is its new parent, we should make replacement's
                    395: children be children of that parent instead.  ***/
                    396: }
                    397: 
                    398: DEFUN ("next-window", Fnext_window, Snext_window, 0, 2, 0,
                    399:   "Return next window after WINDOW in canonical ordering of windows.")
                    400:   (window, yesmini)
                    401:      Lisp_Object window, yesmini;
                    402: {
                    403:   Lisp_Object tem;
                    404:   if (NULL (window))
                    405:     window = selected_window;
                    406:   else
                    407:     CHECK_WINDOW (window, 0);
                    408:   do
                    409:     {
                    410:       while (tem = XWINDOW (window)->next, NULL (tem))
                    411:        if (tem = XWINDOW (window)->parent, !NULL (tem))
                    412:          window = tem;
                    413:         else  /* window must be minibuf_window now */
                    414:          {
                    415:            tem = XWINDOW (window)->prev;
                    416:            break;
                    417:          }
                    418:       window = tem;
                    419:       while (1)
                    420:        {
                    421:          if (!NULL (XWINDOW (window)->hchild))
                    422:            window = XWINDOW (window)->hchild;
                    423:          else if (!NULL (XWINDOW (window)->vchild))
                    424:            window = XWINDOW (window)->vchild;
                    425:          else break;
                    426:        }
                    427:     }
                    428:   while (EQ (window, minibuf_window) && NULL (yesmini) && !MinibufDepth);
                    429:   return window;
                    430: }
                    431: 
                    432: DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 1, 0,
                    433:   "Return previous window before WINDOW in canonical ordering of windows.")
                    434:   (window)
                    435:      Lisp_Object window;
                    436: {
                    437:   Lisp_Object tem;
                    438:   if (NULL (window))
                    439:     window = selected_window;
                    440:   else
                    441:     CHECK_WINDOW (window, 0);
                    442:   do  /* at least once, and until not the minibuffer */
                    443:     {
                    444:       while (tem = XWINDOW (window)->prev, NULL (tem))
                    445:        if (tem = XWINDOW (window)->parent, !NULL (tem))
                    446:          window = tem;
                    447:         else  /* window must be the root window now */
                    448:          {
                    449:            tem = minibuf_window;
                    450:            break;
                    451:          }
                    452:       window = tem;
                    453:       while (1)
                    454:        {
                    455:          if (!NULL (XWINDOW (window)->hchild))
                    456:            window = XWINDOW (window)->hchild;
                    457:          else if (!NULL (XWINDOW (window)->vchild))
                    458:            window = XWINDOW (window)->vchild;
                    459:          else break;
                    460:          while (tem = XWINDOW (window)->next, !NULL (tem))
                    461:            window = tem;
                    462:        }
                    463:     }
                    464:   while (EQ (window, minibuf_window) && !MinibufDepth);
                    465:   return window;
                    466: }
                    467: 
                    468: DEFUN ("other-window", Fother_window, Sother_window, 1, 1, "p",
                    469:   "Select the ARG'th different window.")
                    470:   (n)
                    471:      Lisp_Object n;
                    472: {
                    473:   int i;
                    474:   Lisp_Object w;
                    475: 
                    476:   CHECK_NUMBER (n, 0);
                    477:   w = selected_window;
                    478:   i = XINT (n);
                    479: 
                    480:   while (i > 0)
                    481:     {
                    482:       w = Fnext_window (w, Qnil);
                    483:       i--;
                    484:     }
                    485:   while (i < 0)
                    486:     {
                    487:       w = Fprevious_window (w);
                    488:       i++;
                    489:     }
                    490:   Fselect_window (w);
                    491:   return Qnil;
                    492: }
                    493: 
                    494: Lisp_Object
                    495: window_loop (type, obj)
                    496:      int type;
                    497:      Lisp_Object obj;
                    498: {
                    499:   Lisp_Object w, w1, ret_w, tem;
                    500:   register struct window *p, *q;
                    501: 
                    502:   w = minibuf_window;
                    503:   ret_w = Qnil;
                    504:   while (1)
                    505:     {
                    506:       p = XWINDOW (w);
                    507:       w1 = Fnext_window (w, Qt);
                    508:       if (!EQ (w, minibuf_window))
                    509:        switch (type)
                    510:          {
                    511:          case 1:
                    512:            if (XBUFFER (p->buffer) == XBUFFER (obj))
                    513:              return w;
                    514:            break;
                    515: 
                    516:          case 2:
                    517:            /* t as arg means consider only full-width windows */
                    518:            if (!NULL (obj) && XFASTINT (p->width) != screen_width)
                    519:              break;
                    520:            if (NULL (ret_w) ||
                    521:                XFASTINT (XWINDOW (ret_w)->use_time) > XFASTINT (p->use_time))
                    522:              ret_w = w;
                    523:            break;
                    524: 
                    525:          case 3:
                    526:            if (p != XWINDOW (obj))
                    527:              Fdelete_window (w);
                    528:            break;
                    529: 
                    530:          case 4:
                    531:            if (EQ (p->buffer, obj))
                    532:              {
                    533:                if (NULL (p->parent))
                    534:                  {
                    535:                    tem = Fother_buffer (obj);
                    536:                    if (NULL (tem))
                    537:                      tem = Fget_buffer_create (build_string ("*scratch*"));
                    538:                    Fshow_buffer (w, tem);
                    539:                    Fset_buffer (p->buffer);
                    540:                  }
                    541:                else
                    542:                  Fdelete_window (w);
                    543:              }
                    544:            break;
                    545: 
                    546:          case 5:
                    547:            q = XWINDOW (ret_w);
                    548:            if (NULL (ret_w) ||
                    549:                (XFASTINT (p->height) * XFASTINT (p->width))
                    550:                >
                    551:                (XFASTINT (q->height) * XFASTINT (q->width)))
                    552:              ret_w = w;
                    553:            break;
                    554: 
                    555:          case 6:
                    556:            if (EQ (p->buffer, obj))
                    557:              {
                    558:                tem = Fother_buffer (obj);
                    559:                if (NULL (tem))
                    560:                  tem = Fget_buffer_create (build_string ("*scratch*"));
                    561:                Fshow_buffer (w, tem);
                    562:                Fset_buffer (p->buffer);
                    563:              }
                    564:            break;
                    565:          }
                    566:       w = w1;
                    567:       if (EQ (w, minibuf_window))
                    568:        return ret_w;
                    569:     }
                    570: }     
                    571: 
                    572: DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 0, 0,
                    573:   "Return the window least recently selected or used for display.")
                    574:   ()
                    575: {
                    576:   Lisp_Object w;
                    577:   /* First try for a window that is full-width */
                    578:   w = window_loop (2, Qt);
                    579:   if (!NULL (w) && !EQ (w, selected_window))
                    580:     return w;
                    581:   /* If none of them, try the rest */
                    582:   return window_loop (2, Qnil);
                    583: }
                    584: 
                    585: DEFUN ("get-largest-window", Fget_largest_window, Sget_largest_window, 0, 0, 0,
                    586:   "Return the largest window in area.")
                    587:   ()
                    588: {
                    589:   return window_loop (5, Qnil);
                    590: }
                    591: 
                    592: DEFUN ("get-buffer-window", Fget_buffer_window, Sget_buffer_window, 1, 1, 0,
                    593:   "Return a window currently displaying BUFFER, or nil if none.")
                    594:   (buffer)
                    595:      Lisp_Object buffer;
                    596: {
                    597:   buffer = Fget_buffer (buffer);
                    598:   if (XTYPE (buffer) == Lisp_Buffer)
                    599:     return window_loop (1, buffer);
                    600:   else return Qnil;
                    601: }
                    602: 
                    603: DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows,
                    604:   0, 1, "",
                    605:   "Make WINDOW (or the selected window) fill the screen.")
                    606:   (w)
                    607:      Lisp_Object w;
                    608: {
                    609:   window_loop (3, !NULL (w) ? w : selected_window);
                    610:   return Qnil;
                    611: }
                    612: 
                    613: DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on,
                    614:   1, 1, "bDelete windows on (buffer): ",
                    615:   "Delete all windows showing BUFFER.")
                    616:   (buffer)
                    617:      Lisp_Object buffer;
                    618: {
                    619:   if (!NULL (buffer))
                    620:     {
                    621:       buffer = Fget_buffer (buffer);
                    622:       CHECK_BUFFER (buffer, 0);
                    623:       window_loop (4, buffer);
                    624:     }
                    625:   return Qnil;
                    626: }
                    627: 
                    628: DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows,
                    629:   Sreplace_buffer_in_windows,
                    630:   1, 1, "bReplace buffer in windows: ",
                    631:   "Replace BUFFER with some other buffer in all windows showing it.")
                    632:   (buffer)
                    633:      Lisp_Object buffer;
                    634: {
                    635:   if (!NULL (buffer))
                    636:     {
                    637:       buffer = Fget_buffer (buffer);
                    638:       CHECK_BUFFER (buffer, 0);
                    639:       window_loop (6, buffer);
                    640:     }
                    641:   return Qnil;
                    642: }
                    643: 
                    644: /* Set the height of WINDOW and all its inferiors.  */
                    645: /* Normally the window is deleted if it gets too small.
                    646:    nodelete nonzero means do not do this.
                    647:    (The caller should check later and do so if appropriate)  */
                    648: 
                    649: set_window_height (window, height, nodelete)
                    650:      Lisp_Object window;
                    651:      int height;
                    652:      int nodelete;
                    653: {
                    654:   register struct window *w = XWINDOW (window);
                    655:   register struct window *c;
                    656:   int oheight = XFASTINT (w->height);
                    657:   int top, pos, lastbot, opos, lastobot;
                    658:   Lisp_Object child;
                    659: 
                    660:   if (window_min_height < 2)
                    661:     window_min_height = 2;
                    662: 
                    663:   if (!nodelete &&
                    664:       height < (EQ(window, minibuf_window) ? 1 : window_min_height))
                    665:     {
                    666:       Fdelete_window (window);
                    667:       return;
                    668:     }
                    669: 
                    670:   XFASTINT (w->last_modified) = 0;
                    671:   windows_or_buffers_changed++;
                    672:   XFASTINT (w->height) = height;
                    673:   if (!NULL (w->hchild))
                    674:     {
                    675:       for (child = w->hchild; !NULL (child); child = XWINDOW (child)->next)
                    676:        {
                    677:          XWINDOW (child)->top = w->top;
                    678:          set_window_height (child, height, nodelete);
                    679:        }
                    680:     }
                    681:   else if (!NULL (w->vchild))
                    682:     {
                    683:       lastbot = top = XFASTINT (w->top);
                    684:       lastobot = 0;
                    685:       for (child = w->vchild; !NULL (child); child = c->next)
                    686:        {
                    687:          c = XWINDOW (child);
                    688: 
                    689:          opos = lastobot + XFASTINT (c->height);
                    690: 
                    691:          XFASTINT (c->top) = lastbot;
                    692: 
                    693:          pos = (((opos * height) << 1) + oheight) / (oheight << 1);
                    694: 
                    695:          /* Avoid confusion: inhibit deletion of child if becomes too small */
                    696:          set_window_height (child, pos + top - lastbot, 1);
                    697: 
                    698:          /* Now advance child to next window,
                    699:             and set lastbot if child was not just deleted.  */
                    700:          lastbot = pos + top, lastobot = opos;
                    701:        }
                    702:       /* Now delete any children that became too small.  */
                    703:       if (!nodelete)
                    704:        for (child = w->vchild; !NULL (child); child = XWINDOW (child)->next)
                    705:          {
                    706:            set_window_height (child, XINT (XWINDOW (child)->height), 0);
                    707:          }
                    708:     }
                    709: }
                    710: 
                    711: /* Recursively set width of WINDOW and its inferiors. */
                    712: 
                    713: set_window_width (window, width, nodelete)
                    714:      Lisp_Object window;
                    715:      int width;
                    716:      int nodelete;
                    717: {
                    718:   register struct window *w = XWINDOW (window);
                    719:   register struct window *c;
                    720:   int owidth = XFASTINT (w->width);
                    721:   int left, pos, lastright, opos, lastoright;
                    722:   Lisp_Object child;
                    723: 
                    724:   if (!nodelete && width < window_min_width)
                    725:     {
                    726:       Fdelete_window (window);
                    727:       return;
                    728:     }
                    729: 
                    730:   XFASTINT (w->last_modified) = 0;
                    731:   XFASTINT (w->width) = width;
                    732:   if (!NULL (w->vchild))
                    733:     {
                    734:       for (child = w->vchild; !NULL (child); child = XWINDOW (child)->next)
                    735:        {
                    736:          XWINDOW (child)->left = w->left;
                    737:          set_window_width (child, width, nodelete);
                    738:        }
                    739:     }
                    740:   else if (!NULL (w->hchild))
                    741:     {
                    742:       lastright = left = XFASTINT (w->left);
                    743:       lastoright = 0;
                    744:       for (child = w->hchild; !NULL (child); child = c->next)
                    745:        {
                    746:          c = XWINDOW (child);
                    747: 
                    748:          opos = lastoright + XFASTINT (c->width);
                    749: 
                    750:          XFASTINT (c->left) = lastright;
                    751: 
                    752:          pos = (((opos * width) << 1) + owidth) / (owidth << 1);
                    753: 
                    754:          /* Inhibit deletion for becoming too small */
                    755:          set_window_width (child, pos + left - lastright, 1);
                    756: 
                    757:          /* Now advance child to next window,
                    758:             and set lastright if child was not just deleted.  */
                    759:          lastright = pos + left, lastoright = opos;
                    760:        }
                    761:       /* Delete children that became too small */
                    762:       if (!nodelete)
                    763:        for (child = w->hchild; !NULL (child); child = XWINDOW (child)->next)
                    764:          {
                    765:            set_window_width (child, XINT (XWINDOW (child)->width), 0);
                    766:          }
                    767:     }
                    768: }
                    769: 
                    770: static int window_select_count;
                    771: 
                    772: DEFUN ("show-buffer", Fshow_buffer, Sshow_buffer, 2, 2, 0,
                    773:   "Make WINDOW display BUFFER as its contents.\n\
                    774: BUFFER can be a buffer or buffer name.")
                    775:   (window, buffer)
                    776:      Lisp_Object window, buffer;
                    777: {
                    778:   Lisp_Object tem;
                    779:   struct window *w = decode_window (window);
                    780: 
                    781:   buffer = Fget_buffer (buffer);
                    782:   CHECK_BUFFER (buffer, 1);
                    783: 
                    784:   if (NULL (XBUFFER (buffer)->name))
                    785:     error ("Attempt to display deleted buffer");
                    786: 
                    787:   tem = w->buffer;
                    788:   if (!NULL (tem))
                    789:     unshow_buffer (w);
                    790: 
                    791:   w->buffer = buffer;
                    792:   Fset_marker (w->pointm,
                    793:               make_number (XBUFFER (buffer) == bf_cur
                    794:                            ? point : XBUFFER (buffer)->text.pointloc),
                    795:               buffer);
                    796:   Fset_marker (w->start, make_number (XBUFFER (buffer)->last_window_start),
                    797:               buffer);
                    798:   XFASTINT (w->last_modified) = 0;
                    799:   windows_or_buffers_changed++;
                    800:   if (EQ (window, selected_window))
                    801:     Fset_buffer (buffer);
                    802: 
                    803:   return Qnil;
                    804: }
                    805: 
                    806: /* Record info on buffer window w is displaying
                    807:  when it is about to cease to display that buffer.  */
                    808: 
                    809: unshow_buffer (w)
                    810:      struct window *w;
                    811: {
                    812:   Lisp_Object buf;
                    813:   buf = w->buffer;
                    814: 
                    815:   if (XBUFFER (buf) != XMARKER (w->pointm)->buffer)
                    816:     abort ();
                    817: 
                    818:   if (w != XWINDOW (selected_window)
                    819:       && EQ (buf, XWINDOW (selected_window)->buffer))
                    820:     return;
                    821: 
                    822:   if (XBUFFER (buf) == bf_cur)
                    823:     {
                    824:       if (w != XWINDOW (selected_window))
                    825:        point = marker_position (w->pointm);
                    826:     }
                    827:   else
                    828:     XBUFFER (buf)->text.pointloc = 
                    829:       marker_position (w->pointm);
                    830:   XBUFFER (buf)->last_window_start = 
                    831:     marker_position (w->start);
                    832: }
                    833: 
                    834: DEFUN ("select-window", Fselect_window, Sselect_window, 1, 1, 0,
                    835:   "Select WINDOW.  Most editing will apply to WINDOW's buffer.\n\
                    836: The main editor command loop selects the buffer of the selected window\n\
                    837: before each command.")
                    838:   (window)
                    839:      Lisp_Object window;
                    840: {
                    841:   register struct window *w = XWINDOW (window);
                    842:   register struct window *ow = XWINDOW (selected_window);
                    843: 
                    844:   CHECK_WINDOW (window, 0);
                    845: 
                    846:   if (NULL (w->buffer))
                    847:     error ("Trying to select window with no buffer");
                    848: 
                    849:   XFASTINT (w->use_time) = ++window_select_count;
                    850:   if (EQ (window, selected_window))
                    851:     return window;
                    852: 
                    853:   if (bf_cur == XBUFFER (ow->buffer))
                    854:     Fset_marker (ow->pointm, make_number (point), ow->buffer);
                    855: 
                    856:   selected_window = window;
                    857: 
                    858:   record_buffer (w->buffer);
                    859:   Fset_buffer (w->buffer);
                    860:   if (bf_cur == XBUFFER (ow->buffer))
                    861:     {
                    862:       /* If the new and old windows show the same buffer,
                    863:         Fset_buffer did nothing.  So we must switch to
                    864:         the new buffer's value of point.  */
                    865:       SetPoint (marker_position (w->pointm));
                    866:       if (point < FirstCharacter)
                    867:        point = FirstCharacter;
                    868:       if (point > NumCharacters + 1)
                    869:        point = NumCharacters + 1;
                    870:     }
                    871: 
                    872:   windows_or_buffers_changed++;
                    873: 
                    874:   return window;
                    875: }
                    876: 
                    877: DEFUN ("display-buffer", Fdisplay_buffer, Sdisplay_buffer, 1, 2, 0,
                    878:   "Make BUFFER appear in some window but don't select it.\n\
                    879: BUFFER can be a buffer or a buffer name.\n\
                    880: If BUFFER is shown already in some window, just uses that one,\n\
                    881: unless the window is the selected window and NOTTHISWINDOW is non-nil.\n\
                    882: Returns the window displaying BUFFER.")
                    883:   (buffer, notthiswindow)
                    884:      Lisp_Object buffer, notthiswindow;
                    885: {
                    886:   Lisp_Object window;
                    887:   buffer = Fget_buffer (buffer);
                    888:   CHECK_BUFFER (buffer, 0);
                    889: 
                    890:   if (NULL (notthiswindow)
                    891:       && XBUFFER (XWINDOW (selected_window)->buffer) == XBUFFER (buffer))
                    892:     return selected_window;
                    893: 
                    894:   window = Fget_buffer_window (buffer);
                    895:   if (!NULL (window)
                    896:       && (NULL (notthiswindow) || !EQ (window, selected_window)))
                    897:     return window;
                    898: 
                    899:   if (pop_up_windows)
                    900:     {
                    901:       /* Don't try to create a window if would get an error */
                    902:       if (window_min_height < 2)
                    903:        window_min_height = 2;
                    904:       if (split_height_threshold < window_min_height << 1)
                    905:        split_height_threshold = window_min_height << 1;
                    906: 
                    907:       window = Fget_largest_window ();
                    908:       if (window_height (window) >= split_height_threshold
                    909:          &&
                    910:          XFASTINT (XWINDOW (window)->width) != screen_width)
                    911:        window = Fsplit_window (window, Qnil, Qnil);
                    912:       else
                    913:        {
                    914:          window = Fget_lru_window ();
                    915:          if ((EQ (window, selected_window)
                    916:               || (EQ (selected_window, minibuf_window)
                    917:                   && EQ (window, XWINDOW (minibuf_window)->prev)))
                    918:              && window_height (window) >= window_min_height << 1)
                    919:            window = Fsplit_window (window, Qnil, Qnil);
                    920:        }
                    921:     }
                    922:   else
                    923:     window = Fget_lru_window ();
                    924: 
                    925:   Fshow_buffer (window, buffer);
                    926:   return window;
                    927: }
                    928: 
                    929: temp_output_buffer_show (buf)
                    930:      Lisp_Object buf;
                    931: {
                    932:   struct buffer *old = bf_cur;
                    933:   Lisp_Object window;
                    934: 
                    935:   Fset_buffer (buf);
                    936:   XBUFFER (buf)->save_modified = bf_modified;
                    937:   SetPoint (1);
                    938:   bf_head_clip = 1;
                    939:   bf_tail_clip = 0;
                    940:   clip_changed = 1;
                    941:   SetBfp (old);
                    942: 
                    943:   window = Fdisplay_buffer (buf, Qnil);
                    944:   XFASTINT (XWINDOW (window)->hscroll) = 0;
                    945:   Fset_marker (XWINDOW (window)->start, make_number (1), buf);
                    946:   Fset_marker (XWINDOW (window)->pointm, make_number (1), buf);
                    947: }
                    948: 
                    949: make_dummy_parent (window)
                    950:      Lisp_Object window;
                    951: {
                    952:   Lisp_Object old, new;
                    953:   register struct window *o, *p;
                    954:   old = window;
                    955:   XSETTYPE (old, Lisp_Vector);
                    956:   new = Fcopy_sequence (old);
                    957:   XSETTYPE (new, Lisp_Window);
                    958: 
                    959:   o = XWINDOW (old);
                    960:   p = XWINDOW (new);
                    961:   XFASTINT (p->sequence_number) = ++sequence_number;
                    962: 
                    963:   /* Put new into window structure in place of window */
                    964:   replace_window (window, new);
                    965: 
                    966:   o->next = Qnil;
                    967:   o->prev = Qnil;
                    968:   o->vchild = Qnil;
                    969:   o->hchild = Qnil;
                    970:   o->parent = new;
                    971: 
                    972:   p->start = Qnil;
                    973:   p->pointm = Qnil;
                    974:   p->buffer = Qnil;
                    975: }
                    976: 
                    977: DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "",
                    978:   "Split WINDOW, putting SIZE lines in the first of the pair.\n\
                    979: WINDOW defaults to selected one and SIZE to half its size.\n\
                    980: If optional third arg HOR-FLAG is non-nil, split side by side\n\
                    981: and put SIZE columns in the first of the pair.")
                    982:   (window, chsize, horflag)
                    983:      Lisp_Object window, chsize, horflag;
                    984: {
                    985:   Lisp_Object new;
                    986:   register struct window *o, *p;
                    987:   int size;
                    988: 
                    989:   if (NULL (window))
                    990:     window = selected_window;
                    991:   else
                    992:     CHECK_WINDOW (window, 0);
                    993: 
                    994:   o = XWINDOW (window);
                    995: 
                    996:   if (NULL (chsize))
                    997:     {
                    998:       if (!NULL (horflag))
                    999:        size = XFASTINT (o->width) >> 1;
                   1000:       else
                   1001:        size = XFASTINT (o->height) >> 1;
                   1002:     }
                   1003:   else
                   1004:     {
                   1005:       CHECK_NUMBER (chsize, 1);
                   1006:       size = XINT (chsize);
                   1007:     }
                   1008: 
                   1009:   if (EQ (window, minibuf_window))
                   1010:     error ("Attempt to split minibuffer window");
                   1011: 
                   1012:   if (NULL (horflag))
                   1013:     {
                   1014:       if (window_min_height < 2)
                   1015:        window_min_height = 2;
                   1016: 
                   1017:       if (size < window_min_height ||
                   1018:          size + window_min_height > XFASTINT (o->height))
                   1019:        args_out_of_range_3 (window, chsize, horflag);
                   1020:       if (NULL (o->parent) ||
                   1021:          NULL (XWINDOW (o->parent)->vchild))
                   1022:        {
                   1023:          make_dummy_parent (window);
                   1024:          new = o->parent;
                   1025:          XWINDOW (new)->vchild = window;
                   1026:        }
                   1027:     }
                   1028:   else
                   1029:     {
                   1030:       if (size < window_min_width ||
                   1031:          size + window_min_width > XFASTINT (o->width))
                   1032:        args_out_of_range_3 (window, chsize, horflag);
                   1033:       if (NULL (o->parent) ||
                   1034:          NULL (XWINDOW (o->parent)->hchild))
                   1035:        {
                   1036:          make_dummy_parent (window);
                   1037:          new = o->parent;
                   1038:          XWINDOW (new)->hchild = window;
                   1039:        }
                   1040:     }
                   1041: 
                   1042:   /* Now we know that window's parent is a vertical combination
                   1043:      if we are dividing vertically, or a horizontal combination
                   1044:      if we are making side-by-side windows */
                   1045: 
                   1046:   windows_or_buffers_changed++;
                   1047:   new = make_window ();
                   1048:   p = XWINDOW (new);
                   1049: 
                   1050:   p->next = o->next;
                   1051:   if (!NULL (p->next))
                   1052:     XWINDOW (p->next)->prev = new;
                   1053:   p->prev = window;
                   1054:   o->next = new;
                   1055:   p->parent = o->parent;
                   1056: 
                   1057:   Fshow_buffer (new, o->buffer);
                   1058: 
                   1059:   /* Apportion the available screen space among the two new windows */
                   1060: 
                   1061:   if (!NULL (horflag))
                   1062:     {
                   1063:       p->height = o->height;
                   1064:       p->top = o->top;
                   1065:       XFASTINT (p->width) = XFASTINT (o->width) - size;
                   1066:       XFASTINT (o->width) = size;
                   1067:       XFASTINT (p->left) = XFASTINT (o->left) + size;
                   1068:     }
                   1069:   else
                   1070:     {
                   1071:       p->left = o->left;
                   1072:       p->width = o->width;
                   1073:       XFASTINT (p->height) = XFASTINT (o->height) - size;
                   1074:       XFASTINT (o->height) = size;
                   1075:       XFASTINT (p->top) = XFASTINT (o->top) + size;
                   1076:     }
                   1077: 
                   1078:   return new;
                   1079: }
                   1080: 
                   1081: DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p",
                   1082:   "Make current window ARG lines bigger.\n\
                   1083: From program, optional second arg non-nil means grow sideways ARG columns.")
                   1084:   (n, side)
                   1085:      Lisp_Object n, side;
                   1086: {
                   1087:   CHECK_NUMBER (n, 0);
                   1088:   change_window_height (XINT (n), !NULL (side));
                   1089:   return Qnil;
                   1090: }
                   1091: 
                   1092: DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
                   1093:   "Make current window ARG lines smaller.\n\
                   1094: From program, optional second arg non-nil means shrink sideways ARG columns.")
                   1095:   (n, side)
                   1096:      Lisp_Object n, side;
                   1097: {
                   1098:   CHECK_NUMBER (n, 0);
                   1099:   change_window_height (-XINT (n), !NULL (side));
                   1100:   return Qnil;
                   1101: }
                   1102: 
                   1103: int
                   1104: window_height (window)
                   1105:      Lisp_Object window;
                   1106: {
                   1107:   register struct window *p = XWINDOW (window);
                   1108:   return XFASTINT (p->height);
                   1109: }
                   1110: 
                   1111: int
                   1112: window_width (window)
                   1113:      Lisp_Object window;
                   1114: {
                   1115:   register struct window *p = XWINDOW (window);
                   1116:   return XFASTINT (p->width);
                   1117: }
                   1118: 
                   1119: #define MINSIZE(window) \
                   1120:   (widthflag ? window_min_width  \
                   1121:    : (EQ (window, minibuf_window) ? 1 : window_min_height))
                   1122: 
                   1123: #define CURBEG(w) \
                   1124:   *(widthflag ? (int *) &w->left : (int *) &w->top)
                   1125: 
                   1126: #define CURSIZE(w) \
                   1127:   *(widthflag ? (int *) &w->width : (int *) &w->height)
                   1128: 
                   1129: /* Unlike set_window_height, this function
                   1130:  also changes the heights of the siblings so as to
                   1131:  keep everything consistent. */
                   1132: 
                   1133: change_window_height (delta, widthflag)
                   1134:      int delta, widthflag;
                   1135: {
                   1136:   Lisp_Object window, parent, tem;
                   1137:   register struct window *p;
                   1138:   int *sizep;
                   1139:   int (*sizefun) () = widthflag ? window_width : window_height;
                   1140:   int (*setsizefun) () = widthflag ? set_window_width : set_window_height;
                   1141:   int opht, maxdelta;
                   1142: 
                   1143:   window = selected_window;
                   1144:   while (1)
                   1145:     {
                   1146:       p = XWINDOW (window);
                   1147:       parent = p->parent;
                   1148:       if (NULL (parent))
                   1149:        {
                   1150:          if (widthflag)
                   1151:            error ("No other window to side of this one");
                   1152:          break;
                   1153:        }
                   1154:       if (widthflag ? !NULL (XWINDOW (parent)->hchild)
                   1155:          : !NULL (XWINDOW (parent)->vchild))
                   1156:        break;
                   1157:       window = parent;
                   1158:     }
                   1159: 
                   1160:   sizep = &CURSIZE (p);
                   1161: 
                   1162:   if (*sizep + delta < MINSIZE (window))
                   1163:     {
                   1164:       Fdelete_window (window);
                   1165:       return;
                   1166:     }
                   1167: 
                   1168:   maxdelta = (!NULL (parent) ? (*sizefun) (parent) - *sizep
                   1169:              : (tem = (!NULL (p->next) ? p->next : p->prev),
                   1170:                 (*sizefun) (tem) - MINSIZE (tem)));
                   1171: 
                   1172:   if (delta > maxdelta)
                   1173:     /* This case traps trying to make the minibuffer
                   1174:        the full screen, or make the only window aside from the
                   1175:        minibuffer the full screen.  */
                   1176:     delta = maxdelta;
                   1177: 
                   1178:   if (!NULL (p->next) &&
                   1179:       (*sizefun) (p->next) - delta >= MINSIZE (p->next))
                   1180:     {
                   1181:       (*setsizefun) (p->next, (*sizefun) (p->next) - delta, 0);
                   1182:       (*setsizefun) (window, *sizep + delta, 0);
                   1183:       CURBEG (XWINDOW (p->next)) += delta;
                   1184:       /* This does not change size of p->next,
                   1185:         but it propagates the new top edge to its children */
                   1186:       (*setsizefun) (p->next, (*sizefun) (p->next), 0);
                   1187:     }
                   1188:   else if (!NULL (p->prev) &&
                   1189:           (*sizefun) (p->prev) - delta >= MINSIZE (p->prev))
                   1190:     {
                   1191:       (*setsizefun) (p->prev, (*sizefun) (p->prev) - delta, 0);
                   1192:       CURBEG (p) -= delta;
                   1193:       (*setsizefun) (window, *sizep + delta, 0);
                   1194:     }
                   1195:   else
                   1196:     {
                   1197:       opht = (*sizefun) (parent);
                   1198: 
                   1199:       delta = (int) ((float) (delta * opht)
                   1200:                     / (float) (opht - *sizep - delta));
                   1201:       /* Add delta lines or columns to this window, and to the parent,
                   1202:         keeping things consistent while not affecting siblings.  */
                   1203:       CURSIZE (XWINDOW (parent)) = opht + delta;
                   1204:       (*setsizefun) (window, *sizep + delta, 0);
                   1205:       /* Squeeze out delta lines or columns from our parent,
                   1206:         shriking this window and siblings proportionately.
                   1207:         This brings parent back to correct size.
                   1208:         Delta was calculated so this makes this window the desired size,
                   1209:         taking it all out of the siblings.  */
                   1210:       (*setsizefun) (parent, opht, 0);
                   1211:     }
                   1212: 
                   1213:   XFASTINT (p->last_modified) = 0;
                   1214: }
                   1215: 
                   1216: static
                   1217: window_scroll (window, n)
                   1218:      Lisp_Object window;
                   1219:      int n;
                   1220: {
                   1221:   register struct window *w = XWINDOW (window);
                   1222:   register int opoint = point;
                   1223:   register int ht, pos;
                   1224:   int lose;
                   1225:   Lisp_Object tem;
                   1226: 
                   1227:   ht = XFASTINT (w->height) - !EQ (window, minibuf_window);
                   1228: 
                   1229:   XFASTINT (tem) = point;
                   1230:   tem = Fpos_visible_in_window_p (tem, window);
                   1231: 
                   1232:   if (NULL (tem))
                   1233:     {
                   1234:       Fvertical_motion (make_number (- ht / 2));
                   1235:       XFASTINT (tem) = point;
                   1236:       Fset_marker (w->start, tem, w->buffer);
                   1237:       w->force_start = Qt;
                   1238:     }
                   1239: 
                   1240:   SetPoint (marker_position (w->start));
                   1241:   lose = n < 0 && point == FirstCharacter;
                   1242:   Fvertical_motion (make_number (n));
                   1243:   pos = point;
                   1244:   SetPoint (opoint);
                   1245: 
                   1246:   if (lose)
                   1247:     Fsignal (Qbeginning_of_buffer, Qnil);
                   1248: 
                   1249:   if (pos < NumCharacters + 1)
                   1250:     {
                   1251:       Fset_marker (w->start, make_number (pos), w->buffer);
                   1252:       w->redo_mode_line = Qt;
                   1253:       XFASTINT (w->last_modified) = 0;
                   1254:       if (pos > opoint)
                   1255:        SetPoint (pos);
                   1256:       if (n < 0)
                   1257:        {
                   1258:          SetPoint (pos);
                   1259:          tem = Fvertical_motion (make_number (ht));
                   1260:          if (point > opoint || XFASTINT (tem) < ht)
                   1261:            SetPoint (opoint);
                   1262:          else
                   1263:            Fvertical_motion (make_number (-1));
                   1264:        }
                   1265:     }
                   1266:   else
                   1267:     Fsignal (Qend_of_buffer, Qnil);
                   1268: }
                   1269: 
                   1270: scroll_command (n, direction)
                   1271:      Lisp_Object n;
                   1272:      int direction;
                   1273: {
                   1274:   register int defalt
                   1275:     = direction * (window_height (selected_window) - 1
                   1276:                   - next_screen_context_lines);
                   1277: 
                   1278:   if (NULL (n))
                   1279:     window_scroll (selected_window, defalt);
                   1280:   else if (EQ (n, Qminus))
                   1281:     window_scroll (selected_window, - defalt);
                   1282:   else
                   1283:     {
                   1284:       n = Fprefix_numeric_value (n);
                   1285:       window_scroll (selected_window, XINT (n) * direction);
                   1286:     }
                   1287: }
                   1288: 
                   1289: DEFUN ("scroll-up", Fscroll_up, Sscroll_up, 0, 1, "P",
                   1290:   "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
                   1291: When calling from a program, supply a number as argument or nil.")
                   1292:   (n)
                   1293:      Lisp_Object n;
                   1294: {
                   1295:   scroll_command (n, 1);
                   1296:   return Qnil;
                   1297: }
                   1298: 
                   1299: DEFUN ("scroll-down", Fscroll_down, Sscroll_down, 0, 1, "P",
                   1300:   "Scroll text of current window downward ARG lines; or near full screen if no ARG.\n\
                   1301: When calling from a program, supply a number as argument or nil.")
                   1302:   (n)
                   1303:      Lisp_Object n;
                   1304: {
                   1305:   scroll_command (n, -1);
                   1306:   return Qnil;
                   1307: }
                   1308: 
                   1309: DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 1, 1, "P",
                   1310:   "Scroll selected window display ARG columns left.\n\
                   1311: Default for ARG is window width minus 2.")
                   1312:   (arg)
                   1313:      Lisp_Object arg;
                   1314: {
                   1315:   if (NULL (arg))
                   1316:     XFASTINT (arg) = XFASTINT (XWINDOW (selected_window)->width) - 2;
                   1317:   else
                   1318:     arg = Fprefix_numeric_value (arg);
                   1319: 
                   1320:   return Fset_window_hscroll (selected_window,
                   1321:                              make_number (XINT (XWINDOW (selected_window)->hscroll)
                   1322:                                           + XINT (arg)));
                   1323: }
                   1324: 
                   1325: DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 1, 1, "P",
                   1326:   "Scroll selected window display ARG columns right.\n\
                   1327: Default for ARG is window width minus 2.")
                   1328:   (arg)
                   1329:      Lisp_Object arg;
                   1330: {
                   1331:   if (NULL (arg))
                   1332:     XFASTINT (arg) = XFASTINT (XWINDOW (selected_window)->width) - 2;
                   1333:   else
                   1334:     arg = Fprefix_numeric_value (arg);
                   1335: 
                   1336:   return Fset_window_hscroll (selected_window,
                   1337:                              make_number (XINT (XWINDOW (selected_window)->hscroll)
                   1338:                                           - XINT (arg)));
                   1339: }
                   1340: 
                   1341: DEFUN ("scroll-other-window", Fscroll_other_window, Sscroll_other_window, 0, 1, "P",
                   1342:   "Scroll text of next window upward ARG lines; or near full screen if no ARG.\n\
                   1343: The next window is the one below the current one; or the one at the top\n\
                   1344: if the current one is at the bottom.\n\
                   1345: When calling from a program, supply a number as argument or nil.")
                   1346:   (n)
                   1347:      Lisp_Object n;
                   1348: {
                   1349:   Lisp_Object window;
                   1350:   struct buffer *old = bf_cur;
                   1351:   register int ht;
                   1352:   register int opoint = point;
                   1353: 
                   1354:   window = Fnext_window (selected_window, Qnil);
                   1355:   ht = window_height (window) - 1;
                   1356: 
                   1357:   if (EQ (window, selected_window))
                   1358:     error ("There is no other window");
                   1359: 
                   1360:   Fset_buffer (XWINDOW (window)->buffer);
                   1361:   SetPoint (marker_position (XWINDOW (window)->pointm));
                   1362: 
                   1363:   if (NULL (n))
                   1364:     window_scroll (window, ht - next_screen_context_lines);
                   1365:   else if (EQ (n, Qminus))
                   1366:     window_scroll (window, next_screen_context_lines - ht);
                   1367:   else
                   1368:     {
                   1369:       if (XTYPE (n) == Lisp_Cons)
                   1370:        n = Fcar (n);
                   1371:       CHECK_NUMBER (n, 0);
                   1372:       window_scroll (window, XINT (n));
                   1373:     }
                   1374: 
                   1375:   Fset_marker (XWINDOW (window)->pointm, make_number (point), Qnil);
                   1376:   SetBfp (old);
                   1377:   SetPoint (opoint);
                   1378:   return Qnil;
                   1379: }
                   1380: 
                   1381: DEFUN ("recenter", Frecenter, Srecenter, 0, 1, "P",
                   1382:   "Center point in window and redisplay screen.  With ARG, put point on line ARG.\n\
                   1383: The desired position of point is always relative to the current window.\n\
                   1384: If there is no ARG (i.e., it is nil) then the entire screen is redisplayed.")
                   1385:   (n)
                   1386:      Lisp_Object n;
                   1387: {
                   1388:   int ht = window_height (selected_window)
                   1389:            - !EQ (selected_window, minibuf_window);
                   1390:   struct window *w = XWINDOW (selected_window);
                   1391:   register int opoint = point;
                   1392: 
                   1393:   if (NULL (n))
                   1394:     {
                   1395:       extern int screen_garbaged;
                   1396:       screen_garbaged++;
                   1397:       XFASTINT (n) = ht / 2;
                   1398:     }
                   1399:   else
                   1400:     {
                   1401:       n = Fprefix_numeric_value (n);
                   1402:       CHECK_NUMBER (n, 0);
                   1403:     }
                   1404: 
                   1405:   if (XINT (n) < 0)
                   1406:     XSETINT (n, XINT (n) + ht);
                   1407: 
                   1408:   XSETINT (n, - XINT (n));
                   1409: 
                   1410:   Fvertical_motion (n);
                   1411:   Fset_marker (w->start, make_number (point), w->buffer);
                   1412: 
                   1413:   SetPoint (opoint);
                   1414:   w->force_start = Qt;
                   1415: 
                   1416:   return Qnil;
                   1417: }
                   1418: 
                   1419: DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line,
                   1420:   1, 1, "P",
                   1421:   "Position point relative to window.\n\
                   1422: With no argument, position at text at center of window.\n\
                   1423: An argument specifies screen line; zero means top of window,\n\
                   1424: negative means relative to bottom of window.")
                   1425:   (arg)
                   1426:      Lisp_Object arg;
                   1427: {
                   1428:   register struct window *w = XWINDOW (selected_window);
                   1429:   int height = XFASTINT (w->height);
                   1430:   register int start;
                   1431: 
                   1432:   if (!EQ (selected_window, minibuf_window)) height--;
                   1433: 
                   1434:   if (NULL (arg))
                   1435:     XFASTINT (arg) = height / 2;
                   1436:   else
                   1437:     {
                   1438:       arg = Fprefix_numeric_value (arg);
                   1439:       if (XINT (arg) < 0)
                   1440:        XSETINT (arg, XINT (arg) + height);
                   1441:     }
                   1442: 
                   1443:   start = marker_position (w->start);
                   1444:   if (start < FirstCharacter || start > NumCharacters + 1)
                   1445:     {
                   1446:       Fvertical_motion (make_number (- height / 2));
                   1447:       Fset_marker (w->start, make_number (point), w->buffer);
                   1448:       w->force_start = Qt;
                   1449:       start = point;
                   1450:     }
                   1451:   else
                   1452:     SetPoint (start);
                   1453: 
                   1454:   return Fvertical_motion (arg);
                   1455: }
                   1456: 
                   1457: struct saved_window
                   1458:   {
                   1459:     Lisp_Object window;
                   1460:     Lisp_Object buffer, start, pointm, mark;
                   1461:     Lisp_Object left, top, width, height, hscroll;
                   1462:     Lisp_Object parent, prev;
                   1463:   };
                   1464: 
                   1465: struct save_window_data
                   1466:   {
                   1467:     long size;
                   1468:     struct Lisp_Vector *unused;
                   1469:     Lisp_Object nsaved;
                   1470:     Lisp_Object current_window;
                   1471:     Lisp_Object current_buffer;
                   1472:     struct saved_window info[1];
                   1473:   };
                   1474: 
                   1475: Lisp_Object
                   1476: save_window_restore (arg)
                   1477:      Lisp_Object arg;
                   1478: {
                   1479:   register struct window *w;
                   1480:   register struct save_window_data *data = (struct save_window_data *) XINTPTR (arg);
                   1481:   register struct saved_window *p = data->info;
                   1482:   Lisp_Object tem;
                   1483:   register int k;
                   1484: 
                   1485:   windows_or_buffers_changed++;
                   1486:   for (k = 0; k < XFASTINT (data->nsaved); k++, p++)
                   1487:     {
                   1488:       w = XWINDOW (p->window);
                   1489:       w->next = Qnil;
                   1490: 
                   1491:       if (!NULL (p->parent))
                   1492:        w->parent = data->info[XFASTINT (p->parent)].window;
                   1493:       else
                   1494:        w->parent = Qnil;
                   1495: 
                   1496:       if (!NULL (p->prev))
                   1497:        {
                   1498:          w->prev = data->info[XFASTINT (p->prev)].window;
                   1499:          XWINDOW (w->prev)->next = p->window;
                   1500:        }
                   1501:       else
                   1502:        {
                   1503:          w->prev = Qnil;
                   1504:          if (!NULL (w->parent))
                   1505:            {
                   1506:              if (EQ (p->width, XWINDOW (w->parent)->width))
                   1507:                {
                   1508:                  XWINDOW (w->parent)->vchild = p->window;
                   1509:                  XWINDOW (w->parent)->hchild = Qnil;
                   1510:                }
                   1511:              else
                   1512:                {
                   1513:                  XWINDOW (w->parent)->hchild = p->window;
                   1514:                  XWINDOW (w->parent)->vchild = Qnil;
                   1515:                }
                   1516:            }
                   1517:        }
                   1518:       w->left = p->left;
                   1519:       w->top = p->top;
                   1520:       w->width = p->width;
                   1521:       w->height = p->height;
                   1522:       w->hscroll = p->hscroll;
                   1523:       XFASTINT (w->last_modified) = 0;
                   1524: 
                   1525:       /* Reinstall the saved buffer and pointers into it.  */
                   1526:       if (NULL (p->buffer))
                   1527:        w->buffer = p->buffer;
                   1528:       else
                   1529:        {
                   1530:          if (!NULL (XBUFFER (p->buffer)->name))
                   1531:            /* If saved buffer is alive, install it.  */
                   1532:            {
                   1533:              w->buffer = p->buffer;
                   1534:              Fset_marker (w->start, Fmarker_position (p->start), w->buffer);
                   1535:              Fset_marker (w->pointm, Fmarker_position (p->pointm), w->buffer);
                   1536:            }
                   1537:          else if (NULL (XBUFFER (w->buffer)->name))
                   1538:            /* Else if window's old buffer is dead too, get a live one.  */
                   1539:            {
                   1540:              w->buffer = Fcdr (Fcar (Vbuffer_alist));
                   1541:              /* Set window markers at start of buffer.
                   1542:                 Rely on Fset_marker to put them within the restriction.  */
                   1543:              Fset_marker (w->start, make_number (0), w->buffer);
                   1544:              Fset_marker (w->pointm, make_number (0), w->buffer);
                   1545:            }
                   1546:          unchain_marker (p->start);
                   1547:          unchain_marker (p->pointm);
                   1548: 
                   1549:          tem = p->mark;
                   1550:          if (NULL (tem))
                   1551:            XBUFFER (w->buffer)->mark = Qnil;
                   1552:          else
                   1553:            {
                   1554:              if (NULL (XBUFFER (w->buffer)->mark))
                   1555:                XBUFFER (w->buffer)->mark = Fmake_marker ();
                   1556: 
                   1557:              Fset_marker (XBUFFER (w->buffer)->mark,
                   1558:                           Fmarker_position (p->mark), w->buffer);
                   1559:              unchain_marker (p->mark);
                   1560:            }
                   1561:        }
                   1562:     }
                   1563: 
                   1564:   Fselect_window (data->current_window);
                   1565:   Fset_buffer (data->current_buffer);
                   1566: 
                   1567:   free (data);
                   1568:   return Qnil;
                   1569: }
                   1570: 
                   1571: count_windows (window)
                   1572:      struct window *window;
                   1573: {
                   1574:   int count = 1;
                   1575:   if (!NULL (window->next))
                   1576:     count += count_windows (XWINDOW (window->next));
                   1577:   if (!NULL (window->vchild))
                   1578:     count += count_windows (XWINDOW (window->vchild));
                   1579:   if (!NULL (window->hchild))
                   1580:     count += count_windows (XWINDOW (window->hchild));
                   1581:   return count;
                   1582: }
                   1583: 
                   1584: #define SAVE_DATA_SIZE(n_windows) \
                   1585:   ((n_windows - 1) * sizeof (struct saved_window) \
                   1586:    + sizeof (struct save_window_data))
                   1587: 
                   1588: Lisp_Object
                   1589: save_window_save ()
                   1590: {
                   1591:   Lisp_Object root;
                   1592:   int n_windows;
                   1593:   struct save_window_data *data;
                   1594:   Lisp_Object tem;
                   1595:   int size;
                   1596: 
                   1597:   root = XWINDOW (minibuf_window)->prev;
                   1598:   n_windows = count_windows (XWINDOW (root));
                   1599: 
                   1600:   size = SAVE_DATA_SIZE (n_windows);
                   1601:   data = (struct save_window_data *) xmalloc (size);
                   1602: 
                   1603:   data->size = (size - sizeof (long) - sizeof (struct Lisp_Vector *))
                   1604:     / sizeof (Lisp_Object);
                   1605:   XFASTINT (data->nsaved) = n_windows;
                   1606:   data->current_window = selected_window;
                   1607:   XSET (data->current_buffer, Lisp_Buffer, bf_cur);
                   1608: 
                   1609:   save_window_save_1 (root, data, 0);
                   1610: 
                   1611:   XSET (tem, Lisp_Temp_Vector, data);
                   1612:   return tem;
                   1613: }
                   1614: 
                   1615: save_window_save_1 (window, data, i)
                   1616:      Lisp_Object window;
                   1617:      struct save_window_data *data;
                   1618:      int i;
                   1619: {
                   1620:   struct saved_window *p;
                   1621:   struct window *w;
                   1622:   Lisp_Object tem;
                   1623: 
                   1624:   for (;!NULL (window); window = w->next)
                   1625:     {
                   1626:       p = &data->info[i];
                   1627:       w = XWINDOW (window);
                   1628: 
                   1629:       XFASTINT (w->temslot) = i++;
                   1630:       p->window = window;
                   1631:       p->buffer = w->buffer;
                   1632:       p->left = w->left;
                   1633:       p->top = w->top;
                   1634:       p->width = w->width;
                   1635:       p->height = w->height;
                   1636:       p->hscroll = w->hscroll;
                   1637:       if (!NULL (w->buffer))
                   1638:        {
                   1639:          if (EQ (window, selected_window)
                   1640:              && XBUFFER (w->buffer) == bf_cur)
                   1641:            p->pointm = Fpoint_marker ();
                   1642:          else
                   1643:            p->pointm = Fcopy_marker (w->pointm);
                   1644: 
                   1645:          p->start = Fcopy_marker (w->start);
                   1646: 
                   1647:          tem = XBUFFER (w->buffer)->mark;
                   1648:          if (!NULL (tem))
                   1649:            p->mark = Fcopy_marker (tem);
                   1650:          else
                   1651:            p->mark = Qnil;
                   1652:        }
                   1653:       else
                   1654:        {
                   1655:          p->pointm = Qnil;
                   1656:          p->start = Qnil;
                   1657:          p->mark = Qnil;
                   1658:        }
                   1659: 
                   1660:       if (NULL (w->parent))
                   1661:        p->parent = Qnil;
                   1662:       else
                   1663:        p->parent = XWINDOW (w->parent)->temslot;
                   1664: 
                   1665:       if (NULL (w->prev))
                   1666:        p->prev = Qnil;
                   1667:       else
                   1668:        p->prev = XWINDOW (w->prev)->temslot;
                   1669: 
                   1670:       if (!NULL (w->vchild))
                   1671:        i = save_window_save_1 (w->vchild, data, i);
                   1672:       if (!NULL (w->hchild))
                   1673:        i = save_window_save_1 (w->hchild, data, i);
                   1674:     }
                   1675: 
                   1676:   return i;
                   1677: }
                   1678: 
                   1679: DEFUN ("save-window-excursion", Fsave_window_excursion, Ssave_window_excursion,
                   1680:   0, UNEVALLED, 0,
                   1681:   "Execute body, preserving window sizes and contents.\n\
                   1682: Restores which buffer appears in which window, where display starts,\n\
                   1683: as well as the current buffer.\n\
                   1684: Does not restore the value of point in that buffer.")
                   1685:   (args)
                   1686:      Lisp_Object args;
                   1687: {
                   1688:   Lisp_Object tem, val;
                   1689:   struct gcpro gcpro1;
                   1690:   int count = specpdl_ptr - specpdl;
                   1691: 
                   1692:   tem = save_window_save ();
                   1693: 
                   1694:   GCPRO1 (*XOBJFWD (tem));
                   1695:   gcpro1.nvars
                   1696:     = SAVE_DATA_SIZE (XFASTINT (((struct save_window_data *) XINTPTR (tem))
                   1697:                                ->nsaved))
                   1698:       / 4;
                   1699: 
                   1700:   record_unwind_protect (save_window_restore, tem);
                   1701:   val = Fprogn (args);
                   1702:   UNGCPRO;
                   1703:   unbind_to (count);
                   1704:   return val;
                   1705: }
                   1706: 
                   1707: init_window_once ()
                   1708: {
                   1709:   extern Lisp_Object get_minibuffer ();
                   1710:   Lisp_Object root_window;
                   1711: 
                   1712:   root_window = make_window ();
                   1713:   minibuf_window = make_window ();
                   1714: 
                   1715:   XWINDOW (root_window)->next = minibuf_window;
                   1716:   XWINDOW (minibuf_window)->prev = root_window;
                   1717: 
                   1718:   /* These values 9 and 10 are arbitrary,
                   1719:      just so that there is "something there."
                   1720:      Correct values are put in in init_xdisp */
                   1721: 
                   1722:   XFASTINT (XWINDOW (root_window)->width) = 10;
                   1723:   XFASTINT (XWINDOW (minibuf_window)->width) = 10;
                   1724: 
                   1725:   XFASTINT (XWINDOW (root_window)->height) = 9;
                   1726:   XFASTINT (XWINDOW (minibuf_window)->top) = 9;
                   1727:   XFASTINT (XWINDOW (minibuf_window)->height) = 1;
                   1728: 
                   1729:   Fshow_buffer (root_window, Fcurrent_buffer ());
                   1730:   Fshow_buffer (minibuf_window, get_minibuffer (0));
                   1731: 
                   1732:   selected_window = root_window;
                   1733: }
                   1734: 
                   1735: syms_of_window ()
                   1736: {
                   1737:   Qwindowp = intern ("windowp");
                   1738:   staticpro (&Qwindowp);
                   1739: 
                   1740:   /* Make sure all windows get marked */
                   1741:   staticpro (&minibuf_window);
                   1742: 
                   1743:   DefBoolVar ("pop-up-windows", &pop_up_windows,
                   1744:     "*Non-nil means display-buffer should make new windows.");
                   1745:   pop_up_windows = 1;
                   1746: 
                   1747:   DefIntVar ("next-screen-context-lines", &next_screen_context_lines,
                   1748:     "*Number of lines of continuity when scrolling by screenfuls.");
                   1749:   next_screen_context_lines = 2;
                   1750: 
                   1751:   DefIntVar ("split-height-threshold", &split_height_threshold,
                   1752:     "*display-buffer would prefer to split the largest window if this large.\n\
                   1753: If there is only one window, it is split regardless of this value.");
                   1754:   split_height_threshold = 500;
                   1755: 
                   1756:   DefIntVar ("window-min-height", &window_min_height,
                   1757:     "*Delete any window less than this tall (including its mode line).");
                   1758:   window_min_height = 4;
                   1759: 
                   1760:   DefIntVar ("window-min-width", &window_min_width,
                   1761:     "*Delete any window less than this wide.");
                   1762:   window_min_width = 10;
                   1763: 
                   1764:   defsubr (&Sselected_window);
                   1765:   defsubr (&Swindowp);
                   1766:   defsubr (&Spos_visible_in_window_p);
                   1767:   defsubr (&Swindow_buffer);
                   1768:   defsubr (&Swindow_height);
                   1769:   defsubr (&Swindow_width);
                   1770:   defsubr (&Swindow_hscroll);
                   1771:   defsubr (&Sset_window_hscroll);
                   1772:   defsubr (&Swindow_edges);
                   1773:   defsubr (&Swindow_point);
                   1774:   defalias (&Swindow_point, "window-dot");
                   1775:   defsubr (&Swindow_start);
                   1776:   defsubr (&Sset_window_point);
                   1777:   defalias (&Sset_window_point, "set-window-dot"); 
                   1778:   defsubr (&Sset_window_start);
                   1779:   defsubr (&Snext_window);
                   1780:   defsubr (&Sprevious_window);
                   1781:   defsubr (&Sother_window);
                   1782:   defsubr (&Sget_lru_window);
                   1783:   defsubr (&Sget_largest_window);
                   1784:   defsubr (&Sget_buffer_window);
                   1785:   defsubr (&Sdelete_other_windows);
                   1786:   defsubr (&Sdelete_windows_on);
                   1787:   defsubr (&Sreplace_buffer_in_windows);
                   1788:   defsubr (&Sdelete_window);
                   1789:   defsubr (&Sshow_buffer);
                   1790:   defsubr (&Sselect_window);
                   1791:   defsubr (&Sdisplay_buffer);
                   1792:   defsubr (&Ssplit_window);
                   1793:   defsubr (&Senlarge_window);
                   1794:   defsubr (&Sshrink_window);
                   1795:   defsubr (&Sscroll_up);
                   1796:   defsubr (&Sscroll_down);
                   1797:   defsubr (&Sscroll_left);
                   1798:   defsubr (&Sscroll_right);
                   1799:   defsubr (&Sscroll_other_window);
                   1800:   defsubr (&Srecenter);
                   1801:   defsubr (&Smove_to_window_line);
                   1802:   defsubr (&Ssave_window_excursion);
                   1803: }
                   1804: 
                   1805: keys_of_window ()
                   1806: {
                   1807:   defkey (CtlXmap, '1', "delete-other-windows");
                   1808:   defkey (CtlXmap, '2', "split-window");
                   1809:   defkey (CtlXmap, '0', "delete-window");
                   1810:   defkey (CtlXmap, 'o', "other-window");
                   1811:   defkey (CtlXmap, '^', "enlarge-window");
                   1812:   defkey (CtlXmap, '<', "scroll-left");
                   1813:   defkey (CtlXmap, '>', "scroll-right");
                   1814: 
                   1815:   defkey (GlobalMap, Ctl ('V'), "scroll-up");
                   1816:   defkey (ESCmap, Ctl ('V'), "scroll-other-window");
                   1817:   defkey (ESCmap, 'v', "scroll-down");
                   1818: 
                   1819:   defkey (GlobalMap, Ctl('L'), "recenter");
                   1820:   defkey (ESCmap, 'r', "move-to-window-line");
                   1821: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.