home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume6 / uemacs3.7 / part12 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  16.4 KB

  1. Subject: v06i082:  MicroEmacs, Version 3.7 (uEmacs3.7), Part12/12
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.UUCP
  4.  
  5. Submitted by: ihnp4!pur-ee!pur-phy!duncan!lawrence
  6. Mod.sources: Volume 6, Issue 82
  7. Archive-name: uEmacs/Part12
  8.  
  9. [  This is the last version of emacs that will be posted here for quite
  10.    some time.  Anyone for a mod.sources.emacs?  --r$ ]
  11.  
  12. echo extracting - word.c
  13. sed 's/^X//' > word.c << 'FRIDAY_NIGHT'
  14. X/*
  15. X * The routines in this file implement commands that work word or a
  16. X * paragraph at a time.  There are all sorts of word mode commands.  If I
  17. X * do any sentence mode commands, they are likely to be put in this file. 
  18. X */
  19. X
  20. X#include        <stdio.h>
  21. X#include        "estruct.h"
  22. X#include    "edef.h"
  23. X
  24. X/* Word wrap on n-spaces. Back-over whatever precedes the point on the current
  25. X * line and stop on the first word-break or the beginning of the line. If we
  26. X * reach the beginning of the line, jump back to the end of the word and start
  27. X * a new line.  Otherwise, break the line at the word-break, eat it, and jump
  28. X * back to the end of the word.
  29. X * Returns TRUE on success, FALSE on errors.
  30. X */
  31. Xwrapword(n)
  32. X
  33. Xint n;
  34. X
  35. X{
  36. X        register int cnt;    /* size of word wrapped to next line */
  37. X    register int c;        /* charector temporary */
  38. X
  39. X    /* backup from the <NL> 1 char */
  40. X        if (!backchar(0, 1))
  41. X            return(FALSE);
  42. X
  43. X    /* back up until we aren't in a word,
  44. X       make sure there is a break in the line */
  45. X        cnt = 0;
  46. X    while (((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ')
  47. X                && (c != '\t')) {
  48. X                cnt++;
  49. X                if (!backchar(0, 1))
  50. X                        return(FALSE);
  51. X        /* if we make it to the begining, start a new line */
  52. X        if (curwp->w_doto == 0) {
  53. X            gotoeol(FALSE, 0);
  54. X            return(newline(0,1));
  55. X        }
  56. X        }
  57. X
  58. X    /* delete the forward white space */
  59. X        if (!forwdel(0, 1))
  60. X                return(FALSE);
  61. X
  62. X    /* put in a end of line */
  63. X        if (!newline(0, 1))
  64. X                return(FALSE);
  65. X
  66. X    /* and past the first word */
  67. X    while (cnt-- > 0) {
  68. X        if (forwchar(FALSE, 1) == FALSE)
  69. X            return(FALSE);
  70. X    }
  71. X        return(TRUE);
  72. X}
  73. X
  74. X/*
  75. X * Move the cursor backward by "n" words. All of the details of motion are
  76. X * performed by the "backchar" and "forwchar" routines. Error if you try to
  77. X * move beyond the buffers.
  78. X */
  79. Xbackword(f, n)
  80. X{
  81. X        if (n < 0)
  82. X                return (forwword(f, -n));
  83. X        if (backchar(FALSE, 1) == FALSE)
  84. X                return (FALSE);
  85. X        while (n--) {
  86. X                while (inword() == FALSE) {
  87. X                        if (backchar(FALSE, 1) == FALSE)
  88. X                                return (FALSE);
  89. X                }
  90. X                while (inword() != FALSE) {
  91. X                        if (backchar(FALSE, 1) == FALSE)
  92. X                                return (FALSE);
  93. X                }
  94. X        }
  95. X        return (forwchar(FALSE, 1));
  96. X}
  97. X
  98. X/*
  99. X * Move the cursor forward by the specified number of words. All of the motion
  100. X * is done by "forwchar". Error if you try and move beyond the buffer's end.
  101. X */
  102. Xforwword(f, n)
  103. X{
  104. X        if (n < 0)
  105. X                return (backword(f, -n));
  106. X        while (n--) {
  107. X#if    NFWORD
  108. X                while (inword() != FALSE) {
  109. X                        if (forwchar(FALSE, 1) == FALSE)
  110. X                                return (FALSE);
  111. X                }
  112. X#endif
  113. X                while (inword() == FALSE) {
  114. X                        if (forwchar(FALSE, 1) == FALSE)
  115. X                                return (FALSE);
  116. X                }
  117. X#if    NFWORD == 0
  118. X                while (inword() != FALSE) {
  119. X                        if (forwchar(FALSE, 1) == FALSE)
  120. X                                return (FALSE);
  121. X                }
  122. X#endif
  123. X        }
  124. X    return(TRUE);
  125. X}
  126. X
  127. X/*
  128. X * Move the cursor forward by the specified number of words. As you move,
  129. X * convert any characters to upper case. Error if you try and move beyond the
  130. X * end of the buffer. Bound to "M-U".
  131. X */
  132. Xupperword(f, n)
  133. X{
  134. X        register int    c;
  135. X
  136. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  137. X        return(rdonly());    /* we are in read only mode    */
  138. X        if (n < 0)
  139. X                return (FALSE);
  140. X        while (n--) {
  141. X                while (inword() == FALSE) {
  142. X                        if (forwchar(FALSE, 1) == FALSE)
  143. X                                return (FALSE);
  144. X                }
  145. X                while (inword() != FALSE) {
  146. X                        c = lgetc(curwp->w_dotp, curwp->w_doto);
  147. X                        if (c>='a' && c<='z') {
  148. X                                c -= 'a'-'A';
  149. X                                lputc(curwp->w_dotp, curwp->w_doto, c);
  150. X                                lchange(WFHARD);
  151. X                        }
  152. X                        if (forwchar(FALSE, 1) == FALSE)
  153. X                                return (FALSE);
  154. X                }
  155. X        }
  156. X        return (TRUE);
  157. X}
  158. X
  159. X/*
  160. X * Move the cursor forward by the specified number of words. As you move
  161. X * convert characters to lower case. Error if you try and move over the end of
  162. X * the buffer. Bound to "M-L".
  163. X */
  164. Xlowerword(f, n)
  165. X{
  166. X        register int    c;
  167. X
  168. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  169. X        return(rdonly());    /* we are in read only mode    */
  170. X        if (n < 0)
  171. X                return (FALSE);
  172. X        while (n--) {
  173. X                while (inword() == FALSE) {
  174. X                        if (forwchar(FALSE, 1) == FALSE)
  175. X                                return (FALSE);
  176. X                }
  177. X                while (inword() != FALSE) {
  178. X                        c = lgetc(curwp->w_dotp, curwp->w_doto);
  179. X                        if (c>='A' && c<='Z') {
  180. X                                c += 'a'-'A';
  181. X                                lputc(curwp->w_dotp, curwp->w_doto, c);
  182. X                                lchange(WFHARD);
  183. X                        }
  184. X                        if (forwchar(FALSE, 1) == FALSE)
  185. X                                return (FALSE);
  186. X                }
  187. X        }
  188. X        return (TRUE);
  189. X}
  190. X
  191. X/*
  192. X * Move the cursor forward by the specified number of words. As you move
  193. X * convert the first character of the word to upper case, and subsequent
  194. X * characters to lower case. Error if you try and move past the end of the
  195. X * buffer. Bound to "M-C".
  196. X */
  197. Xcapword(f, n)
  198. X{
  199. X        register int    c;
  200. X
  201. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  202. X        return(rdonly());    /* we are in read only mode    */
  203. X        if (n < 0)
  204. X                return (FALSE);
  205. X        while (n--) {
  206. X                while (inword() == FALSE) {
  207. X                        if (forwchar(FALSE, 1) == FALSE)
  208. X                                return (FALSE);
  209. X                }
  210. X                if (inword() != FALSE) {
  211. X                        c = lgetc(curwp->w_dotp, curwp->w_doto);
  212. X                        if (c>='a' && c<='z') {
  213. X                                c -= 'a'-'A';
  214. X                                lputc(curwp->w_dotp, curwp->w_doto, c);
  215. X                                lchange(WFHARD);
  216. X                        }
  217. X                        if (forwchar(FALSE, 1) == FALSE)
  218. X                                return (FALSE);
  219. X                        while (inword() != FALSE) {
  220. X                                c = lgetc(curwp->w_dotp, curwp->w_doto);
  221. X                                if (c>='A' && c<='Z') {
  222. X                                        c += 'a'-'A';
  223. X                                        lputc(curwp->w_dotp, curwp->w_doto, c);
  224. X                                        lchange(WFHARD);
  225. X                                }
  226. X                                if (forwchar(FALSE, 1) == FALSE)
  227. X                                        return (FALSE);
  228. X                        }
  229. X                }
  230. X        }
  231. X        return (TRUE);
  232. X}
  233. X
  234. X/*
  235. X * Kill forward by "n" words. Remember the location of dot. Move forward by
  236. X * the right number of words. Put dot back where it was and issue the kill
  237. X * command for the right number of characters. Bound to "M-D".
  238. X */
  239. Xdelfword(f, n)
  240. X{
  241. X        register LINE   *dotp;
  242. X        register int    doto;
  243. X        long size;
  244. X
  245. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  246. X        return(rdonly());    /* we are in read only mode    */
  247. X        if (n < 0)
  248. X                return (FALSE);
  249. X        if ((lastflag&CFKILL) == 0)     /* Clear kill buffer if */
  250. X                kdelete();              /* last wasn't a kill.  */
  251. X        thisflag |= CFKILL;
  252. X        dotp = curwp->w_dotp;
  253. X        doto = curwp->w_doto;
  254. X        size = 0;
  255. X        while (n--) {
  256. X#if    NFWORD
  257. X        if (curwp->w_doto == llength(curwp->w_dotp)) {
  258. X            if (forwchar(FALSE,1) == FALSE)
  259. X                return(FALSE);
  260. X            ++size;
  261. X        }
  262. X
  263. X        while (inword() != FALSE) {
  264. X            if (forwchar(FALSE,1) == FALSE)
  265. X                return(FALSE);
  266. X            ++size;
  267. X        }
  268. X
  269. X                while ((inword() == FALSE) &&
  270. X                (curwp->w_doto != llength(curwp->w_dotp))) {
  271. X                        if (forwchar(FALSE, 1) == FALSE)
  272. X                                return (FALSE);
  273. X                        ++size;
  274. X                }
  275. X#else
  276. X                while (inword() == FALSE) {
  277. X                        if (forwchar(FALSE, 1) == FALSE)
  278. X                                return (FALSE);
  279. X                        ++size;
  280. X                }
  281. X
  282. X                while (inword() != FALSE) {
  283. X                        if (forwchar(FALSE, 1) == FALSE)
  284. X                                return (FALSE);
  285. X                        ++size;
  286. X                }
  287. X#endif
  288. X        }
  289. X        curwp->w_dotp = dotp;
  290. X        curwp->w_doto = doto;
  291. X        return (ldelete(size, TRUE));
  292. X}
  293. X
  294. X/*
  295. X * Kill backwards by "n" words. Move backwards by the desired number of words,
  296. X * counting the characters. When dot is finally moved to its resting place,
  297. X * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
  298. X */
  299. Xdelbword(f, n)
  300. X{
  301. X        long size;
  302. X
  303. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  304. X        return(rdonly());    /* we are in read only mode    */
  305. X        if (n < 0)
  306. X                return (FALSE);
  307. X        if ((lastflag&CFKILL) == 0)     /* Clear kill buffer if */
  308. X                kdelete();              /* last wasn't a kill.  */
  309. X        thisflag |= CFKILL;
  310. X        if (backchar(FALSE, 1) == FALSE)
  311. X                return (FALSE);
  312. X        size = 0;
  313. X        while (n--) {
  314. X                while (inword() == FALSE) {
  315. X                        if (backchar(FALSE, 1) == FALSE)
  316. X                                return (FALSE);
  317. X                        ++size;
  318. X                }
  319. X                while (inword() != FALSE) {
  320. X                        if (backchar(FALSE, 1) == FALSE)
  321. X                                return (FALSE);
  322. X                        ++size;
  323. X                }
  324. X        }
  325. X        if (forwchar(FALSE, 1) == FALSE)
  326. X                return (FALSE);
  327. X        return (ldelete(size, TRUE));
  328. X}
  329. X
  330. X/*
  331. X * Return TRUE if the character at dot is a character that is considered to be
  332. X * part of a word. The word character list is hard coded. Should be setable.
  333. X */
  334. Xinword()
  335. X{
  336. X        register int    c;
  337. X
  338. X        if (curwp->w_doto == llength(curwp->w_dotp))
  339. X                return (FALSE);
  340. X        c = lgetc(curwp->w_dotp, curwp->w_doto);
  341. X        if (c>='a' && c<='z')
  342. X                return (TRUE);
  343. X        if (c>='A' && c<='Z')
  344. X                return (TRUE);
  345. X        if (c>='0' && c<='9')
  346. X                return (TRUE);
  347. X        if (c=='$' || c=='_')                   /* For identifiers      */
  348. X                return (TRUE);
  349. X        return (FALSE);
  350. X}
  351. X
  352. X#if    WORDPRO
  353. Xfillpara(f, n)    /* Fill the current paragraph according to the current
  354. X           fill column                        */
  355. X
  356. Xint f, n;    /* deFault flag and Numeric argument */
  357. X
  358. X{
  359. X    register int c;            /* current char durring scan    */
  360. X    register int wordlen;        /* length of current word    */
  361. X    register int clength;        /* position on line during fill    */
  362. X    register int i;            /* index during word copy    */
  363. X    register int newlength;        /* tentative new line length    */
  364. X    register int eopflag;        /* Are we at the End-Of-Paragraph? */
  365. X    register int firstflag;        /* first word? (needs no space)    */
  366. X    register LINE *eopline;        /* pointer to line just past EOP */
  367. X    register int dotflag;        /* was the last char a period?    */
  368. X    char wbuf[NSTRING];        /* buffer for current word    */
  369. X
  370. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  371. X        return(rdonly());    /* we are in read only mode    */
  372. X    if (fillcol == 0) {    /* no fill column set */
  373. X        mlwrite("No fill column set");
  374. X        return(FALSE);
  375. X    }
  376. X
  377. X    /* record the pointer to the line just past the EOP */
  378. X    gotoeop(FALSE, 1);
  379. X    eopline = lforw(curwp->w_dotp);
  380. X
  381. X    /* and back top the begining of the paragraph */
  382. X    gotobop(FALSE, 1);
  383. X
  384. X    /* initialize various info */
  385. X    clength = curwp->w_doto;
  386. X    if (clength && curwp->w_dotp->l_text[0] == TAB)
  387. X        clength = 8;
  388. X    wordlen = 0;
  389. X    dotflag = FALSE;
  390. X
  391. X    /* scan through lines, filling words */
  392. X    firstflag = TRUE;
  393. X    eopflag = FALSE;
  394. X    while (!eopflag) {
  395. X        /* get the next character in the paragraph */
  396. X        if (curwp->w_doto == llength(curwp->w_dotp)) {
  397. X            c = ' ';
  398. X            if (lforw(curwp->w_dotp) == eopline)
  399. X                eopflag = TRUE;
  400. X        } else
  401. X            c = lgetc(curwp->w_dotp, curwp->w_doto);
  402. X
  403. X        /* and then delete it */
  404. X        ldelete(1L, FALSE);
  405. X
  406. X        /* if not a separator, just add it in */
  407. X        if (c != ' ' && c != '    ') {
  408. X            dotflag = (c == '.');        /* was it a dot */
  409. X            if (wordlen < NSTRING - 1)
  410. X                wbuf[wordlen++] = c;
  411. X        } else if (wordlen) {
  412. X            /* at a word break with a word waiting */
  413. X            /* calculate tantitive new length with word added */
  414. X            newlength = clength + 1 + wordlen;
  415. X            if (newlength <= fillcol) {
  416. X                /* add word to current line */
  417. X                if (!firstflag) {
  418. X                    linsert(1, ' '); /* the space */
  419. X                    ++clength;
  420. X                }
  421. X                firstflag = FALSE;
  422. X            } else {
  423. X                /* start a new line */
  424. X                lnewline();
  425. X                clength = 0;
  426. X            }
  427. X
  428. X            /* and add the word in in either case */
  429. X            for (i=0; i<wordlen; i++) {
  430. X                linsert(1, wbuf[i]);
  431. X                ++clength;
  432. X            }
  433. X            if (dotflag) {
  434. X                linsert(1, ' ');
  435. X                ++clength;
  436. X            }
  437. X            wordlen = 0;
  438. X        }
  439. X    }
  440. X    /* and add a last newline for the end of our new paragraph */
  441. X    lnewline();
  442. X    return(TRUE);
  443. X}
  444. X
  445. Xkillpara(f, n)    /* delete n paragraphs starting with the current one */
  446. X
  447. Xint f;    /* default flag */
  448. Xint n;    /* # of paras to delete */
  449. X
  450. X{
  451. X    register int status;    /* returned status of functions */
  452. X
  453. X    while (n--) {        /* for each paragraph to delete */
  454. X
  455. X        /* mark out the end and begining of the para to delete */
  456. X        gotoeop(FALSE, 1);
  457. X
  458. X        /* set the mark here */
  459. X            curwp->w_markp = curwp->w_dotp;
  460. X            curwp->w_marko = curwp->w_doto;
  461. X
  462. X        /* go to the begining of the paragraph */
  463. X        gotobop(FALSE, 1);
  464. X        curwp->w_doto = 0;    /* force us to the begining of line */
  465. X    
  466. X        /* and delete it */
  467. X        if ((status = killregion(FALSE, 1)) != TRUE)
  468. X            return(status);
  469. X
  470. X        /* and clean up the 2 extra lines */
  471. X        ldelete(2L, TRUE);
  472. X    }
  473. X    return(TRUE);
  474. X}
  475. X
  476. X
  477. X/*    wordcount:    count the # of words in the marked region,
  478. X            along with average word sizes, # of chars, etc,
  479. X            and report on them.            */
  480. X
  481. Xwordcount(f, n)
  482. X
  483. Xint f, n;    /* ignored numeric arguments */
  484. X
  485. X{
  486. X    register LINE *lp;    /* current line to scan */
  487. X    register int offset;    /* current char to scan */
  488. X    long size;        /* size of region left to count */
  489. X    register int ch;    /* current character to scan */
  490. X    register int wordflag;    /* are we in a word now? */
  491. X    register int lastflag;    /* were we just in a word? */
  492. X    long nwords;        /* total # of words */
  493. X    long nchars;        /* total number of chars */
  494. X    int nlines;        /* total number of lines in region */
  495. X    int avgch;        /* average number of chars/word */
  496. X    int status;        /* status return code */
  497. X    REGION region;        /* region to look at */
  498. X
  499. X    /* make sure we have a region to count */
  500. X        if ((status = getregion(®ion)) != TRUE)
  501. X                return(status);
  502. X    lp = region.r_linep;
  503. X    offset = region.r_offset;
  504. X    size = region.r_size;
  505. X
  506. X    /* count up things */
  507. X    lastflag = FALSE;
  508. X    nchars = 0L;
  509. X    nwords = 0L;
  510. X    nlines = 0;
  511. X    while (size--) {
  512. X
  513. X        /* get the current character */
  514. X        if (offset == llength(lp)) {    /* end of line */
  515. X            ch = '\n';
  516. X            lp = lforw(lp);
  517. X            offset = 0;
  518. X            ++nlines;
  519. X        } else {
  520. X            ch = lgetc(lp, offset);
  521. X            ++offset;
  522. X        }
  523. X
  524. X        /* and tabulate it */
  525. X        wordflag = ((ch >= 'a' && ch <= 'z') ||
  526. X                (ch >= 'A' && ch <= 'Z') ||
  527. X                (ch >= '0' && ch <= '9') ||
  528. X                (ch == '$' || ch == '_'));
  529. X        if (wordflag == TRUE && lastflag == FALSE)
  530. X            ++nwords;
  531. X        lastflag = wordflag;
  532. X        ++nchars;
  533. X    }
  534. X
  535. X    /* and report on the info */
  536. X    if (nwords > 0L)
  537. X        avgch = (int)((100L * nchars) / nwords);
  538. X    else
  539. X        avgch = 0;
  540. X
  541. X    mlwrite("Words %D Chars %D Lines %d Avg chars/word %f",
  542. X        nwords, nchars, nlines + 1, avgch);
  543. X    return(TRUE);
  544. X}
  545. X#endif
  546. FRIDAY_NIGHT
  547.  
  548.