[mod.sources] v06i079: MicroEmacs, Version 3.7

sources-request@mirror.UUCP (07/30/86)

Submitted by: ihnp4!pur-ee!pur-phy!duncan!lawrence
Mod.sources: Volume 6, Issue 79
Archive-name: uEmacs3.7/Part09

[  This is the latest revision of one of two programs named "MicroEmacs";
   when discussing these on the net, or in contacting the authors, make
   sure to mention the version number -- in this case 3.7 -- as that is
   the easiest way to distinguish between them.  Daniel will be posting
   uuencoded executables in net.micro.pc and net.micro.amiga; the file
   'readme' contains information on how to also get these from him
   directly.   --r$ ]

echo extracting - menu1
sed 's/^X//' > menu1 << 'FRIDAY_NIGHT'
X--<<01>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 WORD CASE/SCREEN CONTROL   F2  PAGING/SCROLLING
X[Main Menu]         F3 CUT & PASTE                F4  SEARCH AND REPLACE
X                    F5 DELETION COMMANDS          F6  WORD PROCESSING
X                    F7 INSERTION COMMANDS         F8  EDITOR CONTROL
X 06/18/86           F9 CURSOR MOVEMENT            F10 exit MicroEMACS
X--<<02>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 BUFFER CONTROL             F2  MACROS
X[Editor control]    F3 COLOR CHANGES              F4  MODES
X                    F5 DOS COMMANDS               F6  SCRIPTS
X                    F7 FILE ACCESS                F8  WINDOWS
X                    F9 KEY BINDINGS               F10 exit to MAIN MENU
X--<<03>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 upper case a word          F2  upper case a region
X Word case &        F3 lower case a word          F4  lower case a region
X  Screen control    F5 capitilize a word
X                    F7 redraw the screen          F8  mark a region
X                    F9 center the current line    F10 exit to MAIN MENU
X--<<04>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1  mark a region
X  Cut & Paste       F3  delete the region
X                    F5  copy the region to the kill buffer
X                    F7  insert the kill buffer into the text here
X                                                  F10 exit to MAIN MENU
X--<<05>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 delete the last character
X  Deletions         F3 delete the next character
X                    F5 delete to the end of the current line
X                    F7 delete all the blank lines around the cursor
X                                                  F10 exit to MAIN MENU
X--<<06>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 open a blank line          F2  insert a prompted string
X  Insertion         F3 insert a tab               F4  quote the next character
X                    F5 insert a space             F6  transpose last 2 chars
X                    F7 insert a newline and indent like the last line
X                    F9 insert a newline           F10 exit to MAIN MENU
X--<<07>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 begining of the file       F2  up one line
X  Cursor Movement   F3 left                       F4  right
X        F^2         F5 end of the file            F6  down one line
X    F3 < + > F4     F7 begining of line           F8  end of line
X        FV6         F9 goto line                  F10 exit to MAIN MENU
X--<<08>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1  go up one page            F2  go down one page
X  Paging and        F3  scroll the screen up      F4  scroll the screen down
X     Scrolling      F5  make the next widow go up one page
X                    F7  make the next window go down one page
X                    F9  exchange cursor & mark    F10 exit to MAIN MENU
X--<<09>>-----------------------------------------------------------------------
XMicroEMACS 3.7      f1  search forward            f2  seach backwards
X  Search and        F3  hunt forward              f4  hunt backwards
X    Replace         F5  isearch forward           F6  isearch backward
X                    F7  replace string            F8  replace string w/query
X                                                  F10 exit to MAIN MENU
X--<<10>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 go back a word             F2  go forward a word
X  Word processing   F3 go back a paragraph        F4  go forward a paragraph
X                    F5 fill paragraph             F6  delete current paragraph
X                    F7 delete last word           F8  delete next word
X                    F9 count words in region      F10 exit to MAIN MENU
X--<<11>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 report position            F2  unmark buffer
X  Buffer Control    F3 delete buffer              F4  switch to next buffer
X                    F5 list all buffers           F6  filter buffer through
X                    F7 rename current buffer             DOS program
X                    F9 select buffer              F10 exit to CONTROL MENU
X--<<12>>-----------------------------------------------------------------------
XMicroEMACS 3.7      Colors:           |  F1 current window's forground color
X  Color changes       Black   Magenta |  F3 current window's background color
X                      Blue    Cyan    |  F5 global forground color
X                      Red     Yellow  |  F7 global background color
X                      Green   White   |           F10  exit to CONTROL MENU
X--<<13>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1  execute one DOS command
X  DOS commands      F3  pipe one DOS command to a buffer
X                    F5  shell up to a new command interpeter
X                    F7  QUICK exit (write out all changed buffers and exit)
X                    F9  exit MicroEMACS           F10 exit to CONTROL MENU
X--<<14>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 find file                  F2 save current file
X  File Access       F3 view file (in VIEW mode)   F4 write file w/ new name
X                    F5 read file into buffer      F6 change current file name
X                    F7 insert file into buffer
X                                                  F10  exit to CONTROL MENU
X--<<15>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 bind a function to a key
X  Key Bindings      F3 unbind a key
X                    F5 describe a key
X                    F7 describe all bindings
X                                                  F10  exit to CONTROL MENU
X--<<16>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 define macro         The keyboard macro only works
X  Keyboard Macro    F3 end macro            for standard commands, NOT for
X                    F5 execute macro        menu selections.
X
X                                                  F10  exit to CONTROL MENU
X--<<17>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 set mode                   F2  set global mode
X  Modes             F3 delete mode                F4  delete global mode
X            Standard modes are:                   F6  set fill column
X                WRAP  VIEW  CMODE  EXACT OVER MAGIC
X                                                  F10 exit to CONTROL MENU
X--<<18>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 execute script file        F2  execute script line
X  Script            F3 execute script in buffer   F4  execute command (by name)
X            Script line format:
X         {<repeat count>} <command name> {<argument(s)> | "<argument(s)>"}
X                                                  F10  exit to CONTROL MENU
X--<<19>>-----------------------------------------------------------------------
XMicroEMACS 3.7      F1 split current window       F2  delete all other windows
X  Windows           F3 resize window              F4  delete current window
X                    F5 shrink window              F6  enlarge window
X                    F7 next window                F8  previous window
X                                                  F10 exit to CONTROL MENU
X-------------------------------------------------------------------------------
FRIDAY_NIGHT
echo extracting - random.c
sed 's/^X//' > random.c << 'FRIDAY_NIGHT'
X/*
X * This file contains the command processing functions for a number of random
X * commands. There is no functional grouping here, for sure.
X */
X
X#include        <stdio.h>
X#include	"estruct.h"
X#include        "edef.h"
X
Xint     tabsize;                        /* Tab size (0: use real tabs)  */
X
X/*
X * Set fill column to n.
X */
Xsetfillcol(f, n)
X{
X        fillcol = n;
X	mlwrite("[Fill column is %d]",n);
X        return(TRUE);
X}
X
X/*
X * Display the current position of the cursor, in origin 1 X-Y coordinates,
X * the character that is under the cursor (in hex), and the fraction of the
X * text that is before the cursor. The displayed column is not the current
X * column, but the column that would be used on an infinite width display.
X * Normally this is bound to "C-X =".
X */
Xshowcpos(f, n)
X{
X        register LINE   *lp;		/* current line */
X        register long   numchars;	/* # of chars in file */
X        register int	numlines;	/* # of lines in file */
X        register long   predchars;	/* # chars preceding point */
X        register int	predlines;	/* # lines preceding point */
X        register int    curchar;	/* character under cursor */
X        int ratio;
X        int col;
X	int savepos;			/* temp save for current offset */
X	int ecol;			/* column pos/end of current line */
X
X	/* starting at the begining of the buffer */
X        lp = lforw(curbp->b_linep);
X
X	/* start counting chars and lines */
X        numchars = 0;
X        numlines = 0;
X        while (lp != curbp->b_linep) {
X		/* if we are on the current line, record it */
X		if (lp == curwp->w_dotp) {
X			predlines = numlines;
X			predchars = numchars + curwp->w_doto;
X			if ((curwp->w_doto) == llength(lp))
X				curchar = '\n';
X			else
X				curchar = lgetc(lp, curwp->w_doto);
X		}
X		/* on to the next line */
X		++numlines;
X		numchars += llength(lp) + 1;
X		lp = lforw(lp);
X        }
X
X	/* if at end of file, record it */
X	if (curwp->w_dotp == curbp->b_linep) {
X		predlines = numlines;
X		predchars = numchars;
X	}
X
X	/* Get real column and end-of-line column. */
X	col = getccol(FALSE);
X	savepos = curwp->w_doto;
X	curwp->w_doto = llength(curwp->w_dotp);
X	ecol = getccol(FALSE);
X	curwp->w_doto = savepos;
X
X        ratio = 0;              /* Ratio before dot. */
X        if (numchars != 0)
X                ratio = (100L*predchars) / numchars;
X
X	/* summarize and report the info */
X	mlwrite("Line %d/%d Col %d/%d Char %D/%D (%d%%) char = 0x%x",
X		predlines+1, numlines+1, col, ecol,
X		predchars, numchars, ratio, curchar);
X        return (TRUE);
X}
X
X/*
X * Return current column.  Stop at first non-blank given TRUE argument.
X */
Xgetccol(bflg)
Xint bflg;
X{
X        register int c, i, col;
X        col = 0;
X        for (i=0; i<curwp->w_doto; ++i) {
X                c = lgetc(curwp->w_dotp, i);
X                if (c!=' ' && c!='\t' && bflg)
X                        break;
X                if (c == '\t')
X                        col |= 0x07;
X                else if (c<0x20 || c==0x7F)
X                        ++col;
X                ++col;
X        }
X        return(col);
X}
X
X/*
X * Twiddle the two characters on either side of dot. If dot is at the end of
X * the line twiddle the two characters before it. Return with an error if dot
X * is at the beginning of line; it seems to be a bit pointless to make this
X * work. This fixes up a very common typo with a single stroke. Normally bound
X * to "C-T". This always works within a line, so "WFEDIT" is good enough.
X */
Xtwiddle(f, n)
X{
X        register LINE   *dotp;
X        register int    doto;
X        register int    cl;
X        register int    cr;
X
X	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
X		return(rdonly());	/* we are in read only mode	*/
X        dotp = curwp->w_dotp;
X        doto = curwp->w_doto;
X        if (doto==llength(dotp) && --doto<0)
X                return (FALSE);
X        cr = lgetc(dotp, doto);
X        if (--doto < 0)
X                return (FALSE);
X        cl = lgetc(dotp, doto);
X        lputc(dotp, doto+0, cr);
X        lputc(dotp, doto+1, cl);
X        lchange(WFEDIT);
X        return (TRUE);
X}
X
X/*
X * Quote the next character, and insert it into the buffer. All the characters
X * are taken literally, with the exception of the newline, which always has
X * its line splitting meaning. The character is always read, even if it is
X * inserted 0 times, for regularity. Bound to "C-Q"
X */
Xquote(f, n)
X{
X        register int    s;
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        c = (*term.t_getchar)();
X        if (n < 0)
X                return (FALSE);
X        if (n == 0)
X                return (TRUE);
X        if (c == '\n') {
X                do {
X                        s = lnewline();
X                } while (s==TRUE && --n);
X                return (s);
X        }
X        return (linsert(n, c));
X}
X
X/*
X * Set tab size if given non-default argument (n <> 1).  Otherwise, insert a
X * tab into file.  If given argument, n, of zero, change to true tabs.
X * If n > 1, simulate tab stop every n-characters using spaces. This has to be
X * done in this slightly funny way because the tab (in ASCII) has been turned
X * into "C-I" (in 10 bit code) already. Bound to "C-I".
X */
Xtab(f, n)
X{
X        if (n < 0)
X                return (FALSE);
X        if (n == 0 || n > 1) {
X                tabsize = n;
X                return(TRUE);
X        }
X        if (! tabsize)
X                return(linsert(1, '\t'));
X        return(linsert(tabsize - (getccol(FALSE) % tabsize), ' '));
X}
X
X/*
X * Open up some blank space. The basic plan is to insert a bunch of newlines,
X * and then back up over them. Everything is done by the subcommand
X * procerssors. They even handle the looping. Normally this is bound to "C-O".
X */
Xopenline(f, n)
X{
X        register int    i;
X        register int    s;
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 (n == 0)
X                return (TRUE);
X        i = n;                                  /* Insert newlines.     */
X        do {
X                s = lnewline();
X        } while (s==TRUE && --i);
X        if (s == TRUE)                          /* Then back up overtop */
X                s = backchar(f, n);             /* of them all.         */
X        return (s);
X}
X
X/*
X * Insert a newline. Bound to "C-M". If we are in CMODE, do automatic
X * indentation as specified.
X */
Xnewline(f, n)
X{
X	register int    s;
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
X	/* if we are in C mode and this is a default <NL> */
X	if (n == 1 && (curbp->b_mode & MDCMOD) &&
X	    curwp->w_dotp != curbp->b_linep)
X		return(cinsert());
X
X	/* insert some lines */
X	while (n--) {
X		if ((s=lnewline()) != TRUE)
X			return (s);
X	}
X	return (TRUE);
X}
X
Xcinsert()	/* insert a newline and indentation for C */
X
X{
X	register char *cptr;	/* string pointer into text to copy */
X	register int tptr;	/* index to scan into line */
X	register int bracef;	/* was there a brace at the end of line? */
X	register int i;
X	char ichar[NSTRING];	/* buffer to hold indent of last line */
X
X	/* grab a pointer to text to copy indentation from */
X	cptr = &curwp->w_dotp->l_text[0];
X
X	/* check for a brace */
X	tptr = curwp->w_doto - 1;
X	bracef = (cptr[tptr] == '{');
X
X	/* save the indent of the previous line */
X	i = 0;
X	while ((i < tptr) && (cptr[i] == ' ' || cptr[i] == '\t')
X		&& (i < NSTRING - 1)) {
X		ichar[i] = cptr[i];
X		++i;
X	}
X	ichar[i] = 0;		/* terminate it */
X
X	/* put in the newline */
X	if (lnewline() == FALSE)
X		return(FALSE);
X
X	/* and the saved indentation */
X	i = 0;
X	while (ichar[i])
X		linsert(1, ichar[i++]);
X
X	/* and one more tab for a brace */
X	if (bracef)
X		tab(FALSE, 1);
X
X	return(TRUE);
X}
X
Xinsbrace(n, c)	/* insert a brace into the text here...we are in CMODE */
X
Xint n;	/* repeat count */
Xint c;	/* brace to insert (always { for now) */
X
X{
X	register int ch;	/* last character before input */
X	register int i;
X	register int target;	/* column brace should go after */
X
X	/* if we are at the begining of the line, no go */
X	if (curwp->w_doto == 0)
X		return(linsert(n,c));
X		
X	/* scan to see if all space before this is white space */
X	for (i = curwp->w_doto - 1; i >= 0; --i) {
X		ch = lgetc(curwp->w_dotp, i);
X		if (ch != ' ' && ch != '\t')
X			return(linsert(n, c));
X	}
X
X	/* delete back first */
X	target = getccol(FALSE);	/* calc where we will delete to */
X	target -= 1;
X	target -= target % (tabsize == 0 ? 8 : tabsize);
X	while (getccol(FALSE) > target)
X		backdel(FALSE, 1);
X
X	/* and insert the required brace(s) */
X	return(linsert(n, c));
X}
X
Xinspound()	/* insert a # into the text here...we are in CMODE */
X
X{
X	register int ch;	/* last character before input */
X	register int i;
X
X	/* if we are at the begining of the line, no go */
X	if (curwp->w_doto == 0)
X		return(linsert(1,'#'));
X		
X	/* scan to see if all space before this is white space */
X	for (i = curwp->w_doto - 1; i >= 0; --i) {
X		ch = lgetc(curwp->w_dotp, i);
X		if (ch != ' ' && ch != '\t')
X			return(linsert(1, '#'));
X	}
X
X	/* delete back first */
X	while (getccol(FALSE) >= 1)
X		backdel(FALSE, 1);
X
X	/* and insert the required pound */
X	return(linsert(1, '#'));
X}
X
X/*
X * Delete blank lines around dot. What this command does depends if dot is
X * sitting on a blank line. If dot is sitting on a blank line, this command
X * deletes all the blank lines above and below the current line. If it is
X * sitting on a non blank line then it deletes all of the blank lines after
X * the line. Normally this command is bound to "C-X C-O". Any argument is
X * ignored.
X */
Xdeblank(f, n)
X{
X        register LINE   *lp1;
X        register LINE   *lp2;
X        long nld;
X
X	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
X		return(rdonly());	/* we are in read only mode	*/
X        lp1 = curwp->w_dotp;
X        while (llength(lp1)==0 && (lp2=lback(lp1))!=curbp->b_linep)
X                lp1 = lp2;
X        lp2 = lp1;
X        nld = 0;
X        while ((lp2=lforw(lp2))!=curbp->b_linep && llength(lp2)==0)
X                ++nld;
X        if (nld == 0)
X                return (TRUE);
X        curwp->w_dotp = lforw(lp1);
X        curwp->w_doto = 0;
X        return (ldelete(nld, FALSE));
X}
X
X/*
X * Insert a newline, then enough tabs and spaces to duplicate the indentation
X * of the previous line. Assumes tabs are every eight characters. Quite simple.
X * Figure out the indentation of the current line. Insert a newline by calling
X * the standard routine. Insert the indentation by inserting the right number
X * of tabs and spaces. Return TRUE if all ok. Return FALSE if one of the
X * subcomands failed. Normally bound to "C-J".
X */
Xindent(f, n)
X{
X        register int    nicol;
X        register int    c;
X        register int    i;
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                nicol = 0;
X                for (i=0; i<llength(curwp->w_dotp); ++i) {
X                        c = lgetc(curwp->w_dotp, i);
X                        if (c!=' ' && c!='\t')
X                                break;
X                        if (c == '\t')
X                                nicol |= 0x07;
X                        ++nicol;
X                }
X                if (lnewline() == FALSE
X                || ((i=nicol/8)!=0 && linsert(i, '\t')==FALSE)
X                || ((i=nicol%8)!=0 && linsert(i,  ' ')==FALSE))
X                        return (FALSE);
X        }
X        return (TRUE);
X}
X
X/*
X * Delete forward. This is real easy, because the basic delete routine does
X * all of the work. Watches for negative arguments, and does the right thing.
X * If any argument is present, it kills rather than deletes, to prevent loss
X * of text if typed with a big argument. Normally bound to "C-D".
X */
Xforwdel(f, n)
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 (backdel(f, -n));
X        if (f != FALSE) {                       /* Really a kill.       */
X                if ((lastflag&CFKILL) == 0)
X                        kdelete();
X                thisflag |= CFKILL;
X        }
X        return (ldelete((long)n, f));
X}
X
X/*
X * Delete backwards. This is quite easy too, because it's all done with other
X * functions. Just move the cursor back, and delete forwards. Like delete
X * forward, this actually does a kill if presented with an argument. Bound to
X * both "RUBOUT" and "C-H".
X */
Xbackdel(f, n)
X{
X        register int    s;
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 (forwdel(f, -n));
X        if (f != FALSE) {                       /* Really a kill.       */
X                if ((lastflag&CFKILL) == 0)
X                        kdelete();
X                thisflag |= CFKILL;
X        }
X        if ((s=backchar(f, n)) == TRUE)
X                s = ldelete((long)n, f);
X        return (s);
X}
X
X/*
X * Kill text. If called without an argument, it kills from dot to the end of
X * the line, unless it is at the end of the line, when it kills the newline.
X * If called with an argument of 0, it kills from the start of the line to dot.
X * If called with a positive argument, it kills from dot forward over that
X * number of newlines. If called with a negative argument it kills backwards
X * that number of newlines. Normally bound to "C-K".
X */
Xkilltext(f, n)
X{
X        register LINE   *nextp;
X        long chunk;
X
X	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
X		return(rdonly());	/* we are in read only mode	*/
X        if ((lastflag&CFKILL) == 0)             /* Clear kill buffer if */
X                kdelete();                      /* last wasn't a kill.  */
X        thisflag |= CFKILL;
X        if (f == FALSE) {
X                chunk = llength(curwp->w_dotp)-curwp->w_doto;
X                if (chunk == 0)
X                        chunk = 1;
X        } else if (n == 0) {
X                chunk = curwp->w_doto;
X                curwp->w_doto = 0;
X        } else if (n > 0) {
X                chunk = llength(curwp->w_dotp)-curwp->w_doto+1;
X                nextp = lforw(curwp->w_dotp);
X                while (--n) {
X                        if (nextp == curbp->b_linep)
X                                return (FALSE);
X                        chunk += llength(nextp)+1;
X                        nextp = lforw(nextp);
X                }
X        } else {
X                mlwrite("neg kill");
X                return (FALSE);
X        }
X        return(ldelete(chunk, TRUE));
X}
X
Xsetmode(f, n)	/* prompt and set an editor mode */
X
Xint f, n;	/* default and argument */
X
X{
X	adjustmode(TRUE, FALSE);
X}
X
Xdelmode(f, n)	/* prompt and delete an editor mode */
X
Xint f, n;	/* default and argument */
X
X{
X	adjustmode(FALSE, FALSE);
X}
X
Xsetgmode(f, n)	/* prompt and set a global editor mode */
X
Xint f, n;	/* default and argument */
X
X{
X	adjustmode(TRUE, TRUE);
X}
X
Xdelgmode(f, n)	/* prompt and delete a global editor mode */
X
Xint f, n;	/* default and argument */
X
X{
X	adjustmode(FALSE, TRUE);
X}
X
Xadjustmode(kind, global)	/* change the editor mode status */
X
Xint kind;	/* true = set,		false = delete */
Xint global;	/* true = global flag,	false = current buffer flag */
X{
X	register char *scan;		/* scanning pointer to convert prompt */
X	register int i;			/* loop index */
X#if	COLOR
X	register int uflag;		/* was modename uppercase?	*/
X#endif
X	char prompt[50];	/* string to prompt user with */
X	char cbuf[NPAT];		/* buffer to recieve mode name into */
X
X	/* build the proper prompt string */
X	if (global)
X		strcpy(prompt,"Global mode to ");
X	else
X		strcpy(prompt,"Mode to ");
X
X	if (kind == TRUE)
X		strcat(prompt, "add: ");
X	else
X		strcat(prompt, "delete: ");
X
X	/* prompt the user and get an answer */
X
X	mlreply(prompt, cbuf, NPAT - 1);
X
X	/* make it uppercase */
X
X	scan = cbuf;
X#if	COLOR
X	uflag = (*scan >= 'A' && *scan <= 'Z');
X#endif
X	while (*scan != 0) {
X		if (*scan >= 'a' && *scan <= 'z')
X			*scan = *scan - 32;
X		scan++;
X	}
X
X	/* test it first against the colors we know */
X	for (i=0; i<NCOLORS; i++) {
X		if (strcmp(cbuf, cname[i]) == 0) {
X			/* finding the match, we set the color */
X#if	COLOR
X			if (uflag)
X				if (global)
X					gfcolor = i;
X				else
X					curwp->w_fcolor = i;
X			else
X				if (global)
X					gbcolor = i;
X				else
X					curwp->w_bcolor = i;
X
X			curwp->w_flag |= WFCOLR;
X#endif
X			mlerase();
X			return(TRUE);
X		}
X	}
X
X	/* test it against the modes we know */
X
X	for (i=0; i < NUMMODES; i++) {
X		if (strcmp(cbuf, modename[i]) == 0) {
X			/* finding a match, we process it */
X			if (kind == TRUE)
X				if (global)
X					gmode |= (1 << i);
X				else
X					curwp->w_bufp->b_mode |= (1 << i);
X			else
X				if (global)
X					gmode &= ~(1 << i);
X				else
X					curwp->w_bufp->b_mode &= ~(1 << i);
X			/* display new mode line */
X			if (global == 0)
X				upmode();
X			mlerase();	/* erase the junk */
X			return(TRUE);
X		}
X	}
X
X	mlwrite("No such mode!");
X	return(FALSE);
X}
X
X/*	This function simply clears the message line,
X		mainly for macro usage			*/
X
Xclrmes(f, n)
X
Xint f, n;	/* arguments ignored */
X
X{
X	mlwrite("");
X	return(TRUE);
X}
X
X/*	This function writes a string on the message line
X		mainly for macro usage			*/
X
Xwritemsg(f, n)
X
Xint f, n;	/* arguments ignored */
X
X{
X	register char *sp;	/* pointer into buf to expand %s */
X	register char *np;	/* ptr into nbuf */
X	register int status;
X	char buf[NPAT];		/* buffer to recieve mode name into */
X	char nbuf[NPAT*2];	/* buffer to expand string into */
X
X	if ((status = mlreply("Message to write: ", buf, NPAT - 1)) != TRUE)
X		return(status);
X
X	/* expand all '%' to "%%" so mlwrite won't expect arguments */
X	sp = buf;
X	np = nbuf;
X	while (*sp) {
X		*np++ = *sp;
X		if (*sp++ == '%')
X			*np++ = '%';
X	}
X	*np = '\0';
X	mlwrite(nbuf);
X	return(TRUE);
X}
X
X/*	Close fences are matched against their partners, and if
X	on screen the cursor briefly lights there		*/
X
Xfmatch(ch)
X
Xchar ch;	/* fence type to match against */
X
X{
X	register LINE *oldlp;	/* original line pointer */
X	register int oldoff;	/* and offset */
X	register LINE *toplp;	/* top line in current window */
X	register int count;	/* current fence level count */
X	register char opench;	/* open fence */
X	register char c;	/* current character in scan */
X	register int i;
X
X	/* first get the display update out there */
X	update(FALSE);
X
X	/* save the original cursor position */
X	oldlp = curwp->w_dotp;
X	oldoff = curwp->w_doto;
X
X	/* setup proper open fence for passed close fence */
X	if (ch == ')')
X		opench = '(';
X	else
X		opench = '{';
X
X	/* find the top line and set up for scan */
X	toplp = curwp->w_linep->l_bp;
X	count = 1;
X	backchar(FALSE, 2);
X
X	/* scan back until we find it, or reach past the top of the window */
X	while (count > 0 && curwp->w_dotp != toplp) {
X		c = lgetc(curwp->w_dotp, curwp->w_doto);
X		if (c == ch)
X			++count;
X		if (c == opench)
X			--count;
X		backchar(FALSE, 1);
X		if (curwp->w_dotp == curwp->w_bufp->b_linep->l_fp &&
X		    curwp->w_doto == 0)
X			break;
X	}
X
X	/* if count is zero, we have a match, display the sucker */
X	/* there is a real machine dependant timing problem here we have
X	   yet to solve......... */
X	if (count == 0) {
X		forwchar(FALSE, 1);
X		for (i = 0; i < term.t_pause; i++)
X			update(FALSE);
X	}
X
X	/* restore the current position */
X	curwp->w_dotp = oldlp;
X	curwp->w_doto = oldoff;
X	return(TRUE);
X}
X
Xistring(f, n)	/* ask for and insert a string into the current
X		   buffer at the current point */
X
Xint f, n;	/* ignored arguments */
X
X{
X	register char *tp;	/* pointer into string to add */
X	register int status;	/* status return code */
X	char tstring[NPAT+1];	/* string to add */
X
X	/* ask for string to insert */
X	status = mlreplyt("String to insert<ESC>: ", tstring, NPAT, 27);
X	if (status != TRUE)
X		return(status);
X
X	/* insert it */
X	tp = &tstring[0];
X	while (*tp) {
X		if (*tp == 0x0a)
X			status = lnewline();
X		else
X			status = linsert(1, *tp);
X		++tp;
X		if (status != TRUE)
X			return(status);
X	}
X	return(TRUE);
X}
X
FRIDAY_NIGHT
echo extracting - readme
sed 's/^X//' > readme << 'FRIDAY_NIGHT'
X		MicroEMACS 3.7 release notes
X
X	First off, I would like to thank all the people that send in
Xvarious comments, bug fixes and code segments.  I have included as many
Xof these as possible in this current source.  All the new features which
Xare larger than a couple of lines are IFDEF'ed by symbols in the
XESTRUCT.H header file.  As long as everyone keeps sending these in, I
Xwill keep trying to incorporate them, at least in spirit. 
X
X	Installation is fairly straight forward.  Copy or compile the
Xappropriate version of the editor into EMACS (EMACS.EXE on MS/PC DOS)
Xsomewhere on your executable path.  Then copy the emacs.hlp file to one
Xof the directories names in the epath.h file for your system.  A startup
Xfile .emacsrc (EMACS.RC on PC/MS DOS) can be placed in the directory
Xpointed to by your HOME environment variable. 
X	
X[	Note for AMIGA users: Lattice 3.02 was giving me some rather
Xmysterious software task failure errors while compiling some of the
Xmodules. Not having the Amiga long enough to solve this, I upgraded to
XLattice 3.03 and these problems disappeared. If enough people are stuck
Xwith 3.02 and someone comes up with a fix and sends it to me, I will
Xincorporate it into the master sources. Remember to say "stack 16000"
Xbefore compiling the larger files.]
X
X	A new reference manual with a listing of all the commands and
Xdescriptions is now included.  Commands are listed in logical groups.
XAlso coming in the near future will be a beginner's document to replace
X"emacs.tut".
X
X	Also included are two files, "menu.cmd" and "menu1" that make up
Xa simple menu driven interface to MicroEMACS 3.7.  For people who prefer
Xmenu driven interfaces, rename "menu.cmd" as "emacs.rc" and place it
Xwhere a startup file would be expected.  Also find a place for the text
Xfile "menu1" and change your "emacs.rc" to view-file from that directory
Xfor "menu1".
X
X	MicroEMACS 3.7 is distributed on three 5 1/4" diskettes, or as one
X3 1/2" diskette, or as apx. ten shell archives.  The shell archives are
Xposted to USENET mod.sources and do not include the executable files. 
XThe executable PC and AMIGA versions will also be posted in the relevent
XUSENET groups. 
X
XDisk ONE contains:
X
X	readme		this file
X
X	acemacs.exe	MSDOS ansi color executable
X	icemacs.exe	PCDOS color executable
X
X	ebind.h		default biding structures
X	edef.h		static global data declarations
X	efunc.h		function names binding table
X	epath.h		help/startup file path definitions
X	estruct.h	structure and configuration header file
X
X	emacs.hlp	online help file
X	emacs.key	command wall chart
X	emacs.rc	standard startup file
X	emacs2.mss	reference manual (in MicroSCRIBE format)
X	emacs.tut	beginers tutorial file
X	makefile	UNIX V7/BSD 4.2 compilation command file
X	azmap.cmd	an example MicroEMACS macro file
X	menu.cmd	Menu driven command driver script
X	menu1		data file for menu.cmd
X
XDisk TWO contains:
X
X	ansi.c		ANSI screen driver
X	basic.c		cursor movement
X	bind.c		bind/unbind and help commands
X	buffer.c	buffer management
X	display.c	display update functions
X	dg10.c		Data General System/10 screen driver
X	exec.c		macro line execution functions
X	file.c		use file commands
X	fileio.c	file I/O functions
X	hp150.c		HP150 screen/keyboard driver
X	ibmpc.c		IBM-PC screen driver
X	input.c		message line input routines
X	isearch.c	interactive search commands
X	line.c		line editing functions
X	lock.c		file locking front end
X	main.c		command line and keyboard command parsing
X	random.c	some random commands
X	region.c	wipe/copy/yank commands
X	search.c	normal search commands
X	spawn.c		DOS interface commands
X	tcap.c		UNIX screen drivers
X	termio.c	Keyboard I/O routines
X	vmsvt.c		VMS screen drivers
X	vt52.c		VT52 screen drivers
X	window.c	window management commands
X	word.c		word move/delete/reformat commands
X
XDisk THREE contains:
X
X	hpemacs.exe	HP150 executable
X	dgemacs.exe	Data General System/10 executable
X	wgemacs.exe	Wang PC executable
X	amemacs.exe	Commodore AMIGA executable
X
X	The next version of MicroEMACS (3.8) will probably not be until
Xlate fall 1986, but it will probably be accompanied by the first version
Xof MicroSCRIBE, a text formater to go along with MicroEMACS.  As I will
Xcontinue to support MicroEMACS, ideas, comments, bug fixes and new code
Xshould be send to:
X
X	Daniel Lawrence
X	617 New York St
X	Lafayette, IN 47091
X
X	or
X
X	ihnp4!pur-ee!pur-phy!duncan!lawrence on USENET
X
X	and, as before, copies of MicroEMACS 3.7 may be gotten by
Xsending a self addressed, self stamped mailer with two 5 1/4" diskettes
Xto the above address.
X
X-------------------------------------------------------------------------------
X		MicroEMACS 3.7	-	New Features
X
X***	COLOR!!!!
X
X	The forground and backgound color of buffers may be set
Xwith the add-mode and add-global-mode commands. Forgound colors
Xare set with capitalized color names, and background colors with
Xlower case color names. Availible colors are the ANSI color set:
X
Xblack, blue, red, green, yellow, cyan, magenta, and white
X
X	This feature is only availible on machines that support
Xcolor properly in text mode. (IBM-PC w/color graphics adapter
Xand its clones)
X
X***	Pipe command
X
X	The pipe-command (^X-@) command allows you to execute an
Xoperating system command and send the results into a buffer.
XMicroEMACS will make a buffer by the name of "command" for the
Xresults. This is only supported on systems that allow I/O redirection.
X
X***	Filter buffer
X
X	The filter-buffer (^X-#) command allows you to send an
Xexisting buffer's contents through a filter which runs under the
Xcurrent operating system. The result replaces the contents of
Xthe current buffer (beware of non-existant filters). Its a good
Xidea to make a backup of the buffer to be filtered.
X
X***	Switchar is fixed
X
X	MicroEMACS under PC/MS DOS no longer cares about the
Xsetting of the switchar. It uses the DOS call to look it up and
Xuse it in its fork and system calls.
X
X***	CMODE is configurable
X
X	Automatic entering of CMODE for .c and .h extension
Xfiles is now configurable with the ACMODE symbol in estruct.h
X
X***	Query-replace UNDO command
X
X	While making a query-replace (M-^R) run, the U key now
Xundoes the last replace.
X
X***	New cursor position report
X
X	Re-wrote the buffer-position (^X-=) command to give more
Xusefull information on # lines in file, current line and column,
Xpercentage of text before cursor and the hex value of the
Xcharacter the cursor is on.
X
X***	Word wrapping improved
X
X	Words are now only broken at spaces and tabs by the word
Xwrapping algorithm. No more disapearing punctuation delimiters.
X
X***	IBM-PC Color board display driver
X
X	A new screen driver for the IBM-PC color board is in the
Xfile IBMPC.C and this vastly improves the paging speed and
Xeliminates the retrace flicker. However, under the color
Xversion, the update while adding text is a little more slugish
Xthan I would hope. We will be working to improve this in the future.
X
X***	Destroying windows!!
X
X	A new command, delete-window (^X-0 [zero]) allows you to
Xdelete just the current window from the screen, leaving all the
Xothers intact, (and one of them bigger). This is very convient
Xwhen you have a lot of windows on the screen.
X
X***	Execute Macro commands
X
X	Buffers holding commands can now be executed as a "macro". The
Xnames of these buffers is in the form "[Macro nn]" where nn is a number
Xfrom 1 to 20.  Each buffer has a corrosponding execute-macro-nn command,
Xthe first ten of which are bound to the shifted function keys on the IBM
Xversions.
X
X***	Macro loading
X
X	Macroes can be loaded from a command file (or startup file) with
Xthe use of the store-macro command. For example, to make macro 5 insert
Xa blank line at the begining of the current line, one would put the
Xfollowing in their startup file:
X
X;	Open up a line before the current line
X
X5 store-macro
X	begining-of-line
X	open-line
X[end]
X
X	more details on this can be found in the standard startup file
Xand the reference manual.
X
X***	Clear message line
X
X	Sometimes when executing macroes you want the last command not
Xto leave a message on the message line at the bottom of the screen. The
Xclear-message-line command does just that.
X
X***	Absolute window resizing
X
X	This new command, resize-window (^X-W) allows you to specify the
Xnumber of lines you wish to have in the current window. For example,
XM 12 ^X W forces the current window to a size of 12 lines if possible.
X
X***	Interactive macro arguments
X
X	When executing a command line, if any of the arguments begin
Xwith an at sign (@) MicroEMACS will prompt the user for that argument on
Xthe message line, using whatever text follows. A quick macro
Xdemonstating this can be:
X
X;	consult file
X2 store-macro
X	2 split-current-window
X	previous-window
X	view-file "@File to Consult: "
X	8 resize-window
X	add-mode "green"
X	add-mode "Black"
X	next-window
X[end]
X
X***	Buffer Macro arguments
X
X	When executing a command line, any arguments begining with a
Xpound sign (#) mean that the argument is to be fetched from the current
Xline of the named buffer. The point in that buffer is then advanced one
Xline if that buffer is not currently being displayed.
X
X***	Split window modified
X
X	The split window command normally leaves the cursor in the window
Xwhere the cursor was originaly. Now a numeric argument of one forces the
Xcursor into the upper window, and an argument of 2 forces the cursor
Xinto the lower window.
X
X***	MicroSoft C compiler support
X
X	The MicroSoft C compiler (version 3) now can be used
Xsuccessfully to compile MicroEMACS. Use the large data, small program
Xmodel for best results. Thanks to Oliver Sharp for the needed
Xmodifications.
X
X***	VMS terminal support upgraded
X
X	VMS now uses the newer terminal modes when executing MicroEMACS.
XAlso some bugs were fixed. Both of these are thanks to Guy Streeter.
X
X***	CMODE enhanced
X
X	Lines starting with # as the first non-blank character (ie
Xpre-processer directives) force the # into column one.  Also, if
Xmatching open parenthises and braces are being displayed when the
Xclosing one is typed, the cursor will breifly flash to the open and
Xback.
X
X***	Special character quoting
X
X	When typing in search/replace strings, ^Q quotes the following
Xcharacter, allowing keys like <ESC> to be searched for.
X
X***	Bindable prefix keys
X
X	The META and ^X prefixes may now be bound to other keys. Only
Xone key may be a prefix key at a time, when one of these is rebound, the
Xold key is automatically unbound.
X
X***	New command line options
X
X	@<file>		Specifies an alternative startup file(s) to
X			run instead of emacs.rc or .emacsrc
X
X	-g<n>		go to line <n> of the first file read in
X
X	-s<string>	search the first file for <string> and leave
X			the cursor there.
X
X***	Wang keyboard support
X
X	The Wang-PC keyboard and is function keys are now supported.
X(Define WANG in estruct.h as 1) Thanks to Sid Shapiro for this code.
X
X***	System V support
X
X	Unix system V should now compile and execute MicroEMACS
Xproperly. Code for this was submited by Linwood Varney.
X
X***	Unix definitions reorginized
X
X	Now only ONE of the unix symbols should be defined when
Xcompiling on unices.
X
X***	Incremental Search added
X
X	For those clamering for it.....Isearch commands. This code was
Xsubmited by D. R. Banks and seems to work well. (Later we will merge it
Xwith parts of the normal searching code to conserve space) This is
Xavailible conditionally depending on the ISRCH symbol in estruct.h
X
X***	Insert string command
X
X	The insert-string command (unbound) allows you to insert text
Xinto a line from a macro.  This can be used to build special help and
Xtext screens.
X
X***	Unmark buffer command
X
X	The unmark-command (unbound) allows you to unmark a buffer. 
XThis will keep the exit commands from complaining abount unchanged
Xbuffers.  This is most usefull when you have built up a text screen from
Xa macro and have no intention of saving it.
X
X***	Special characters
X
X	Inside of string argument in macroes, the following special
Xcharacters are active:
X
X	~n	newline
X	~t	tab
X	~b	backspace
X	~f	formfeed
X
X***	Fixed large file problems
X
X	Several problems caused by keeping character counts in integers
Xhave been fixed by making these counts be longs.  Also regions can now
Xbe larger than 65535 chars.
X
X***	Kill buffer re-coded
X
X	New kill buffer routines should (and do) work faster.  Also an
Xunlimited (except by RAM) amount of text can be killed safely.
X
X***	Word counting
X
X	The count-words (M-^C) command counts the number of words,
Xcharacters and lines in the current region.  It also gives an average
Xwords/character total. 
X
X***	Changed delete-word behavior
X
X	Delete-next-word no longer kills the newline as it deletes tha
Xlast word on the line.  It does however then delete the newline as it
Xdeletes the first word on the next line.
X
X***	Next/Previous buffer cammands augmented
X
X	Both now take a numeric argument to switch to the nth window
Xfrom the top/bottom.
X
X***	Data General Support
X
X	MicroEMACS now supprts the Data General System/10 computer under
XMSDOS.
X
X
FRIDAY_NIGHT
echo es.9 completed!
: That's all folks!