home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume1 / 8711 / microemacs-3.9 / 13 < prev    next >
Text File  |  1987-11-20  |  38KB  |  1,491 lines

  1. Article 90 of comp.sources.misc:
  2. Path: tut!osu-cis!cbosgd!mandrill!hal!ncoast!allbery
  3. From: nwd@j.cc.purdue.edu (Daniel Lawrence)
  4. Newsgroups: comp.sources.misc
  5. Subject: MicroEmacs 3.9 (Part 13 of 16)
  6. Message-ID: <5689@ncoast.UUCP>
  7. Date: 17 Nov 87 02:35:24 GMT
  8. Sender: allbery@ncoast.UUCP
  9. Lines: 1476
  10. Approved: allbery@ncoast.UUCP
  11. X-Archive: comp.sources.misc/microemacs-3.9/12
  12.  
  13. # This is a shar archive.
  14. # Remove everything above this line.
  15. # Run the file through sh, not csh.
  16. # (type `sh mes.13')
  17. # If you do not see the message
  18. #    `mes.13 completed!'
  19. # then the file was incomplete.
  20. echo extracting - vt52.c
  21. sed 's/^X//' > vt52.c << 'FRIDAY_NIGHT'
  22. X/*
  23. X * The routines in this file
  24. X * provide support for VT52 style terminals
  25. X * over a serial line. The serial I/O services are
  26. X * provided by routines in "termio.c". It compiles
  27. X * into nothing if not a VT52 style device. The
  28. X * bell on the VT52 is terrible, so the "beep"
  29. X * routine is conditionalized on defining BEL.
  30. X */
  31. X#define    termdef    1            /* don't define "term" external */
  32. X
  33. X#include        <stdio.h>
  34. X#include        "estruct.h"
  35. X#include    "edef.h"
  36. X
  37. X#if     VT52
  38. X
  39. X#define NROW    24                      /* Screen size.                 */
  40. X#define NCOL    80                      /* Edit if you want to.         */
  41. X#define    MARGIN    8            /* size of minimim margin and    */
  42. X#define    SCRSIZ    64            /* scroll size for extended lines */
  43. X#define    NPAUSE    100            /* # times thru update to pause */
  44. X#define BIAS    0x20                    /* Origin 0 coordinate bias.    */
  45. X#define ESC     0x1B                    /* ESC character.               */
  46. X#define BEL     0x07                    /* ascii bell character         */
  47. X
  48. Xextern  int     ttopen();               /* Forward references.          */
  49. Xextern  int     ttgetc();
  50. Xextern  int     ttputc();
  51. Xextern  int     ttflush();
  52. Xextern  int     ttclose();
  53. Xextern  int     vt52move();
  54. Xextern  int     vt52eeol();
  55. Xextern  int     vt52eeop();
  56. Xextern  int     vt52beep();
  57. Xextern  int     vt52open();
  58. Xextern    int    vt52rev();
  59. Xextern    int    vt52cres();
  60. Xextern    int    vt52kopen();
  61. Xextern    int    vt52kclose();
  62. X
  63. X#if    COLOR
  64. Xextern    int    vt52fcol();
  65. Xextern    int    vt52bcol();
  66. X#endif
  67. X
  68. X/*
  69. X * Dispatch table. All the
  70. X * hard fields just point into the
  71. X * terminal I/O code.
  72. X */
  73. XTERM    term    = {
  74. X    NROW-1,
  75. X        NROW-1,
  76. X        NCOL,
  77. X        NCOL,
  78. X    MARGIN,
  79. X    SCRSIZ,
  80. X    NPAUSE,
  81. X        &vt52open,
  82. X        &ttclose,
  83. X    &vt52kopen,
  84. X    &vt52kclose,
  85. X        &ttgetc,
  86. X        &ttputc,
  87. X        &ttflush,
  88. X        &vt52move,
  89. X        &vt52eeol,
  90. X        &vt52eeop,
  91. X        &vt52beep,
  92. X        &vt52rev,
  93. X        &vt52cres
  94. X#if    COLOR
  95. X    , &vt52fcol,
  96. X    &vt52bcol
  97. X#endif
  98. X};
  99. X
  100. Xvt52move(row, col)
  101. X{
  102. X        ttputc(ESC);
  103. X        ttputc('Y');
  104. X        ttputc(row+BIAS);
  105. X        ttputc(col+BIAS);
  106. X}
  107. X
  108. Xvt52eeol()
  109. X{
  110. X        ttputc(ESC);
  111. X        ttputc('K');
  112. X}
  113. X
  114. Xvt52eeop()
  115. X{
  116. X        ttputc(ESC);
  117. X        ttputc('J');
  118. X}
  119. X
  120. Xvt52rev(status)    /* set the reverse video state */
  121. X
  122. Xint status;    /* TRUE = reverse video, FALSE = normal video */
  123. X
  124. X{
  125. X    /* can't do this here, so we won't */
  126. X}
  127. X
  128. Xvt52cres()    /* change screen resolution - (not here though) */
  129. X
  130. X{
  131. X    return(TRUE);
  132. X}
  133. X
  134. Xspal()        /* change palette string */
  135. X
  136. X{
  137. X    /*    Does nothing here    */
  138. X}
  139. X
  140. X#if    COLOR
  141. Xvt52fcol()    /* set the forground color [NOT IMPLIMENTED] */
  142. X{
  143. X}
  144. X
  145. Xvt52bcol()    /* set the background color [NOT IMPLIMENTED] */
  146. X{
  147. X}
  148. X#endif
  149. X
  150. Xvt52beep()
  151. X{
  152. X#ifdef  BEL
  153. X        ttputc(BEL);
  154. X        ttflush();
  155. X#endif
  156. X}
  157. X
  158. Xvt52open()
  159. X{
  160. X#if     V7 | BSD
  161. X        register char *cp;
  162. X        char *getenv();
  163. X
  164. X        if ((cp = getenv("TERM")) == NULL) {
  165. X                puts("Shell variable TERM not defined!");
  166. X                exit(1);
  167. X        }
  168. X        if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) {
  169. X                puts("Terminal type not 'vt52'or 'z19' !");
  170. X                exit(1);
  171. X        }
  172. X#endif
  173. X        ttopen();
  174. X}
  175. X
  176. Xvt52kopen()
  177. X
  178. X{
  179. X}
  180. X
  181. Xvt52kclose()
  182. X
  183. X{
  184. X}
  185. X
  186. X
  187. X#if    FLABEL
  188. Xfnclabel(f, n)        /* label a function key */
  189. X
  190. Xint f,n;    /* default flag, numeric argument [unused] */
  191. X
  192. X{
  193. X    /* on machines with no function keys...don't bother */
  194. X    return(TRUE);
  195. X}
  196. X#endif
  197. X#else
  198. X
  199. Xvt52hello()
  200. X
  201. X{
  202. X}
  203. X
  204. X#endif
  205. FRIDAY_NIGHT
  206. echo extracting - window.c
  207. sed 's/^X//' > window.c << 'FRIDAY_NIGHT'
  208. X/*
  209. X * Window management. Some of the functions are internal, and some are
  210. X * attached to keys that the user actually types.
  211. X */
  212. X
  213. X#include        <stdio.h>
  214. X#include        "estruct.h"
  215. X#include    "edef.h"
  216. X
  217. X#if    MEGAMAX & ST520
  218. Xoverlay    "window"
  219. X#endif
  220. X
  221. X/*
  222. X * Reposition dot in the current window to line "n". If the argument is
  223. X * positive, it is that line. If it is negative it is that line from the
  224. X * bottom. If it is 0 the window is centered (this is what the standard
  225. X * redisplay code does). With no argument it defaults to 0. Bound to M-!.
  226. X */
  227. Xreposition(f, n)
  228. X    {
  229. X    if (f == FALSE)    /* default to 0 to center screen */
  230. X    n = 0;
  231. X    curwp->w_force = n;
  232. X    curwp->w_flag |= WFFORCE;
  233. X    return (TRUE);
  234. X    }
  235. X
  236. X/*
  237. X * Refresh the screen. With no argument, it just does the refresh. With an
  238. X * argument it recenters "." in the current window. Bound to "C-L".
  239. X */
  240. Xrefresh(f, n)
  241. X    {
  242. X    if (f == FALSE)
  243. X        sgarbf = TRUE;
  244. X    else
  245. X        {
  246. X        curwp->w_force = 0;             /* Center dot. */
  247. X        curwp->w_flag |= WFFORCE;
  248. X        }
  249. X
  250. X    return (TRUE);
  251. X    }
  252. X
  253. X/*
  254. X * The command make the next window (next => down the screen) the current
  255. X * window. There are no real errors, although the command does nothing if
  256. X * there is only 1 window on the screen. Bound to "C-X C-N".
  257. X *
  258. X * with an argument this command finds the <n>th window from the top
  259. X *
  260. X */
  261. Xnextwind(f, n)
  262. X
  263. Xint f, n;    /* default flag and numeric argument */
  264. X
  265. X{
  266. X    register WINDOW *wp;
  267. X    register int nwindows;        /* total number of windows */
  268. X
  269. X    if (f) {
  270. X
  271. X        /* first count the # of windows */
  272. X        wp = wheadp;
  273. X        nwindows = 1;
  274. X        while (wp->w_wndp != NULL) {
  275. X            nwindows++;
  276. X            wp = wp->w_wndp;
  277. X        }
  278. X
  279. X        /* if the argument is negative, it is the nth window
  280. X           from the bottom of the screen            */
  281. X        if (n < 0)
  282. X            n = nwindows + n + 1;
  283. X
  284. X        /* if an argument, give them that window from the top */
  285. X        if (n > 0 && n <= nwindows) {
  286. X            wp = wheadp;
  287. X            while (--n)
  288. X                wp = wp->w_wndp;
  289. X        } else {
  290. X            mlwrite("Window number out of range");
  291. X            return(FALSE);
  292. X        }
  293. X    } else
  294. X        if ((wp = curwp->w_wndp) == NULL)
  295. X            wp = wheadp;
  296. X    curwp = wp;
  297. X    curbp = wp->w_bufp;
  298. X    upmode();
  299. X    return (TRUE);
  300. X}
  301. X
  302. X/*
  303. X * This command makes the previous window (previous => up the screen) the
  304. X * current window. There arn't any errors, although the command does not do a
  305. X * lot if there is 1 window.
  306. X */
  307. Xprevwind(f, n)
  308. X{
  309. X    register WINDOW *wp1;
  310. X    register WINDOW *wp2;
  311. X
  312. X    /* if we have an argument, we mean the nth window from the bottom */
  313. X    if (f)
  314. X        return(nextwind(f, -n));
  315. X
  316. X    wp1 = wheadp;
  317. X    wp2 = curwp;
  318. X
  319. X    if (wp1 == wp2)
  320. X        wp2 = NULL;
  321. X
  322. X    while (wp1->w_wndp != wp2)
  323. X        wp1 = wp1->w_wndp;
  324. X
  325. X    curwp = wp1;
  326. X    curbp = wp1->w_bufp;
  327. X    upmode();
  328. X    return (TRUE);
  329. X}
  330. X
  331. X/*
  332. X * This command moves the current window down by "arg" lines. Recompute the
  333. X * top line in the window. The move up and move down code is almost completely
  334. X * the same; most of the work has to do with reframing the window, and picking
  335. X * a new dot. We share the code by having "move down" just be an interface to
  336. X * "move up". Magic. Bound to "C-X C-N".
  337. X */
  338. Xmvdnwind(f, n)
  339. X
  340. Xint n;
  341. X
  342. X{
  343. X    return (mvupwind(f, -n));
  344. X}
  345. X
  346. X/*
  347. X * Move the current window up by "arg" lines. Recompute the new top line of
  348. X * the window. Look to see if "." is still on the screen. If it is, you win.
  349. X * If it isn't, then move "." to center it in the new framing of the window
  350. X * (this command does not really move "."; it moves the frame). Bound to
  351. X * "C-X C-P".
  352. X */
  353. Xmvupwind(f, n)
  354. X    int n;
  355. X
  356. X    {
  357. X    register LINE *lp;
  358. X    register int i;
  359. X
  360. X    lp = curwp->w_linep;
  361. X
  362. X    if (n < 0)
  363. X        {
  364. X        while (n++ && lp!=curbp->b_linep)
  365. X            lp = lforw(lp);
  366. X        }
  367. X    else
  368. X        {
  369. X        while (n-- && lback(lp)!=curbp->b_linep)
  370. X            lp = lback(lp);
  371. X        }
  372. X
  373. X    curwp->w_linep = lp;
  374. X    curwp->w_flag |= WFHARD;            /* Mode line is OK. */
  375. X
  376. X    for (i = 0; i < curwp->w_ntrows; ++i)
  377. X        {
  378. X        if (lp == curwp->w_dotp)
  379. X            return (TRUE);
  380. X        if (lp == curbp->b_linep)
  381. X            break;
  382. X        lp = lforw(lp);
  383. X        }
  384. X
  385. X    lp = curwp->w_linep;
  386. X    i  = curwp->w_ntrows/2;
  387. X
  388. X    while (i-- && lp != curbp->b_linep)
  389. X        lp = lforw(lp);
  390. X
  391. X    curwp->w_dotp  = lp;
  392. X    curwp->w_doto  = 0;
  393. X    return (TRUE);
  394. X    }
  395. X
  396. X/*
  397. X * This command makes the current window the only window on the screen. Bound
  398. X * to "C-X 1". Try to set the framing so that "." does not have to move on the
  399. X * display. Some care has to be taken to keep the values of dot and mark in
  400. X * the buffer structures right if the distruction of a window makes a buffer
  401. X * become undisplayed.
  402. X */
  403. Xonlywind(f, n)
  404. X{
  405. X        register WINDOW *wp;
  406. X        register LINE   *lp;
  407. X        register int    i;
  408. X
  409. X        while (wheadp != curwp) {
  410. X                wp = wheadp;
  411. X                wheadp = wp->w_wndp;
  412. X                if (--wp->w_bufp->b_nwnd == 0) {
  413. X                        wp->w_bufp->b_dotp  = wp->w_dotp;
  414. X                        wp->w_bufp->b_doto  = wp->w_doto;
  415. X                        wp->w_bufp->b_markp = wp->w_markp;
  416. X                        wp->w_bufp->b_marko = wp->w_marko;
  417. X                }
  418. X                free((char *) wp);
  419. X        }
  420. X        while (curwp->w_wndp != NULL) {
  421. X                wp = curwp->w_wndp;
  422. X                curwp->w_wndp = wp->w_wndp;
  423. X                if (--wp->w_bufp->b_nwnd == 0) {
  424. X                        wp->w_bufp->b_dotp  = wp->w_dotp;
  425. X                        wp->w_bufp->b_doto  = wp->w_doto;
  426. X                        wp->w_bufp->b_markp = wp->w_markp;
  427. X                        wp->w_bufp->b_marko = wp->w_marko;
  428. X                }
  429. X                free((char *) wp);
  430. X        }
  431. X        lp = curwp->w_linep;
  432. X        i  = curwp->w_toprow;
  433. X        while (i!=0 && lback(lp)!=curbp->b_linep) {
  434. X                --i;
  435. X                lp = lback(lp);
  436. X        }
  437. X        curwp->w_toprow = 0;
  438. X        curwp->w_ntrows = term.t_nrow-1;
  439. X        curwp->w_linep  = lp;
  440. X        curwp->w_flag  |= WFMODE|WFHARD;
  441. X        return (TRUE);
  442. X}
  443. X
  444. X/*
  445. X * Delete the current window, placing its space in the window above,
  446. X * or, if it is the top window, the window below. Bound to C-X 0.
  447. X */
  448. X
  449. Xdelwind(f,n)
  450. X
  451. Xint f, n;    /* arguments are ignored for this command */
  452. X
  453. X{
  454. X    register WINDOW *wp;    /* window to recieve deleted space */
  455. X    register WINDOW *lwp;    /* ptr window before curwp */
  456. X    register int target;    /* target line to search for */
  457. X
  458. X    /* if there is only one window, don't delete it */
  459. X    if (wheadp->w_wndp == NULL) {
  460. X        mlwrite("Can not delete this window");
  461. X        return(FALSE);
  462. X    }
  463. X
  464. X    /* find window before curwp in linked list */
  465. X    wp = wheadp;
  466. X    lwp = NULL;
  467. X    while (wp != NULL) {
  468. X        if (wp == curwp)
  469. X            break;
  470. X        lwp = wp;
  471. X        wp = wp->w_wndp;
  472. X    }
  473. X
  474. X    /* find recieving window and give up our space */
  475. X    wp = wheadp;
  476. X    if (curwp->w_toprow == 0) {
  477. X        /* find the next window down */
  478. X        target = curwp->w_ntrows + 1;
  479. X        while (wp != NULL) {
  480. X            if (wp->w_toprow == target)
  481. X                break;
  482. X            wp = wp->w_wndp;
  483. X        }
  484. X        if (wp == NULL)
  485. X            return(FALSE);
  486. X        wp->w_toprow = 0;
  487. X        wp->w_ntrows += target;
  488. X    } else {
  489. X        /* find the next window up */
  490. X        target = curwp->w_toprow - 1;
  491. X        while (wp != NULL) {
  492. X            if ((wp->w_toprow + wp->w_ntrows) == target)
  493. X                break;
  494. X            wp = wp->w_wndp;
  495. X        }
  496. X        if (wp == NULL)
  497. X            return(FALSE);
  498. X        wp->w_ntrows += 1 + curwp->w_ntrows;
  499. X    }
  500. X
  501. X    /* get rid of the current window */
  502. X    if (--curwp->w_bufp->b_nwnd == 0) {
  503. X        curwp->w_bufp->b_dotp = curwp->w_dotp;
  504. X        curwp->w_bufp->b_doto = curwp->w_doto;
  505. X        curwp->w_bufp->b_markp = curwp->w_markp;
  506. X        curwp->w_bufp->b_marko = curwp->w_marko;
  507. X    }
  508. X    if (lwp == NULL)
  509. X        wheadp = curwp->w_wndp;
  510. X    else
  511. X        lwp->w_wndp = curwp->w_wndp;
  512. X    free((char *)curwp);
  513. X    curwp = wp;
  514. X    wp->w_flag |= WFHARD;
  515. X    curbp = wp->w_bufp;
  516. X    upmode();
  517. X    return(TRUE);
  518. X}
  519. X
  520. X/*
  521. X
  522. XSplit the current window.  A window smaller than 3 lines cannot be
  523. Xsplit.  An argument of 1 forces the cursor into the upper window, an
  524. Xargument of two forces the cursor to the lower window.  The only other
  525. Xerror that is possible is a "malloc" failure allocating the structure
  526. Xfor the new window.  Bound to "C-X 2". 
  527. X
  528. X */
  529. Xsplitwind(f, n)
  530. X
  531. Xint f, n;    /* default flag and numeric argument */
  532. X
  533. X{
  534. X        register WINDOW *wp;
  535. X        register LINE   *lp;
  536. X        register int    ntru;
  537. X        register int    ntrl;
  538. X        register int    ntrd;
  539. X        register WINDOW *wp1;
  540. X        register WINDOW *wp2;
  541. X    char *malloc();
  542. X
  543. X        if (curwp->w_ntrows < 3) {
  544. X                mlwrite("Cannot split a %d line window", curwp->w_ntrows);
  545. X                return (FALSE);
  546. X        }
  547. X        if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
  548. X                mlwrite("[OUT OF MEMORY]");
  549. X                return (FALSE);
  550. X        }
  551. X        ++curbp->b_nwnd;                        /* Displayed twice.     */
  552. X        wp->w_bufp  = curbp;
  553. X        wp->w_dotp  = curwp->w_dotp;
  554. X        wp->w_doto  = curwp->w_doto;
  555. X        wp->w_markp = curwp->w_markp;
  556. X        wp->w_marko = curwp->w_marko;
  557. X        wp->w_flag  = 0;
  558. X        wp->w_force = 0;
  559. X#if    COLOR
  560. X    /* set the colors of the new window */
  561. X    wp->w_fcolor = gfcolor;
  562. X    wp->w_bcolor = gbcolor;
  563. X#endif
  564. X        ntru = (curwp->w_ntrows-1) / 2;         /* Upper size           */
  565. X        ntrl = (curwp->w_ntrows-1) - ntru;      /* Lower size           */
  566. X        lp = curwp->w_linep;
  567. X        ntrd = 0;
  568. X        while (lp != curwp->w_dotp) {
  569. X                ++ntrd;
  570. X                lp = lforw(lp);
  571. X        }
  572. X        lp = curwp->w_linep;
  573. X        if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) {
  574. X                /* Old is upper window. */
  575. X                if (ntrd == ntru)               /* Hit mode line.       */
  576. X                        lp = lforw(lp);
  577. X                curwp->w_ntrows = ntru;
  578. X                wp->w_wndp = curwp->w_wndp;
  579. X                curwp->w_wndp = wp;
  580. X                wp->w_toprow = curwp->w_toprow+ntru+1;
  581. X                wp->w_ntrows = ntrl;
  582. X        } else {                                /* Old is lower window  */
  583. X                wp1 = NULL;
  584. X                wp2 = wheadp;
  585. X                while (wp2 != curwp) {
  586. X                        wp1 = wp2;
  587. X                        wp2 = wp2->w_wndp;
  588. X                }
  589. X                if (wp1 == NULL)
  590. X                        wheadp = wp;
  591. X                else
  592. X                        wp1->w_wndp = wp;
  593. X                wp->w_wndp   = curwp;
  594. X                wp->w_toprow = curwp->w_toprow;
  595. X                wp->w_ntrows = ntru;
  596. X                ++ntru;                         /* Mode line.           */
  597. X                curwp->w_toprow += ntru;
  598. X                curwp->w_ntrows  = ntrl;
  599. X                while (ntru--)
  600. X                        lp = lforw(lp);
  601. X        }
  602. X        curwp->w_linep = lp;                    /* Adjust the top lines */
  603. X        wp->w_linep = lp;                       /* if necessary.        */
  604. X        curwp->w_flag |= WFMODE|WFHARD;
  605. X        wp->w_flag |= WFMODE|WFHARD;
  606. X        return (TRUE);
  607. X}
  608. X
  609. X/*
  610. X * Enlarge the current window. Find the window that loses space. Make sure it
  611. X * is big enough. If so, hack the window descriptions, and ask redisplay to do
  612. X * all the hard work. You don't just set "force reframe" because dot would
  613. X * move. Bound to "C-X Z".
  614. X */
  615. Xenlargewind(f, n)
  616. X{
  617. X        register WINDOW *adjwp;
  618. X        register LINE   *lp;
  619. X        register int    i;
  620. X
  621. X        if (n < 0)
  622. X                return (shrinkwind(f, -n));
  623. X        if (wheadp->w_wndp == NULL) {
  624. X                mlwrite("Only one window");
  625. X                return (FALSE);
  626. X        }
  627. X        if ((adjwp=curwp->w_wndp) == NULL) {
  628. X                adjwp = wheadp;
  629. X                while (adjwp->w_wndp != curwp)
  630. X                        adjwp = adjwp->w_wndp;
  631. X        }
  632. X        if (adjwp->w_ntrows <= n) {
  633. X                mlwrite("Impossible change");
  634. X                return (FALSE);
  635. X        }
  636. X        if (curwp->w_wndp == adjwp) {           /* Shrink below.        */
  637. X                lp = adjwp->w_linep;
  638. X                for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
  639. X                        lp = lforw(lp);
  640. X                adjwp->w_linep  = lp;
  641. X                adjwp->w_toprow += n;
  642. X        } else {                                /* Shrink above.        */
  643. X                lp = curwp->w_linep;
  644. X                for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
  645. X                        lp = lback(lp);
  646. X                curwp->w_linep  = lp;
  647. X                curwp->w_toprow -= n;
  648. X        }
  649. X        curwp->w_ntrows += n;
  650. X        adjwp->w_ntrows -= n;
  651. X        curwp->w_flag |= WFMODE|WFHARD;
  652. X        adjwp->w_flag |= WFMODE|WFHARD;
  653. X        return (TRUE);
  654. X}
  655. X
  656. X/*
  657. X * Shrink the current window. Find the window that gains space. Hack at the
  658. X * window descriptions. Ask the redisplay to do all the hard work. Bound to
  659. X * "C-X C-Z".
  660. X */
  661. Xshrinkwind(f, n)
  662. X{
  663. X        register WINDOW *adjwp;
  664. X        register LINE   *lp;
  665. X        register int    i;
  666. X
  667. X        if (n < 0)
  668. X                return (enlargewind(f, -n));
  669. X        if (wheadp->w_wndp == NULL) {
  670. X                mlwrite("Only one window");
  671. X                return (FALSE);
  672. X        }
  673. X        if ((adjwp=curwp->w_wndp) == NULL) {
  674. X                adjwp = wheadp;
  675. X                while (adjwp->w_wndp != curwp)
  676. X                        adjwp = adjwp->w_wndp;
  677. X        }
  678. X        if (curwp->w_ntrows <= n) {
  679. X                mlwrite("Impossible change");
  680. X                return (FALSE);
  681. X        }
  682. X        if (curwp->w_wndp == adjwp) {           /* Grow below.          */
  683. X                lp = adjwp->w_linep;
  684. X                for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
  685. X                        lp = lback(lp);
  686. X                adjwp->w_linep  = lp;
  687. X                adjwp->w_toprow -= n;
  688. X        } else {                                /* Grow above.          */
  689. X                lp = curwp->w_linep;
  690. X                for (i=0; i<n && lp!=curbp->b_linep; ++i)
  691. X                        lp = lforw(lp);
  692. X                curwp->w_linep  = lp;
  693. X                curwp->w_toprow += n;
  694. X        }
  695. X        curwp->w_ntrows -= n;
  696. X        adjwp->w_ntrows += n;
  697. X        curwp->w_flag |= WFMODE|WFHARD;
  698. X        adjwp->w_flag |= WFMODE|WFHARD;
  699. X        return (TRUE);
  700. X}
  701. X
  702. X/*    Resize the current window to the requested size    */
  703. X
  704. Xresize(f, n)
  705. X
  706. Xint f, n;    /* default flag and numeric argument */
  707. X
  708. X{
  709. X    int clines;    /* current # of lines in window */
  710. X    
  711. X    /* must have a non-default argument, else ignore call */
  712. X    if (f == FALSE)
  713. X        return(TRUE);
  714. X
  715. X    /* find out what to do */
  716. X    clines = curwp->w_ntrows;
  717. X
  718. X    /* already the right size? */
  719. X    if (clines == n)
  720. X        return(TRUE);
  721. X
  722. X    return(enlargewind(TRUE, n - clines));
  723. X}
  724. X
  725. X/*
  726. X * Pick a window for a pop-up. Split the screen if there is only one window.
  727. X * Pick the uppermost window that isn't the current window. An LRU algorithm
  728. X * might be better. Return a pointer, or NULL on error.
  729. X */
  730. XWINDOW  *
  731. Xwpopup()
  732. X{
  733. X        register WINDOW *wp;
  734. X
  735. X        if (wheadp->w_wndp == NULL              /* Only 1 window        */
  736. X        && splitwind(FALSE, 0) == FALSE)        /* and it won't split   */
  737. X                return (NULL);
  738. X        wp = wheadp;                            /* Find window to use   */
  739. X        while (wp!=NULL && wp==curwp)
  740. X                wp = wp->w_wndp;
  741. X        return (wp);
  742. X}
  743. X
  744. Xscrnextup(f, n)        /* scroll the next window up (back) a page */
  745. X
  746. X{
  747. X    nextwind(FALSE, 1);
  748. X    backpage(f, n);
  749. X    prevwind(FALSE, 1);
  750. X}
  751. X
  752. Xscrnextdw(f, n)        /* scroll the next window down (forward) a page */
  753. X
  754. X{
  755. X    nextwind(FALSE, 1);
  756. X    forwpage(f, n);
  757. X    prevwind(FALSE, 1);
  758. X}
  759. X
  760. Xsavewnd(f, n)        /* save ptr to current window */
  761. X
  762. X{
  763. X    swindow = curwp;
  764. X    return(TRUE);
  765. X}
  766. X
  767. Xrestwnd(f, n)        /* restore the saved screen */
  768. X
  769. X{
  770. X    register WINDOW *wp;
  771. X
  772. X    /* find the window */
  773. X    wp = wheadp;
  774. X    while (wp != NULL) {
  775. X        if (wp == swindow) {
  776. X            curwp = wp;
  777. X            curbp = wp->w_bufp;
  778. X            upmode();
  779. X            return (TRUE);
  780. X        }
  781. X        wp = wp->w_wndp;
  782. X    }
  783. X
  784. X    mlwrite("[No such window exists]");
  785. X    return(FALSE);
  786. X}
  787. X
  788. Xnewsize(f, n)    /* resize the screen, re-writing the screen */
  789. X
  790. Xint f;    /* default flag */
  791. Xint n;    /* numeric argument */
  792. X
  793. X{
  794. X    WINDOW *wp;    /* current window being examined */
  795. X    WINDOW *nextwp;    /* next window to scan */
  796. X    WINDOW *lastwp;    /* last window scanned */
  797. X    int lastline;    /* screen line of last line of current window */
  798. X
  799. X    /* if the command defaults, assume the largest */
  800. X    if (f == FALSE)
  801. X        n = term.t_mrow + 1;
  802. X
  803. X    /* make sure it's in range */
  804. X    if (n < 3 || n > term.t_mrow + 1) {
  805. X        mlwrite("%%Screen size out of range");
  806. X        return(FALSE);
  807. X    }
  808. X
  809. X    if (term.t_nrow == n - 1)
  810. X        return(TRUE);
  811. X    else if (term.t_nrow < n - 1) {
  812. X
  813. X        /* go to the last window */
  814. X        wp = wheadp;
  815. X        while (wp->w_wndp != NULL)
  816. X            wp = wp->w_wndp;
  817. X
  818. X        /* and enlarge it as needed */
  819. X        wp->w_ntrows = n - wp->w_toprow - 2;
  820. X        wp->w_flag |= WFHARD|WFMODE;
  821. X
  822. X    } else {
  823. X
  824. X        /* rebuild the window structure */
  825. X        nextwp = wheadp;
  826. X        wp = NULL;
  827. X        lastwp = NULL;
  828. X        while (nextwp != NULL) {
  829. X            wp = nextwp;
  830. X            nextwp = wp->w_wndp;
  831. X    
  832. X            /* get rid of it if it is too low */
  833. X            if (wp->w_toprow > n - 2) {
  834. X
  835. X                /* save the point/mark if needed */
  836. X                if (--wp->w_bufp->b_nwnd == 0) {
  837. X                    wp->w_bufp->b_dotp = wp->w_dotp;
  838. X                    wp->w_bufp->b_doto = wp->w_doto;
  839. X                    wp->w_bufp->b_markp = wp->w_markp;
  840. X                    wp->w_bufp->b_marko = wp->w_marko;
  841. X                }
  842. X    
  843. X                /* update curwp and lastwp if needed */
  844. X                if (wp == curwp)
  845. X                    curwp = wheadp;
  846. X                    curbp = curwp->w_bufp;
  847. X                if (lastwp != NULL)
  848. X                    lastwp->w_wndp = NULL;
  849. X
  850. X                /* free the structure */
  851. X                free((char *)wp);
  852. X                wp = NULL;
  853. X
  854. X            } else {
  855. X                /* need to change this window size? */
  856. X                lastline = wp->w_toprow + wp->w_ntrows - 1;
  857. X                if (lastline >= n - 2) {
  858. X                    wp->w_ntrows = n - wp->w_toprow - 2;
  859. X                    wp->w_flag |= WFHARD|WFMODE;
  860. X                }
  861. X            }
  862. X    
  863. X            lastwp = wp;
  864. X        }
  865. X    }
  866. X
  867. X    /* screen is garbage */
  868. X    term.t_nrow = n - 1;
  869. X    sgarbf = TRUE;
  870. X    return(TRUE);
  871. X}
  872. X
  873. Xnewwidth(f, n)    /* resize the screen, re-writing the screen */
  874. X
  875. Xint f;    /* default flag */
  876. Xint n;    /* numeric argument */
  877. X
  878. X{
  879. X    register WINDOW *wp;
  880. X
  881. X    /* if the command defaults, assume the largest */
  882. X    if (f == FALSE)
  883. X        n = term.t_mcol;
  884. X
  885. X    /* make sure it's in range */
  886. X    if (n < 10 || n > term.t_mcol) {
  887. X        mlwrite("%%Screen width out of range");
  888. X        return(FALSE);
  889. X    }
  890. X
  891. X    /* otherwise, just re-width it (no big deal) */
  892. X    term.t_ncol = n;
  893. X    term.t_margin = n / 10;
  894. X    term.t_scrsiz = n - (term.t_margin * 2);
  895. X
  896. X    /* florce all windows to redraw */
  897. X    wp = wheadp;
  898. X    while (wp) {
  899. X        wp->w_flag |= WFHARD | WFMOVE | WFMODE;
  900. X        wp = wp->w_wndp;
  901. X    }
  902. X    sgarbf = TRUE;
  903. X
  904. X    return(TRUE);
  905. X}
  906. X
  907. Xint getwpos()    /* get screen offset of current line in current window */
  908. X
  909. X{
  910. X    register int sline;    /* screen line from top of window */
  911. X    register LINE *lp;    /* scannile line pointer */
  912. X
  913. X    /* search down the line we want */
  914. X    lp = curwp->w_linep;
  915. X    sline = 1;
  916. X    while (lp != curwp->w_dotp) {
  917. X        ++sline;
  918. X        lp = lforw(lp);
  919. X    }
  920. X
  921. X    /* and return the value */
  922. X    return(sline);
  923. X}
  924. FRIDAY_NIGHT
  925. echo extracting - word.c
  926. sed 's/^X//' > word.c << 'FRIDAY_NIGHT'
  927. X/*
  928. X * The routines in this file implement commands that work word or a
  929. X * paragraph at a time.  There are all sorts of word mode commands.  If I
  930. X * do any sentence mode commands, they are likely to be put in this file. 
  931. X */
  932. X
  933. X#include    <stdio.h>
  934. X#include    "estruct.h"
  935. X#include    "edef.h"
  936. X
  937. X/* Word wrap on n-spaces. Back-over whatever precedes the point on the current
  938. X * line and stop on the first word-break or the beginning of the line. If we
  939. X * reach the beginning of the line, jump back to the end of the word and start
  940. X * a new line.    Otherwise, break the line at the word-break, eat it, and jump
  941. X * back to the end of the word.
  942. X * Returns TRUE on success, FALSE on errors.
  943. X */
  944. Xwrapword(f, n)
  945. X
  946. Xint f;        /* default flag */
  947. Xint n;        /* numeric argument */
  948. X{
  949. X    register int cnt;    /* size of word wrapped to next line */
  950. X    register int c;        /* charector temporary */
  951. X
  952. X    /* backup from the <NL> 1 char */
  953. X    if (!backchar(0, 1))
  954. X        return(FALSE);
  955. X
  956. X    /* back up until we aren't in a word,
  957. X       make sure there is a break in the line */
  958. X    cnt = 0;
  959. X    while (((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ')
  960. X                && (c != '\t')) {
  961. X        cnt++;
  962. X        if (!backchar(0, 1))
  963. X            return(FALSE);
  964. X        /* if we make it to the beginning, start a new line */
  965. X        if (curwp->w_doto == 0) {
  966. X            gotoeol(FALSE, 0);
  967. X            return(lnewline());
  968. X        }
  969. X    }
  970. X
  971. X    /* delete the forward white space */
  972. X    if (!forwdel(0, 1))
  973. X        return(FALSE);
  974. X
  975. X    /* put in a end of line */
  976. X    if (!lnewline())
  977. X        return(FALSE);
  978. X
  979. X    /* and past the first word */
  980. X    while (cnt-- > 0) {
  981. X        if (forwchar(FALSE, 1) == FALSE)
  982. X            return(FALSE);
  983. X    }
  984. X    return(TRUE);
  985. X}
  986. X
  987. X/*
  988. X * Move the cursor backward by "n" words. All of the details of motion are
  989. X * performed by the "backchar" and "forwchar" routines. Error if you try to
  990. X * move beyond the buffers.
  991. X */
  992. Xbackword(f, n)
  993. X{
  994. X    if (n < 0)
  995. X        return (forwword(f, -n));
  996. X    if (backchar(FALSE, 1) == FALSE)
  997. X        return (FALSE);
  998. X    while (n--) {
  999. X        while (inword() == FALSE) {
  1000. X            if (backchar(FALSE, 1) == FALSE)
  1001. X                return (FALSE);
  1002. X        }
  1003. X        while (inword() != FALSE) {
  1004. X            if (backchar(FALSE, 1) == FALSE)
  1005. X                return (FALSE);
  1006. X        }
  1007. X    }
  1008. X    return (forwchar(FALSE, 1));
  1009. X}
  1010. X
  1011. X/*
  1012. X * Move the cursor forward by the specified number of words. All of the motion
  1013. X * is done by "forwchar". Error if you try and move beyond the buffer's end.
  1014. X */
  1015. Xforwword(f, n)
  1016. X{
  1017. X    if (n < 0)
  1018. X        return (backword(f, -n));
  1019. X    while (n--) {
  1020. X        while (inword() == TRUE) {
  1021. X            if (forwchar(FALSE, 1) == FALSE)
  1022. X                return (FALSE);
  1023. X        }
  1024. X
  1025. X        while (inword() == FALSE) {
  1026. X            if (forwchar(FALSE, 1) == FALSE)
  1027. X                return (FALSE);
  1028. X        }
  1029. X    }
  1030. X    return(TRUE);
  1031. X}
  1032. X
  1033. X/*
  1034. X * Move the cursor forward by the specified number of words. As you move,
  1035. X * convert any characters to upper case. Error if you try and move beyond the
  1036. X * end of the buffer. Bound to "M-U".
  1037. X */
  1038. Xupperword(f, n)
  1039. X{
  1040. X    register int    c;
  1041. X
  1042. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1043. X        return(rdonly());    /* we are in read only mode    */
  1044. X    if (n < 0)
  1045. X        return (FALSE);
  1046. X    while (n--) {
  1047. X        while (inword() == FALSE) {
  1048. X            if (forwchar(FALSE, 1) == FALSE)
  1049. X                return (FALSE);
  1050. X        }
  1051. X        while (inword() != FALSE) {
  1052. X            c = lgetc(curwp->w_dotp, curwp->w_doto);
  1053. X            if (c>='a' && c<='z') {
  1054. X                c -= 'a'-'A';
  1055. X                lputc(curwp->w_dotp, curwp->w_doto, c);
  1056. X                lchange(WFHARD);
  1057. X            }
  1058. X            if (forwchar(FALSE, 1) == FALSE)
  1059. X                return (FALSE);
  1060. X        }
  1061. X    }
  1062. X    return (TRUE);
  1063. X}
  1064. X
  1065. X/*
  1066. X * Move the cursor forward by the specified number of words. As you move
  1067. X * convert characters to lower case. Error if you try and move over the end of
  1068. X * the buffer. Bound to "M-L".
  1069. X */
  1070. Xlowerword(f, n)
  1071. X{
  1072. X    register int    c;
  1073. X
  1074. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1075. X        return(rdonly());    /* we are in read only mode    */
  1076. X    if (n < 0)
  1077. X        return (FALSE);
  1078. X    while (n--) {
  1079. X        while (inword() == FALSE) {
  1080. X            if (forwchar(FALSE, 1) == FALSE)
  1081. X                return (FALSE);
  1082. X        }
  1083. X        while (inword() != FALSE) {
  1084. X            c = lgetc(curwp->w_dotp, curwp->w_doto);
  1085. X            if (c>='A' && c<='Z') {
  1086. X                c += 'a'-'A';
  1087. X                lputc(curwp->w_dotp, curwp->w_doto, c);
  1088. X                lchange(WFHARD);
  1089. X            }
  1090. X            if (forwchar(FALSE, 1) == FALSE)
  1091. X                return (FALSE);
  1092. X        }
  1093. X    }
  1094. X    return (TRUE);
  1095. X}
  1096. X
  1097. X/*
  1098. X * Move the cursor forward by the specified number of words. As you move
  1099. X * convert the first character of the word to upper case, and subsequent
  1100. X * characters to lower case. Error if you try and move past the end of the
  1101. X * buffer. Bound to "M-C".
  1102. X */
  1103. Xcapword(f, n)
  1104. X{
  1105. X    register int    c;
  1106. X
  1107. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1108. X        return(rdonly());    /* we are in read only mode    */
  1109. X    if (n < 0)
  1110. X        return (FALSE);
  1111. X    while (n--) {
  1112. X        while (inword() == FALSE) {
  1113. X            if (forwchar(FALSE, 1) == FALSE)
  1114. X                return (FALSE);
  1115. X        }
  1116. X        if (inword() != FALSE) {
  1117. X            c = lgetc(curwp->w_dotp, curwp->w_doto);
  1118. X            if (c>='a' && c<='z') {
  1119. X                c -= 'a'-'A';
  1120. X                lputc(curwp->w_dotp, curwp->w_doto, c);
  1121. X                lchange(WFHARD);
  1122. X            }
  1123. X            if (forwchar(FALSE, 1) == FALSE)
  1124. X                return (FALSE);
  1125. X            while (inword() != FALSE) {
  1126. X                c = lgetc(curwp->w_dotp, curwp->w_doto);
  1127. X                if (c>='A' && c<='Z') {
  1128. X                    c += 'a'-'A';
  1129. X                    lputc(curwp->w_dotp, curwp->w_doto, c);
  1130. X                    lchange(WFHARD);
  1131. X                }
  1132. X                if (forwchar(FALSE, 1) == FALSE)
  1133. X                    return (FALSE);
  1134. X            }
  1135. X        }
  1136. X    }
  1137. X    return (TRUE);
  1138. X}
  1139. X
  1140. X/*
  1141. X * Kill forward by "n" words. Remember the location of dot. Move forward by
  1142. X * the right number of words. Put dot back where it was and issue the kill
  1143. X * command for the right number of characters. With a zero argument, just
  1144. X * kill one word and no whitespace. Bound to "M-D".
  1145. X */
  1146. Xdelfword(f, n)
  1147. X{
  1148. X    register LINE    *dotp;    /* original cursor line */
  1149. X    register int    doto;    /*    and row */
  1150. X    register int c;        /* temp char */
  1151. X    long size;        /* # of chars to delete */
  1152. X
  1153. X    /* don't allow this command if we are in read only mode */
  1154. X    if (curbp->b_mode&MDVIEW)
  1155. X        return(rdonly());
  1156. X
  1157. X    /* ignore the command if there is a negative argument */
  1158. X    if (n < 0)
  1159. X        return (FALSE);
  1160. X
  1161. X    /* Clear the kill buffer if last command wasn't a kill */
  1162. X    if ((lastflag&CFKILL) == 0)
  1163. X        kdelete();
  1164. X    thisflag |= CFKILL;    /* this command is a kill */
  1165. X
  1166. X    /* save the current cursor position */
  1167. X    dotp = curwp->w_dotp;
  1168. X    doto = curwp->w_doto;
  1169. X
  1170. X    /* figure out how many characters to give the axe */
  1171. X    size = 0;
  1172. X
  1173. X    /* get us into a word.... */
  1174. X    while (inword() == FALSE) {
  1175. X        if (forwchar(FALSE, 1) == FALSE)
  1176. X            return(FALSE);
  1177. X        ++size;
  1178. X    }
  1179. X
  1180. X    if (n == 0) {
  1181. X        /* skip one word, no whitespace! */
  1182. X        while (inword() == TRUE) {
  1183. X            if (forwchar(FALSE, 1) == FALSE)
  1184. X                return(FALSE);
  1185. X            ++size;
  1186. X        }
  1187. X    } else {
  1188. X        /* skip n words.... */
  1189. X        while (n--) {
  1190. X    
  1191. X            /* if we are at EOL; skip to the beginning of the next */
  1192. X            while (curwp->w_doto == llength(curwp->w_dotp)) {
  1193. X                if (forwchar(FALSE, 1) == FALSE)
  1194. X                    return(FALSE);
  1195. X                ++size;
  1196. X            }
  1197. X    
  1198. X            /* move forward till we are at the end of the word */
  1199. X            while (inword() == TRUE) {
  1200. X                if (forwchar(FALSE, 1) == FALSE)
  1201. X                    return(FALSE);
  1202. X                ++size;
  1203. X            }
  1204. X    
  1205. X            /* if there are more words, skip the interword stuff */
  1206. X            if (n != 0)
  1207. X                while (inword() == FALSE) {
  1208. X                    if (forwchar(FALSE, 1) == FALSE)
  1209. X                        return(FALSE);
  1210. X                    ++size;
  1211. X                }
  1212. X        }
  1213. X    
  1214. X        /* skip whitespace and newlines */
  1215. X        while ((curwp->w_doto == llength(curwp->w_dotp)) ||
  1216. X            ((c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' ') ||
  1217. X            (c == '\t')) {
  1218. X                if (forwchar(FALSE, 1) == FALSE)
  1219. X                    break;
  1220. X                ++size;
  1221. X        }
  1222. X    }
  1223. X
  1224. X    /* restore the original position and delete the words */
  1225. X    curwp->w_dotp = dotp;
  1226. X    curwp->w_doto = doto;
  1227. X    return (ldelete(size, TRUE));
  1228. X}
  1229. X
  1230. X/*
  1231. X * Kill backwards by "n" words. Move backwards by the desired number of words,
  1232. X * counting the characters. When dot is finally moved to its resting place,
  1233. X * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
  1234. X */
  1235. Xdelbword(f, n)
  1236. X{
  1237. X    long size;
  1238. X
  1239. X    /* don't allow this command if we are in read only mode */
  1240. X    if (curbp->b_mode&MDVIEW)
  1241. X        return(rdonly());
  1242. X
  1243. X    /* ignore the command if there is a nonpositive argument */
  1244. X    if (n <= 0)
  1245. X        return (FALSE);
  1246. X
  1247. X    /* Clear the kill buffer if last command wasn't a kill */
  1248. X    if ((lastflag&CFKILL) == 0)
  1249. X        kdelete();
  1250. X    thisflag |= CFKILL;    /* this command is a kill */
  1251. X
  1252. X    if (backchar(FALSE, 1) == FALSE)
  1253. X        return (FALSE);
  1254. X    size = 0;
  1255. X    while (n--) {
  1256. X        while (inword() == FALSE) {
  1257. X            if (backchar(FALSE, 1) == FALSE)
  1258. X                return (FALSE);
  1259. X            ++size;
  1260. X        }
  1261. X        while (inword() != FALSE) {
  1262. X            ++size;
  1263. X            if (backchar(FALSE, 1) == FALSE)
  1264. X                goto bckdel;
  1265. X        }
  1266. X    }
  1267. X    if (forwchar(FALSE, 1) == FALSE)
  1268. X        return (FALSE);
  1269. Xbckdel:    return (ldelete(size, TRUE));
  1270. X}
  1271. X
  1272. X/*
  1273. X * Return TRUE if the character at dot is a character that is considered to be
  1274. X * part of a word. The word character list is hard coded. Should be setable.
  1275. X */
  1276. Xinword()
  1277. X{
  1278. X    register int    c;
  1279. X
  1280. X    if (curwp->w_doto == llength(curwp->w_dotp))
  1281. X        return (FALSE);
  1282. X    c = lgetc(curwp->w_dotp, curwp->w_doto);
  1283. X    if (c>='a' && c<='z')
  1284. X        return (TRUE);
  1285. X    if (c>='A' && c<='Z')
  1286. X        return (TRUE);
  1287. X    if (c>='0' && c<='9')
  1288. X        return (TRUE);
  1289. X    return (FALSE);
  1290. X}
  1291. X
  1292. X#if    WORDPRO
  1293. Xfillpara(f, n)    /* Fill the current paragraph according to the current
  1294. X           fill column                        */
  1295. X
  1296. Xint f, n;    /* deFault flag and Numeric argument */
  1297. X
  1298. X{
  1299. X    register int c;            /* current char durring scan    */
  1300. X    register int wordlen;        /* length of current word    */
  1301. X    register int clength;        /* position on line during fill    */
  1302. X    register int i;            /* index during word copy    */
  1303. X    register int newlength;        /* tentative new line length    */
  1304. X    register int eopflag;        /* Are we at the End-Of-Paragraph? */
  1305. X    register int firstflag;        /* first word? (needs no space)    */
  1306. X    register LINE *eopline;        /* pointer to line just past EOP */
  1307. X    register int dotflag;        /* was the last char a period?    */
  1308. X    char wbuf[NSTRING];        /* buffer for current word    */
  1309. X
  1310. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1311. X        return(rdonly());    /* we are in read only mode    */
  1312. X    if (fillcol == 0) {    /* no fill column set */
  1313. X        mlwrite("No fill column set");
  1314. X        return(FALSE);
  1315. X    }
  1316. X
  1317. X    /* record the pointer to the line just past the EOP */
  1318. X    gotoeop(FALSE, 1);
  1319. X    eopline = lforw(curwp->w_dotp);
  1320. X
  1321. X    /* and back top the beginning of the paragraph */
  1322. X    gotobop(FALSE, 1);
  1323. X
  1324. X    /* initialize various info */
  1325. X    clength = curwp->w_doto;
  1326. X    if (clength && curwp->w_dotp->l_text[0] == TAB)
  1327. X        clength = 8;
  1328. X    wordlen = 0;
  1329. X    dotflag = FALSE;
  1330. X
  1331. X    /* scan through lines, filling words */
  1332. X    firstflag = TRUE;
  1333. X    eopflag = FALSE;
  1334. X    while (!eopflag) {
  1335. X        /* get the next character in the paragraph */
  1336. X        if (curwp->w_doto == llength(curwp->w_dotp)) {
  1337. X            c = ' ';
  1338. X            if (lforw(curwp->w_dotp) == eopline)
  1339. X                eopflag = TRUE;
  1340. X        } else
  1341. X            c = lgetc(curwp->w_dotp, curwp->w_doto);
  1342. X
  1343. X        /* and then delete it */
  1344. X        ldelete(1L, FALSE);
  1345. X
  1346. X        /* if not a separator, just add it in */
  1347. X        if (c != ' ' && c != '\t') {
  1348. X            dotflag = (c == '.');        /* was it a dot */
  1349. X            if (wordlen < NSTRING - 1)
  1350. X                wbuf[wordlen++] = c;
  1351. X        } else if (wordlen) {
  1352. X            /* at a word break with a word waiting */
  1353. X            /* calculate tentitive new length with word added */
  1354. X            newlength = clength + 1 + wordlen;
  1355. X            if (newlength <= fillcol) {
  1356. X                /* add word to current line */
  1357. X                if (!firstflag) {
  1358. X                    linsert(1, ' '); /* the space */
  1359. X                    ++clength;
  1360. X                }
  1361. X                firstflag = FALSE;
  1362. X            } else {
  1363. X                /* start a new line */
  1364. X                lnewline();
  1365. X                clength = 0;
  1366. X            }
  1367. X
  1368. X            /* and add the word in in either case */
  1369. X            for (i=0; i<wordlen; i++) {
  1370. X                linsert(1, wbuf[i]);
  1371. X                ++clength;
  1372. X            }
  1373. X            if (dotflag) {
  1374. X                linsert(1, ' ');
  1375. X                ++clength;
  1376. X            }
  1377. X            wordlen = 0;
  1378. X        }
  1379. X    }
  1380. X    /* and add a last newline for the end of our new paragraph */
  1381. X    lnewline();
  1382. X    return(TRUE);
  1383. X}
  1384. X
  1385. Xkillpara(f, n)    /* delete n paragraphs starting with the current one */
  1386. X
  1387. Xint f;    /* default flag */
  1388. Xint n;    /* # of paras to delete */
  1389. X
  1390. X{
  1391. X    register int status;    /* returned status of functions */
  1392. X
  1393. X    while (n--) {        /* for each paragraph to delete */
  1394. X
  1395. X        /* mark out the end and beginning of the para to delete */
  1396. X        gotoeop(FALSE, 1);
  1397. X
  1398. X        /* set the mark here */
  1399. X        curwp->w_markp = curwp->w_dotp;
  1400. X        curwp->w_marko = curwp->w_doto;
  1401. X
  1402. X        /* go to the beginning of the paragraph */
  1403. X        gotobop(FALSE, 1);
  1404. X        curwp->w_doto = 0;    /* force us to the beginning of line */
  1405. X    
  1406. X        /* and delete it */
  1407. X        if ((status = killregion(FALSE, 1)) != TRUE)
  1408. X            return(status);
  1409. X
  1410. X        /* and clean up the 2 extra lines */
  1411. X        ldelete(2L, TRUE);
  1412. X    }
  1413. X    return(TRUE);
  1414. X}
  1415. X
  1416. X
  1417. X/*    wordcount:    count the # of words in the marked region,
  1418. X            along with average word sizes, # of chars, etc,
  1419. X            and report on them.            */
  1420. X
  1421. Xwordcount(f, n)
  1422. X
  1423. Xint f, n;    /* ignored numeric arguments */
  1424. X
  1425. X{
  1426. X    register LINE *lp;    /* current line to scan */
  1427. X    register int offset;    /* current char to scan */
  1428. X    long size;        /* size of region left to count */
  1429. X    register int ch;    /* current character to scan */
  1430. X    register int wordflag;    /* are we in a word now? */
  1431. X    register int lastword;    /* were we just in a word? */
  1432. X    long nwords;        /* total # of words */
  1433. X    long nchars;        /* total number of chars */
  1434. X    int nlines;        /* total number of lines in region */
  1435. X    int avgch;        /* average number of chars/word */
  1436. X    int status;        /* status return code */
  1437. X    REGION region;        /* region to look at */
  1438. X
  1439. X    /* make sure we have a region to count */
  1440. X    if ((status = getregion(®ion)) != TRUE)
  1441. X        return(status);
  1442. X    lp = region.r_linep;
  1443. X    offset = region.r_offset;
  1444. X    size = region.r_size;
  1445. X
  1446. X    /* count up things */
  1447. X    lastword = FALSE;
  1448. X    nchars = 0L;
  1449. X    nwords = 0L;
  1450. X    nlines = 0;
  1451. X    while (size--) {
  1452. X
  1453. X        /* get the current character */
  1454. X        if (offset == llength(lp)) {    /* end of line */
  1455. X            ch = '\n';
  1456. X            lp = lforw(lp);
  1457. X            offset = 0;
  1458. X            ++nlines;
  1459. X        } else {
  1460. X            ch = lgetc(lp, offset);
  1461. X            ++offset;
  1462. X        }
  1463. X
  1464. X        /* and tabulate it */
  1465. X        wordflag = ((ch >= 'a' && ch <= 'z') ||
  1466. X                (ch >= 'A' && ch <= 'Z') ||
  1467. X                (ch >= '0' && ch <= '9'));
  1468. X        if (wordflag == TRUE && lastword == FALSE)
  1469. X            ++nwords;
  1470. X        lastword = wordflag;
  1471. X        ++nchars;
  1472. X    }
  1473. X
  1474. X    /* and report on the info */
  1475. X    if (nwords > 0L)
  1476. X        avgch = (int)((100L * nchars) / nwords);
  1477. X    else
  1478. X        avgch = 0;
  1479. X
  1480. X    mlwrite("Words %D Chars %D Lines %d Avg chars/word %f",
  1481. X        nwords, nchars, nlines + 1, avgch);
  1482. X    return(TRUE);
  1483. X}
  1484. X#endif
  1485. FRIDAY_NIGHT
  1486. echo mes.13 completed!
  1487. # That's all folks!
  1488.  
  1489.  
  1490.