home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume3 / mg2a / part04 < prev    next >
Encoding:
Text File  |  1989-02-03  |  58.7 KB  |  2,446 lines

  1. Path: xanth!mcnc!uvaarpa!umd5!ames!necntc!ncoast!allbery
  2. From: BLARSON@ECLA.USC.EDU (Bob Larson)
  3. Newsgroups: comp.sources.misc
  4. Subject: v03i028: mg 2a part 4 of 15
  5. Message-ID: <12401299447.47.BLARSON@ECLA.USC.EDU>
  6. Date: 26 May 88 04:52:27 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: BLARSON@ECLA.USC.EDU (Bob Larson)
  9. Lines: 2434
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. comp.sources.misc: Volume 3, Issue 28
  13. Submitted-By: "Bob Larson" <BLARSON@ECLA.USC.EDU>
  14. Archive-Name: mg2a/Part4
  15.  
  16. #    This is a shell archive.
  17. #    Remove everything above and including the cut line.
  18. #    Then run the rest of the file through sh.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar:    Shell Archiver
  22. #    Run the following text with /bin/sh to create:
  23. #    kbd.c
  24. #    kbd.h
  25. #    key.h
  26. #    keymap.c
  27. #    line.c
  28. #    macro.h
  29. #    main.c
  30. # This archive created: Tue May 17 18:06:01 1988
  31. # By:    blarson
  32. cat << \SHAR_EOF > kbd.c
  33. /*
  34.  *        Terminal independent keyboard handling.
  35.  */
  36. #include    "def.h"
  37. #include    "kbd.h"
  38.  
  39. #define EXTERN
  40. #include    "key.h"
  41.  
  42. #ifndef NO_MACRO
  43. #include "macro.h"
  44. #endif
  45.  
  46. #ifdef    DO_METAKEY
  47. #ifndef METABIT
  48. #define METABIT 0x80
  49. #endif
  50.  
  51. int use_metakey = TRUE;
  52.  
  53. /*
  54.  * Toggle the value of use_metakey
  55.  */
  56. do_meta(f, n)
  57. {
  58.     if(f & FFARG)    use_metakey = n > 0;
  59.     else        use_metakey = !use_metakey;
  60.     ewprintf("Meta keys %sabled", use_metakey ? "en" : "dis");
  61.     return TRUE;
  62. }
  63. #endif
  64.  
  65. #ifdef    BSMAP
  66. static int bs_map = BSMAP;
  67. /*
  68.  * Toggle backspace mapping
  69.  */
  70. bsmap(f, n)
  71. {
  72.     if(f & FFARG)    bs_map = n > 0;
  73.     else        bs_map = ! bs_map;
  74.     ewprintf("Backspace mapping %sabled", bs_map ? "en" : "dis");
  75.     return TRUE;
  76. }
  77. #endif
  78.  
  79. #ifndef NO_DPROMPT
  80. #define PROMPTL 80
  81.   char    prompt[PROMPTL], *promptp;
  82. #endif
  83.  
  84. static    int    pushed = FALSE;
  85. static    int    pushedc;
  86.  
  87. VOID    ungetkey(c)
  88. int    c;
  89. {
  90. #ifdef    DO_METAKEY
  91.     if(use_metakey && pushed && c==CCHR('[')) pushedc |= METABIT;
  92.     else
  93. #endif
  94.         pushedc = c;
  95.     pushed = TRUE;
  96. }
  97.  
  98. int getkey(flag)
  99. int    flag;
  100. {
  101.     int    c;
  102.     char    *keyname();
  103.  
  104. #ifndef NO_DPROMPT
  105.     if(flag && !pushed) {
  106.         if(prompt[0]!='\0' && ttwait()) {
  107.             ewprintf("%s", prompt);    /* avoid problems with % */
  108.             update();        /* put the cursor back     */
  109.             epresf = KPROMPT;
  110.         }
  111.         if(promptp > prompt) *(promptp-1) = ' ';
  112.     }
  113. #endif
  114.     if(pushed) {
  115.         c = pushedc;
  116.         pushed = FALSE;
  117.     } else    c = getkbd();
  118. #ifdef     BSMAP
  119.     if(bs_map)
  120.         if(c==CCHR('H')) c=CCHR('?');
  121.         else if(c==CCHR('?')) c=CCHR('H');
  122. #endif    
  123. #ifdef    DO_METAKEY
  124.     if(use_metakey && (c&METABIT)) {
  125.         pushedc = c & ~METABIT;
  126.         pushed = TRUE;
  127.         c = CCHR('[');
  128.     }
  129. #endif
  130. #ifndef NO_DPROMPT
  131.     if(flag && promptp < &prompt[PROMPTL - 5]) {
  132.         promptp = keyname(promptp, c);
  133.         *promptp++ = '-';
  134.         *promptp = '\0';
  135.     }
  136. #endif
  137.     return c;
  138. }
  139.  
  140. /*
  141.  * doscan scans a keymap for a keyboard character and returns a pointer
  142.  * to the function associated with that character.  Sets ele to the
  143.  * keymap element the keyboard was found in as a side effect.
  144.  */
  145.  
  146. MAP_ELEMENT *ele;
  147.  
  148. PF    doscan(map, c)
  149. register KEYMAP *map;
  150. register int    c;
  151. {
  152.     register MAP_ELEMENT *elec = &map->map_element[0];    /* local register copy for faster access */
  153.     register MAP_ELEMENT *last = &map->map_element[map->map_num];
  154.  
  155.     while(elec < last && c > elec->k_num) elec++;
  156.     ele = elec;            /* used by prefix and binding code    */
  157.     if(elec >= last || c < elec->k_base)
  158.     return map->map_default;
  159.     return elec->k_funcp[c - elec->k_base];
  160. }
  161.  
  162. doin()
  163. {
  164.     KEYMAP    *curmap;
  165.     PF    funct;
  166.  
  167. #ifndef NO_DPROMPT
  168.     *(promptp = prompt) = '\0';
  169. #endif
  170.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  171.     key.k_count = 0;
  172.     while((funct=doscan(curmap,(key.k_chars[key.k_count++]=getkey(TRUE))))
  173.         == prefix)
  174.     curmap = ele->k_prefmap;
  175. #ifndef NO_MACRO
  176.     if(macrodef && macrocount < MAXMACRO)
  177.     macro[macrocount++].m_funct = funct;
  178. #endif
  179.     return (*funct)(0, 1);
  180. }
  181.  
  182. rescan(f, n)
  183. int f, n;
  184. {
  185.     int c;
  186.     register KEYMAP *curmap;
  187.     int i;
  188.     PF    fp;
  189.     int mode = curbp->b_nmodes;
  190.  
  191.     for(;;) {
  192.     if(ISUPPER(key.k_chars[key.k_count-1])) {
  193.         c = TOLOWER(key.k_chars[key.k_count-1]);
  194.         curmap = curbp->b_modes[mode]->p_map;
  195.         for(i=0; i < key.k_count-1; i++) {
  196.         if((fp=doscan(curmap,(key.k_chars[i]))) != prefix) break;
  197.         curmap = ele->k_prefmap;
  198.         }
  199.         if(fp==prefix) {
  200.         if((fp = doscan(curmap, c)) == prefix)
  201.             while((fp=doscan(curmap,key.k_chars[key.k_count++] =
  202.                 getkey(TRUE))) == prefix)
  203.             curmap = ele->k_prefmap;
  204.         if(fp!=rescan) {
  205. #ifndef NO_MACRO
  206.             if(macrodef && macrocount <= MAXMACRO)
  207.             macro[macrocount-1].m_funct = fp;
  208. #endif
  209.             return (*fp)(f, n);
  210.         }
  211.         }
  212.     }
  213.     /* try previous mode */
  214.     if(--mode < 0) return ABORT;
  215.     curmap = curbp->b_modes[mode]->p_map;
  216.     for(i=0; i < key.k_count; i++) {
  217.         if((fp=doscan(curmap,(key.k_chars[i]))) != prefix) break;
  218.         curmap = ele->k_prefmap;
  219.     }
  220.     if(fp==prefix) {
  221.         while((fp=doscan(curmap,key.k_chars[i++]=getkey(TRUE)))
  222.             == prefix)
  223.         curmap = ele->k_prefmap;
  224.         key.k_count = i;
  225.     }
  226.     if(fp!=rescan && i>=key.k_count-1) {
  227. #ifndef NO_MACRO
  228.         if(macrodef && macrocount <= MAXMACRO)
  229.         macro[macrocount-1].m_funct = fp;
  230. #endif
  231.         return (*fp)(f, n);
  232.     }
  233.     }
  234. }
  235.  
  236. universal_argument(f, n)
  237. int f, n;
  238. {
  239.     int c, nn=4;
  240.     KEYMAP *curmap;
  241.     PF    funct;
  242.  
  243.     if(f&FFUNIV) nn *= n;
  244.     for(;;) {
  245.     key.k_chars[0] = c = getkey(TRUE);
  246.     key.k_count = 1;
  247.     if(c == '-') return negative_argument(f, nn);
  248.     if(c >= '0' && c <= '9') return digit_argument(f, nn);
  249.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  250.     while((funct=doscan(curmap,c)) == prefix) {
  251.         curmap = ele->k_prefmap;
  252.         key.k_chars[key.k_count++] = c = getkey(TRUE);
  253.     }
  254.     if(funct != universal_argument) {
  255. #ifndef NO_MACRO
  256.         if(macrodef && macrocount < MAXMACRO-1) {
  257.         if(f&FFARG) macrocount--;
  258.         macro[macrocount++].m_count = nn;
  259.         macro[macrocount++].m_funct = funct;
  260.         }
  261. #endif
  262.         return (*funct)(FFUNIV, nn);
  263.     }
  264.     nn <<= 2;
  265.     }
  266. }
  267.  
  268. /*ARGSUSED*/
  269. digit_argument(f, n)
  270. int f, n;
  271. {
  272.     int nn, c;
  273.     KEYMAP *curmap;
  274.     PF    funct;
  275.  
  276.     nn = key.k_chars[key.k_count-1] - '0';
  277.     for(;;) {
  278.     c = getkey(TRUE);
  279.     if(c < '0' || c > '9') break;
  280.     nn *= 10;
  281.     nn += c - '0';
  282.     }
  283.     key.k_chars[0] = c;
  284.     key.k_count = 1;
  285.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  286.     while((funct=doscan(curmap,c)) == prefix) {
  287.     curmap = ele->k_prefmap;
  288.     key.k_chars[key.k_count++] = c = getkey(TRUE);
  289.     }
  290. #ifndef NO_MACRO
  291.     if(macrodef && macrocount < MAXMACRO-1) {
  292.     if(f&FFARG) macrocount--;
  293.     else macro[macrocount-1].m_funct = universal_argument;
  294.     macro[macrocount++].m_count = nn;
  295.     macro[macrocount++].m_funct = funct;
  296.     }
  297. #endif
  298.     return (*funct)(FFOTHARG, nn);
  299. }
  300.  
  301. negative_argument(f, n)
  302. int f, n;
  303. {
  304.     int nn = 0, c;
  305.     KEYMAP *curmap;
  306.     PF    funct;
  307.  
  308.     for(;;) {
  309.     c = getkey(TRUE);
  310.     if(c < '0' || c > '9') break;
  311.     nn *= 10;
  312.     nn += c - '0';
  313.     }
  314.     if(nn) nn = -nn;
  315.     else nn = -n;
  316.     key.k_chars[0] = c;
  317.     key.k_count = 1;
  318.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  319.     while((funct=doscan(curmap,c)) == prefix) {
  320.     curmap = ele->k_prefmap;
  321.     key.k_chars[key.k_count++] = c = getkey(TRUE);
  322.     }
  323. #ifndef NO_MACRO
  324.     if(macrodef && macrocount < MAXMACRO-1) {
  325.     if(f&FFARG) macrocount--;
  326.     else macro[macrocount-1].m_funct = universal_argument;
  327.     macro[macrocount++].m_count = nn;
  328.     macro[macrocount++].m_funct = funct;
  329.     }
  330. #endif
  331.     return (*funct)(FFNEGARG, nn);
  332. }
  333.  
  334. /*
  335.  * Insert a character.    While defining a macro, create a "LINE" containing
  336.  * all inserted characters.
  337.  */
  338.  
  339. selfinsert(f, n)
  340. int f, n;
  341. {
  342.     register int c;
  343.     int count;
  344.     VOID lchange();
  345. #ifndef NO_MACRO
  346.     LINE *lp;
  347.     int insert();
  348. #endif
  349.  
  350.     if (n < 0)    return FALSE;
  351.     if (n == 0) return TRUE;
  352.     c = key.k_chars[key.k_count-1];
  353. #ifndef NO_MACRO
  354.     if(macrodef && macrocount < MAXMACRO) {
  355.     if(f & FFARG) macrocount -= 2;
  356.     if(lastflag & CFINS) {    /* last command was insert -- tack on end */
  357.         macrocount--;
  358.         if(maclcur->l_size < maclcur->l_used + n) {
  359.         if((lp = lallocx(maclcur->l_used + n)) == NULL)
  360.             return FALSE;
  361.         lp->l_fp = maclcur->l_fp;
  362.         lp->l_bp = maclcur->l_bp;
  363.         lp->l_fp->l_bp = lp->l_bp->l_fp = lp;
  364.         bcopy(maclcur->l_text, lp->l_text, maclcur->l_used);
  365.         for(count = maclcur->l_used; count < lp->l_used; count++)
  366.             lp->l_text[count] = c;
  367.         free((char *)maclcur);
  368.         maclcur = lp;
  369.         } else {
  370.         maclcur->l_used += n;
  371.         for(count = maclcur->l_used-n; count < maclcur->l_used; count++)
  372.             maclcur->l_text[count] = c;
  373.         }
  374.     } else {
  375.         macro[macrocount-1].m_funct = insert;
  376.         if((lp = lallocx(n)) == NULL) return FALSE;
  377.         lp->l_bp = maclcur;
  378.         lp->l_fp = maclcur->l_fp;
  379.         maclcur->l_fp = lp;
  380.         maclcur = lp;
  381.         for(count = 0; count < n; count++)
  382.         lp->l_text[count] = c;
  383.     }
  384.     thisflag |= CFINS;
  385.     }
  386. #endif
  387.     if(c == '\n') {
  388.     do {
  389.         count = lnewline();
  390.     } while (--n && count==TRUE);
  391.     return count;
  392.     }
  393.     if(curbp->b_flag & BFOVERWRITE) {        /* Overwrite mode    */
  394.     lchange(WFEDIT);
  395.     while(curwp->w_doto < llength(curwp->w_dotp) && n--)
  396.         lputc(curwp->w_dotp, curwp->w_doto++, c);
  397.     if(n<=0) return TRUE;
  398.     }
  399.     return linsert(n, c);
  400. }
  401.  
  402. /*
  403.  * this could be implemented as a keymap with everthing defined
  404.  * as self-insert.
  405.  */
  406. quote(f, n)
  407. {
  408.     register int c;
  409.  
  410.     key.k_count = 1;
  411.     if((key.k_chars[0] = getkey(TRUE)) >= '0' && key.k_chars[0] <= '7') {
  412.     key.k_chars[0] -= '0';
  413.     if((c = getkey(TRUE)) >= '0' && c <= '7') {
  414.         key.k_chars[0] <<= 3;
  415.         key.k_chars[0] += c - '0';
  416.         if((c = getkey(TRUE)) >= '0' && c <= '7') {
  417.         key.k_chars[0] <<= 3;
  418.         key.k_chars[0] += c - '0';
  419.         } else ungetkey(c);
  420.     } else ungetkey(c);
  421.     }
  422.     return selfinsert(f, n);
  423. }
  424. SHAR_EOF
  425. cat << \SHAR_EOF > kbd.h
  426. /*
  427.  * kbd.h: type definitions for symbol.c and kbd.c for mg experimental
  428.  */
  429.  
  430. typedef struct    {
  431.     KCHAR    k_base;        /* first key in element            */
  432.     KCHAR    k_num;        /* last key in element            */
  433.     PF    *k_funcp;    /* pointer to array of pointers to functions */
  434.     struct    keymap_s    *k_prefmap;    /* keymap of ONLY prefix key in element */
  435. }    MAP_ELEMENT;
  436.  
  437. /* predefined keymaps are NOT type KEYMAP because final array needs
  438.  * dimension.  If any changes are made to this struct, they must be
  439.  * reflected in all keymap declarations.
  440.  */
  441.  
  442. #define KEYMAPE(NUM)    {\
  443.     short    map_num;\
  444.     short    map_max;\
  445.     PF    map_default;\
  446.     MAP_ELEMENT map_element[NUM];\
  447. }
  448.         /* elements used        */
  449.         /* elements allocated        */
  450.         /* default function        */
  451.         /* realy [e_max]        */
  452. typedef struct    keymap_s KEYMAPE(1)    KEYMAP;
  453.  
  454. #define none    ctrlg
  455. #define prefix    (PF)NULL
  456.  
  457. /* number of map_elements to grow an overflowed keymap by */
  458. #define IMAPEXT 0
  459. #define MAPGROW 3
  460. #define MAPINIT (MAPGROW+1)
  461.  
  462. /* max number of default bindings added to avoid creating new element */
  463. #define MAPELEDEF 4
  464.  
  465. typedef struct MAPS_S {
  466.     KEYMAP    *p_map;
  467.     char    *p_name;
  468. }    MAPS;
  469.  
  470. extern    MAPS    map_table[];
  471.  
  472. typedef struct {
  473.     PF    n_funct;
  474.     char    *n_name;
  475. }    FUNCTNAMES;
  476.  
  477. extern    FUNCTNAMES    functnames[];
  478. extern    int    nfunct;
  479.  
  480. extern    PF    doscan();
  481. extern    PF    name_function();
  482. extern    char    *function_name();
  483. extern    int    complete_function();
  484. extern    KEYMAP    *name_map();
  485. extern    char    *map_name();
  486. extern    MAPS    *name_mode();
  487.  
  488. extern    MAP_ELEMENT *ele;
  489. SHAR_EOF
  490. cat << \SHAR_EOF > key.h
  491. /* key.h: Insert file for mg 2 functions that need to reference key pressed */
  492.  
  493. #ifndef EXTERN
  494. #define EXTERN    extern
  495. #endif
  496.  
  497. #define MAXKEY    8            /* maximum number of prefix chars */
  498.  
  499. EXTERN    struct {            /* the chacter sequence in a key */
  500.     int    k_count;        /* number of chars        */
  501.     KCHAR    k_chars[MAXKEY];    /* chars            */
  502. }    key;
  503. #undef    EXTERN
  504. SHAR_EOF
  505. cat << \SHAR_EOF > keymap.c
  506. /*
  507.  * Keyboard maps.  This is character set dependent.
  508.  * The terminal specific parts of building the
  509.  * keymap has been moved to a better place.
  510.  */
  511. #include    "def.h"
  512. #include    "kbd.h"
  513.  
  514. /*
  515.  * Defined by "basic.c".
  516.  */
  517. extern    int    gotobol();        /* Move to start of line    */
  518. extern    int    backchar();        /* Move backward by characters    */
  519. extern    int    gotoeol();        /* Move to end of line        */
  520. extern    int    forwchar();        /* Move forward by characters    */
  521. extern    int    gotobob();        /* Move to start of buffer    */
  522. extern    int    gotoeob();        /* Move to end of buffer    */
  523. extern    int    forwline();        /* Move forward by lines    */
  524. extern    int    backline();        /* Move backward by lines    */
  525. extern    int    forwpage();        /* Move forward by pages    */
  526. extern    int    backpage();        /* Move backward by pages    */
  527. extern    int    pagenext();        /* Page forward next window    */
  528. extern    int    setmark();        /* Set mark            */
  529. extern    int    swapmark();        /* Swap "." and mark        */
  530. extern    int    gotoline();        /* Go to a specified line.    */
  531. #ifdef    GOSMACS
  532. extern    int    forw1page();        /* move forward by lines    */
  533. extern    int    back1page();        /* move back by lines        */
  534. #endif
  535.  
  536. /*
  537.  * Defined by "buffer.c".
  538.  */
  539. extern    int    listbuffers();        /* Display list of buffers    */
  540. extern    int    usebuffer();        /* Switch a window to a buffer    */
  541. extern    int    poptobuffer();        /* Other window to a buffer    */
  542. extern    int    killbuffer();        /* Make a buffer go away.    */
  543. extern    int    savebuffers();        /* Save unmodified buffers    */
  544. extern    int    bufferinsert();        /* Insert buffer into another    */
  545. extern    int    notmodified();        /* Reset modification flag    */
  546.  
  547. #ifndef NO_DIR
  548. /*
  549.  * Defined by "dir.c"
  550.  */
  551. extern    int    changedir();        /* change current directory    */
  552. extern    int    showcwdir();        /* show current directory    */
  553.  
  554. #ifndef NO_DIRED
  555. /*
  556.  * defined by "dired.c"
  557.  */
  558. extern    int    dired();        /* dired            */
  559. extern    int    d_findfile();        /* dired find file        */
  560. extern    int    d_del();        /* dired mark for deletion    */
  561. extern    int    d_undel();        /* dired unmark            */
  562. extern    int    d_undelbak();        /* dired unmark backwards    */
  563. extern    int    d_expunge();        /* dired expunge        */
  564. extern    int    d_copy();        /* dired copy            */
  565. extern    int    d_rename();        /* dired rename            */
  566. extern    int    d_otherwindow();    /* dired other window        */
  567. extern    int    d_ffotherwindow();    /* dired find file other window */
  568. #endif
  569. #endif
  570.  
  571. /*
  572.  * Defined by "extend.c".
  573.  */
  574. extern    int    extend();        /* Extended commands.        */
  575. extern    int    bindtokey();        /* Modify global key bindings.    */
  576. extern    int    localbind();        /* Modify mode key bindings.    */
  577. extern    int    define_key();        /* modify any key map        */
  578. extern    int    unbindtokey();        /* delete global binding    */
  579. extern    int    localunbind();        /* delete local binding        */
  580. extern    int    insert();        /* insert string        */
  581. #ifndef NO_STARTUP
  582. extern    int    evalexpr();        /* Extended commands (again)    */
  583. extern    int    evalbuffer();        /* Evaluate current buffer    */
  584. extern    int    evalfile();        /* Evaluate a file        */
  585. #endif
  586.  
  587. /*
  588.  * Defined by "file.c".
  589.  */
  590. extern    int    filevisit();        /* Get a file, read write    */
  591. extern    int    poptofile();        /* Get a file, other window    */
  592. extern    int    filewrite();        /* Write a file            */
  593. extern    int    filesave();        /* Save current file        */
  594. extern    int    fileinsert();        /* Insert file into buffer    */
  595. #ifndef NO_BACKUP
  596. extern    int    makebkfile();        /* Control backups on saves    */
  597. #endif
  598.  
  599. /*
  600.  * defined by help.c
  601.  */
  602. #ifndef NO_HELP
  603. extern    int    desckey();        /* describe key            */
  604. extern    int    wallchart();        /* Make wall chart.        */
  605. extern    int    help_help();        /* help help            */
  606. extern    int    apropos_command();    /* apropos            */
  607. #endif
  608.  
  609. /*
  610.  * defined by "kbd.c"
  611.  */
  612. #ifdef    DO_METAKEY
  613. extern    int    do_meta();        /* interpret meta keys        */
  614. #endif
  615. #ifdef    BSMAP
  616. extern    int    bsmap();        /* backspace mapping        */
  617. #endif
  618. extern    int    universal_argument();    /* Ctrl-U            */
  619. extern    int    digit_argument();    /* M-1, etc.            */
  620. extern    int    negative_argument();    /* M--                */
  621. extern    int    selfinsert();        /* Insert character        */
  622. extern    int    rescan();        /* internal try again function    */
  623.  
  624. /*
  625.  * defined by "macro.c"
  626.  */
  627. #ifndef NO_MACRO
  628. extern    int    definemacro();        /* Begin macro            */
  629. extern    int    finishmacro();        /* End macro            */
  630. extern    int    executemacro();        /* Execute macro        */
  631. #endif
  632.  
  633. /*
  634.  * Defined by "main.c".
  635.  */
  636. extern    int    ctrlg();        /* Abort out of things        */
  637. extern    int    quit();            /* Quit                */
  638.  
  639. /*
  640.  * Defined by "match.c"
  641.  */
  642. extern    int    showmatch();        /* Hack to show matching paren     */
  643.  
  644. /* defined by "modes.c" */
  645.  
  646. extern    int    indentmode();        /* set auto-indent mode        */
  647. extern    int    fillmode();        /* set word-wrap mode        */
  648. extern    int    blinkparen();        /* Fake blink-matching-paren var */
  649. #ifdef    NOTAB
  650. extern    int    notabmode();        /* no tab mode            */
  651. #endif
  652. extern    int    overwrite();        /* overwrite mode        */
  653. extern    int    set_default_mode();    /* set default modes        */
  654.  
  655. /*
  656.  * defined by "paragraph.c" - the paragraph justification code.
  657.  */
  658. extern    int    gotobop();        /* Move to start of paragraph.    */
  659. extern    int    gotoeop();        /* Move to end of paragraph.    */
  660. extern    int    fillpara();        /* Justify a paragraph.        */
  661. extern    int    killpara();        /* Delete a paragraph.        */
  662. extern    int    setfillcol();        /* Set fill column for justify. */
  663. extern    int    fillword();        /* Insert char with word wrap.    */
  664.  
  665. /*
  666.  * Defined by "random.c".
  667.  */
  668. extern    int    showcpos();        /* Show the cursor position    */
  669. extern    int    twiddle();        /* Twiddle characters        */
  670. extern    int    quote();        /* Insert literal        */
  671. extern    int    openline();        /* Open up a blank line        */
  672. extern    int    newline();        /* Insert newline        */
  673. extern    int    deblank();        /* Delete blank lines        */
  674. extern    int    justone();        /* Delete extra whitespace    */
  675. extern    int    delwhite();        /* Delete all whitespace    */
  676. extern    int    indent();        /* Insert newline, then indent    */
  677. extern    int    forwdel();        /* Forward delete        */
  678. extern    int    backdel();        /* Backward delete in        */
  679. extern    int    killline();        /* Kill forward            */
  680. extern    int    yank();            /* Yank back from killbuffer.    */
  681. #ifdef NOTAB
  682. extern    int    space_to_tabstop();
  683. #endif
  684.  
  685. #ifdef    REGEX
  686. /*
  687.  * Defined by "re_search.c"
  688.  */
  689. extern    int    re_forwsearch();    /* Regex search forward         */
  690. extern    int    re_backsearch();    /* Regex search backwards     */
  691. extern    int    re_searchagain();    /* Repeat regex search command     */
  692. extern    int    re_queryrepl();        /* Regex query replace         */
  693. extern    int    setcasefold();        /* Set case fold in searches     */
  694. extern    int    delmatchlines();    /* Delete all lines matching     */
  695. extern    int    delnonmatchlines();    /* Delete all lines not matching */
  696. extern    int    cntmatchlines();    /* Count matching lines         */
  697. extern    int    cntnonmatchlines();    /* Count nonmatching lines     */
  698. #endif
  699.  
  700. /*
  701.  * Defined by "region.c".
  702.  */
  703. extern    int    killregion();        /* Kill region.            */
  704. extern    int    copyregion();        /* Copy region to kill buffer.    */
  705. extern    int    lowerregion();        /* Lower case region.        */
  706. extern    int    upperregion();        /* Upper case region.        */
  707. #ifdef    PREFIXREGION
  708. extern    int    prefixregion();        /* Prefix all lines in region    */
  709. extern    int    setprefix();        /* Set line prefix string    */
  710. #endif
  711.  
  712. /*
  713.  * Defined by "search.c".
  714.  */
  715. extern    int    forwsearch();        /* Search forward        */
  716. extern    int    backsearch();        /* Search backwards        */
  717. extern    int    searchagain();        /* Repeat last search command    */
  718. extern    int    forwisearch();        /* Incremental search forward    */
  719. extern    int    backisearch();        /* Incremental search backwards */
  720. extern    int    queryrepl();        /* Query replace        */
  721.  
  722. /*
  723.  * Defined by "spawn.c".
  724.  */
  725. extern    int    spawncli();        /* Run CLI in a subjob.        */
  726. #ifdef    VMS
  727. extern    int    attachtoparent();    /* Attach to parent process    */
  728. #endif
  729.  
  730. /* defined by "version.c" */
  731.  
  732. extern    int    showversion();        /* Show version numbers, etc.    */
  733.  
  734. /*
  735.  * Defined by "window.c".
  736.  */
  737. extern    int    reposition();        /* Reposition window        */
  738. extern    int    refresh();        /* Refresh the screen        */
  739. extern    int    nextwind();        /* Move to the next window    */
  740. #ifdef    GOSMACS
  741. extern    int    prevwind();        /* Move to the previous window    */
  742. #endif
  743. extern    int    onlywind();        /* Make current window only one */
  744. extern    int    splitwind();        /* Split current window        */
  745. extern    int    delwind();        /* Delete current window    */
  746. extern    int    enlargewind();        /* Enlarge display window.    */
  747. extern    int    shrinkwind();        /* Shrink window.        */
  748.  
  749. /*
  750.  * Defined by "word.c".
  751.  */
  752. extern    int    backword();        /* Backup by words        */
  753. extern    int    forwword();        /* Advance by words        */
  754. extern    int    upperword();        /* Upper case word.        */
  755. extern    int    lowerword();        /* Lower case word.        */
  756. extern    int    capword();        /* Initial capitalize word.    */
  757. extern    int    delfword();        /* Delete forward word.        */
  758. extern    int    delbword();        /* Delete backward word.    */
  759.  
  760. #ifdef    AMIGA
  761. #ifdef    DO_ICONIFY
  762. extern    int tticon();
  763. #endif
  764. #ifdef    DO_MENU
  765. extern    int    amigamenu();        /* Menu function        */
  766. #endif
  767. #ifdef    MOUSE
  768. extern    int    amigamouse();        /* Amiga mouse functions    */
  769. extern    int    mgotobob();
  770. extern    int    mforwdel();
  771. extern    int    mdelwhite();
  772. extern    int    mdelwind();
  773. extern    int    mgotoeob();
  774. extern    int    menlargewind();
  775. extern    int    mkillline();
  776. extern    int    mkillregion();
  777. extern    int    mdelfword();
  778. extern    int    mreposition();
  779. extern    int    mbackpage();
  780. extern    int    mforwpage();
  781. extern    int    mshrinkwind();
  782. extern    int    msplitwind();
  783. extern    int    myank();
  784. #endif    MOUSE
  785.  
  786. extern    int    togglewindow();        /* Defined by "ttyio.c"        */
  787. extern    int    togglezooms();        /*    ""         ""        */
  788.  
  789. #ifdef    CHANGE_FONT
  790. extern    int    setfont();        /* Defined by "ttyio.c"        */
  791. #endif
  792.  
  793. #ifdef    CHANGE_COLOR
  794.     /* functions to mess with the mode line rendition, window colors*/
  795. extern    int    ttmode();        /* Defined by "tty.c"        */
  796. extern    int    tttext();        /*  ""                */
  797. extern    int    textforeground();    /*  ""                */
  798. extern    int    textbackground();    /*  ""                */
  799. extern    int    modeforeground();    /*  ""                */
  800. extern    int    modebackground();    /*  ""                */
  801. #endif
  802.  
  803. /*
  804.  * This file contains map segment definitions for adding function keys to
  805.  * keymap declarations.  Currently you can add things to the fundamental
  806.  * mode keymap and the dired mode keymap.  See the declaration of
  807.  * diredmap and fundmap for details.
  808.  */
  809. #include "amiga_maps.c"
  810.  
  811. #endif    /* AMIGA */
  812.  
  813. /* initial keymap declarations, deepest first */
  814.  
  815. #ifndef NO_HELP
  816. static    PF    cHcG[] = {
  817.     ctrlg,        /* ^G */
  818.     help_help,    /* ^H */
  819. };
  820. static    PF    cHa[]    = {
  821.     apropos_command,/* a */
  822.     wallchart,    /* b */
  823.     desckey,    /* c */
  824. };
  825. static    struct    KEYMAPE(2+IMAPEXT)    helpmap = {
  826.     2,
  827.     2+IMAPEXT,
  828.     rescan,
  829.     {
  830.         {CCHR('G'),CCHR('H'),    cHcG,    (KEYMAP *)NULL},
  831.         {'a',    'c',        cHa,    (KEYMAP *)NULL},
  832.     }
  833. };
  834. #endif
  835.  
  836. static    PF    cX4cF[] = {
  837.     poptofile,    /* ^f */
  838.     ctrlg,        /* ^g */
  839. };
  840. static    PF    cX4b[] = {
  841.     poptobuffer,    /* b */
  842.     rescan,        /* c */
  843.     rescan,        /* d */
  844.     rescan,        /* e */
  845.     poptofile,    /* f */
  846. };
  847. static    struct    KEYMAPE(2+IMAPEXT)    cX4map    = {
  848.     2,
  849.     2+IMAPEXT,
  850.     rescan,
  851.     {
  852.         {CCHR('F'),CCHR('G'),    cX4cF,    (KEYMAP *)NULL},
  853.         {'b',    'f',        cX4b,    (KEYMAP *)NULL},
  854.     }
  855. };
  856.  
  857. static    PF    cXcB[] = {
  858.     listbuffers,    /* ^B */
  859.     quit,        /* ^C */
  860.     rescan,        /* ^D */
  861.     rescan,        /* ^E */
  862.     filevisit,    /* ^F */
  863.     ctrlg,        /* ^G */
  864. };
  865. static    PF    cXcL[] = {
  866.     lowerregion,    /* ^L */
  867.     rescan,        /* ^M */
  868.     rescan,        /* ^N */
  869.     deblank,    /* ^O */
  870.     rescan,        /* ^P */
  871.     rescan,        /* ^Q */
  872.     rescan,        /* ^R */
  873.     filesave,    /* ^S */
  874.     rescan,        /* ^T */
  875.     upperregion,    /* ^U */
  876.     rescan,        /* ^V */
  877.     filewrite,    /* ^W */
  878.     swapmark,    /* ^X */
  879. };
  880. #ifndef NO_MACRO
  881. static    PF    cXlp[]    = {
  882.     definemacro,    /* ( */
  883.     finishmacro,    /* ) */
  884. };
  885. #endif
  886. static    PF    cX0[]    = {
  887.     delwind,    /* 0 */
  888.     onlywind,    /* 1 */
  889.     splitwind,    /* 2 */
  890.     rescan,        /* 3 */
  891.     prefix,        /* 4 */
  892. };
  893. static    PF    cXeq[]    = {
  894.     showcpos,    /* = */
  895. };
  896. static    PF    cXcar[] = {
  897.     enlargewind,    /* ^ */
  898.     rescan,        /* _ */
  899.     rescan,        /* ` */
  900.     rescan,        /* a */
  901.     usebuffer,    /* b */
  902.     rescan,        /* c */
  903. #ifndef NO_DIRED
  904.     dired,        /* d */
  905. #else
  906.     rescan,        /* d */
  907. #endif
  908. #ifndef NO_MACRO
  909.     executemacro,    /* e */
  910. #else
  911.     rescan,        /* e */
  912. #endif
  913.     setfillcol,    /* f */
  914.     rescan,        /* g */
  915.     rescan,        /* h */
  916.     fileinsert,    /* i */
  917.     rescan,        /* j */
  918.     killbuffer,    /* k */
  919.     rescan,        /* l */
  920.     rescan,        /* m */
  921.     rescan,        /* n */
  922.     nextwind,    /* o */
  923.     rescan,        /* p */
  924.     rescan,        /* q */
  925.     rescan,        /* r */
  926.     savebuffers,    /* s */
  927. };
  928. #ifndef NO_MACRO
  929. static    struct    KEYMAPE(6+IMAPEXT)    cXmap = {
  930.     6,
  931.     6+IMAPEXT,
  932. #else
  933. static    struct    KEYMAPE(5+IMAPEXT)    cXmap = {
  934.     5,
  935.     5+IMAPEXT,
  936. #endif
  937.     rescan,
  938.     {
  939.         {CCHR('B'),CCHR('G'),    cXcB,    (KEYMAP *)NULL},
  940.         {CCHR('L'),CCHR('X'),    cXcL,    (KEYMAP *)NULL},
  941. #ifndef NO_MACRO
  942.         {'(',    ')',        cXlp,    (KEYMAP *)NULL},
  943. #endif
  944.         {'0',    '4',        cX0,    (KEYMAP *)&cX4map},
  945.         {'=',    '=',        cXeq,    (KEYMAP *)NULL},
  946.         {'^',    's',        cXcar,    (KEYMAP *)NULL},
  947.     }
  948. };
  949.  
  950. static    PF    metacG[] = {
  951.     ctrlg,        /* ^G */
  952. };
  953. static    PF    metacV[] = {
  954.     pagenext,    /* ^V */
  955. };
  956. static    PF    metasp[] = {
  957.     justone,    /* space */
  958. };
  959. static    PF    metapct[] = {
  960.     queryrepl,    /* % */
  961. };
  962. static    PF    metami[] = {
  963.     negative_argument,    /* - */
  964.     rescan,        /* . */
  965.     rescan,        /* / */
  966.     digit_argument, /* 0 */
  967.     digit_argument, /* 1 */
  968.     digit_argument, /* 2 */
  969.     digit_argument, /* 3 */
  970.     digit_argument, /* 4 */
  971.     digit_argument, /* 5 */
  972.     digit_argument, /* 6 */
  973.     digit_argument, /* 7 */
  974.     digit_argument, /* 8 */
  975.     digit_argument, /* 9 */
  976.     rescan,        /* : */
  977.     rescan,        /* ; */
  978.     gotobob,    /* < */
  979.     rescan,        /* = */
  980.     gotoeob,    /* > */
  981. };
  982. static    PF    metalb[] = {
  983.     gotobop,    /* [ */
  984.     delwhite,    /* \ */
  985.     gotoeop,    /* ] */
  986.     rescan,        /* ^ */
  987.     rescan,        /* _ */
  988.     rescan,        /* ` */
  989.     rescan,        /* a */
  990.     backword,    /* b */
  991.     capword,    /* c */
  992.     delfword,    /* d */
  993.     rescan,        /* e */
  994.     forwword,    /* f */
  995. };
  996. static    PF    metal[] = {
  997.     lowerword,    /* l */
  998.     rescan,        /* m */
  999.     rescan,        /* n */
  1000.     rescan,        /* o */
  1001.     rescan,        /* p */
  1002.     fillpara,    /* q */
  1003.     backsearch,    /* r */
  1004.     forwsearch,    /* s */
  1005.     rescan,        /* t */
  1006.     upperword,    /* u */
  1007.     backpage,    /* v */
  1008.     copyregion,    /* w */
  1009.     extend,        /* x */
  1010. };
  1011. static    PF    metatilde[] = {
  1012.     notmodified,    /* ~ */
  1013.     delbword,    /* DEL */
  1014. };
  1015. static    struct    KEYMAPE(8+IMAPEXT)    metamap = {
  1016.     8,
  1017.     8+IMAPEXT,
  1018.     rescan,
  1019.     {
  1020.         {CCHR('G'),CCHR('G'),    metacG, (KEYMAP *)NULL},
  1021.         {CCHR('V'),CCHR('V'),    metacV, (KEYMAP *)NULL},
  1022.         {' ',    ' ',        metasp, (KEYMAP *)NULL},
  1023.         {'%',    '%',        metapct,(KEYMAP *)NULL},
  1024.         {'-',    '>',        metami, (KEYMAP *)NULL},
  1025.         {'[',    'f',        metalb, (KEYMAP *)NULL},
  1026.         {'l',    'x',        metal,    (KEYMAP *)NULL},
  1027.         {'~',    CCHR('?'),    metatilde,(KEYMAP *)NULL},
  1028.     }
  1029. };
  1030.  
  1031. static    PF    fund_at[] = {
  1032.     setmark,    /* ^@ */
  1033.     gotobol,    /* ^A */
  1034.     backchar,    /* ^B */
  1035.     rescan,        /* ^C */
  1036.     forwdel,    /* ^D */
  1037.     gotoeol,    /* ^E */
  1038.     forwchar,    /* ^F */
  1039.     ctrlg,        /* ^G */
  1040. #ifndef NO_HELP
  1041.     prefix,        /* ^H */
  1042. #else
  1043.     rescan,        /* ^H */
  1044. #endif
  1045. };
  1046. /* ^I is selfinsert */
  1047. static    PF    fund_CJ[] = {
  1048.     indent,        /* ^J */
  1049.     killline,    /* ^K */
  1050.     reposition,    /* ^L */
  1051.     newline,    /* ^M */
  1052.     forwline,    /* ^N */
  1053.     openline,    /* ^O */
  1054.     backline,    /* ^P */
  1055.     quote,        /* ^Q */
  1056.     backisearch,    /* ^R */
  1057.     forwisearch,    /* ^S */
  1058.     twiddle,    /* ^T */
  1059.     universal_argument,    /* ^U */
  1060.     forwpage,    /* ^V */
  1061.     killregion,    /* ^W */
  1062.     prefix,        /* ^X */
  1063.     yank,        /* ^Y */
  1064. #ifndef VMS
  1065.     spawncli,    /* ^Z */
  1066. #else
  1067.     attachtoparent, /* ^Z */
  1068. #endif
  1069. };
  1070. static    PF    fund_esc[] = {
  1071.     prefix,        /* esc */
  1072.     rescan,        /* ^\ */    /* selfinsert is default on fundamental */
  1073.     rescan,        /* ^] */
  1074.     rescan,        /* ^^ */
  1075.     rescan,        /* ^_ */
  1076. };
  1077. static    PF    fund_del[] = {
  1078.     backdel,    /* DEL */
  1079. };
  1080.  
  1081. #ifndef    FUND_XMAPS
  1082. #define NFUND_XMAPS    0    /* extra map sections after normal ones */
  1083. #endif
  1084.  
  1085. static    struct    KEYMAPE(4+NFUND_XMAPS+IMAPEXT)    fundmap = {
  1086.     4 + NFUND_XMAPS,
  1087.     4 + NFUND_XMAPS + IMAPEXT,
  1088.     selfinsert,
  1089.     {
  1090. #ifndef NO_HELP
  1091.         {CCHR('@'),CCHR('H'),    fund_at, (KEYMAP *)&helpmap},
  1092. #else
  1093.         {CCHR('@'),CCHR('H'),    fund_at, (KEYMAP *)NULL},
  1094. #endif
  1095.         {CCHR('J'),CCHR('Z'),    fund_CJ, (KEYMAP *)&cXmap},
  1096.         {CCHR('['),CCHR('_'),    fund_esc,(KEYMAP *)&metamap},
  1097.         {CCHR('?'),CCHR('?'),    fund_del,(KEYMAP *)NULL},
  1098. #ifdef    FUND_XMAPS
  1099.         FUND_XMAPS,
  1100. #endif
  1101.     }
  1102. };
  1103.  
  1104. static    PF    fill_sp[] = {
  1105.     fillword,    /* ' ' */
  1106. };
  1107. static struct KEYMAPE(1+IMAPEXT)    fillmap = {
  1108.     1,
  1109.     1+IMAPEXT,
  1110.     rescan,
  1111.     {
  1112.         {' ',    ' ',    fill_sp,    (KEYMAP *)NULL},
  1113.     }
  1114. };
  1115.  
  1116. static    PF    indent_lf[] = {
  1117.     newline,    /* ^J */
  1118.     rescan,        /* ^K */
  1119.     rescan,        /* ^L */
  1120.     indent,        /* ^M */
  1121. };
  1122. static    struct    KEYMAPE(1+IMAPEXT)    indntmap = {
  1123.     1,
  1124.     1+IMAPEXT,
  1125.     rescan,
  1126.     {
  1127.         {CCHR('J'), CCHR('M'),    indent_lf,    (KEYMAP *)NULL},
  1128.     }
  1129. };
  1130. static    PF    blink_rp[] = {
  1131.     showmatch,    /* ) */
  1132. };
  1133. static    struct    KEYMAPE(1+IMAPEXT)    blinkmap = {
  1134.     1,
  1135.     1+IMAPEXT,
  1136.     rescan,
  1137.     {
  1138.         {')',    ')',    blink_rp,    (KEYMAP *)NULL},
  1139.     }
  1140. };
  1141.  
  1142. #ifdef    NOTAB
  1143. static    PF    notab_tab[] = {
  1144.     space_to_tabstop,    /* ^I */
  1145. };
  1146. static    struct    KEYMAPE(1+IMAPEXT)    notabmap = {
  1147.     1,
  1148.     1+IMAPEXT,
  1149.     rescan,
  1150.     {
  1151.         {CCHR('I'),CCHR('I'),    notab_tab,    (KEYMAP *)NULL},
  1152.     }
  1153. };
  1154. #endif
  1155.  
  1156. static    struct    KEYMAPE(1+IMAPEXT)    overwmap = {
  1157.     0,
  1158.     1+IMAPEXT,            /* 1 to avoid 0 sized array */
  1159.     rescan,
  1160.     {
  1161.         /* unused dummy entry for VMS C */
  1162.         {(KCHAR)0,    (KCHAR)0, (PF *)NULL,    (KEYMAP *)NULL},
  1163.     }
  1164. };
  1165.  
  1166. #ifndef NO_DIRED
  1167. static    PF    dirednul[] = {
  1168.     setmark,    /* ^@ */
  1169.     gotobol,    /* ^A */
  1170.     backchar,    /* ^B */
  1171.     rescan,        /* ^C */
  1172.     d_del,        /* ^D */
  1173.     gotoeol,    /* ^E */
  1174.     forwchar,    /* ^F */
  1175.     ctrlg,        /* ^G */
  1176. #ifndef NO_HELP
  1177.     prefix,        /* ^H */
  1178. #endif
  1179. };
  1180. static    PF    diredcl[] = {
  1181.     reposition,    /* ^L */
  1182.     forwline,    /* ^M */
  1183.     forwline,    /* ^N */
  1184.     rescan,        /* ^O */
  1185.     backline,    /* ^P */
  1186.     rescan,        /* ^Q */
  1187.     backisearch,    /* ^R */
  1188.     forwisearch,    /* ^S */
  1189.     rescan,        /* ^T */
  1190.     universal_argument, /* ^U */
  1191.     forwpage,    /* ^V */
  1192.     rescan,        /* ^W */
  1193.     prefix,        /* ^X */
  1194. };
  1195. static    PF    diredcz[] = {
  1196. #ifndef VMS
  1197.     spawncli,    /* ^Z */
  1198. #else
  1199.     attachtoparent, /* ^Z */
  1200. #endif
  1201.     prefix,        /* esc */
  1202.     rescan,        /* ^\ */
  1203.     rescan,        /* ^] */
  1204.     rescan,        /* ^^ */
  1205.     rescan,        /* ^_ */
  1206.     forwline,    /* SP */
  1207. };
  1208. static    PF    diredc[] = {
  1209.     d_copy,        /* c */
  1210.     d_del,        /* d */
  1211.     d_findfile,    /* e */
  1212.     d_findfile,    /* f */
  1213. };
  1214. static    PF    diredn[] = {
  1215.     forwline,    /* n */
  1216.     d_ffotherwindow,/* o */
  1217.     backline,    /* p */
  1218.     rescan,        /* q */
  1219.     d_rename,    /* r */
  1220.     rescan,        /* s */
  1221.     rescan,        /* t */
  1222.     d_undel,    /* u */
  1223.     rescan,        /* v */
  1224.     rescan,        /* w */
  1225.     d_expunge,    /* x */
  1226. };
  1227. static    PF    direddl[] = {
  1228.     d_undelbak,    /* del */
  1229. };
  1230.  
  1231. #ifndef    DIRED_XMAPS
  1232. #define    NDIRED_XMAPS    0    /* number of extra map sections */
  1233. #endif
  1234.  
  1235. static    struct    KEYMAPE(6 + NDIRED_XMAPS + IMAPEXT)    diredmap = {
  1236.     6 + NDIRED_XMAPS,
  1237.     6 + NDIRED_XMAPS + IMAPEXT,
  1238.     rescan,
  1239.     {
  1240. #ifndef NO_HELP
  1241.         {CCHR('@'),    CCHR('H'),    dirednul, (KEYMAP *)&helpmap},
  1242. #else
  1243.         {CCHR('@'),    CCHR('G'),    dirednul, (KEYMAP *)NULL},
  1244. #endif
  1245.         {CCHR('L'),    CCHR('X'),    diredcl,  (KEYMAP *)&cXmap},
  1246.         {CCHR('Z'),    ' ',        diredcz,  (KEYMAP *)&metamap},
  1247.         {'c',        'f',        diredc,   (KEYMAP *)NULL},
  1248.         {'n',        'x',        diredn,   (KEYMAP *)NULL},
  1249.         {CCHR('?'),    CCHR('?'),    direddl,  (KEYMAP *)NULL},
  1250. #ifdef    DIRED_XMAPS
  1251.         DIRED_XMAPS,    /* map sections for dired mode keys    */
  1252. #endif
  1253.     }
  1254. };
  1255. #endif
  1256.  
  1257. /* give names to the maps, for use by help etc.
  1258.  * If the map is to be bindable, it must also be listed in the
  1259.  * function name table below with the same name.
  1260.  * Maps created dynamicly currently don't get added here, thus are unnamed.
  1261.  * Modes are just named keymaps with functions to add/subtract them from
  1262.  * a buffer's list of modes.  If you change a mode name, change it in
  1263.  * modes.c also.
  1264.  */
  1265.  
  1266. MAPS    map_table[] = {
  1267.     /* fundamental map MUST be first entry */
  1268.     {(KEYMAP *)&fundmap,    "fundamental"},
  1269.     {(KEYMAP *)&fillmap,    "fill"},
  1270.     {(KEYMAP *)&indntmap,    "indent"},
  1271.     {(KEYMAP *)&blinkmap,    "blink"},
  1272. #ifdef    NOTAB
  1273.     {(KEYMAP *)¬abmap,    "notab"},
  1274. #endif
  1275.     {(KEYMAP *)&overwmap,    "overwrite"},
  1276.     {(KEYMAP *)&metamap,    "esc prefix"},
  1277.     {(KEYMAP *)&cXmap,    "c-x prefix"},
  1278.     {(KEYMAP *)&cX4map,    "c-x 4 prefix"},
  1279. #ifndef NO_HELP
  1280.     {(KEYMAP *)&helpmap,    "help"},
  1281. #endif
  1282. #ifndef NO_DIRED
  1283.     {(KEYMAP *)&diredmap,    "dired"},
  1284. #endif
  1285. };
  1286.  
  1287. #define NMAPS    (sizeof map_table/sizeof(MAPS))
  1288. int    nmaps = NMAPS;        /* for use by rebind in extend.c */
  1289.  
  1290. char *map_name(map)
  1291. KEYMAP *map;
  1292. {
  1293.     MAPS *mp = &map_table[0];
  1294.  
  1295.     do {
  1296.         if(mp->p_map == map) return mp->p_name;
  1297.     } while(++mp < &map_table[NMAPS]);
  1298.     return (char *)NULL;
  1299. }
  1300.  
  1301. MAPS *name_mode(name)
  1302. char *name;
  1303. {
  1304.     MAPS *mp = &map_table[0];
  1305.  
  1306.     do {
  1307.         if(strcmp(mp->p_name,name)==0) return mp;
  1308.     } while(++mp < &map_table[NMAPS]);
  1309.     return (MAPS *)NULL;
  1310. }
  1311.  
  1312. KEYMAP *name_map(name)
  1313. char *name;
  1314. {
  1315.     MAPS *mp;
  1316.     return (mp=name_mode(name))==NULL ? (KEYMAP *)NULL : mp->p_map;
  1317. }
  1318.  
  1319. /* Warning: functnames MUST be in alphabetical order!  (due to binary
  1320.  * search in name_function.)  If the function is prefix, it must be listed
  1321.  * with the same name in the map_table above.
  1322.  */
  1323.  
  1324. FUNCTNAMES    functnames[] = {
  1325. #ifdef    AMIGA
  1326. #ifdef    DO_ICONIFY
  1327.     {tticon,    "amiga-iconify"},
  1328. #endif
  1329. #ifdef    DO_MENU
  1330.     {amigamenu,    "amiga-menu"},
  1331. #endif
  1332. #ifdef    CHANGE_COLOR
  1333.     {modebackground,"amiga-mode-background"},
  1334.     {modeforeground,"amiga-mode-foreground"},
  1335.     {ttmode,    "amiga-mode-rendition"},
  1336. #endif
  1337. #ifdef    CHANGE_FONT
  1338.     {setfont,    "amiga-set-font"},
  1339. #endif
  1340. #ifdef    CHANGE_COLOR
  1341.     {textbackground,"amiga-text-background"},
  1342.     {textforeground,"amiga-text-foreground"},
  1343.     {tttext,    "amiga-text-rendition"},
  1344. #endif
  1345.     {togglewindow,    "amiga-toggle-border"},
  1346.     {togglezooms,    "amiga-zoom-mode"},
  1347. #endif    /* AMIGA */
  1348. #ifndef    NO_HELP
  1349.     {apropos_command, "apropos"},
  1350. #endif
  1351.     {fillmode,    "auto-fill-mode"},
  1352.     {indentmode,    "auto-indent-mode"},
  1353.     {backchar,    "backward-char"},
  1354.     {delbword,    "backward-kill-word"},
  1355.     {gotobop,    "backward-paragraph"},
  1356.     {backword,    "backward-word"},
  1357.     {gotobob,    "beginning-of-buffer"},
  1358.     {gotobol,    "beginning-of-line"},
  1359.     {blinkparen,    "blink-matching-paren"},
  1360.     {showmatch,    "blink-matching-paren-hack"},
  1361. #ifdef    BSMAP
  1362.     {bsmap,        "bsmap-mode"},
  1363. #endif
  1364.     {prefix,    "c-x 4 prefix"},
  1365.     {prefix,    "c-x prefix"},
  1366. #ifndef NO_MACRO
  1367.     {executemacro,    "call-last-kbd-macro"},
  1368. #endif
  1369.     {capword,    "capitalize-word"},
  1370. #ifndef NO_DIR
  1371.     {changedir,    "cd"},
  1372. #endif
  1373.     {copyregion,    "copy-region-as-kill"},
  1374. #ifdef    REGEX
  1375.     {cntmatchlines, "count-matches"},
  1376.     {cntnonmatchlines,"count-non-matches"},
  1377. #endif
  1378.     {define_key,    "define-key"},
  1379.     {backdel,    "delete-backward-char"},
  1380.     {deblank,    "delete-blank-lines"},
  1381.     {forwdel,    "delete-char"},
  1382.     {delwhite,    "delete-horizontal-space"},
  1383. #ifdef    REGEX
  1384.     {delmatchlines, "delete-matching-lines"},
  1385.     {delnonmatchlines,"delete-non-matching-lines"},
  1386. #endif
  1387.     {onlywind,    "delete-other-windows"},
  1388.     {delwind,    "delete-window"},
  1389. #ifndef NO_HELP
  1390.     {wallchart,    "describe-bindings"},
  1391.     {desckey,    "describe-key-briefly"},
  1392. #endif
  1393.     {digit_argument,"digit-argument"},
  1394. #ifndef NO_DIRED
  1395.     {dired,        "dired"},
  1396.     {d_undelbak,    "dired-backup-unflag"},
  1397.     {d_copy,    "dired-copy-file"},
  1398.     {d_expunge,    "dired-do-deletions"},
  1399.     {d_findfile,    "dired-find-file"},
  1400.     {d_ffotherwindow, "dired-find-file-other-window"},
  1401.     {d_del,        "dired-flag-file-deleted"},
  1402.     {d_otherwindow, "dired-other-window"},
  1403.     {d_rename,    "dired-rename-file"},
  1404.     {d_undel,    "dired-unflag"},
  1405. #endif
  1406.     {lowerregion,    "downcase-region"},
  1407.     {lowerword,    "downcase-word"},
  1408.     {showversion,    "emacs-version"},
  1409. #ifndef NO_MACRO
  1410.     {finishmacro,    "end-kbd-macro"},
  1411. #endif
  1412.     {gotoeob,    "end-of-buffer"},
  1413.     {gotoeol,    "end-of-line"},
  1414.     {enlargewind,    "enlarge-window"},
  1415.     {prefix,    "esc prefix"},
  1416. #ifndef NO_STARTUP
  1417.     {evalbuffer,    "eval-current-buffer"},
  1418.     {evalexpr,    "eval-expression"},
  1419. #endif
  1420.     {swapmark,    "exchange-point-and-mark"},
  1421.     {extend,    "execute-extended-command"},
  1422.     {fillpara,    "fill-paragraph"},
  1423.     {filevisit,    "find-file"},
  1424.     {poptofile,    "find-file-other-window"},
  1425.     {forwchar,    "forward-char"},
  1426.     {gotoeop,    "forward-paragraph"},
  1427.     {forwword,    "forward-word"},
  1428.     {bindtokey,    "global-set-key"},
  1429.     {unbindtokey,    "global-unset-key"},
  1430.     {gotoline,    "goto-line"},
  1431. #ifndef NO_HELP
  1432.     {prefix,    "help"},
  1433.     {help_help,    "help-help"},
  1434. #endif
  1435.     {insert,    "insert"},
  1436.     {bufferinsert,    "insert-buffer"},
  1437.     {fileinsert,    "insert-file"},
  1438.     {fillword,    "insert-with-wrap"},
  1439.     {backisearch,    "isearch-backward"},
  1440.     {forwisearch,    "isearch-forward"},
  1441.     {justone,    "just-one-space"},
  1442.     {ctrlg,        "keyboard-quit"},
  1443.     {killbuffer,    "kill-buffer"},
  1444.     {killline,    "kill-line"},
  1445.     {killpara,    "kill-paragraph"},
  1446.     {killregion,    "kill-region"},
  1447.     {delfword,    "kill-word"},
  1448.     {listbuffers,    "list-buffers"},
  1449. #ifndef NO_STARTUP
  1450.     {evalfile,    "load"},
  1451. #endif
  1452.     {localbind,    "local-set-key"},
  1453.     {localunbind,    "local-unset-key"},
  1454. #ifndef NO_BACKUP
  1455.     {makebkfile,    "make-backup-files"},
  1456. #endif
  1457. #ifdef    DO_METAKEY
  1458.     {do_meta,    "meta-key-mode"},    /* better name, anyone? */
  1459. #endif
  1460. #ifdef    AMIGA
  1461. #ifdef    MOUSE
  1462.     {mgotobob,    "mouse-beginning-of-buffer"},
  1463.     {mforwdel,    "mouse-delete-char"},
  1464.     {mdelwhite,    "mouse-delete-horizontal-space"},
  1465.     {mdelwind,    "mouse-delete-window"},
  1466.     {mgotoeob,    "mouse-end-of-buffer"},
  1467.     {menlargewind,    "mouse-enlarge-window"},
  1468.     {mkillline,    "mouse-kill-line"},
  1469.     {mkillregion,    "mouse-kill-region"},
  1470.     {mdelfword,    "mouse-kill-word"},
  1471.     {mreposition,    "mouse-recenter"},
  1472.     {mbackpage,    "mouse-scroll-down"},
  1473.     {mforwpage,    "mouse-scroll-up"},
  1474.     {amigamouse,    "mouse-set-point"},
  1475.     {mshrinkwind,    "mouse-shrink-window"},
  1476.     {msplitwind,    "mouse-split-window-vertically"},
  1477.     {myank,        "mouse-yank"},
  1478. #endif
  1479. #endif
  1480.     {negative_argument, "negative-argument"},
  1481.     {newline,    "newline"},
  1482.     {indent,    "newline-and-indent"},
  1483.     {forwline,    "next-line"},
  1484. #ifdef    NOTAB
  1485.     {notabmode,    "no-tab-mode"},
  1486. #endif
  1487.     {notmodified,    "not-modified"},
  1488.     {openline,    "open-line"},
  1489.     {nextwind,    "other-window"},
  1490.     {overwrite,    "overwrite-mode"},
  1491. #ifdef    PREFIXREGION
  1492.     {prefixregion,    "prefix-region"},
  1493. #endif
  1494.     {backline,    "previous-line"},
  1495. #ifdef    GOSMACS
  1496.     {prevwind,    "previous-window"},
  1497. #endif
  1498. #ifdef    VMS
  1499.     {spawncli,    "push-to-dcl"},
  1500. #endif
  1501. #ifndef NO_DIR
  1502.     {showcwdir,    "pwd"},
  1503. #endif
  1504.     {queryrepl,    "query-replace"},
  1505. #ifdef    REGEX
  1506.     {re_queryrepl,    "query-replace-regexp"},
  1507. #endif
  1508.     {quote,        "quoted-insert"},
  1509. #ifdef    REGEX
  1510.     {re_searchagain,"re-search-again"},
  1511.     {re_backsearch, "re-search-backward"},
  1512.     {re_forwsearch, "re-search-forward"},
  1513. #endif
  1514.     {reposition,    "recenter"},
  1515.     {refresh,    "redraw-display"},
  1516.     {filesave,    "save-buffer"},
  1517.     {quit,        "save-buffers-kill-emacs"},
  1518.     {savebuffers,    "save-some-buffers"},
  1519.     {backpage,    "scroll-down"},
  1520. #ifdef    GOSMACS
  1521.     {back1page,    "scroll-one-line-down"},
  1522.     {forw1page,    "scroll-one-line-up"},
  1523. #endif
  1524.     {pagenext,    "scroll-other-window"},
  1525.     {forwpage,    "scroll-up"},
  1526.     {searchagain,    "search-again"},
  1527.     {backsearch,    "search-backward"},
  1528.     {forwsearch,    "search-forward"},
  1529.     {selfinsert,    "self-insert-command"},
  1530. #ifdef    REGEX
  1531.     {setcasefold,    "set-case-fold-search"},
  1532. #endif
  1533.     {set_default_mode, "set-default-mode"},
  1534.     {setfillcol,    "set-fill-column"},
  1535.     {setmark,    "set-mark-command"},
  1536. #ifdef    PREFIXREGION
  1537.     {setprefix,    "set-prefix-string"},
  1538. #endif
  1539.     {shrinkwind,    "shrink-window"},
  1540. #ifdef    NOTAB
  1541.     {space_to_tabstop, "space-to-tabstop"},
  1542. #endif
  1543.     {splitwind,    "split-window-vertically"},
  1544. #ifndef NO_MACRO
  1545.     {definemacro,    "start-kbd-macro"},
  1546. #endif
  1547. #ifdef    VMS
  1548.     {attachtoparent,"suspend-emacs"},
  1549. #else
  1550.     {spawncli,    "suspend-emacs"},
  1551. #endif
  1552.     {usebuffer,    "switch-to-buffer"},
  1553.     {poptobuffer,    "switch-to-buffer-other-window"},
  1554.     {twiddle,    "transpose-chars"},
  1555.     {universal_argument, "universal-argument"},
  1556.     {upperregion,    "upcase-region"},
  1557.     {upperword,    "upcase-word"},
  1558.     {showcpos,    "what-cursor-position"},
  1559.     {filewrite,    "write-file"},
  1560.     {yank,        "yank"},
  1561. };
  1562.  
  1563. #define NFUNCT    (sizeof(functnames)/sizeof(FUNCTNAMES))
  1564.  
  1565. int    nfunct = NFUNCT;        /* used by help.c */
  1566.  
  1567. /*
  1568.  * The general-purpose version of ROUND2 blows osk C (2.0) out of the water.
  1569.  * (reboot required)  If you need to build a version of mg with less than 32
  1570.  * or more than 511 functions, something better must be done.
  1571.  * The version that should work, but doesn't is:
  1572.  * #define ROUND2(x) (1+((x>>1)|(x>>2)|(x>>3)|(x>>4)|(x>>5)|(x>>6)|(x>>7)|\
  1573.  *    (x>>8)|(x>>9)|(x>>10)|(x>>11)|(x>>12)|(x>>13)|(x>>14)|(x>>15)))
  1574.  */
  1575. #define ROUND2(x) (x<128?(x<64?32:64):(x<256?128:256))
  1576.  
  1577. static    name_fent(fname, flag)
  1578. register char *fname;
  1579. int    flag;
  1580. {
  1581.     register int    try;
  1582.     register int    x = ROUND2(NFUNCT);
  1583.     register int    base = 0;
  1584.     register int    notit;
  1585.  
  1586.     do {
  1587.         /* + can be used instead of | here if more efficent.    */
  1588.         if((try = base | x) < NFUNCT) {
  1589.         if((notit = strcmp(fname, functnames[try].n_name)) >= 0) {
  1590.             if(!notit) return try;
  1591.             base = try;
  1592.         }
  1593.         }
  1594.     } while((x>>=1) || (try==1 && base==0));    /* try 0 once if needed */
  1595.     return flag ? base : -1;
  1596. }
  1597.  
  1598. /*
  1599.  * Translate from function name to function pointer, using binary search.
  1600.  */
  1601.  
  1602. PF    name_function(fname)
  1603. char    *fname;
  1604. {
  1605.     int i;
  1606.     if((i = name_fent(fname, FALSE)) >= 0) return functnames[i].n_funct;
  1607.     return (PF)NULL;
  1608. }
  1609.  
  1610. /* complete function name */
  1611.  
  1612. complete_function(fname, c)
  1613. register char    *fname;
  1614. {
  1615.     register int i, j, k, l;
  1616.     int    oj;
  1617.  
  1618.     i = name_fent(fname, TRUE);
  1619.     for(j=0; (l=fname[j]) && functnames[i].n_name[j]==l; j++) {}
  1620.     if(fname[j]!='\0') {
  1621.         if(++i >= NFUNCT) return -2;    /* no match */
  1622.         for(j=0; (l=fname[j]) && functnames[i].n_name[j]==l; j++) {}
  1623.         if(fname[j]!='\0') return -2;    /* no match */
  1624.     }
  1625.     if(c==CCHR('M') && functnames[i].n_name[j]=='\0') return -1;
  1626.     for(k=i+1; k<NFUNCT; k++) {        /* find last match */
  1627.         for(l=0; functnames[k].n_name[l]==fname[l]; l++) {}
  1628.         if(l<j) break;
  1629.     }
  1630.     k--;
  1631.     oj = j;
  1632.     if(k>i) {                    /* multiple matches */
  1633.         while((l = functnames[i].n_name[j]) == functnames[k].n_name[j]) {
  1634.         fname[j++] = l;
  1635.         if(l=='-' && c==' ') break;
  1636.         }
  1637.         if(j==oj) return -3;            /* ambiguous    */
  1638.     } else {                    /* single match */
  1639.         while(l = functnames[i].n_name[j]) {
  1640.         fname[j++] = l;
  1641.         if(l=='-' && c==' ') break;
  1642.         }
  1643.     }
  1644.     fname[j] = '\0';
  1645.     return j - oj;
  1646. }
  1647.  
  1648. /* translate from function pointer to function name. */
  1649.  
  1650. char *function_name(fpoint)
  1651. register PF fpoint;
  1652. {
  1653.     register FUNCTNAMES    *fnp = &functnames[0];
  1654.  
  1655.     if(fpoint == prefix) return (char *)NULL;    /* ambiguous */
  1656.     do {
  1657.         if(fnp->n_funct == fpoint) return fnp->n_name;
  1658.     } while(++fnp < &functnames[NFUNCT]);
  1659.     return (char *)NULL;
  1660. }
  1661. SHAR_EOF
  1662. cat << \SHAR_EOF > line.c
  1663. /*
  1664.  *        Text line handling.
  1665.  * The functions in this file
  1666.  * are a general set of line management
  1667.  * utilities. They are the only routines that
  1668.  * touch the text. They also touch the buffer
  1669.  * and window structures, to make sure that the
  1670.  * necessary updating gets done. There are routines
  1671.  * in this file that handle the kill buffer too.
  1672.  * It isn't here for any good reason.
  1673.  *
  1674.  * Note that this code only updates the dot and
  1675.  * mark values in the window list. Since all the code
  1676.  * acts on the current window, the buffer that we
  1677.  * are editing must be being displayed, which means
  1678.  * that "b_nwnd" is non zero, which means that the
  1679.  * dot and mark values in the buffer headers are
  1680.  * nonsense.
  1681.  */
  1682. #include    "def.h"
  1683.  
  1684. /* number of bytes member is from start of structure type    */
  1685. /* should be computed at compile time                */
  1686.  
  1687. #ifndef OFFSET
  1688. #define OFFSET(type,member) ((char *)&(((type *)0)->member)-(char *)((type *)0))
  1689. #endif
  1690.  
  1691. #ifndef NBLOCK
  1692. #define NBLOCK    16            /* Line block chunk size    */
  1693. #endif
  1694.  
  1695. #ifndef KBLOCK
  1696. #define KBLOCK    256            /* Kill buffer block size.    */
  1697. #endif
  1698.  
  1699. static char    *kbufp    = NULL;        /* Kill buffer data.        */
  1700. static RSIZE    kused    = 0;        /* # of bytes used in KB.    */
  1701. static RSIZE    ksize    = 0;        /* # of bytes allocated in KB.    */
  1702. static RSIZE    kstart    = 0;        /* # of first used byte in KB.    */
  1703.  
  1704. /*
  1705.  * This routine allocates a block of memory large enough to hold a LINE
  1706.  * containing "used" characters. The block is rounded up to whatever
  1707.  * needs to be allocated. (use lallocx for lines likely to grow.)
  1708.  * Return a pointer to the new block, or NULL if there isn't
  1709.  * any memory left. Print a message in the message line if no space.
  1710.  */
  1711. LINE *
  1712. lalloc(used) register int used; {
  1713.     register LINE    *lp;
  1714.     register int    size;
  1715.  
  1716.     /* any padding at the end of the structure is used */
  1717.     if((size = used + OFFSET(LINE, l_text[0])) < sizeof(LINE))
  1718.         size = sizeof(LINE);
  1719. #ifdef MALLOCROUND
  1720.     MALLOCROUND(size);    /* round up to a size optimal to malloc */
  1721. #endif
  1722.     if((lp = (LINE *)malloc((unsigned)size)) == NULL) {
  1723.         ewprintf("Can't get %d bytes", size);
  1724.         return (LINE *)NULL;
  1725.     }
  1726.     lp->l_size = size - OFFSET(LINE, l_text[0]);
  1727.     lp->l_used = used;
  1728.     return lp;
  1729. }
  1730.  
  1731. /*
  1732.  * Like lalloc, only round amount desired up because this line will
  1733.  * probably grow.  We always make room for at least one more char.
  1734.  * (thus making 0 not a special case anymore.)
  1735.  */
  1736. LINE *
  1737. lallocx(used)
  1738. int used;
  1739. {
  1740.     register int size;
  1741.     register LINE *lp;
  1742.  
  1743.     size = (NBLOCK+used) & ~(NBLOCK-1);
  1744.     if((lp = lalloc(size)) != NULL) lp->l_used = used;
  1745.     return lp;
  1746. }
  1747.  
  1748. /*
  1749.  * Delete line "lp". Fix all of the
  1750.  * links that might point at it (they are
  1751.  * moved to offset 0 of the next line.
  1752.  * Unlink the line from whatever buffer it
  1753.  * might be in. Release the memory. The
  1754.  * buffers are updated too; the magic conditions
  1755.  * described in the above comments don't hold
  1756.  * here.
  1757.  */
  1758. VOID
  1759. lfree(lp) register LINE *lp; {
  1760.     register BUFFER *bp;
  1761.     register WINDOW *wp;
  1762.  
  1763.     for(wp = wheadp; wp != NULL; wp = wp->w_wndp) {
  1764.         if (wp->w_linep == lp)
  1765.             wp->w_linep = lp->l_fp;
  1766.         if (wp->w_dotp    == lp) {
  1767.             wp->w_dotp  = lp->l_fp;
  1768.             wp->w_doto  = 0;
  1769.         }
  1770.         if (wp->w_markp == lp) {
  1771.             wp->w_markp = lp->l_fp;
  1772.             wp->w_marko = 0;
  1773.         }
  1774.     }
  1775.     for(bp = bheadp; bp != NULL; bp = bp->b_bufp) {
  1776.         if (bp->b_nwnd == 0) {
  1777.             if (bp->b_dotp    == lp) {
  1778.                 bp->b_dotp = lp->l_fp;
  1779.                 bp->b_doto = 0;
  1780.             }
  1781.             if (bp->b_markp == lp) {
  1782.                 bp->b_markp = lp->l_fp;
  1783.                 bp->b_marko = 0;
  1784.             }
  1785.         }
  1786.     }
  1787.     lp->l_bp->l_fp = lp->l_fp;
  1788.     lp->l_fp->l_bp = lp->l_bp;
  1789.     free((char *) lp);
  1790. }
  1791.  
  1792. /*
  1793.  * This routine gets called when
  1794.  * a character is changed in place in the
  1795.  * current buffer. It updates all of the required
  1796.  * flags in the buffer and window system. The flag
  1797.  * used is passed as an argument; if the buffer is being
  1798.  * displayed in more than 1 window we change EDIT to
  1799.  * HARD. Set MODE if the mode line needs to be
  1800.  * updated (the "*" has to be set).
  1801.  */
  1802. VOID
  1803. lchange(flag) register int flag; {
  1804.     register WINDOW *wp;
  1805.  
  1806.     if ((curbp->b_flag&BFCHG) == 0) {    /* First change, so    */
  1807.         flag |= WFMODE;            /* update mode lines.    */
  1808.         curbp->b_flag |= BFCHG;
  1809.     }
  1810.     for(wp = wheadp; wp != NULL; wp = wp->w_wndp) {
  1811.         if (wp->w_bufp == curbp) {
  1812.             wp->w_flag |= flag;
  1813.             if(wp != curwp) wp->w_flag |= WFHARD;
  1814.         }
  1815.     }
  1816. }
  1817.  
  1818. /*
  1819.  * Insert "n" copies of the character "c"
  1820.  * at the current location of dot. In the easy case
  1821.  * all that happens is the text is stored in the line.
  1822.  * In the hard case, the line has to be reallocated.
  1823.  * When the window list is updated, take special
  1824.  * care; I screwed it up once. You always update dot
  1825.  * in the current window. You update mark, and a
  1826.  * dot in another window, if it is greater than
  1827.  * the place where you did the insert. Return TRUE
  1828.  * if all is well, and FALSE on errors.
  1829.  */
  1830. linsert(n, c)
  1831. int n;
  1832. {
  1833.     register char    *cp1;
  1834.     register char    *cp2;
  1835.     register LINE    *lp1;
  1836.     LINE        *lp2;
  1837.     LINE        *lp3;
  1838.     register int    doto;
  1839.     register RSIZE    i;
  1840.     WINDOW        *wp;
  1841.  
  1842.     lchange(WFEDIT);
  1843.     lp1 = curwp->w_dotp;            /* Current line        */
  1844.     if (lp1 == curbp->b_linep) {        /* At the end: special    */
  1845.             /* (now should only happen in empty buffer    */
  1846.         if (curwp->w_doto != 0) {
  1847.             ewprintf("bug: linsert");
  1848.             return FALSE;
  1849.         }
  1850.         if ((lp2=lallocx(n)) == NULL) /* Allocate new line */
  1851.             return FALSE;
  1852.         lp3 = lp1->l_bp;        /* Previous line    */
  1853.         lp3->l_fp = lp2;        /* Link in        */
  1854.         lp2->l_fp = lp1;
  1855.         lp1->l_bp = lp2;
  1856.         lp2->l_bp = lp3;
  1857.         for (i=0; i<n; ++i)
  1858.             lp2->l_text[i] = c;
  1859.         for(wp = wheadp; wp != NULL; wp = wp->w_wndp) {
  1860.             if (wp->w_linep == lp1)
  1861.                 wp->w_linep = lp2;
  1862.             if (wp->w_dotp == lp1)
  1863.                 wp->w_dotp = lp2;
  1864.             if (wp->w_markp == lp1)
  1865.                 wp->w_markp = lp2;
  1866.         }
  1867.         /*NOSTRICT*/
  1868.         curwp->w_doto = n;
  1869.         return TRUE;
  1870.     }
  1871.     doto = curwp->w_doto;            /* Save for later.    */
  1872.     /*NOSTRICT (2) */
  1873.     if (lp1->l_used+n > lp1->l_size) {    /* Hard: reallocate    */
  1874.         if ((lp2=lallocx(lp1->l_used+n)) == NULL)
  1875.             return FALSE;
  1876.         cp1 = &lp1->l_text[0];
  1877.         cp2 = &lp2->l_text[0];
  1878.         while (cp1 != &lp1->l_text[doto])
  1879.             *cp2++ = *cp1++;
  1880.         /*NOSTRICT*/
  1881.         cp2 += n;
  1882.         while (cp1 != &lp1->l_text[lp1->l_used])
  1883.             *cp2++ = *cp1++;
  1884.         lp1->l_bp->l_fp = lp2;
  1885.         lp2->l_fp = lp1->l_fp;
  1886.         lp1->l_fp->l_bp = lp2;
  1887.         lp2->l_bp = lp1->l_bp;
  1888.         free((char *) lp1);
  1889.     } else {                /* Easy: in place    */
  1890.         lp2 = lp1;            /* Pretend new line    */
  1891.         /*NOSTRICT*/
  1892.         lp2->l_used += n;
  1893.         cp2 = &lp1->l_text[lp1->l_used];
  1894.  
  1895.         cp1 = cp2-n;
  1896.         while (cp1 != &lp1->l_text[doto])
  1897.             *--cp2 = *--cp1;
  1898.     }
  1899.     for (i=0; i<n; ++i)            /* Add the characters    */
  1900.         lp2->l_text[doto+i] = c;
  1901.  
  1902.     for(wp = wheadp; wp != NULL; wp = wp->w_wndp) {
  1903.         if (wp->w_linep == lp1)
  1904.             wp->w_linep = lp2;
  1905.         if (wp->w_dotp == lp1) {
  1906.             wp->w_dotp = lp2;
  1907.             if (wp==curwp || wp->w_doto>doto)
  1908.                 /*NOSTRICT*/
  1909.                 wp->w_doto += n;
  1910.         }
  1911.         if (wp->w_markp == lp1) {
  1912.             wp->w_markp = lp2;
  1913.             if (wp->w_marko > doto)
  1914.                 /*NOSTRICT*/
  1915.                 wp->w_marko += n;
  1916.         }
  1917.     }
  1918.     return TRUE;
  1919. }
  1920.  
  1921. /*
  1922.  * Insert a newline into the buffer
  1923.  * at the current location of dot in the current
  1924.  * window.  The funny ass-backwards way is no longer used.
  1925.  */
  1926. lnewline()
  1927. {
  1928.     register LINE    *lp1;
  1929.     register LINE    *lp2;
  1930.     register int    doto;
  1931.     register int    nlen;
  1932.     WINDOW        *wp;
  1933.  
  1934.     lchange(WFHARD);
  1935.     lp1  = curwp->w_dotp;            /* Get the address and    */
  1936.     doto = curwp->w_doto;            /* offset of "."    */
  1937.     if(doto == 0) {                /* avoid unnessisary copying */
  1938.         if((lp2 = lallocx(0)) == NULL)    /* new first part    */
  1939.             return FALSE;
  1940.         lp2->l_bp = lp1->l_bp;
  1941.         lp1->l_bp->l_fp = lp2;
  1942.         lp2->l_fp = lp1;
  1943.         lp1->l_bp = lp2;
  1944.         for(wp = wheadp; wp!=NULL; wp = wp->w_wndp)
  1945.             if(wp->w_linep == lp1) wp->w_linep = lp2;
  1946.         return    TRUE;
  1947.     }
  1948.     nlen = llength(lp1) - doto;        /* length of new part    */
  1949.     if((lp2=lallocx(nlen)) == NULL)        /* New second half line */
  1950.         return FALSE;
  1951.     if(nlen!=0) bcopy(&lp1->l_text[doto], &lp2->l_text[0], nlen);
  1952.     lp1->l_used = doto;
  1953.     lp2->l_bp = lp1;
  1954.     lp2->l_fp = lp1->l_fp;
  1955.     lp1->l_fp = lp2;
  1956.     lp2->l_fp->l_bp = lp2;
  1957.     for(wp = wheadp; wp != NULL; wp = wp->w_wndp) { /* Windows    */
  1958.         if (wp->w_dotp == lp1 && wp->w_doto >= doto) {
  1959.             wp->w_dotp = lp2;
  1960.             wp->w_doto -= doto;
  1961.         }
  1962.         if (wp->w_markp == lp1 && wp->w_marko >= doto) {
  1963.             wp->w_markp = lp2;
  1964.             wp->w_marko -= doto;
  1965.         }
  1966.     }
  1967.     return TRUE;
  1968. }
  1969.  
  1970. /*
  1971.  * This function deletes "n" bytes,
  1972.  * starting at dot. It understands how do deal
  1973.  * with end of lines, etc. It returns TRUE if all
  1974.  * of the characters were deleted, and FALSE if
  1975.  * they were not (because dot ran into the end of
  1976.  * the buffer. The "kflag" indicates either no insertion,
  1977.  * or direction of insertion into the kill buffer.
  1978.  */
  1979. ldelete(n, kflag) RSIZE n; {
  1980.     register char    *cp1;
  1981.     register char    *cp2;
  1982.     register LINE    *dotp;
  1983.     register int    doto;
  1984.     register RSIZE    chunk;
  1985.     WINDOW        *wp;
  1986.  
  1987.     /*
  1988.      * HACK - doesn't matter, and fixes back-over-nl bug for empty
  1989.      *    kill buffers.
  1990.      */
  1991.     if (kused == kstart) kflag = KFORW;
  1992.  
  1993.     while (n != 0) {
  1994.         dotp = curwp->w_dotp;
  1995.         doto = curwp->w_doto;
  1996.         if (dotp == curbp->b_linep)    /* Hit end of buffer.    */
  1997.             return FALSE;
  1998.         chunk = dotp->l_used-doto;    /* Size of chunk.    */
  1999.         if (chunk > n)
  2000.             chunk = n;
  2001.         if (chunk == 0) {        /* End of line, merge.    */
  2002.             if(dotp == lback(curbp->b_linep))
  2003.                 return FALSE;    /* End of buffer.    */
  2004.             lchange(WFHARD);
  2005.             if (ldelnewline() == FALSE
  2006.             || (kflag!=KNONE && kinsert('\n', kflag)==FALSE))
  2007.                 return FALSE;
  2008.             --n;
  2009.             continue;
  2010.         }
  2011.         lchange(WFEDIT);
  2012.         cp1 = &dotp->l_text[doto];    /* Scrunch text.    */
  2013.         cp2 = cp1 + chunk;
  2014.         if (kflag == KFORW) {
  2015.             while (ksize - kused < chunk)
  2016.                 if (kgrow(FALSE) == FALSE) return FALSE;
  2017.             bcopy(cp1, &(kbufp[kused]), (int) chunk);
  2018.             kused += chunk;
  2019.         } else if (kflag == KBACK) {
  2020.             while (kstart < chunk)
  2021.                 if (kgrow(TRUE) == FALSE) return FALSE;
  2022.             bcopy(cp1, &(kbufp[kstart-chunk]), (int) chunk);
  2023.             kstart -= chunk;
  2024.         } else if (kflag != KNONE) panic("broken ldelete call");
  2025.         while (cp2 != &dotp->l_text[dotp->l_used])
  2026.             *cp1++ = *cp2++;
  2027.         dotp->l_used -= (int) chunk;
  2028.         for(wp = wheadp; wp != NULL; wp = wp->w_wndp ) {
  2029.             if (wp->w_dotp==dotp && wp->w_doto>=doto) {
  2030.                 /*NOSTRICT*/
  2031.                 wp->w_doto -= chunk;
  2032.                 if (wp->w_doto < doto)
  2033.                     wp->w_doto = doto;
  2034.             }
  2035.             if (wp->w_markp==dotp && wp->w_marko>=doto) {
  2036.                 /*NOSTRICT*/
  2037.                 wp->w_marko -= chunk;
  2038.                 if (wp->w_marko < doto)
  2039.                     wp->w_marko = doto;
  2040.             }
  2041.         }
  2042.         n -= chunk;
  2043.     }
  2044.     return TRUE;
  2045. }
  2046.  
  2047. /*
  2048.  * Delete a newline. Join the current line
  2049.  * with the next line. If the next line is the magic
  2050.  * header line always return TRUE; merging the last line
  2051.  * with the header line can be thought of as always being a
  2052.  * successful operation, even if nothing is done, and this makes
  2053.  * the kill buffer work "right". Easy cases can be done by
  2054.  * shuffling data around. Hard cases require that lines be moved
  2055.  * about in memory. Return FALSE on error and TRUE if all
  2056.  * looks ok.
  2057.  */
  2058. ldelnewline() {
  2059.     register LINE    *lp1;
  2060.     register LINE    *lp2;
  2061.     register WINDOW *wp;
  2062.     LINE        *lp3;
  2063.  
  2064.     lp1 = curwp->w_dotp;
  2065.     lp2 = lp1->l_fp;
  2066.     if (lp2 == curbp->b_linep)        /* At the buffer end.    */
  2067.         return TRUE;
  2068.     if (lp2->l_used <= lp1->l_size - lp1->l_used) {
  2069.         bcopy(&lp2->l_text[0], &lp1->l_text[lp1->l_used], lp2->l_used);
  2070.         for(wp = wheadp; wp != NULL; wp = wp->w_wndp) {
  2071.             if (wp->w_linep == lp2)
  2072.                 wp->w_linep = lp1;
  2073.             if (wp->w_dotp == lp2) {
  2074.                 wp->w_dotp  = lp1;
  2075.                 wp->w_doto += lp1->l_used;
  2076.             }
  2077.             if (wp->w_markp == lp2) {
  2078.                 wp->w_markp  = lp1;
  2079.                 wp->w_marko += lp1->l_used;
  2080.             }
  2081.         }
  2082.         lp1->l_used += lp2->l_used;
  2083.         lp1->l_fp = lp2->l_fp;
  2084.         lp2->l_fp->l_bp = lp1;
  2085.         free((char *) lp2);
  2086.         return TRUE;
  2087.     }
  2088.     if ((lp3=lalloc(lp1->l_used + lp2->l_used)) == NULL)
  2089.         return FALSE;
  2090.     bcopy(&lp1->l_text[0], &lp3->l_text[0], lp1->l_used);
  2091.     bcopy(&lp2->l_text[0], &lp3->l_text[lp1->l_used], lp2->l_used);
  2092.     lp1->l_bp->l_fp = lp3;
  2093.     lp3->l_fp = lp2->l_fp;
  2094.     lp2->l_fp->l_bp = lp3;
  2095.     lp3->l_bp = lp1->l_bp;
  2096.     for(wp = wheadp; wp != NULL; wp = wp->w_wndp) {
  2097.         if (wp->w_linep==lp1 || wp->w_linep==lp2)
  2098.             wp->w_linep = lp3;
  2099.         if (wp->w_dotp == lp1)
  2100.             wp->w_dotp  = lp3;
  2101.         else if (wp->w_dotp == lp2) {
  2102.             wp->w_dotp  = lp3;
  2103.             wp->w_doto += lp1->l_used;
  2104.         }
  2105.         if (wp->w_markp == lp1)
  2106.             wp->w_markp  = lp3;
  2107.         else if (wp->w_markp == lp2) {
  2108.             wp->w_markp  = lp3;
  2109.             wp->w_marko += lp1->l_used;
  2110.         }
  2111.     }
  2112.     free((char *) lp1);
  2113.     free((char *) lp2);
  2114.     return TRUE;
  2115. }
  2116.  
  2117. /*
  2118.  * Replace plen characters before dot with argument string.
  2119.  * Control-J characters in st are interpreted as newlines.
  2120.  * There is a casehack disable flag (normally it likes to match
  2121.  * case of replacement to what was there).
  2122.  */
  2123. lreplace(plen, st, f)
  2124. register RSIZE    plen;            /* length to remove        */
  2125. char        *st;            /* replacement string        */
  2126. int        f;            /* case hack disable        */
  2127. {
  2128.     register RSIZE    rlen;        /* replacement length        */
  2129.     register int    rtype;        /* capitalization        */
  2130.     register int    c;        /* used for random characters    */
  2131.     register int    doto;        /* offset into line        */
  2132.  
  2133.     /*
  2134.      * Find the capitalization of the word that was found.
  2135.      * f says use exact case of replacement string (same thing that
  2136.      * happens with lowercase found), so bypass check.
  2137.      */
  2138.     /*NOSTRICT*/
  2139.     (VOID) backchar(FFARG | FFRAND, (int) plen);
  2140.     rtype = _L;
  2141.     c = lgetc(curwp->w_dotp, curwp->w_doto);
  2142.     if (ISUPPER(c)!=FALSE  &&  f==FALSE) {
  2143.         rtype = _U|_L;
  2144.         if (curwp->w_doto+1 < llength(curwp->w_dotp)) {
  2145.             c = lgetc(curwp->w_dotp, curwp->w_doto+1);
  2146.             if (ISUPPER(c) != FALSE) {
  2147.                 rtype = _U;
  2148.             }
  2149.         }
  2150.     }
  2151.  
  2152.     /*
  2153.      * make the string lengths match (either pad the line
  2154.      * so that it will fit, or scrunch out the excess).
  2155.      * be careful with dot's offset.
  2156.      */
  2157.     rlen = strlen(st);
  2158.     doto = curwp->w_doto;
  2159.     if (plen > rlen)
  2160.         (VOID) ldelete((RSIZE) (plen-rlen), KNONE);
  2161.     else if (plen < rlen) {
  2162.         if (linsert((int)(rlen-plen), ' ') == FALSE)
  2163.             return FALSE;
  2164.     }
  2165.     curwp->w_doto = doto;
  2166.  
  2167.     /*
  2168.      * do the replacement:    If was capital, then place first
  2169.      * char as if upper, and subsequent chars as if lower.
  2170.      * If inserting upper, check replacement for case.
  2171.      */
  2172.     while ((c = CHARMASK(*st++)) != '\0') {
  2173.         if ((rtype&_U)!=0  &&  ISLOWER(c)!=0)
  2174.             c = TOUPPER(c);
  2175.         if (rtype == (_U|_L))
  2176.             rtype = _L;
  2177.         if (c == CCHR('J')) {
  2178.             if (curwp->w_doto == llength(curwp->w_dotp))
  2179.                 (VOID) forwchar(FFRAND, 1);
  2180.             else {
  2181.                 if (ldelete((RSIZE) 1, KNONE) != FALSE)
  2182.                     (VOID) lnewline();
  2183.             }
  2184.         } else if (curwp->w_dotp == curbp->b_linep) {
  2185.             (VOID) linsert(1, c);
  2186.         } else if (curwp->w_doto == llength(curwp->w_dotp)) {
  2187.             if (ldelete((RSIZE) 1, KNONE) != FALSE)
  2188.                 (VOID) linsert(1, c);
  2189.         } else
  2190.             lputc(curwp->w_dotp, curwp->w_doto++, c);
  2191.     }
  2192.     lchange(WFHARD);
  2193.     return (TRUE);
  2194. }
  2195.  
  2196. /*
  2197.  * Delete all of the text
  2198.  * saved in the kill buffer. Called by commands
  2199.  * when a new kill context is being created. The kill
  2200.  * buffer array is released, just in case the buffer has
  2201.  * grown to immense size. No errors.
  2202.  */
  2203. VOID
  2204. kdelete() {
  2205.     if (kbufp != NULL) {
  2206.         free((char *) kbufp);
  2207.         kbufp = NULL;
  2208.         kstart = kused = ksize = 0;
  2209.     }
  2210. }
  2211.  
  2212. /*
  2213.  * Insert a character to the kill buffer,
  2214.  * enlarging the buffer if there isn't any room. Always
  2215.  * grow the buffer in chunks, on the assumption that if you
  2216.  * put something in the kill buffer you are going to put
  2217.  * more stuff there too later. Return TRUE if all is
  2218.  * well, and FALSE on errors. Print a message on
  2219.  * errors. Dir says whether to put it at back or front.
  2220.  */
  2221. kinsert(c, dir) {
  2222.  
  2223.     if (kused == ksize && dir == KFORW && kgrow(FALSE) == FALSE)
  2224.         return FALSE;
  2225.     if (kstart == 0 && dir == KBACK && kgrow(TRUE) == FALSE)
  2226.         return FALSE;
  2227.     if (dir == KFORW) kbufp[kused++] = c;
  2228.     else if (dir == KBACK) kbufp[--kstart] = c;
  2229.     else panic("broken kinsert call");        /* Oh shit! */
  2230.     return (TRUE);
  2231. }
  2232.  
  2233. /*
  2234.  * kgrow - just get more kill buffer for the callee. back is true if
  2235.  * we are trying to get space at the beginning of the kill buffer.
  2236.  */
  2237. kgrow(back) {
  2238.     register int    nstart;
  2239.     register char    *nbufp;
  2240.  
  2241.     if ((unsigned)(ksize+KBLOCK) <= (unsigned)ksize) {
  2242.         /* probably 16 bit unsigned */
  2243.         ewprintf("Kill buffer size at maximum");
  2244.         return FALSE;
  2245.     }
  2246.     if ((nbufp=malloc((unsigned)(ksize+KBLOCK))) == NULL) {
  2247.         ewprintf("Can't get %ld bytes", (long)(ksize+KBLOCK));
  2248.         return FALSE;
  2249.     }
  2250.     nstart = (back == TRUE) ? (kstart + KBLOCK) : (KBLOCK / 4) ;
  2251.     bcopy(&(kbufp[kstart]), &(nbufp[nstart]), (int) (kused-kstart));
  2252.     if (kbufp != NULL)
  2253.         free((char *) kbufp);
  2254.     kbufp  = nbufp;
  2255.     ksize += KBLOCK;
  2256.     kused = kused - kstart + nstart;
  2257.     kstart = nstart;
  2258.     return TRUE;
  2259. }
  2260.  
  2261. /*
  2262.  * This function gets characters from
  2263.  * the kill buffer. If the character index "n" is
  2264.  * off the end, it returns "-1". This lets the caller
  2265.  * just scan along until it gets a "-1" back.
  2266.  */
  2267. kremove(n) {
  2268.     if (n < 0 || n + kstart >= kused)
  2269.         return -1;
  2270.     return CHARMASK(kbufp[n + kstart]);
  2271. }
  2272. SHAR_EOF
  2273. cat << \SHAR_EOF > macro.h
  2274. /* definitions for keyboard macros */
  2275.  
  2276. #ifndef EXTERN
  2277. #define EXTERN extern
  2278. #define INIT(i)
  2279. #endif
  2280.  
  2281. #define MAXMACRO 256        /* maximum functs in a macro */
  2282.  
  2283. EXTERN    int inmacro    INIT(FALSE);
  2284. EXTERN    int macrodef    INIT(FALSE);
  2285. EXTERN    int macrocount    INIT(0);
  2286.  
  2287. EXTERN    union {
  2288.     PF    m_funct;
  2289.     int    m_count;    /* for count-prefix    */
  2290. }    macro[MAXMACRO];
  2291.  
  2292. EXTERN    LINE *maclhead    INIT(NULL);
  2293. EXTERN    LINE *maclcur;
  2294.  
  2295. #undef    EXTERN
  2296. #undef    INIT
  2297. SHAR_EOF
  2298. cat << \SHAR_EOF > main.c
  2299. /*
  2300.  *        Mainline
  2301.  */
  2302. #include    "def.h"
  2303. #ifndef NO_MACRO
  2304. #include    "macro.h"
  2305. #endif
  2306.  
  2307. int    thisflag;            /* Flags, this command        */
  2308. int    lastflag;            /* Flags, last command        */
  2309. int    curgoal;            /* Goal column            */
  2310. BUFFER    *curbp;                /* Current buffer        */
  2311. WINDOW    *curwp;                /* Current window        */
  2312. BUFFER    *bheadp;            /* BUFFER listhead        */
  2313. WINDOW    *wheadp = (WINDOW *)NULL;    /* WINDOW listhead        */
  2314. char    pat[NPAT];            /* Pattern            */
  2315. #ifndef NO_DPROMPT
  2316. extern char prompt[], *promptp;        /* delayed prompting        */
  2317. #endif
  2318.  
  2319. static VOID    edinit();
  2320.  
  2321. VOID
  2322. main(argc, argv)
  2323. int  argc;
  2324. char **argv;
  2325. {
  2326. #ifndef NO_STARTUP
  2327.     char    *startupfile();
  2328. #endif
  2329.     char    *cp;
  2330.     VOID    vtinit(), makename(), eerase();
  2331.     BUFFER    *findbuffer();
  2332.  
  2333. #ifdef SYSINIT
  2334.     SYSINIT;                /* system dependent.    */
  2335. #endif
  2336.     vtinit();                /* Virtual terminal.    */
  2337. #ifndef NO_DIR
  2338.     dirinit();                /* Get current directory */
  2339. #endif
  2340.     edinit();                /* Buffers, windows.    */
  2341.     ttykeymapinit();            /* Symbols, bindings.    */
  2342.     /* doing update() before reading files causes the error messages from
  2343.      * the file I/O show up on the screen.    (and also an extra display
  2344.      * of the mode line if there are files specified on the command line.)
  2345.      */
  2346.     update();
  2347. #ifndef NO_STARTUP                /* User startup file.    */
  2348.     if ((cp = startupfile((char *)NULL)) != NULL)
  2349.         (VOID) load(cp);
  2350. #endif
  2351.     while (--argc > 0) {
  2352.         cp = adjustname(*++argv);
  2353.         curbp = findbuffer(cp);
  2354.         (VOID) showbuffer(curbp, curwp, 0);
  2355.         (VOID) readin(cp);
  2356.     }
  2357.     thisflag = 0;                /* Fake last flags.    */
  2358.     for(;;) {
  2359. #ifndef NO_DPROMPT
  2360.         *(promptp = prompt) = '\0';
  2361.         if(epresf == KPROMPT) eerase();
  2362. #endif
  2363.         update();
  2364.         lastflag = thisflag;
  2365.         thisflag = 0;
  2366.         switch(doin()) {
  2367.         case TRUE: break;
  2368.         case ABORT:
  2369.             ewprintf("Quit");        /* and fall through    */
  2370.         case FALSE:
  2371.         default:
  2372.             ttbeep();
  2373. #ifndef NO_MACRO
  2374.             macrodef = FALSE;
  2375. #endif
  2376.         }
  2377.     }
  2378. }
  2379.  
  2380. /*
  2381.  * Initialize default buffer and window.
  2382.  */
  2383. static VOID
  2384. edinit() {
  2385.     register BUFFER *bp;
  2386.     register WINDOW *wp;
  2387.  
  2388.     bheadp = NULL;
  2389.     bp = bfind("*scratch*", TRUE);        /* Text buffer.        */
  2390.     wp = (WINDOW *)malloc(sizeof(WINDOW));    /* Initial window.    */
  2391.     if (bp==NULL || wp==NULL) panic("edinit");
  2392.     curbp  = bp;                /* Current ones.    */
  2393.     wheadp = wp;
  2394.     curwp  = wp;
  2395.     wp->w_wndp  = NULL;            /* Initialize window.    */
  2396.     wp->w_bufp  = bp;
  2397.     bp->b_nwnd  = 1;            /* Displayed.        */
  2398.     wp->w_linep = wp->w_dotp = bp->b_linep;
  2399.     wp->w_doto  = 0;
  2400.     wp->w_markp = NULL;
  2401.     wp->w_marko = 0;
  2402.     wp->w_toprow = 0;
  2403.     wp->w_ntrows = nrow-2;            /* 2 = mode, echo.    */
  2404.     wp->w_force = 0;
  2405.     wp->w_flag  = WFMODE|WFHARD;        /* Full.        */
  2406. }
  2407.  
  2408. /*
  2409.  * Quit command. If an argument, always
  2410.  * quit. Otherwise confirm if a buffer has been
  2411.  * changed and not written out. Normally bound
  2412.  * to "C-X C-C".
  2413.  */
  2414. /*ARGSUSED*/
  2415. quit(f, n)
  2416. {
  2417.     register int    s;
  2418.     VOID        vttidy();
  2419.  
  2420.     if ((s = anycb(FALSE)) == ABORT) return ABORT;
  2421.     if (s == FALSE
  2422.     || eyesno("Some modified buffers exist, really exit") == TRUE) {
  2423.         vttidy();
  2424. #ifdef    SYSCLEANUP
  2425.     SYSCLEANUP;
  2426. #endif
  2427.         exit(GOOD);
  2428.     }
  2429.     return TRUE;
  2430. }
  2431.  
  2432. /*
  2433.  * User abort. Should be called by any input routine that sees a C-g
  2434.  * to abort whatever C-g is aborting these days. Currently does
  2435.  * nothing.
  2436.  */
  2437. /*ARGSUSED*/
  2438. ctrlg(f, n)
  2439. {
  2440.     return ABORT;
  2441. }
  2442. SHAR_EOF
  2443. #    End of shell archive
  2444. exit 0
  2445. -------
  2446.