Subject: v06i082: MicroEmacs, Version 3.7 (uEmacs3.7), Part12/12 Newsgroups: mod.sources Approved: rs@mirror.UUCP Submitted by: ihnp4!pur-ee!pur-phy!duncan!lawrence Mod.sources: Volume 6, Issue 82 Archive-name: uEmacs/Part12 [ This is the last version of emacs that will be posted here for quite some time. Anyone for a mod.sources.emacs? --r$ ] echo extracting - word.c sed 's/^X//' > word.c << 'FRIDAY_NIGHT' X/* X * The routines in this file implement commands that work word or a X * paragraph at a time. There are all sorts of word mode commands. If I X * do any sentence mode commands, they are likely to be put in this file. X */ X X#include X#include "estruct.h" X#include "edef.h" X X/* Word wrap on n-spaces. Back-over whatever precedes the point on the current X * line and stop on the first word-break or the beginning of the line. If we X * reach the beginning of the line, jump back to the end of the word and start X * a new line. Otherwise, break the line at the word-break, eat it, and jump X * back to the end of the word. X * Returns TRUE on success, FALSE on errors. X */ Xwrapword(n) X Xint n; X X{ X register int cnt; /* size of word wrapped to next line */ X register int c; /* charector temporary */ X X /* backup from the 1 char */ X if (!backchar(0, 1)) X return(FALSE); X X /* back up until we aren't in a word, X make sure there is a break in the line */ X cnt = 0; X while (((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ') X && (c != '\t')) { X cnt++; X if (!backchar(0, 1)) X return(FALSE); X /* if we make it to the begining, start a new line */ X if (curwp->w_doto == 0) { X gotoeol(FALSE, 0); X return(newline(0,1)); X } X } X X /* delete the forward white space */ X if (!forwdel(0, 1)) X return(FALSE); X X /* put in a end of line */ X if (!newline(0, 1)) X return(FALSE); X X /* and past the first word */ X while (cnt-- > 0) { X if (forwchar(FALSE, 1) == FALSE) X return(FALSE); X } X return(TRUE); X} X X/* X * Move the cursor backward by "n" words. All of the details of motion are X * performed by the "backchar" and "forwchar" routines. Error if you try to X * move beyond the buffers. X */ Xbackword(f, n) X{ X if (n < 0) X return (forwword(f, -n)); X if (backchar(FALSE, 1) == FALSE) X return (FALSE); X while (n--) { X while (inword() == FALSE) { X if (backchar(FALSE, 1) == FALSE) X return (FALSE); X } X while (inword() != FALSE) { X if (backchar(FALSE, 1) == FALSE) X return (FALSE); X } X } X return (forwchar(FALSE, 1)); X} X X/* X * Move the cursor forward by the specified number of words. All of the motion X * is done by "forwchar". Error if you try and move beyond the buffer's end. X */ Xforwword(f, n) X{ X if (n < 0) X return (backword(f, -n)); X while (n--) { X#if NFWORD X while (inword() != FALSE) { X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X } X#endif X while (inword() == FALSE) { X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X } X#if NFWORD == 0 X while (inword() != FALSE) { X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X } X#endif X } X return(TRUE); X} X X/* X * Move the cursor forward by the specified number of words. As you move, X * convert any characters to upper case. Error if you try and move beyond the X * end of the buffer. Bound to "M-U". X */ Xupperword(f, n) X{ X register int c; X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X if (n < 0) X return (FALSE); X while (n--) { X while (inword() == FALSE) { X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X } X while (inword() != FALSE) { X c = lgetc(curwp->w_dotp, curwp->w_doto); X if (c>='a' && c<='z') { X c -= 'a'-'A'; X lputc(curwp->w_dotp, curwp->w_doto, c); X lchange(WFHARD); X } X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X } X } X return (TRUE); X} X X/* X * Move the cursor forward by the specified number of words. As you move X * convert characters to lower case. Error if you try and move over the end of X * the buffer. Bound to "M-L". X */ Xlowerword(f, n) X{ X register int c; X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X if (n < 0) X return (FALSE); X while (n--) { X while (inword() == FALSE) { X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X } X while (inword() != FALSE) { X c = lgetc(curwp->w_dotp, curwp->w_doto); X if (c>='A' && c<='Z') { X c += 'a'-'A'; X lputc(curwp->w_dotp, curwp->w_doto, c); X lchange(WFHARD); X } X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X } X } X return (TRUE); X} X X/* X * Move the cursor forward by the specified number of words. As you move X * convert the first character of the word to upper case, and subsequent X * characters to lower case. Error if you try and move past the end of the X * buffer. Bound to "M-C". X */ Xcapword(f, n) X{ X register int c; X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X if (n < 0) X return (FALSE); X while (n--) { X while (inword() == FALSE) { X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X } X if (inword() != FALSE) { X c = lgetc(curwp->w_dotp, curwp->w_doto); X if (c>='a' && c<='z') { X c -= 'a'-'A'; X lputc(curwp->w_dotp, curwp->w_doto, c); X lchange(WFHARD); X } X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X while (inword() != FALSE) { X c = lgetc(curwp->w_dotp, curwp->w_doto); X if (c>='A' && c<='Z') { X c += 'a'-'A'; X lputc(curwp->w_dotp, curwp->w_doto, c); X lchange(WFHARD); X } X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X } X } X } X return (TRUE); X} X X/* X * Kill forward by "n" words. Remember the location of dot. Move forward by X * the right number of words. Put dot back where it was and issue the kill X * command for the right number of characters. Bound to "M-D". X */ Xdelfword(f, n) X{ X register LINE *dotp; X register int doto; X long size; X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X if (n < 0) X return (FALSE); X if ((lastflag&CFKILL) == 0) /* Clear kill buffer if */ X kdelete(); /* last wasn't a kill. */ X thisflag |= CFKILL; X dotp = curwp->w_dotp; X doto = curwp->w_doto; X size = 0; X while (n--) { X#if NFWORD X if (curwp->w_doto == llength(curwp->w_dotp)) { X if (forwchar(FALSE,1) == FALSE) X return(FALSE); X ++size; X } X X while (inword() != FALSE) { X if (forwchar(FALSE,1) == FALSE) X return(FALSE); X ++size; X } X X while ((inword() == FALSE) && X (curwp->w_doto != llength(curwp->w_dotp))) { X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X ++size; X } X#else X while (inword() == FALSE) { X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X ++size; X } X X while (inword() != FALSE) { X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X ++size; X } X#endif X } X curwp->w_dotp = dotp; X curwp->w_doto = doto; X return (ldelete(size, TRUE)); X} X X/* X * Kill backwards by "n" words. Move backwards by the desired number of words, X * counting the characters. When dot is finally moved to its resting place, X * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace". X */ Xdelbword(f, n) X{ X long size; X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X if (n < 0) X return (FALSE); X if ((lastflag&CFKILL) == 0) /* Clear kill buffer if */ X kdelete(); /* last wasn't a kill. */ X thisflag |= CFKILL; X if (backchar(FALSE, 1) == FALSE) X return (FALSE); X size = 0; X while (n--) { X while (inword() == FALSE) { X if (backchar(FALSE, 1) == FALSE) X return (FALSE); X ++size; X } X while (inword() != FALSE) { X if (backchar(FALSE, 1) == FALSE) X return (FALSE); X ++size; X } X } X if (forwchar(FALSE, 1) == FALSE) X return (FALSE); X return (ldelete(size, TRUE)); X} X X/* X * Return TRUE if the character at dot is a character that is considered to be X * part of a word. The word character list is hard coded. Should be setable. X */ Xinword() X{ X register int c; X X if (curwp->w_doto == llength(curwp->w_dotp)) X return (FALSE); X c = lgetc(curwp->w_dotp, curwp->w_doto); X if (c>='a' && c<='z') X return (TRUE); X if (c>='A' && c<='Z') X return (TRUE); X if (c>='0' && c<='9') X return (TRUE); X if (c=='$' || c=='_') /* For identifiers */ X return (TRUE); X return (FALSE); X} X X#if WORDPRO Xfillpara(f, n) /* Fill the current paragraph according to the current X fill column */ X Xint f, n; /* deFault flag and Numeric argument */ X X{ X register int c; /* current char durring scan */ X register int wordlen; /* length of current word */ X register int clength; /* position on line during fill */ X register int i; /* index during word copy */ X register int newlength; /* tentative new line length */ X register int eopflag; /* Are we at the End-Of-Paragraph? */ X register int firstflag; /* first word? (needs no space) */ X register LINE *eopline; /* pointer to line just past EOP */ X register int dotflag; /* was the last char a period? */ X char wbuf[NSTRING]; /* buffer for current word */ X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X if (fillcol == 0) { /* no fill column set */ X mlwrite("No fill column set"); X return(FALSE); X } X X /* record the pointer to the line just past the EOP */ X gotoeop(FALSE, 1); X eopline = lforw(curwp->w_dotp); X X /* and back top the begining of the paragraph */ X gotobop(FALSE, 1); X X /* initialize various info */ X clength = curwp->w_doto; X if (clength && curwp->w_dotp->l_text[0] == TAB) X clength = 8; X wordlen = 0; X dotflag = FALSE; X X /* scan through lines, filling words */ X firstflag = TRUE; X eopflag = FALSE; X while (!eopflag) { X /* get the next character in the paragraph */ X if (curwp->w_doto == llength(curwp->w_dotp)) { X c = ' '; X if (lforw(curwp->w_dotp) == eopline) X eopflag = TRUE; X } else X c = lgetc(curwp->w_dotp, curwp->w_doto); X X /* and then delete it */ X ldelete(1L, FALSE); X X /* if not a separator, just add it in */ X if (c != ' ' && c != ' ') { X dotflag = (c == '.'); /* was it a dot */ X if (wordlen < NSTRING - 1) X wbuf[wordlen++] = c; X } else if (wordlen) { X /* at a word break with a word waiting */ X /* calculate tantitive new length with word added */ X newlength = clength + 1 + wordlen; X if (newlength <= fillcol) { X /* add word to current line */ X if (!firstflag) { X linsert(1, ' '); /* the space */ X ++clength; X } X firstflag = FALSE; X } else { X /* start a new line */ X lnewline(); X clength = 0; X } X X /* and add the word in in either case */ X for (i=0; iw_markp = curwp->w_dotp; X curwp->w_marko = curwp->w_doto; X X /* go to the begining of the paragraph */ X gotobop(FALSE, 1); X curwp->w_doto = 0; /* force us to the begining of line */ X X /* and delete it */ X if ((status = killregion(FALSE, 1)) != TRUE) X return(status); X X /* and clean up the 2 extra lines */ X ldelete(2L, TRUE); X } X return(TRUE); X} X X X/* wordcount: count the # of words in the marked region, X along with average word sizes, # of chars, etc, X and report on them. */ X Xwordcount(f, n) X Xint f, n; /* ignored numeric arguments */ X X{ X register LINE *lp; /* current line to scan */ X register int offset; /* current char to scan */ X long size; /* size of region left to count */ X register int ch; /* current character to scan */ X register int wordflag; /* are we in a word now? */ X register int lastflag; /* were we just in a word? */ X long nwords; /* total # of words */ X long nchars; /* total number of chars */ X int nlines; /* total number of lines in region */ X int avgch; /* average number of chars/word */ X int status; /* status return code */ X REGION region; /* region to look at */ X X /* make sure we have a region to count */ X if ((status = getregion(®ion)) != TRUE) X return(status); X lp = region.r_linep; X offset = region.r_offset; X size = region.r_size; X X /* count up things */ X lastflag = FALSE; X nchars = 0L; X nwords = 0L; X nlines = 0; X while (size--) { X X /* get the current character */ X if (offset == llength(lp)) { /* end of line */ X ch = '\n'; X lp = lforw(lp); X offset = 0; X ++nlines; X } else { X ch = lgetc(lp, offset); X ++offset; X } X X /* and tabulate it */ X wordflag = ((ch >= 'a' && ch <= 'z') || X (ch >= 'A' && ch <= 'Z') || X (ch >= '0' && ch <= '9') || X (ch == '$' || ch == '_')); X if (wordflag == TRUE && lastflag == FALSE) X ++nwords; X lastflag = wordflag; X ++nchars; X } X X /* and report on the info */ X if (nwords > 0L) X avgch = (int)((100L * nchars) / nwords); X else X avgch = 0; X X mlwrite("Words %D Chars %D Lines %d Avg chars/word %f", X nwords, nchars, nlines + 1, avgch); X return(TRUE); X} X#endif FRIDAY_NIGHT