[mod.sources] MicroEmacs, Version 3.7

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

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

[  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.  Lawrence 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 - Makefile
sed 's/^X//' > Makefile << 'FRIDAY_NIGHT'
XCFLAGS=		-O -I/usr/tools/include/bland
X
XOFILES=		ansi.o basic.o bind.o buffer.o display.o file.o \
X		fileio.o hp150.o line.o lock.c main.o random.o region.o \
X		search.o spawn.o tcap.o termio.o vt52.o window.o word.o \
X		exec.o input.o isearch.o
X
XCFILES=		ansi.c basic.c bind.c buffer.c display.c  file.c \
X		fileio.c hp150.c line.c lock.c main.c random.c region.c \
X		search.c spawn.c tcap.c termio.c vt52.c window.c word.c \
X		exec.c input.c isearch.c
X
XHFILES=		estruct.h edef.h efunc.h epath.h
X
Xemacs:		$(OFILES)
X		$(CC) $(CFLAGS) $(OFILES) -ltermcap -lc -o emacs
X
X$(OFILES):	$(HFILES)
FRIDAY_NIGHT
echo extracting - ansi.c
sed 's/^X//' > ansi.c << 'FRIDAY_NIGHT'
X/*
X * The routines in this file provide support for ANSI style terminals
X * over a serial line. The serial I/O services are provided by routines in
X * "termio.c". It compiles into nothing if not an ANSI device.
X */
X
X#define	termdef	1			/* don't define "term" external */
X
X#include        <stdio.h>
X#include	"estruct.h"
X#include        "edef.h"
X
X#if     ANSI
X
X#if	AMIGA
X#define NROW    23                      /* Screen size.                 */
X#define NCOL    77                      /* Edit if you want to.         */
X#else
X#define NROW    25                      /* Screen size.                 */
X#define NCOL    80                      /* Edit if you want to.         */
X#endif
X#define	NPAUSE	100			/* # times thru update to pause */
X#define	MARGIN	8			/* size of minimim margin and	*/
X#define	SCRSIZ	64			/* scroll size for extended lines */
X#define BEL     0x07                    /* BEL character.               */
X#define ESC     0x1B                    /* ESC character.               */
X
Xextern  int     ttopen();               /* Forward references.          */
Xextern  int     ttgetc();
Xextern  int     ttputc();
Xextern  int     ttflush();
Xextern  int     ttclose();
Xextern  int     ansimove();
Xextern  int     ansieeol();
Xextern  int     ansieeop();
Xextern  int     ansibeep();
Xextern  int     ansiopen();
Xextern	int	ansirev();
Xextern	int	ansiclose();
X
X#if	COLOR
Xextern	int	ansifcol();
Xextern	int	ansibcol();
X
Xint	cfcolor = -1;		/* current forground color */
Xint	cbcolor = -1;		/* current background color */
X#endif
X
X/*
X * Standard terminal interface dispatch table. Most of the fields point into
X * "termio" code.
X */
XTERM    term    = {
X        NROW-1,
X        NCOL,
X	MARGIN,
X	SCRSIZ,
X	NPAUSE,
X        ansiopen,
X        ansiclose,
X        ttgetc,
X        ttputc,
X        ttflush,
X        ansimove,
X        ansieeol,
X        ansieeop,
X        ansibeep,
X	ansirev
X#if	COLOR
X	, ansifcol,
X	ansibcol
X#endif
X};
X
X#if	COLOR
Xansifcol(color)		/* set the current output color */
X
Xint color;	/* color to set */
X
X{
X	if (color == cfcolor)
X		return;
X	ttputc(ESC);
X	ttputc('[');
X	ansiparm(color+30);
X	ttputc('m');
X	cfcolor = color;
X}
X
Xansibcol(color)		/* set the current background color */
X
Xint color;	/* color to set */
X
X{
X	if (color == cbcolor)
X		return;
X	ttputc(ESC);
X	ttputc('[');
X	ansiparm(color+40);
X	ttputc('m');
X        cbcolor = color;
X}
X#endif
X
Xansimove(row, col)
X{
X        ttputc(ESC);
X        ttputc('[');
X        ansiparm(row+1);
X        ttputc(';');
X        ansiparm(col+1);
X        ttputc('H');
X}
X
Xansieeol()
X{
X        ttputc(ESC);
X        ttputc('[');
X        ttputc('K');
X}
X
Xansieeop()
X{
X#if	COLOR
X	ansifcol(gfcolor);
X	ansibcol(gbcolor);
X#endif
X        ttputc(ESC);
X        ttputc('[');
X        ttputc('J');
X}
X
Xansirev(state)		/* change reverse video state */
X
Xint state;	/* TRUE = reverse, FALSE = normal */
X
X{
X#if	COLOR
X	int ftmp, btmp;		/* temporaries for colors */
X#endif
X
X	ttputc(ESC);
X	ttputc('[');
X	ttputc(state ? '7': '0');
X	ttputc('m');
X#if	COLOR
X	if (state == FALSE) {
X		ftmp = cfcolor;
X		btmp = cbcolor;
X		cfcolor = -1;
X		cbcolor = -1;
X		ansifcol(ftmp);
X		ansibcol(btmp);
X	}
X#endif
X}
X
Xansibeep()
X{
X        ttputc(BEL);
X        ttflush();
X}
X
Xansiparm(n)
Xregister int    n;
X{
X        register int q,r;
X
X        q = n/10;
X        if (q != 0) {
X		r = q/10;
X		if (r != 0) {
X			ttputc((r%10)+'0');
X		}
X		ttputc((q%10) + '0');
X        }
X        ttputc((n%10) + '0');
X}
X
Xansiopen()
X{
X#if     V7 | USG | BSD
X        register char *cp;
X        char *getenv();
X
X        if ((cp = getenv("TERM")) == NULL) {
X                puts("Shell variable TERM not defined!");
X                exit(1);
X        }
X        if (strcmp(cp, "vt100") != 0) {
X                puts("Terminal type not 'vt100'!");
X                exit(1);
X        }
X#endif
X	revexist = TRUE;
X        ttopen();
X}
X
Xansiclose()
X
X{
X#if	COLOR
X	ansifcol(7);
X	ansibcol(0);
X#endif
X	ttclose();
X}
X#else
Xansihello()
X{
X}
X#endif
FRIDAY_NIGHT
echo extracting - azmap.cmd
sed 's/^X//' > azmap.cmd << 'FRIDAY_NIGHT'
X;	AZMAP.CMD:	MicroEMACS Macro file
X;			to translate an AZTEC C .SYM map file into
X;			the form needed to read it into ADDSYMS
X;			to be used with Pheonix's PFIX plus (C) debugger
X;
X;			written 6/5/86 by Daniel Lawrence
X
Xbegining-of-file
Xnewline
Xprevious-line
Xreplace-string ~n "~n 0000:"
Xbegining-of-line
Xkill-to-end-of-line
Xnewline
Xnewline
Xnewline
Xbegining-of-file
Xnewline
Xinsert-string "  Address         Publics by Name"
Xnewline
Xset-mark
Xend-of-file
Xcase-region-upper
Xbegining-of-file
Xreplace-string _~n ~n
X
FRIDAY_NIGHT
echo extracting - basic.c
sed 's/^X//' > basic.c << 'FRIDAY_NIGHT'
X/*
X * The routines in this file move the cursor around on the screen. They
X * compute a new value for the cursor, then adjust ".". The display code
X * always updates the cursor location, so only moves between lines, or
X * functions that adjust the top line in the window and invalidate the
X * framing, are hard.
X */
X#include        <stdio.h>
X#include	"estruct.h"
X#include        "edef.h"
X
X/*
X * Move the cursor to the
X * beginning of the current line.
X * Trivial.
X */
Xgotobol(f, n)
X{
X        curwp->w_doto  = 0;
X        return (TRUE);
X}
X
X/*
X * Move the cursor backwards by "n" characters. If "n" is less than zero call
X * "forwchar" to actually do the move. Otherwise compute the new cursor
X * location. Error if you try and move out of the buffer. Set the flag if the
X * line pointer for dot changes.
X */
Xbackchar(f, n)
Xregister int    n;
X{
X        register LINE   *lp;
X
X        if (n < 0)
X                return (forwchar(f, -n));
X        while (n--) {
X                if (curwp->w_doto == 0) {
X                        if ((lp=lback(curwp->w_dotp)) == curbp->b_linep)
X                                return (FALSE);
X                        curwp->w_dotp  = lp;
X                        curwp->w_doto  = llength(lp);
X                        curwp->w_flag |= WFMOVE;
X                } else
X                        curwp->w_doto--;
X        }
X        return (TRUE);
X}
X
X/*
X * Move the cursor to the end of the current line. Trivial. No errors.
X */
Xgotoeol(f, n)
X{
X        curwp->w_doto  = llength(curwp->w_dotp);
X        return (TRUE);
X}
X
X/*
X * Move the cursor forwwards by "n" characters. If "n" is less than zero call
X * "backchar" to actually do the move. Otherwise compute the new cursor
X * location, and move ".". Error if you try and move off the end of the
X * buffer. Set the flag if the line pointer for dot changes.
X */
Xforwchar(f, n)
Xregister int    n;
X{
X        if (n < 0)
X                return (backchar(f, -n));
X        while (n--) {
X                if (curwp->w_doto == llength(curwp->w_dotp)) {
X                        if (curwp->w_dotp == curbp->b_linep)
X                                return (FALSE);
X                        curwp->w_dotp  = lforw(curwp->w_dotp);
X                        curwp->w_doto  = 0;
X                        curwp->w_flag |= WFMOVE;
X                } else
X                        curwp->w_doto++;
X        }
X        return (TRUE);
X}
X
Xgotoline(f, n)		/* move to a particular line.
X			   argument (n) must be a positive integer for
X			   this to actually do anything		*/
X
X{
X	if (n < 1)		/* if a bogus argument...then leave */
X		return(FALSE);
X
X	/* first, we go to the start of the buffer */
X        curwp->w_dotp  = lforw(curbp->b_linep);
X        curwp->w_doto  = 0;
X	return(forwline(f, n-1));
X}
X
X/*
X * Goto the beginning of the buffer. Massive adjustment of dot. This is
X * considered to be hard motion; it really isn't if the original value of dot
X * is the same as the new value of dot. Normally bound to "M-<".
X */
Xgotobob(f, n)
X{
X        curwp->w_dotp  = lforw(curbp->b_linep);
X        curwp->w_doto  = 0;
X        curwp->w_flag |= WFHARD;
X        return (TRUE);
X}
X
X/*
X * Move to the end of the buffer. Dot is always put at the end of the file
X * (ZJ). The standard screen code does most of the hard parts of update.
X * Bound to "M->".
X */
Xgotoeob(f, n)
X{
X        curwp->w_dotp  = curbp->b_linep;
X        curwp->w_doto  = 0;
X        curwp->w_flag |= WFHARD;
X        return (TRUE);
X}
X
X/*
X * Move forward by full lines. If the number of lines to move is less than
X * zero, call the backward line function to actually do it. The last command
X * controls how the goal column is set. Bound to "C-N". No errors are
X * possible.
X */
Xforwline(f, n)
X{
X        register LINE   *dlp;
X
X        if (n < 0)
X                return (backline(f, -n));
X        if ((lastflag&CFCPCN) == 0)             /* Reset goal if last   */
X                curgoal = getccol(FALSE);       /* not C-P or C-N       */
X        thisflag |= CFCPCN;
X        dlp = curwp->w_dotp;
X        while (n-- && dlp!=curbp->b_linep)
X                dlp = lforw(dlp);
X        curwp->w_dotp  = dlp;
X        curwp->w_doto  = getgoal(dlp);
X        curwp->w_flag |= WFMOVE;
X        return (TRUE);
X}
X
X/*
X * This function is like "forwline", but goes backwards. The scheme is exactly
X * the same. Check for arguments that are less than zero and call your
X * alternate. Figure out the new line and call "movedot" to perform the
X * motion. No errors are possible. Bound to "C-P".
X */
Xbackline(f, n)
X{
X        register LINE   *dlp;
X
X        if (n < 0)
X                return (forwline(f, -n));
X        if ((lastflag&CFCPCN) == 0)             /* Reset goal if the    */
X                curgoal = getccol(FALSE);       /* last isn't C-P, C-N  */
X        thisflag |= CFCPCN;
X        dlp = curwp->w_dotp;
X        while (n-- && lback(dlp)!=curbp->b_linep)
X                dlp = lback(dlp);
X        curwp->w_dotp  = dlp;
X        curwp->w_doto  = getgoal(dlp);
X        curwp->w_flag |= WFMOVE;
X        return (TRUE);
X}
X
X#if	WORDPRO
Xgotobop(f, n)	/* go back to the begining of the current paragraph
X		   here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
X		   combination to delimit the begining of a paragraph	*/
X
Xint f, n;	/* default Flag & Numeric argument */
X
X{
X	register int suc;	/* success of last backchar */
X
X	if (n < 0)	/* the other way...*/
X		return(gotoeop(f, -n));
X
X	while (n-- > 0) {	/* for each one asked for */
X
X		/* first scan back until we are in a word */
X		suc = backchar(FALSE, 1);
X		while (!inword() && suc)
X			suc = backchar(FALSE, 1);
X		curwp->w_doto = 0;	/* and go to the B-O-Line */
X
X		/* and scan back until we hit a <NL><NL> or <NL><TAB>
X		   or a <NL><SPACE>					*/
X		while (lback(curwp->w_dotp) != curbp->b_linep)
X			if (llength(curwp->w_dotp) != 0 &&
X			    lgetc(curwp->w_dotp, curwp->w_doto) != TAB &&
X			    lgetc(curwp->w_dotp, curwp->w_doto) != ' ')
X				curwp->w_dotp = lback(curwp->w_dotp);
X			else
X				break;
X
X		/* and then forward until we are in a word */
X		suc = forwchar(FALSE, 1);
X		while (suc && !inword())
X			suc = forwchar(FALSE, 1);
X	}
X	curwp->w_flag |= WFMOVE;	/* force screen update */
X	return(TRUE);
X}
X
Xgotoeop(f, n)	/* go forword to the end of the current paragraph
X		   here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
X		   combination to delimit the begining of a paragraph	*/
X
Xint f, n;	/* default Flag & Numeric argument */
X
X{
X	register int suc;	/* success of last backchar */
X
X	if (n < 0)	/* the other way...*/
X		return(gotobop(f, -n));
X
X	while (n-- > 0) {	/* for each one asked for */
X
X		/* first scan forward until we are in a word */
X		suc = forwchar(FALSE, 1);
X		while (!inword() && suc)
X			suc = forwchar(FALSE, 1);
X		curwp->w_doto = 0;	/* and go to the B-O-Line */
X		if (suc)	/* of next line if not at EOF */
X			curwp->w_dotp = lforw(curwp->w_dotp);
X
X		/* and scan forword until we hit a <NL><NL> or <NL><TAB>
X		   or a <NL><SPACE>					*/
X		while (curwp->w_dotp != curbp->b_linep) {
X			if (llength(curwp->w_dotp) != 0 &&
X			    lgetc(curwp->w_dotp, curwp->w_doto) != TAB &&
X			    lgetc(curwp->w_dotp, curwp->w_doto) != ' ')
X				curwp->w_dotp = lforw(curwp->w_dotp);
X			else
X				break;
X		}
X
X		/* and then backward until we are in a word */
X		suc = backchar(FALSE, 1);
X		while (suc && !inword()) {
X			suc = backchar(FALSE, 1);
X		}
X		curwp->w_doto = llength(curwp->w_dotp);	/* and to the EOL */
X	}
X	curwp->w_flag |= WFMOVE;	/* force screen update */
X	return(TRUE);
X}
X#endif
X
X/*
X * This routine, given a pointer to a LINE, and the current cursor goal
X * column, return the best choice for the offset. The offset is returned.
X * Used by "C-N" and "C-P".
X */
Xgetgoal(dlp)
Xregister LINE   *dlp;
X{
X        register int    c;
X        register int    col;
X        register int    newcol;
X        register int    dbo;
X
X        col = 0;
X        dbo = 0;
X        while (dbo != llength(dlp)) {
X                c = lgetc(dlp, dbo);
X                newcol = col;
X                if (c == '\t')
X                        newcol |= 0x07;
X                else if (c<0x20 || c==0x7F)
X                        ++newcol;
X                ++newcol;
X                if (newcol > curgoal)
X                        break;
X                col = newcol;
X                ++dbo;
X        }
X        return (dbo);
X}
X
X/*
X * Scroll forward by a specified number of lines, or by a full page if no
X * argument. Bound to "C-V". The "2" in the arithmetic on the window size is
X * the overlap; this value is the default overlap value in ITS EMACS. Because
X * this zaps the top line in the display window, we have to do a hard update.
X */
Xforwpage(f, n)
Xregister int    n;
X{
X        register LINE   *lp;
X
X        if (f == FALSE) {
X                n = curwp->w_ntrows - 2;        /* Default scroll.      */
X                if (n <= 0)                     /* Forget the overlap   */
X                        n = 1;                  /* if tiny window.      */
X        } else if (n < 0)
X                return (backpage(f, -n));
X#if     CVMVAS
X        else                                    /* Convert from pages   */
X                n *= curwp->w_ntrows;           /* to lines.            */
X#endif
X        lp = curwp->w_linep;
X        while (n-- && lp!=curbp->b_linep)
X                lp = lforw(lp);
X        curwp->w_linep = lp;
X        curwp->w_dotp  = lp;
X        curwp->w_doto  = 0;
X        curwp->w_flag |= WFHARD;
X        return (TRUE);
X}
X
X/*
X * This command is like "forwpage", but it goes backwards. The "2", like
X * above, is the overlap between the two windows. The value is from the ITS
X * EMACS manual. Bound to "M-V". We do a hard update for exactly the same
X * reason.
X */
Xbackpage(f, n)
Xregister int    n;
X{
X        register LINE   *lp;
X
X        if (f == FALSE) {
X                n = curwp->w_ntrows - 2;        /* Default scroll.      */
X                if (n <= 0)                     /* Don't blow up if the */
X                        n = 1;                  /* window is tiny.      */
X        } else if (n < 0)
X                return (forwpage(f, -n));
X#if     CVMVAS
X        else                                    /* Convert from pages   */
X                n *= curwp->w_ntrows;           /* to lines.            */
X#endif
X        lp = curwp->w_linep;
X        while (n-- && lback(lp)!=curbp->b_linep)
X                lp = lback(lp);
X        curwp->w_linep = lp;
X        curwp->w_dotp  = lp;
X        curwp->w_doto  = 0;
X        curwp->w_flag |= WFHARD;
X        return (TRUE);
X}
X
X/*
X * Set the mark in the current window to the value of "." in the window. No
X * errors are possible. Bound to "M-.".
X */
Xsetmark(f, n)
X{
X        curwp->w_markp = curwp->w_dotp;
X        curwp->w_marko = curwp->w_doto;
X        mlwrite("[Mark set]");
X        return (TRUE);
X}
X
X/*
X * Swap the values of "." and "mark" in the current window. This is pretty
X * easy, bacause all of the hard work gets done by the standard routine
X * that moves the mark about. The only possible error is "no mark". Bound to
X * "C-X C-X".
X */
Xswapmark(f, n)
X{
X        register LINE   *odotp;
X        register int    odoto;
X
X        if (curwp->w_markp == NULL) {
X                mlwrite("No mark in this window");
X                return (FALSE);
X        }
X        odotp = curwp->w_dotp;
X        odoto = curwp->w_doto;
X        curwp->w_dotp  = curwp->w_markp;
X        curwp->w_doto  = curwp->w_marko;
X        curwp->w_markp = odotp;
X        curwp->w_marko = odoto;
X        curwp->w_flag |= WFMOVE;
X        return (TRUE);
X}
FRIDAY_NIGHT
echo extracting - bind.c
sed 's/^X//' > bind.c << 'FRIDAY_NIGHT'
X/*	This file is for functions having to do with key bindings,
X	descriptions, help commands and startup file.
X
X	written 11-feb-86 by Daniel Lawrence
X								*/
X
X#include	<stdio.h>
X#include	"estruct.h"
X#include	"edef.h"
X#include	"epath.h"
X
Xextern int meta(), cex();	/* dummy prefix binding functions */
X
Xdeskey(f, n)	/* describe the command for a certain key */
X
X{
X	register int c;		/* command character to describe */
X	register char *ptr;	/* string pointer to scan output strings */
X	register KEYTAB *ktp;	/* pointer into the command table */
X	register int found;	/* matched command flag */
X	register NBIND *nptr;	/* pointer into the name binding table */
X	char outseq[80];	/* output buffer for command sequence */
X
X	/* prompt the user to type us a key to describe */
X	mlwrite(": describe-key ");
X
X	/* get the command sequence to describe */
X	c = getckey(FALSE);			/* get a command sequence */
X
X	/* change it to something we can print as well */
X	cmdstr(c, &outseq[0]);
X
X	/* and dump it out */
X	ptr = &outseq[0];
X	while (*ptr)
X		(*term.t_putchar)(*ptr++);
X	(*term.t_putchar)(' ');		/* space it out */
X
X	/* find the right ->function */
X	ktp = &keytab[0];
X	found = FALSE;
X	while (ktp->k_fp != NULL) {
X		if (ktp->k_code == c) {
X			found = TRUE;
X			break;
X		}
X		++ktp;
X	}
X
X	if (!found)
X		strcpy(outseq,"Not Bound");
X	else {
X		/* match it against the name binding table */
X		nptr = &names[0];
X		strcpy(outseq,"[Bad binding]");
X		while (nptr->n_func != NULL) {
X			if (nptr->n_func == ktp->k_fp) {
X				strcpy(outseq, nptr->n_name);
X				break;
X			}
X			++nptr;
X		}
X	}
X
X	/* output the command sequence */
X	ptr = &outseq[0];
X	while (*ptr)
X		(*term.t_putchar)(*ptr++);
X}
X
Xcmdstr(c, seq)	/* change a key command to a string we can print out */
X
Xint c;		/* sequence to translate */
Xchar *seq;	/* destination string for sequence */
X
X{
X	char *ptr;	/* pointer into current position in sequence */
X
X	ptr = seq;
X
X	/* apply meta sequence if needed */
X	if (c & META) {
X		*ptr++ = 'M';
X		*ptr++ = '-';
X	}
X
X	/* apply ^X sequence if needed */
X	if (c & CTLX) {
X		*ptr++ = '^';
X		*ptr++ = 'X';
X	}
X
X	/* apply SPEC sequence if needed */
X	if (c & SPEC) {
X		*ptr++ = 'F';
X		*ptr++ = 'N';
X	}
X
X	/* apply control sequence if needed */
X	if (c & CTRL) {
X		*ptr++ = '^';
X	}
X
X	c = c & 255;	/* strip the prefixes */
X
X	/* and output the final sequence */
X
X	*ptr++ = c;
X	*ptr = 0;	/* terminate the string */
X}
X
Xhelp(f, n)	/* give me some help!!!!
X		   bring up a fake buffer and read the help file
X		   into it with view mode			*/
X{
X	register int status;	/* status of I/O operations */
X	register WINDOW *wp;	/* scaning pointer to windows */
X	register BUFFER *bp;	/* buffer pointer to help */
X	register int i;		/* index into help file names */
X	char fname[NSTRING];	/* buffer to construct file name in */
X
X	/* first check if we are already here */
X	bp = bfind("emacs.hlp", FALSE, BFINVS);
X
X	if (bp == NULL) {
X		/* search through the list of help files */
X		for (i=2; i < NPNAMES; i++) {
X			strcpy(fname, pathname[i]);
X			strcat(fname, pathname[1]);
X			status = ffropen(fname);
X			if (status == FIOSUC)
X				break;
X		}
X
X		if (status == FIOFNF) {
X			mlwrite("[Help file is not online]");
X			return(FALSE);
X		}
X
X		/* close the file to prepare for to read it in */
X		ffclose();
X	}
X
X	/* split the current window to make room for the help stuff */
X	if (splitwind(FALSE, 1) == FALSE)
X			return(FALSE);
X
X	if (bp == NULL) {
X		/* and read the stuff in */
X		if (getfile(fname, FALSE) == FALSE)
X			return(FALSE);
X	} else
X		swbuffer(bp);
X
X	/* make this window in VIEW mode, update all mode lines */
X	curwp->w_bufp->b_mode |= MDVIEW;
X	curwp->w_bufp->b_flag |= BFINVS;
X	wp = wheadp;
X	while (wp != NULL) {
X		wp->w_flag |= WFMODE;
X		wp = wp->w_wndp;
X	}
X	return(TRUE);
X}
X
Xint (*fncmatch(fname))() /* match fname to a function in the names table
X			    and return any match or NULL if none		*/
X
Xchar *fname;	/* name to attempt to match */
X
X{
X	register NBIND *ffp;	/* pointer to entry in name binding table */
X
X	/* scan through the table, returning any match */
X	ffp = &names[0];
X	while (ffp->n_func != NULL) {
X		if (strcmp(fname, ffp->n_name) == 0)
X			return(ffp->n_func);
X		++ffp;
X	}
X	return(NULL);
X}
X
X/* bindtokey:	add a new key to the key binding table
X*/
X
Xbindtokey(f, n)
X
Xint f, n;	/* command arguments [IGNORED] */
X
X{
X	register int c;		/* command key to bind */
X	register (*kfunc)();	/* ptr to the requexted function to bind to */
X	register char *ptr;	/* ptr to dump out input key string */
X	register KEYTAB *ktp;	/* pointer into the command table */
X	register int found;	/* matched command flag */
X	char outseq[80];	/* output buffer for keystroke sequence */
X	int (*getname())();
X
X	/* prompt the user to type in a key to bind */
X	mlwrite(": bind-to-key ");
X
X	/* get the function name to bind it to */
X	kfunc = getname();
X	if (kfunc == NULL) {
X		mlwrite("[No such function]");
X		return(FALSE);
X	}
X	(*term.t_putchar)(' ');		/* space it out */
X	(*term.t_flush)();
X
X	/* get the command sequence to bind */
X	c = getckey((kfunc == meta) || (kfunc == cex));
X
X	/* change it to something we can print as well */
X	cmdstr(c, &outseq[0]);
X
X	/* and dump it out */
X	ptr = &outseq[0];
X	while (*ptr)
X		(*term.t_putchar)(*ptr++);
X
X	/* if the function is a prefix key */
X	if (kfunc == meta || kfunc == cex) {
X
X		/* search for an existing binding for the prefix key */
X		ktp = &keytab[0];
X		found = FALSE;
X		while (ktp->k_fp != NULL) {
X			if (ktp->k_fp == kfunc) {
X				found = TRUE;
X				break;
X			}
X			++ktp;
X		}
X
X		/* reset the appropriate global prefix variable */
X		if (kfunc == meta)
X			metac = c;
X		if (kfunc == cex)
X			ctlxc = c;
X
X		/* if we found it, just reset it
X		   otherwise, let it fall through and be added to the end */
X		if (found) {
X			ktp->k_code = c;
X			return(TRUE);
X		}
X	} else {
X
X		/* search the table to see if it exists */
X		ktp = &keytab[0];
X		found = FALSE;
X		while (ktp->k_fp != NULL) {
X			if (ktp->k_code == c) {
X				found = TRUE;
X				break;
X			}
X			++ktp;
X		}
X	}
X
X	if (found) {	/* it exists, just change it then */
X		ktp->k_fp = kfunc;
X	} else {	/* otherwise we need to add it to the end */
X		/* if we run out of binding room, bitch */
X		if (ktp >= &keytab[NBINDS]) {
X			mlwrite("Binding table FULL!");
X			return(FALSE);
X		}
X
X		ktp->k_code = c;	/* add keycode */
X		ktp->k_fp = kfunc;	/* and the function pointer */
X		++ktp;			/* and make sure the next is null */
X		ktp->k_code = 0;
X		ktp->k_fp = NULL;
X	}
X	return(TRUE);
X}
X
X/* unbindkey:	delete a key from the key binding table
X*/
X
Xunbindkey(f, n)
X
Xint f, n;	/* command arguments [IGNORED] */
X
X{
X	register int c;		/* command key to unbind */
X	register char *ptr;	/* ptr to dump out input key string */
X	register KEYTAB *ktp;	/* pointer into the command table */
X	register KEYTAB *sktp;	/* saved pointer into the command table */
X	register int found;	/* matched command flag */
X	char outseq[80];	/* output buffer for keystroke sequence */
X
X	/* prompt the user to type in a key to unbind */
X	mlwrite(": unbind-key ");
X
X	/* get the command sequence to unbind */
X	c = getckey(FALSE);		/* get a command sequence */
X
X	/* change it to something we can print as well */
X	cmdstr(c, &outseq[0]);
X
X	/* and dump it out */
X	ptr = &outseq[0];
X	while (*ptr)
X		(*term.t_putchar)(*ptr++);
X
X	/* search the table to see if the key exists */
X	ktp = &keytab[0];
X	found = FALSE;
X	while (ktp->k_fp != NULL) {
X		if (ktp->k_code == c) {
X			found = TRUE;
X			break;
X		}
X		++ktp;
X	}
X
X	/* if it isn't bound, bitch */
X	if (!found) {
X		mlwrite("[Key not bound]");
X		return(FALSE);
X	}
X
X	/* save the pointer and scan to the end of the table */
X	sktp = ktp;
X	while (ktp->k_fp != NULL)
X		++ktp;
X	--ktp;		/* backup to the last legit entry */
X
X	/* copy the last entry to the current one */
X	sktp->k_code = ktp->k_code;
X	sktp->k_fp   = ktp->k_fp;
X
X	/* null out the last one */
X	ktp->k_code = 0;
X	ktp->k_fp = NULL;
X	return(TRUE);
X}
X
Xdesbind(f, n)	/* describe bindings
X		   bring up a fake buffer and list the key bindings
X		   into it with view mode			*/
X{
X	register WINDOW *wp;	/* scnaning pointer to windows */
X	register KEYTAB *ktp;	/* pointer into the command table */
X	register NBIND *nptr;	/* pointer into the name binding table */
X	register BUFFER *bp;	/* buffer to put binding list into */
X	char *strp;		/* pointer int string to send */
X	int cpos;		/* current position to use in outseq */
X	char outseq[80];	/* output buffer for keystroke sequence */
X
X	/* split the current window to make room for the binding list */
X	if (splitwind(FALSE, 1) == FALSE)
X			return(FALSE);
X
X	/* and get a buffer for it */
X	bp = bfind("Binding list", TRUE, 0);
X	if (bp == NULL || bclear(bp) == FALSE) {
X		mlwrite("Can not display binding list");
X		return(FALSE);
X	}
X
X	/* let us know this is in progress */
X	mlwrite("[Building buffer list]");
X
X	/* disconect the current buffer */
X        if (--curbp->b_nwnd == 0) {             /* Last use.            */
X                curbp->b_dotp  = curwp->w_dotp;
X                curbp->b_doto  = curwp->w_doto;
X                curbp->b_markp = curwp->w_markp;
X                curbp->b_marko = curwp->w_marko;
X        }
X
X	/* connect the current window to this buffer */
X	curbp = bp;	/* make this buffer current in current window */
X	bp->b_mode = 0;		/* no modes active in binding list */
X	bp->b_nwnd++;		/* mark us as more in use */
X	wp = curwp;
X	wp->w_bufp = bp;
X	wp->w_linep = bp->b_linep;
X	wp->w_flag = WFHARD|WFFORCE;
X	wp->w_dotp = bp->b_dotp;
X	wp->w_doto = bp->b_doto;
X	wp->w_markp = NULL;
X	wp->w_marko = 0;
X
X	/* build the contents of this window, inserting it line by line */
X	nptr = &names[0];
X	while (nptr->n_func != NULL) {
X
X		/* add in the command name */
X		strcpy(outseq, nptr->n_name);
X		cpos = strlen(outseq);
X		
X		/* search down any keys bound to this */
X		ktp = &keytab[0];
X		while (ktp->k_fp != NULL) {
X			if (ktp->k_fp == nptr->n_func) {
X				/* padd out some spaces */
X				while (cpos < 25)
X					outseq[cpos++] = ' ';
X
X				/* add in the command sequence */
X				cmdstr(ktp->k_code, &outseq[cpos]);
X				while (outseq[cpos] != 0)
X					++cpos;
X
X				/* and add it as a line into the buffer */
X				strp = &outseq[0];
X				while (*strp != 0)
X					linsert(1, *strp++);
X				lnewline();
X
X				cpos = 0;	/* and clear the line */
X			}
X			++ktp;
X		}
X
X		/* if no key was bound, we need to dump it anyway */
X		if (cpos > 0) {
X			outseq[cpos] = 0;
X			strp = &outseq[0];
X			while (*strp != 0)
X				linsert(1, *strp++);
X			lnewline();
X		}
X
X		/* and on to the next name */
X		++nptr;
X	}
X
X	curwp->w_bufp->b_mode |= MDVIEW;/* put this buffer view mode */
X	curbp->b_flag &= ~BFCHG;	/* don't flag this as a change */
X	wp->w_dotp = lforw(bp->b_linep);/* back to the begining */
X	wp->w_doto = 0;
X	wp = wheadp;			/* and update ALL mode lines */
X	while (wp != NULL) {
X		wp->w_flag |= WFMODE;
X		wp = wp->w_wndp;
X	}
X	mlwrite("");	/* clear the mode line */
X	return(TRUE);
X}
X
Xgetckey(mflag)	/* get a command key sequence from the keyboard	*/
X
Xint mflag;	/* going for a meta sequence? */
X
X{
X	register int c;		/* character fetched */
X	register char *tp;	/* pointer into the token */
X	char tok[NSTRING];	/* command incoming */
X
X	/* check to see if we are executing a command line */
X	if (clexec) {
X		nxtarg(tok);	/* get the next token */
X
X		/* parse it up */
X		tp = &tok[0];
X		c = 0;
X
X		/* first, the META prefix */
X		if (*tp == 'M' && *(tp+1) == '-') {
X			c = META;
X			tp += 2;
X		} else
X
X			/* next the function prefix */
X			if (*tp == 'F' && *(tp+1) == 'N') {
X				c |= SPEC;
X				tp += 2;
X			} else
X
X				/* control-x as well... */
X				if (*tp == '^' && *(tp+1) == 'X') {
X					c |= CTLX;
X					tp += 2;
X				}
X
X		/* a control char? */
X		if (*tp == '^' & *(tp+1) != 0) {
X			c |= CTRL;
X			++tp;
X		}
X
X		/* make sure we are not lower case */
X		if (c >= 'a' && c <= 'z')
X			c -= 32;
X
X		/* the final sequence... */
X		c |= *tp;
X
X		return(c);
X	}
X
X	/* or the normal way */
X	if (mflag)
X		c = get1key();
X	else
X		c = getcmd();
X	return(c);
X}
X
X/* execute the startup file */
X
Xstartup(sfname)
X
Xchar *sfname;	/* name of startup file (null if default) */
X
X{
X	register int status;	/* status of I/O operations */
X	register int i;		/* index into help file names */
X	char fname[NSTRING];	/* buffer to construct file name in */
X	char *sfroot;		/* root of startup file name */
X
X#if	(MSDOS & (LATTICE | AZTEC | MSC)) | V7 | USG | BSD
X	char *homedir;		/* pointer to your home directory */
X	char *getenv();
X#endif
X
X	if (sfname[0] == 0)
X		sfroot = pathname[0];
X	else
X		sfroot = sfname;
X
X#if	(MSDOS & (LATTICE | AZTEC | MSC)) | V7 | USG | BSD
X	/* get the HOME from the environment */
X	if ((homedir = getenv("HOME")) != NULL) {
X		/* build the file name */
X		strcpy(fname, homedir);
X		strcat(fname, "/");
X		strcat(fname, sfroot);
X
X		/* and test it */
X		status = ffropen(fname);
X		if (status == FIOSUC) {
X			ffclose();
X			return(dofile(fname));
X		}
X	}
X#endif
X
X	/* search through the list of startup files */
X	for (i=2; i < NPNAMES; i++) {
X		strcpy(fname, pathname[i]);
X		strcat(fname, sfroot);
X		status = ffropen(fname);
X		if (status == FIOSUC)
X			break;
X	}
X
X	/* if it isn't around, don't sweat it */
X	if (status == FIOFNF)
X		return(TRUE);
X
X	ffclose();	/* close the file to prepare for to read it in */
X
X	return(dofile(fname));
X}
X
FRIDAY_NIGHT
echo extracting - buffer.c
sed 's/^X//' > buffer.c << 'FRIDAY_NIGHT'
X/*
X * Buffer management.
X * Some of the functions are internal,
X * and some are actually attached to user
X * keys. Like everyone else, they set hints
X * for the display system.
X */
X#include        <stdio.h>
X#include	"estruct.h"
X#include        "edef.h"
X
X/*
X * Attach a buffer to a window. The
X * values of dot and mark come from the buffer
X * if the use count is 0. Otherwise, they come
X * from some other window.
X */
Xusebuffer(f, n)
X{
X        register BUFFER *bp;
X        register int    s;
X        char            bufn[NBUFN];
X
X        if ((s=mlreply("Use buffer: ", bufn, NBUFN)) != TRUE)
X                return (s);
X        if ((bp=bfind(bufn, TRUE, 0)) == NULL)
X                return (FALSE);
X	return(swbuffer(bp));
X}
X
Xnextbuffer(f, n)	/* switch to the next buffer in the buffer list */
X
X{
X        register BUFFER *bp;
X
X	bp = curbp->b_bufp;
X	/* cycle through the buffers to find an eligable one */
X	while (bp == NULL || bp->b_flag & BFINVS) {
X		if (bp == NULL)
X			bp = bheadp;
X		else
X			bp = bp->b_bufp;
X	}
X	return(swbuffer(bp));
X}
X
Xswbuffer(bp)	/* make buffer BP current */
X
XBUFFER *bp;
X
X{
X        register WINDOW *wp;
X
X        if (--curbp->b_nwnd == 0) {             /* Last use.            */
X                curbp->b_dotp  = curwp->w_dotp;
X                curbp->b_doto  = curwp->w_doto;
X                curbp->b_markp = curwp->w_markp;
X                curbp->b_marko = curwp->w_marko;
X        }
X        curbp = bp;                             /* Switch.              */
X	if (curbp->b_active != TRUE) {		/* buffer not active yet*/
X		/* read it in and activate it */
X		readin(curbp->b_fname, TRUE);
X		curbp->b_dotp = lforw(curbp->b_linep);
X		curbp->b_doto = 0;
X		curbp->b_active = TRUE;
X	}
X        curwp->w_bufp  = bp;
X        curwp->w_linep = bp->b_linep;           /* For macros, ignored. */
X        curwp->w_flag |= WFMODE|WFFORCE|WFHARD; /* Quite nasty.         */
X        if (bp->b_nwnd++ == 0) {                /* First use.           */
X                curwp->w_dotp  = bp->b_dotp;
X                curwp->w_doto  = bp->b_doto;
X                curwp->w_markp = bp->b_markp;
X                curwp->w_marko = bp->b_marko;
X                return (TRUE);
X        }
X        wp = wheadp;                            /* Look for old.        */
X        while (wp != NULL) {
X                if (wp!=curwp && wp->w_bufp==bp) {
X                        curwp->w_dotp  = wp->w_dotp;
X                        curwp->w_doto  = wp->w_doto;
X                        curwp->w_markp = wp->w_markp;
X                        curwp->w_marko = wp->w_marko;
X                        break;
X                }
X                wp = wp->w_wndp;
X        }
X        return (TRUE);
X}
X
X/*
X * Dispose of a buffer, by name.
X * Ask for the name. Look it up (don't get too
X * upset if it isn't there at all!). Get quite upset
X * if the buffer is being displayed. Clear the buffer (ask
X * if the buffer has been changed). Then free the header
X * line and the buffer header. Bound to "C-X K".
X */
Xkillbuffer(f, n)
X
X{
X	register BUFFER *bp;
X        register int    s;
X        char bufn[NBUFN];
X
X        if ((s=mlreply("Kill buffer: ", bufn, NBUFN)) != TRUE)
X                return(s);
X        if ((bp=bfind(bufn, FALSE, 0)) == NULL) /* Easy if unknown.     */
X                return (TRUE);
X	return(zotbuf(bp));
X}
X
Xzotbuf(bp)	/* kill the buffer pointed to by bp */
X
Xregister BUFFER *bp;
X
X{
X        register BUFFER *bp1;
X        register BUFFER *bp2;
X        register int    s;
X
X        if (bp->b_nwnd != 0) {                  /* Error if on screen.  */
X                mlwrite("Buffer is being displayed");
X                return (FALSE);
X        }
X        if ((s=bclear(bp)) != TRUE)             /* Blow text away.      */
X                return (s);
X        free((char *) bp->b_linep);             /* Release header line. */
X        bp1 = NULL;                             /* Find the header.     */
X        bp2 = bheadp;
X        while (bp2 != bp) {
X                bp1 = bp2;
X                bp2 = bp2->b_bufp;
X        }
X        bp2 = bp2->b_bufp;                      /* Next one in chain.   */
X        if (bp1 == NULL)                        /* Unlink it.           */
X                bheadp = bp2;
X        else
X                bp1->b_bufp = bp2;
X        free((char *) bp);                      /* Release buffer block */
X        return (TRUE);
X}
X
Xnamebuffer(f,n)		/*	Rename the current buffer	*/
X
Xint f, n;		/* default Flag & Numeric arg */
X
X{
X	register BUFFER *bp;	/* pointer to scan through all buffers */
X	char bufn[NBUFN];	/* buffer to hold buffer name */
X
X	/* prompt for and get the new buffer name */
Xask:	if (mlreply("Change buffer name to: ", bufn, NBUFN) != TRUE)
X		return(FALSE);
X
X	/* and check for duplicates */
X	bp = bheadp;
X	while (bp != NULL) {
X		if (bp != curbp) {
X			/* if the names the same */
X			if (strcmp(bufn, bp->b_bname) == 0)
X				goto ask;  /* try again */
X		}
X		bp = bp->b_bufp;	/* onward */
X	}
X
X	strcpy(curbp->b_bname, bufn);	/* copy buffer name to structure */
X	curwp->w_flag |= WFMODE;	/* make mode line replot */
X	mlerase();
X	return(TRUE);
X}
X
X/*
X * List all of the active
X * buffers. First update the special
X * buffer that holds the list. Next make
X * sure at least 1 window is displaying the
X * buffer list, splitting the screen if this
X * is what it takes. Lastly, repaint all of
X * the windows that are displaying the
X * list. Bound to "C-X C-B".
X */
Xlistbuffers(f, n)
X{
X        register WINDOW *wp;
X        register BUFFER *bp;
X        register int    s;
X
X        if ((s=makelist()) != TRUE)
X                return (s);
X        if (blistp->b_nwnd == 0) {              /* Not on screen yet.   */
X                if ((wp=wpopup()) == NULL)
X                        return (FALSE);
X                bp = wp->w_bufp;
X                if (--bp->b_nwnd == 0) {
X                        bp->b_dotp  = wp->w_dotp;
X                        bp->b_doto  = wp->w_doto;
X                        bp->b_markp = wp->w_markp;
X                        bp->b_marko = wp->w_marko;
X                }
X                wp->w_bufp  = blistp;
X                ++blistp->b_nwnd;
X        }
X        wp = wheadp;
X        while (wp != NULL) {
X                if (wp->w_bufp == blistp) {
X                        wp->w_linep = lforw(blistp->b_linep);
X                        wp->w_dotp  = lforw(blistp->b_linep);
X                        wp->w_doto  = 0;
X                        wp->w_markp = NULL;
X                        wp->w_marko = 0;
X                        wp->w_flag |= WFMODE|WFHARD;
X                }
X                wp = wp->w_wndp;
X        }
X        return (TRUE);
X}
X
X/*
X * This routine rebuilds the
X * text in the special secret buffer
X * that holds the buffer list. It is called
X * by the list buffers command. Return TRUE
X * if everything works. Return FALSE if there
X * is an error (if there is no memory).
X */
Xmakelist()
X{
X        register char   *cp1;
X        register char   *cp2;
X        register int    c;
X        register BUFFER *bp;
X        register LINE   *lp;
X        register int    s;
X	register int	i;
X        long	nbytes;		/* # of bytes in current buffer */
X        char            b[7+1];
X        char            line[128];
X
X        blistp->b_flag &= ~BFCHG;               /* Don't complain!      */
X        if ((s=bclear(blistp)) != TRUE)         /* Blow old text away   */
X                return (s);
X        strcpy(blistp->b_fname, "");
X        if (addline("AC MODES      Size Buffer        File") == FALSE
X        ||  addline("-- -----      ---- ------        ----") == FALSE)
X                return (FALSE);
X        bp = bheadp;                            /* For all buffers      */
X
X	/* build line to report global mode settings */
X	cp1 = &line[0];
X	*cp1++ = ' ';
X	*cp1++ = ' ';
X	*cp1++ = ' ';
X
X	/* output the mode codes */
X	for (i = 0; i < NUMMODES; i++)
X		if (gmode & (1 << i))
X			*cp1++ = modecode[i];
X		else
X			*cp1++ = '.';
X	strcpy(cp1, "         Global Modes");
X	if (addline(line) == FALSE)
X		return(FALSE);
X
X	/* output the list of buffers */
X        while (bp != NULL) {
X                if ((bp->b_flag&BFINVS) != 0) { /* Skip magic ones.     */
X                        bp = bp->b_bufp;
X                        continue;
X                }
X                cp1 = &line[0];                 /* Start at left edge   */
X
X		/* output status of ACTIVE flag (has the file been read in? */
X                if (bp->b_active == TRUE)    /* "@" if activated       */
X                        *cp1++ = '@';
X                else
X                        *cp1++ = ' ';
X
X		/* output status of changed flag */
X                if ((bp->b_flag&BFCHG) != 0)    /* "*" if changed       */
X                        *cp1++ = '*';
X                else
X                        *cp1++ = ' ';
X                *cp1++ = ' ';                   /* Gap.                 */
X
X		/* output the mode codes */
X		for (i = 0; i < NUMMODES; i++) {
X			if (bp->b_mode & (1 << i))
X				*cp1++ = modecode[i];
X			else
X				*cp1++ = '.';
X		}
X                *cp1++ = ' ';                   /* Gap.                 */
X                nbytes = 0L;                    /* Count bytes in buf.  */
X                lp = lforw(bp->b_linep);
X                while (lp != bp->b_linep) {
X                        nbytes += (long)llength(lp)+1L;
X                        lp = lforw(lp);
X                }
X                ltoa(b, 7, nbytes);             /* 6 digit buffer size. */
X                cp2 = &b[0];
X                while ((c = *cp2++) != 0)
X                        *cp1++ = c;
X                *cp1++ = ' ';                   /* Gap.                 */
X                cp2 = &bp->b_bname[0];          /* Buffer name          */
X                while ((c = *cp2++) != 0)
X                        *cp1++ = c;
X                cp2 = &bp->b_fname[0];          /* File name            */
X                if (*cp2 != 0) {
X                        while (cp1 < &line[2+1+5+1+6+1+NBUFN])
X                                *cp1++ = ' ';
X                        while ((c = *cp2++) != 0) {
X                                if (cp1 < &line[128-1])
X                                        *cp1++ = c;
X                        }
X                }
X                *cp1 = 0;                       /* Add to the buffer.   */
X                if (addline(line) == FALSE)
X                        return (FALSE);
X                bp = bp->b_bufp;
X        }
X        return (TRUE);                          /* All done             */
X}
X
Xltoa(buf, width, num)
X
Xchar   buf[];
Xint    width;
Xlong   num;
X
X{
X        buf[width] = 0;                         /* End of string.       */
X        while (num >= 10) {                     /* Conditional digits.  */
X                buf[--width] = (int)(num%10L) + '0';
X                num /= 10L;
X        }
X        buf[--width] = (int)num + '0';          /* Always 1 digit.      */
X        while (width != 0)                      /* Pad with blanks.     */
X                buf[--width] = ' ';
X}
X
X/*
X * The argument "text" points to
X * a string. Append this line to the
X * buffer list buffer. Handcraft the EOL
X * on the end. Return TRUE if it worked and
X * FALSE if you ran out of room.
X */
Xaddline(text)
Xchar    *text;
X{
X        register LINE   *lp;
X        register int    i;
X        register int    ntext;
X
X        ntext = strlen(text);
X        if ((lp=lalloc(ntext)) == NULL)
X                return (FALSE);
X        for (i=0; i<ntext; ++i)
X                lputc(lp, i, text[i]);
X        blistp->b_linep->l_bp->l_fp = lp;       /* Hook onto the end    */
X        lp->l_bp = blistp->b_linep->l_bp;
X        blistp->b_linep->l_bp = lp;
X        lp->l_fp = blistp->b_linep;
X        if (blistp->b_dotp == blistp->b_linep)  /* If "." is at the end */
X                blistp->b_dotp = lp;            /* move it to new line  */
X        return (TRUE);
X}
X
X/*
X * Look through the list of
X * buffers. Return TRUE if there
X * are any changed buffers. Buffers
X * that hold magic internal stuff are
X * not considered; who cares if the
X * list of buffer names is hacked.
X * Return FALSE if no buffers
X * have been changed.
X */
Xanycb()
X{
X        register BUFFER *bp;
X
X        bp = bheadp;
X        while (bp != NULL) {
X                if ((bp->b_flag&BFINVS)==0 && (bp->b_flag&BFCHG)!=0)
X                        return (TRUE);
X                bp = bp->b_bufp;
X        }
X        return (FALSE);
X}
X
X/*
X * Find a buffer, by name. Return a pointer
X * to the BUFFER structure associated with it.
X * If the buffer is not found
X * and the "cflag" is TRUE, create it. The "bflag" is
X * the settings for the flags in in buffer.
X */
XBUFFER  *
Xbfind(bname, cflag, bflag)
Xregister char   *bname;
X{
X        register BUFFER *bp;
X	register BUFFER *sb;	/* buffer to insert after */
X        register LINE   *lp;
X	char *malloc();
X
X        bp = bheadp;
X        while (bp != NULL) {
X                if (strcmp(bname, bp->b_bname) == 0)
X                        return (bp);
X                bp = bp->b_bufp;
X        }
X        if (cflag != FALSE) {
X                if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
X                        return (NULL);
X                if ((lp=lalloc(0)) == NULL) {
X                        free((char *) bp);
X                        return (NULL);
X                }
X		/* find the place in the list to insert this buffer */
X		if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0) {
X			/* insert at the begining */
X	                bp->b_bufp = bheadp;
X        	        bheadp = bp;
X        	} else {
X			sb = bheadp;
X			while (sb->b_bufp != NULL) {
X				if (strcmp(sb->b_bufp->b_bname, bname) > 0)
X					break;
X				sb = sb->b_bufp;
X			}
X
X			/* and insert it */
X       			bp->b_bufp = sb->b_bufp;
X        		sb->b_bufp = bp;
X       		}
X
X		/* and set up the other buffer fields */
X		bp->b_active = TRUE;
X                bp->b_dotp  = lp;
X                bp->b_doto  = 0;
X                bp->b_markp = NULL;
X                bp->b_marko = 0;
X                bp->b_flag  = bflag;
X		bp->b_mode  = gmode;
X                bp->b_nwnd  = 0;
X                bp->b_linep = lp;
X                strcpy(bp->b_fname, "");
X                strcpy(bp->b_bname, bname);
X                lp->l_fp = lp;
X                lp->l_bp = lp;
X        }
X        return (bp);
X}
X
X/*
X * This routine blows away all of the text
X * in a buffer. If the buffer is marked as changed
X * then we ask if it is ok to blow it away; this is
X * to save the user the grief of losing text. The
X * window chain is nearly always wrong if this gets
X * called; the caller must arrange for the updates
X * that are required. Return TRUE if everything
X * looks good.
X */
Xbclear(bp)
Xregister BUFFER *bp;
X{
X        register LINE   *lp;
X        register int    s;
X
X        if ((bp->b_flag&BFINVS) == 0            /* Not scratch buffer.  */
X        && (bp->b_flag&BFCHG) != 0              /* Something changed    */
X        && (s=mlyesno("Discard changes")) != TRUE)
X                return (s);
X        bp->b_flag  &= ~BFCHG;                  /* Not changed          */
X        while ((lp=lforw(bp->b_linep)) != bp->b_linep)
X                lfree(lp);
X        bp->b_dotp  = bp->b_linep;              /* Fix "."              */
X        bp->b_doto  = 0;
X        bp->b_markp = NULL;                     /* Invalidate "mark"    */
X        bp->b_marko = 0;
X        return (TRUE);
X}
X
Xunmark(f, n)	/* unmark the current buffers change flag */
X
Xint f, n;	/* unused command arguments */
X
X{
X	curbp->b_flag &= ~BFCHG;
X	curwp->w_flag |= WFMODE;
X	return(TRUE);
X}
FRIDAY_NIGHT
echo es.1 completed!
: That's all folks!

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

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

[  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.  Lawrence 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 - dg10.c
sed 's/^X//' > dg10.c << 'FRIDAY_NIGHT'
X/*
X * The routines in this file provide support for the Data General Model 10
X * Microcomputer.
X */
X
X#define	termdef	1			/* don't define "term" external */
X
X#include        <stdio.h>
X#include	"estruct.h"
X#include        "edef.h"
X
X#if     DG10
X
X#define NROW    24                      /* Screen size.                 */
X#define NCOL    80                      /* Edit if you want to.         */
X#define	NPAUSE	100			/* # times thru update to pause */
X#define	MARGIN	8			/* size of minimim margin and	*/
X#define	SCRSIZ	64			/* scroll size for extended lines */
X#define BEL     0x07                    /* BEL character.               */
X#define ESC     30                      /* DG10 ESC character.          */
X
Xextern  int     ttopen();               /* Forward references.          */
Xextern  int     ttgetc();
Xextern  int     ttputc();
Xextern  int     ttflush();
Xextern  int     ttclose();
Xextern  int     dg10move();
Xextern  int     dg10eeol();
Xextern  int     dg10eeop();
Xextern  int     dg10beep();
Xextern  int     dg10open();
Xextern	int	dg10rev();
Xextern	int	dg10close();
X
X#if	COLOR
Xextern	int	dg10fcol();
Xextern	int	dg10bcol();
X
Xint	cfcolor = -1;		/* current forground color */
Xint	cbcolor = -1;		/* current background color */
Xint	ctrans[] = {		/* emacs -> DG10 color translation table */
X	0, 4, 2, 6, 1, 5, 3, 7};
X#endif
X
X/*
X * Standard terminal interface dispatch table. Most of the fields point into
X * "termio" code.
X */
XTERM    term    = {
X        NROW-1,
X        NCOL,
X	MARGIN,
X	SCRSIZ,
X	NPAUSE,
X        dg10open,
X        dg10close,
X        ttgetc,
X        ttputc,
X        ttflush,
X        dg10move,
X        dg10eeol,
X        dg10eeop,
X        dg10beep,
X	dg10rev
X#if	COLOR
X	, dg10fcol,
X	dg10bcol
X#endif
X};
X
X#if	COLOR
Xdg10fcol(color)		/* set the current output color */
X
Xint color;	/* color to set */
X
X{
X	if (color == cfcolor)
X		return;
X	ttputc(ESC);
X	ttputc(0101);
X	ttputc(ctrans[color]);
X	cfcolor = color;
X}
X
Xdg10bcol(color)		/* set the current background color */
X
Xint color;	/* color to set */
X
X{
X	if (color == cbcolor)
X		return;
X	ttputc(ESC);
X	ttputc(0102);
X	ttputc(ctrans[color]);
X        cbcolor = color;
X}
X#endif
X
Xdg10move(row, col)
X{
X	ttputc(16);
X        ttputc(col);
X	ttputc(row);
X}
X
Xdg10eeol()
X{
X        ttputc(11);
X}
X
Xdg10eeop()
X{
X#if	COLOR
X	dg10fcol(gfcolor);
X	dg10bcol(gbcolor);
X#endif
X        ttputc(ESC);
X        ttputc(0106);
X        ttputc(0106);
X}
X
Xdg10rev(state)		/* change reverse video state */
X
Xint state;	/* TRUE = reverse, FALSE = normal */
X
X{
X#if	COLOR
X	if (state == TRUE) {
X		dg10fcol(0);
X		dg10bcol(7);
X	}
X#else
X	ttputc(ESC);
X	ttputc(state ? 0104: 0105);
X#endif
X}
X
Xdg10beep()
X{
X        ttputc(BEL);
X        ttflush();
X}
X
Xdg10open()
X{
X	revexist = TRUE;
X        ttopen();
X}
X
Xdg10close()
X
X{
X#if	COLOR
X	dg10fcol(7);
X	dg10bcol(0);
X#endif
X	ttclose();
X}
X#else
Xdg10hello()
X{
X}
X#endif
FRIDAY_NIGHT
echo extracting - display.c
sed 's/^X//' > display.c << 'FRIDAY_NIGHT'
X/*
X * The functions in this file handle redisplay. There are two halves, the
X * ones that update the virtual display screen, and the ones that make the
X * physical display screen the same as the virtual display screen. These
X * functions use hints that are left in the windows by the commands.
X *
X */
X
X#include        <stdio.h>
X#include	"estruct.h"
X#include        "edef.h"
X
X#define WFDEBUG 0                       /* Window flag debug. */
X
Xtypedef struct  VIDEO {
X        int	v_flag;                 /* Flags */
X#if	COLOR
X	int	v_fcolor;		/* current forground color */
X	int	v_bcolor;		/* current background color */
X	int	v_rfcolor;		/* requested forground color */
X	int	v_rbcolor;		/* requested background color */
X#endif
X        char    v_text[1];              /* Screen data. */
X}       VIDEO;
X
X#define VFCHG   0x0001                  /* Changed flag			*/
X#define	VFEXT	0x0002			/* extended (beyond column 80)	*/
X#define	VFREV	0x0004			/* reverse video status		*/
X#define	VFREQ	0x0008			/* reverse video request	*/
X#define	VFCOL	0x0010			/* color change requested	*/
X
XVIDEO   **vscreen;                      /* Virtual screen. */
X#if	IBMPC == 0
XVIDEO   **pscreen;                      /* Physical screen. */
X#endif
X
X/*
X * Initialize the data structures used by the display code. The edge vectors
X * used to access the screens are set up. The operating system's terminal I/O
X * channel is set up. All the other things get initialized at compile time.
X * The original window has "WFCHG" set, so that it will get completely
X * redrawn on the first call to "update".
X */
Xvtinit()
X{
X    register int i;
X    register VIDEO *vp;
X    char *malloc();
X
X    (*term.t_open)();
X    (*term.t_rev)(FALSE);
X    vscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *));
X
X    if (vscreen == NULL)
X        exit(1);
X
X#if	IBMPC == 0
X    pscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *));
X
X    if (pscreen == NULL)
X        exit(1);
X#endif
X
X    for (i = 0; i < term.t_nrow; ++i)
X        {
X        vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_ncol);
X
X        if (vp == NULL)
X            exit(1);
X
X	vp->v_flag = 0;
X#if	COLOR
X	vp->v_rfcolor = 7;
X	vp->v_rbcolor = 0;
X#endif
X        vscreen[i] = vp;
X#if	IBMPC == 0
X        vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_ncol);
X
X        if (vp == NULL)
X            exit(1);
X
X	vp->v_flag = 0;
X        pscreen[i] = vp;
X#endif
X        }
X}
X
X/*
X * Clean up the virtual terminal system, in anticipation for a return to the
X * operating system. Move down to the last line and clear it out (the next
X * system prompt will be written in the line). Shut down the channel to the
X * terminal.
X */
Xvttidy()
X{
X    mlerase();
X    movecursor(term.t_nrow, 0);
X    (*term.t_flush)();
X    (*term.t_close)();
X}
X
X/*
X * Set the virtual cursor to the specified row and column on the virtual
X * screen. There is no checking for nonsense values; this might be a good
X * idea during the early stages.
X */
Xvtmove(row, col)
X{
X    vtrow = row;
X    vtcol = col;
X}
X
X/*
X * Write a character to the virtual screen. The virtual row and column are
X * updated. If the line is too long put a "$" in the last column. This routine
X * only puts printing characters into the virtual terminal buffers. Only
X * column overflow is checked.
X */
Xvtputc(c)
X    int c;
X{
X    register VIDEO      *vp;
X
X    vp = vscreen[vtrow];
X
X    if (vtcol >= term.t_ncol) {
X        vtcol = (vtcol + 0x07) & ~0x07;
X        vp->v_text[term.t_ncol - 1] = '$';
X    } else if (c == '\t')
X        {
X        do
X            {
X            vtputc(' ');
X            }
X        while ((vtcol&0x07) != 0);
X        }
X    else if (c < 0x20 || c == 0x7F)
X        {
X        vtputc('^');
X        vtputc(c ^ 0x40);
X        }
X    else
X	vp->v_text[vtcol++] = c;
X}
X
X/*	put a character to the virtual screen in an extended line. If we are
X	not yet on left edge, don't print it yet. check for overflow on
X	the right margin						*/
X
Xvtpute(c)
X
Xint c;
X
X{
X    register VIDEO      *vp;
X
X    vp = vscreen[vtrow];
X
X    if (vtcol >= term.t_ncol) {
X        vtcol = (vtcol + 0x07) & ~0x07;
X        vp->v_text[term.t_ncol - 1] = '$';
X    } else if (c == '\t')
X        {
X        do
X            {
X            vtpute(' ');
X            }
X        while (((vtcol + lbound)&0x07) != 0);
X        }
X    else if (c < 0x20 || c == 0x7F)
X        {
X        vtpute('^');
X        vtpute(c ^ 0x40);
X        }
X    else {
X	if (vtcol >= 0)
X		vp->v_text[vtcol] = c;
X	++vtcol;
X    }
X}
X
X/*
X * Erase from the end of the software cursor to the end of the line on which
X * the software cursor is located.
X */
Xvteeol()
X{
X    register VIDEO      *vp;
X
X    vp = vscreen[vtrow];
X    while (vtcol < term.t_ncol)
X        vp->v_text[vtcol++] = ' ';
X}
X
X/* upscreen:	user routine to force a screen update
X		always finishes complete update		*/
X
Xupscreen(f, n)
X
X{
X	update(TRUE);
X	return(TRUE);
X}
X
X/*
X * Make sure that the display is right. This is a three part process. First,
X * scan through all of the windows looking for dirty ones. Check the framing,
X * and refresh the screen. Second, make sure that "currow" and "curcol" are
X * correct for the current window. Third, make the virtual and physical
X * screens the same.
X */
Xupdate(force)
X
Xint force;	/* force update past type ahead? */
X
X{
X	register WINDOW *wp;
X
X#if	TYPEAH
X	if (force == FALSE && typahead())
X		return(TRUE);
X#endif
X
X	/* update any windows that need refreshing */
X	wp = wheadp;
X	while (wp != NULL) {
X		if (wp->w_flag) {
X			/* if the window has changed, service it */
X			reframe(wp);	/* check the framing */
X			if ((wp->w_flag & ~WFMODE) == WFEDIT)
X				updone(wp);	/* update EDITed line */
X			else if (wp->w_flag & ~WFMOVE)
X				updall(wp);	/* update all lines */
X#if	~WFDEBUG
X			if (wp->w_flag & WFMODE)
X				modeline(wp);	/* update modeline */
X#endif
X			wp->w_flag = 0;
X			wp->w_force = 0;
X		}
X#if	WFDEBUG
X		modeline();
X#endif
X		/* on to the next window */
X		wp = wp->w_wndp;
X	}
X
X	/* recalc the current hardware cursor location */
X	updpos();
X
X#if	IBMPC
X	/* update the cursor and flush the buffers */
X	movecursor(currow, curcol - lbound);
X#endif
X
X	/* check for lines to de-extend */
X	upddex();
X
X	/* if screen is garbage, re-plot it */
X	if (sgarbf != FALSE)
X		updgar();
X
X	/* update the virtual screen to the physical screen */
X	updupd(force);
X
X	/* update the cursor and flush the buffers */
X	movecursor(currow, curcol - lbound);
X	(*term.t_flush)();
X	return(TRUE);
X}
X
X/*	reframe:	check to see if the cursor is on in the window
X			and re-frame it if needed or wanted		*/
X
Xreframe(wp)
X
XWINDOW *wp;
X
X{
X	register LINE *lp;
X	register int i;
X
X	/* if not a requested reframe, check for a needed one */
X	if ((wp->w_flag & WFFORCE) == 0) {
X		lp = wp->w_linep;
X		for (i = 0; i < wp->w_ntrows; i++) {
X
X			/* if the line is in the window, no reframe */
X			if (lp == wp->w_dotp)
X				return(TRUE);
X
X			/* if we are at the end of the file, reframe */
X			if (lp == wp->w_bufp->b_linep)
X				break;
X
X			/* on to the next line */
X			lp = lforw(lp);
X		}
X	}
X
X	/* reaching here, we need a window refresh */
X	i = wp->w_force;
X
X	/* how far back to reframe? */
X	if (i > 0) {		/* only one screen worth of lines max */
X		if (--i >= wp->w_ntrows)
X			i = wp->w_ntrows - 1;
X	} else if (i < 0) {	/* negative update???? */
X		i += wp->w_ntrows;
X		if (i < 0)
X			i = 0;
X	} else
X		i = wp->w_ntrows / 2;
X
X	/* backup to new line at top of window */
X	lp = wp->w_dotp;
X	while (i != 0 && lback(lp) != wp->w_bufp->b_linep) {
X		--i;
X		lp = lback(lp);
X	}
X
X	/* and reset the current line at top of window */
X	wp->w_linep = lp;
X	wp->w_flag |= WFHARD;
X	wp->w_flag &= ~WFFORCE;
X	return(TRUE);
X}
X
X/*	updone:	update the current line	to the virtual screen		*/
X
Xupdone(wp)
X
XWINDOW *wp;	/* window to update current line in */
X
X{
X	register LINE *lp;	/* line to update */
X	register int sline;	/* physical screen line to update */
X	register int i;
X
X	/* search down the line we want */
X	lp = wp->w_linep;
X	sline = wp->w_toprow;
X	while (lp != wp->w_dotp) {
X		++sline;
X		lp = lforw(lp);
X	}
X
X	/* and update the virtual line */
X	vscreen[sline]->v_flag |= VFCHG;
X	vscreen[sline]->v_flag &= ~VFREQ;
X	vtmove(sline, 0);
X	for (i=0; i < llength(lp); ++i)
X		vtputc(lgetc(lp, i));
X#if	COLOR
X	vscreen[sline]->v_rfcolor = wp->w_fcolor;
X	vscreen[sline]->v_rbcolor = wp->w_bcolor;
X#endif
X	vteeol();
X}
X
X/*	updall:	update all the lines in a window on the virtual screen */
X
Xupdall(wp)
X
XWINDOW *wp;	/* window to update lines in */
X
X{
X	register LINE *lp;	/* line to update */
X	register int sline;	/* physical screen line to update */
X	register int i;
X
X	/* search down the lines, updating them */
X	lp = wp->w_linep;
X	sline = wp->w_toprow;
X	while (sline < wp->w_toprow + wp->w_ntrows) {
X
X		/* and update the virtual line */
X		vscreen[sline]->v_flag |= VFCHG;
X		vscreen[sline]->v_flag &= ~VFREQ;
X		vtmove(sline, 0);
X		if (lp != wp->w_bufp->b_linep) {
X			/* if we are not at the end */
X			for (i=0; i < llength(lp); ++i)
X				vtputc(lgetc(lp, i));
X			lp = lforw(lp);
X		}
X
X		/* on to the next one */
X#if	COLOR
X		vscreen[sline]->v_rfcolor = wp->w_fcolor;
X		vscreen[sline]->v_rbcolor = wp->w_bcolor;
X#endif
X		vteeol();
X		++sline;
X	}
X
X}
X
X/*	updpos:	update the position of the hardware cursor and handle extended
X		lines. This is the only update for simple moves.	*/
X
Xupdpos()
X
X{
X	register LINE *lp;
X	register int c;
X	register int i;
X
X	/* find the current row */
X	lp = curwp->w_linep;
X	currow = curwp->w_toprow;
X	while (lp != curwp->w_dotp) {
X		++currow;
X		lp = lforw(lp);
X	}
X
X	/* find the current column */
X	curcol = 0;
X	i = 0;
X	while (i < curwp->w_doto) {
X		c = lgetc(lp, i++);
X		if (c == '\t')
X			curcol |= 0x07;
X		else
X			if (c < 0x20 || c == 0x7f)
X				++curcol;
X
X		++curcol;
X	}
X
X	/* if extended, flag so and update the virtual line image */
X	if (curcol >=  term.t_ncol - 1) {
X		vscreen[currow]->v_flag |= (VFEXT | VFCHG);
X		updext();
X	} else
X		lbound = 0;
X}
X
X/*	upddex:	de-extend any line that derserves it		*/
X
Xupddex()
X
X{
X	register WINDOW *wp;
X	register LINE *lp;
X	register int i,j;
X
X	wp = wheadp;
X
X	while (wp != NULL) {
X		lp = wp->w_linep;
X		i = wp->w_toprow;
X
X		while (i < wp->w_toprow + wp->w_ntrows) {
X			if (vscreen[i]->v_flag & VFEXT) {
X				if ((wp != curwp) || (lp != wp->w_dotp) ||
X				   (curcol < term.t_ncol - 1)) {
X					vtmove(i, 0);
X					for (j = 0; j < llength(lp); ++j)
X						vtputc(lgetc(lp, j));
X					vteeol();
X
X					/* this line no longer is extended */
X					vscreen[i]->v_flag &= ~VFEXT;
X					vscreen[i]->v_flag |= VFCHG;
X				}
X			}
X			lp = lforw(lp);
X			++i;
X		}
X		/* and onward to the next window */
X		wp = wp->w_wndp;
X	}
X}
X
X/*	updgar:	if the screen is garbage, clear the physical screen and
X		the virtual screen and force a full update		*/
X
Xupdgar()
X
X{
X	register char *txt;
X	register int i,j;
X
X	for (i = 0; i < term.t_nrow; ++i) {
X		vscreen[i]->v_flag |= VFCHG;
X#if	REVSTA
X		vscreen[i]->v_flag &= ~VFREV;
X#endif
X#if	COLOR
X		vscreen[i]->v_fcolor = gfcolor;
X		vscreen[i]->v_bcolor = gbcolor;
X#endif
X#if	IBMPC == 0
X		txt = pscreen[i]->v_text;
X		for (j = 0; j < term.t_ncol; ++j)
X			txt[j] = ' ';
X#endif
X	}
X
X	movecursor(0, 0);		 /* Erase the screen. */
X	(*term.t_eeop)();
X	sgarbf = FALSE;			 /* Erase-page clears */
X	mpresf = FALSE;			 /* the message area. */
X#if	COLOR
X	mlerase();			/* needs to be cleared if colored */
X#endif
X}
X
X/*	updupd:	update the physical screen from the virtual screen	*/
X
Xupdupd(force)
X
Xint force;	/* forced update flag */
X
X{
X	register VIDEO *vp1;
X	register int i;
X
X	for (i = 0; i < term.t_nrow; ++i) {
X		vp1 = vscreen[i];
X
X		/* for each line that needs to be updated*/
X		if ((vp1->v_flag & VFCHG) != 0) {
X#if	TYPEAH
X			if (force == FALSE && typahead())
X				return(TRUE);
X#endif
X#if	IBMPC
X			updateline(i, vp1);
X#else
X			updateline(i, vp1, pscreen[i]);
X#endif
X		}
X	}
X	return(TRUE);
X}
X
X/*	updext: update the extended line which the cursor is currently
X		on at a column greater than the terminal width. The line
X		will be scrolled right or left to let the user see where
X		the cursor is
X								*/
X
Xupdext()
X
X{
X	register int rcursor;	/* real cursor location */
X	register LINE *lp;	/* pointer to current line */
X	register int j;		/* index into line */
X
X	/* calculate what column the real cursor will end up in */
X	rcursor = ((curcol - term.t_ncol) % term.t_scrsiz) + term.t_margin;
X	lbound = curcol - rcursor + 1;
X
X	/* scan through the line outputing characters to the virtual screen */
X	/* once we reach the left edge					*/
X	vtmove(currow, -lbound);	/* start scanning offscreen */
X	lp = curwp->w_dotp;		/* line to output */
X	for (j=0; j<llength(lp); ++j)	/* until the end-of-line */
X		vtpute(lgetc(lp, j));
X
X	/* truncate the virtual line */
X	vteeol();
X
X	/* and put a '$' in column 1 */
X	vscreen[currow]->v_text[0] = '$';
X}
X
X/*
X * Update a single line. This does not know how to use insert or delete
X * character sequences; we are using VT52 functionality. Update the physical
X * row and column variables. It does try an exploit erase to end of line. The
X * RAINBOW version of this routine uses fast video.
X */
X#if	IBMPC
X/*	UPDATELINE specific code for the IBM-PC and other compatables */
X
Xupdateline(row, vp1)
X
Xint row;		/* row of screen to update */
Xstruct VIDEO *vp1;	/* virtual screen image */
X
X{
X#if	COLOR
X	scwrite(row, vp1->v_text, vp1->v_rfcolor, vp1->v_rbcolor);
X	vp1->v_fcolor = vp1->v_rfcolor;
X	vp1->v_bcolor = vp1->v_rbcolor;
X#else
X	if (vp1->v_flag & VFREQ)
X		scwrite(row, vp1->v_text, 0, 7);
X	else
X		scwrite(row, vp1->v_text, 7, 0);
X#endif
X	vp1->v_flag &= ~(VFCHG | VFCOL);	/* flag this line as changed */
X
X}
X
X#else
X
Xupdateline(row, vp1, vp2)
X
Xint row;		/* row of screen to update */
Xstruct VIDEO *vp1;	/* virtual screen image */
Xstruct VIDEO *vp2;	/* physical screen image */
X
X{
X#if RAINBOW
X/*	UPDATELINE specific code for the DEC rainbow 100 micro	*/
X
X    register char *cp1;
X    register char *cp2;
X    register int nch;
X
X    /* since we don't know how to make the rainbow do this, turn it off */
X    flags &= (~VFREV & ~VFREQ);
X
X    cp1 = &vp1->v_text[0];                    /* Use fast video. */
X    cp2 = &vp2->v_text[0];
X    putline(row+1, 1, cp1);
X    nch = term.t_ncol;
X
X    do
X        {
X        *cp2 = *cp1;
X        ++cp2;
X        ++cp1;
X        }
X    while (--nch);
X    *flags &= ~VFCHG;
X#else
X/*	UPDATELINE code for all other versions		*/
X
X	register char *cp1;
X	register char *cp2;
X	register char *cp3;
X	register char *cp4;
X	register char *cp5;
X	register int nbflag;	/* non-blanks to the right flag? */
X	int rev;		/* reverse video flag */
X	int req;		/* reverse video request flag */
X
X
X	/* set up pointers to virtual and physical lines */
X	cp1 = &vp1->v_text[0];
X	cp2 = &vp2->v_text[0];
X
X#if	COLOR
X	(*term.t_setfor)(vp1->v_rfcolor);
X	(*term.t_setback)(vp1->v_rbcolor);
X#endif
X
X#if	REVSTA | COLOR
X	/* if we need to change the reverse video status of the
X	   current line, we need to re-write the entire line     */
X	rev = (vp1->v_flag & VFREV) == VFREV;
X	req = (vp1->v_flag & VFREQ) == VFREQ;
X	if ((rev != req)
X#if	COLOR
X	    || (vp1->v_fcolor != vp1->v_rfcolor) || (vp1->v_bcolor != vp1->v_rbcolor)
X#endif
X			) {
X		movecursor(row, 0);	/* Go to start of line. */
X		/* set rev video if needed */
X		if (rev != req)
X			(*term.t_rev)(req);
X
X		/* scan through the line and dump it to the screen and
X		   the virtual screen array				*/
X		cp3 = &vp1->v_text[term.t_ncol];
X		while (cp1 < cp3) {
X			(*term.t_putchar)(*cp1);
X			++ttcol;
X			*cp2++ = *cp1++;
X		}
X		/* turn rev video off */
X		if (rev != req)
X			(*term.t_rev)(FALSE);
X
X		/* update the needed flags */
X		vp1->v_flag &= ~VFCHG;
X		if (req)
X			vp1->v_flag |= VFREV;
X		else
X			vp1->v_flag &= ~VFREV;
X#if	COLOR
X		vp1->v_fcolor = vp1->v_rfcolor;
X		vp1->v_bcolor = vp1->v_rbcolor;
X#endif
X		return(TRUE);
X	}
X#endif
X
X	/* advance past any common chars at the left */
X	while (cp1 != &vp1->v_text[term.t_ncol] && cp1[0] == cp2[0]) {
X		++cp1;
X		++cp2;
X	}
X
X/* This can still happen, even though we only call this routine on changed
X * lines. A hard update is always done when a line splits, a massive
X * change is done, or a buffer is displayed twice. This optimizes out most
X * of the excess updating. A lot of computes are used, but these tend to
X * be hard operations that do a lot of update, so I don't really care.
X */
X	/* if both lines are the same, no update needs to be done */
X	if (cp1 == &vp1->v_text[term.t_ncol])
X		return(TRUE);
X
X	/* find out if there is a match on the right */
X	nbflag = FALSE;
X	cp3 = &vp1->v_text[term.t_ncol];
X	cp4 = &vp2->v_text[term.t_ncol];
X
X	while (cp3[-1] == cp4[-1]) {
X		--cp3;
X		--cp4;
X		if (cp3[0] != ' ')		/* Note if any nonblank */
X			nbflag = TRUE;		/* in right match. */
X	}
X
X	cp5 = cp3;
X
X	/* Erase to EOL ? */
X	if (nbflag == FALSE && eolexist == TRUE && (req != TRUE)) {
X		while (cp5!=cp1 && cp5[-1]==' ')
X			--cp5;
X
X		if (cp3-cp5 <= 3)		/* Use only if erase is */
X			cp5 = cp3;		/* fewer characters. */
X	}
X
X	movecursor(row, cp1 - &vp1->v_text[0]);	/* Go to start of line. */
X#if	REVSTA
X	(*term.t_rev)((vp1->v_flag & VFREV) == VFREV);
X#endif
X
X	while (cp1 != cp5) {		/* Ordinary. */
X		(*term.t_putchar)(*cp1);
X		++ttcol;
X		*cp2++ = *cp1++;
X	}
X
X	if (cp5 != cp3) {		/* Erase. */
X		(*term.t_eeol)();
X		while (cp1 != cp3)
X			*cp2++ = *cp1++;
X	}
X#if	REVSTA
X	(*term.t_rev)(FALSE);
X#endif
X	vp1->v_flag &= ~VFCHG;		/* flag this line is changed */
X	return(TRUE);
X#endif
X}
X#endif
X
X/*
X * Redisplay the mode line for the window pointed to by the "wp". This is the
X * only routine that has any idea of how the modeline is formatted. You can
X * change the modeline format by hacking at this routine. Called by "update"
X * any time there is a dirty window.
X */
Xmodeline(wp)
X    WINDOW *wp;
X{
X    register char *cp;
X    register int c;
X    register int n;		/* cursor position count */
X    register BUFFER *bp;
X    register i;			/* loop index */
X    register lchar;		/* character to draw line in buffer with */
X    register firstm;		/* is this the first mode? */
X    char tline[NLINE];		/* buffer for part of mode line */
X
X    n = wp->w_toprow+wp->w_ntrows;      	/* Location. */
X    vscreen[n]->v_flag |= VFCHG | VFREQ | VFCOL;/* Redraw next time. */
X#if	COLOR
X    vscreen[n]->v_rfcolor = 0;			/* black on */
X    vscreen[n]->v_rbcolor = 7;			/* white.....*/
X#endif
X    vtmove(n, 0);                       	/* Seek to right line. */
X    if (wp == curwp)				/* mark the current buffer */
X	lchar = '=';
X    else
X#if	REVSTA
X	if (revexist)
X		lchar = ' ';
X	else
X#endif
X		lchar = '-';
X
X    vtputc(lchar);
X    bp = wp->w_bufp;
X
X    if ((bp->b_flag&BFCHG) != 0)                /* "*" if changed. */
X        vtputc('*');
X    else
X        vtputc(lchar);
X
X    n  = 2;
X    strcpy(tline, " MicroEMACS 3.7 (");		/* Buffer name. */
X
X    /* display the modes */
X
X	firstm = TRUE;
X	for (i = 0; i < NUMMODES; i++)	/* add in the mode flags */
X		if (wp->w_bufp->b_mode & (1 << i)) {
X			if (firstm != TRUE)
X				strcat(tline, " ");
X			firstm = FALSE;
X			strcat(tline, modename[i]);
X		}
X	strcat(tline,") ");
X
X    cp = &tline[0];
X    while ((c = *cp++) != 0)
X        {
X        vtputc(c);
X        ++n;
X        }
X
X#if WFDEBUG
X    vtputc(lchar);
X    vtputc((wp->w_flag&WFCOLR) != 0  ? 'C' : lchar);
X    vtputc((wp->w_flag&WFMODE) != 0  ? 'M' : lchar);
X    vtputc((wp->w_flag&WFHARD) != 0  ? 'H' : lchar);
X    vtputc((wp->w_flag&WFEDIT) != 0  ? 'E' : lchar);
X    vtputc((wp->w_flag&WFMOVE) != 0  ? 'V' : lchar);
X    vtputc((wp->w_flag&WFFORCE) != 0 ? 'F' : lchar);
X    vtputc(lchar);
X    n += 8;
X#endif
X
X    vtputc(lchar);
X    vtputc(lchar);
X    vtputc(' ');
X    n += 3;
X    cp = &bp->b_bname[0];
X
X    while ((c = *cp++) != 0)
X        {
X        vtputc(c);
X        ++n;
X        }
X
X    vtputc(' ');
X    vtputc(lchar);
X    vtputc(lchar);
X    n += 3;
X
X    if (bp->b_fname[0] != 0)            /* File name. */
X        {
X	vtputc(' ');
X	++n;
X        cp = "File: ";
X
X        while ((c = *cp++) != 0)
X            {
X            vtputc(c);
X            ++n;
X            }
X
X        cp = &bp->b_fname[0];
X
X        while ((c = *cp++) != 0)
X            {
X            vtputc(c);
X            ++n;
X            }
X
X        vtputc(' ');
X        ++n;
X        }
X
X    while (n < term.t_ncol)             /* Pad to full width. */
X        {
X        vtputc(lchar);
X        ++n;
X        }
X}
X
Xupmode()	/* update all the mode lines */
X
X{
X	register WINDOW *wp;
X
X	wp = wheadp;
X	while (wp != NULL) {
X		wp->w_flag |= WFMODE;
X		wp = wp->w_wndp;
X	}
X}
X
X/*
X * Send a command to the terminal to move the hardware cursor to row "row"
X * and column "col". The row and column arguments are origin 0. Optimize out
X * random calls. Update "ttrow" and "ttcol".
X */
Xmovecursor(row, col)
X    {
X    if (row!=ttrow || col!=ttcol)
X        {
X        ttrow = row;
X        ttcol = col;
X        (*term.t_move)(row, col);
X        }
X    }
X
X/*
X * Erase the message line. This is a special routine because the message line
X * is not considered to be part of the virtual screen. It always works
X * immediately; the terminal buffer is flushed via a call to the flusher.
X */
Xmlerase()
X    {
X    int i;
X    
X    movecursor(term.t_nrow, 0);
X#if	COLOR
X     (*term.t_setfor)(7);
X     (*term.t_setback)(0);
X#endif
X    if (eolexist == TRUE)
X	    (*term.t_eeol)();
X    else {
X        for (i = 0; i < term.t_ncol - 1; i++)
X            (*term.t_putchar)(' ');
X        movecursor(term.t_nrow, 1);	/* force the move! */
X        movecursor(term.t_nrow, 0);
X    }
X    (*term.t_flush)();
X    mpresf = FALSE;
X    }
X
X/*
X * Write a message into the message line. Keep track of the physical cursor
X * position. A small class of printf like format items is handled. Assumes the
X * stack grows down; this assumption is made by the "++" in the argument scan
X * loop. Set the "message line" flag TRUE.
X */
X
Xmlwrite(fmt, arg)
X    char *fmt;
X    {
X    register int c;
X    register char *ap;
X
X#if	COLOR
X	(*term.t_setfor)(7);
X	(*term.t_setback)(0);
X#endif
X    if (eolexist == FALSE) {
X        mlerase();
X        (*term.t_flush)();
X    }
X
X    movecursor(term.t_nrow, 0);
X    ap = (char *) &arg;
X    while ((c = *fmt++) != 0) {
X        if (c != '%') {
X            (*term.t_putchar)(c);
X            ++ttcol;
X            }
X        else
X            {
X            c = *fmt++;
X            switch (c) {
X                case 'd':
X                    mlputi(*(int *)ap, 10);
X                    ap += sizeof(int);
X                    break;
X
X                case 'o':
X                    mlputi(*(int *)ap,  8);
X                    ap += sizeof(int);
X                    break;
X
X                case 'x':
X                    mlputi(*(int *)ap, 16);
X                    ap += sizeof(int);
X                    break;
X
X                case 'D':
X                    mlputli(*(long *)ap, 10);
X                    ap += sizeof(long);
X                    break;
X
X                case 's':
X                    mlputs(*(char **)ap);
X                    ap += sizeof(char *);
X                    break;
X
X		case 'f':
X		    mlputf(*(int *)ap);
X		    ap += sizeof(int);
X		    break;
X
X                default:
X                    (*term.t_putchar)(c);
X                    ++ttcol;
X                }
X            }
X        }
X    if (eolexist == TRUE)
X        (*term.t_eeol)();
X    (*term.t_flush)();
X    mpresf = TRUE;
X    }
X
X/*
X * Write out a string. Update the physical cursor position. This assumes that
X * the characters in the string all have width "1"; if this is not the case
X * things will get screwed up a little.
X */
Xmlputs(s)
X    char *s;
X    {
X    register int c;
X
X    while ((c = *s++) != 0)
X        {
X        (*term.t_putchar)(c);
X        ++ttcol;
X        }
X    }
X
X/*
X * Write out an integer, in the specified radix. Update the physical cursor
X * position.
X */
Xmlputi(i, r)
X    {
X    register int q;
X    static char hexdigits[] = "0123456789ABCDEF";
X
X    if (i < 0)
X        {
X        i = -i;
X        (*term.t_putchar)('-');
X        }
X
X    q = i/r;
X
X    if (q != 0)
X        mlputi(q, r);
X
X    (*term.t_putchar)(hexdigits[i%r]);
X    ++ttcol;
X    }
X
X/*
X * do the same except as a long integer.
X */
Xmlputli(l, r)
X    long l;
X    {
X    register long q;
X
X    if (l < 0)
X        {
X        l = -l;
X        (*term.t_putchar)('-');
X        }
X
X    q = l/r;
X
X    if (q != 0)
X        mlputli(q, r);
X
X    (*term.t_putchar)((int)(l%r)+'0');
X    ++ttcol;
X    }
X
X/*
X *	write out a scaled integer with two decimal places
X */
X
Xmlputf(s)
X
Xint s;	/* scaled integer to output */
X
X{
X	int i;	/* integer portion of number */
X	int f;	/* fractional portion of number */
X
X	/* break it up */
X	i = s / 100;
X	f = s % 100;
X
X	/* send out the integer portion */
X	mlputi(i, 10);
X	(*term.t_putchar)('.');
X	(*term.t_putchar)((f / 10) + '0');
X	(*term.t_putchar)((f % 10) + '0');
X	ttcol += 3;
X}	
X
X#if RAINBOW
X
Xputline(row, col, buf)
X    int row, col;
X    char buf[];
X    {
X    int n;
X
X    n = strlen(buf);
X    if (col + n - 1 > term.t_ncol)
X        n = term.t_ncol - col + 1;
X    Put_Data(row, col, n, buf);
X    }
X#endif
X
FRIDAY_NIGHT
echo extracting - ebind.h
sed 's/^X//' > ebind.h << 'FRIDAY_NIGHT'
X/*	EBIND:		Initial default key to function bindings for
X			MicroEMACS 3.7
X*/
X
X/*
X * Command table.
X * This table  is *roughly* in ASCII order, left to right across the
X * characters of the command. This expains the funny location of the
X * control-X commands.
X */
XKEYTAB  keytab[NBINDS] = {
X	{CTRL|'A',		gotobol},
X	{CTRL|'B',		backchar},
X	{CTRL|'C',		insspace},
X	{CTRL|'D',		forwdel},
X	{CTRL|'E',		gotoeol},
X	{CTRL|'F',		forwchar},
X	{CTRL|'G',		ctrlg},
X	{CTRL|'H',		backdel},
X	{CTRL|'I',		tab},
X	{CTRL|'J',		indent},
X	{CTRL|'K',		killtext},
X	{CTRL|'L',		refresh},
X	{CTRL|'M',		newline},
X	{CTRL|'N',		forwline},
X	{CTRL|'O',		openline},
X	{CTRL|'P',		backline},
X	{CTRL|'Q',		quote},
X	{CTRL|'R',		backsearch},
X	{CTRL|'S',		forwsearch},
X	{CTRL|'T',		twiddle},
X	{CTRL|'V',		forwpage},
X	{CTRL|'W',		killregion},
X	{CTRL|'X',		cex},
X	{CTRL|'Y',		yank},
X	{CTRL|'Z',		backpage},
X	{CTRL|']',		meta},
X	{CTLX|CTRL|'B',		listbuffers},
X	{CTLX|CTRL|'C',		quit},          /* Hard quit.           */
X	{CTLX|CTRL|'F',		filefind},
X	{CTLX|CTRL|'I',		insfile},
X	{CTLX|CTRL|'L',		lowerregion},
X	{CTLX|CTRL|'M',		delmode},
X	{CTLX|CTRL|'N',		mvdnwind},
X	{CTLX|CTRL|'O',		deblank},
X	{CTLX|CTRL|'P',		mvupwind},
X	{CTLX|CTRL|'R',		fileread},
X	{CTLX|CTRL|'S',		filesave},
X	{CTLX|CTRL|'U',		upperregion},
X	{CTLX|CTRL|'V',		viewfile},
X	{CTLX|CTRL|'W',		filewrite},
X	{CTLX|CTRL|'X',		swapmark},
X	{CTLX|CTRL|'Z',		shrinkwind},
X	{CTLX|'?',		deskey},
X	{CTLX|'!',		spawn},
X	{CTLX|'@',		pipe},
X	{CTLX|'#',		filter},
X	{CTLX|'=',		showcpos},
X	{CTLX|'(',		ctlxlp},
X	{CTLX|')',		ctlxrp},
X	{CTLX|'^',		enlargewind},
X	{CTLX|'0',		delwind},
X	{CTLX|'1',		onlywind},
X	{CTLX|'2',		splitwind},
X	{CTLX|'B',		usebuffer},
X	{CTLX|'C',		spawncli},
X#if	BSD
X	{CTLX|'D',		bktoshell},
X#endif
X	{CTLX|'E',		ctlxe},
X	{CTLX|'F',		setfillcol},
X	{CTLX|'K',		killbuffer},
X	{CTLX|'M',		setmode},
X	{CTLX|'N',		filename},
X	{CTLX|'O',		nextwind},
X	{CTLX|'P',		prevwind},
X#if	ISRCH
X	{CTLX|'R',		risearch},
X	{CTLX|'S',		fisearch},
X#endif
X	{CTLX|'W',		resize},
X	{CTLX|'X',		nextbuffer},
X	{CTLX|'Z',		enlargewind},
X#if	WORDPRO
X	{META|CTRL|'C',		wordcount},
X#endif
X	{META|CTRL|'H',		delbword},
X	{META|CTRL|'K',		unbindkey},
X	{META|CTRL|'L',		reposition},
X	{META|CTRL|'M',		delgmode},
X	{META|CTRL|'N',		namebuffer},
X	{META|CTRL|'R',		qreplace},
X	{META|CTRL|'V',		scrnextdw},
X#if	WORDPRO
X	{META|CTRL|'W',		killpara},
X#endif
X	{META|CTRL|'Z',		scrnextup},
X	{META|' ',		setmark},
X	{META|'?',		help},
X	{META|'!',		reposition},
X	{META|'.',		setmark},
X	{META|'>',		gotoeob},
X	{META|'<',		gotobob},
X	{META|'~',		unmark},
X	{META|'B',		backword},
X	{META|'C',		capword},
X	{META|'D',		delfword},
X	{META|'F',		forwword},
X	{META|'G',		gotoline},
X	{META|'K',		bindtokey},
X	{META|'L',		lowerword},
X	{META|'M',		setgmode},
X#if	WORDPRO
X	{META|'N',		gotoeop},
X	{META|'P',		gotobop},
X	{META|'Q',		fillpara},
X#endif
X	{META|'R',		sreplace},
X#if	BSD
X	{META|'S',		bktoshell},
X#endif
X	{META|'U',		upperword},
X	{META|'V',		backpage},
X	{META|'W',		copyregion},
X	{META|'X',		namedcmd},
X	{META|'Z',		quickexit},
X	{META|0x7F,              delbword},
X
X#if	MSDOS & (HP150 == 0) & (WANGPC == 0)
X	{SPEC|CTRL|'_',		forwhunt},
X	{SPEC|CTRL|'S',		backhunt},
X	{SPEC|71,		gotobob},
X	{SPEC|72,		backline},
X	{SPEC|73,		backpage},
X	{SPEC|75,		backchar},
X	{SPEC|77,		forwchar},
X	{SPEC|79,		gotoeob},
X	{SPEC|80,		forwline},
X	{SPEC|81,		forwpage},
X	{SPEC|82,		insspace},
X	{SPEC|83,		forwdel},
X	{SPEC|115,		backword},
X	{SPEC|116,		forwword},
X	{SPEC|132,		gotobop},
X	{SPEC|118,		gotoeop},
X	{SPEC|84,		cbuf1},
X	{SPEC|85,		cbuf2},
X	{SPEC|86,		cbuf3},
X	{SPEC|87,		cbuf4},
X	{SPEC|88,		cbuf5},
X	{SPEC|89,		cbuf6},
X	{SPEC|90,		cbuf7},
X	{SPEC|91,		cbuf8},
X	{SPEC|92,		cbuf9},
X	{SPEC|93,		cbuf10},
X#endif
X
X#if	HP150
X	{SPEC|32,		backline},
X	{SPEC|33,		forwline},
X	{SPEC|35,		backchar},
X	{SPEC|34,		forwchar},
X	{SPEC|44,		gotobob},
X	{SPEC|46,		forwpage},
X	{SPEC|47,		backpage},
X	{SPEC|82,		nextwind},
X	{SPEC|68,		openline},
X	{SPEC|69,		killtext},
X	{SPEC|65,		forwdel},
X	{SPEC|64,		ctlxe},
X	{SPEC|67,		refresh},
X	{SPEC|66,		reposition},
X	{SPEC|83,		help},
X	{SPEC|81,		deskey},
X#endif
X
X#if	AMIGA
X	{SPEC|'?',		help},
X	{SPEC|'A',		backline},
X	{SPEC|'B',		forwline},
X	{SPEC|'C',		forwchar},
X	{SPEC|'D',		backchar},
X	{SPEC|'T',		backpage},
X	{SPEC|'S',		forwpage},
X	{SPEC|'a',		backword},
X	{SPEC|'`',		forwword},
X	{SPEC|'P',		cbuf1},
X	{SPEC|'Q',		cbuf2},
X	{SPEC|'R',		cbuf3},
X	{SPEC|'S',		cbuf4},
X	{SPEC|'T',		cbuf5},
X	{SPEC|'U',		cbuf6},
X	{SPEC|'V',		cbuf7},
X	{SPEC|'W',		cbuf8},
X	{SPEC|'X',		cbuf9},
X	{SPEC|'Y',		cbuf10},
X
X#endif
X
X#if  WANGPC
X	SPEC|0xE0,              quit,           /* Cancel */
X	SPEC|0xE1,              help,           /* Help */
X	SPEC|0xF1,              help,           /* ^Help */
X	SPEC|0xE3,              ctrlg,          /* Print */
X	SPEC|0xF3,              ctrlg,          /* ^Print */
X	SPEC|0xC0,              backline,       /* North */
X	SPEC|0xD0,              gotobob,        /* ^North */
X	SPEC|0xC1,              forwchar,       /* East */
X	SPEC|0xD1,              gotoeol,        /* ^East */
X	SPEC|0xC2,              forwline,       /* South */
X	SPEC|0xD2,              gotobop,        /* ^South */
X	SPEC|0xC3,              backchar,       /* West */
X	SPEC|0xD3,              gotobol,        /* ^West */
X	SPEC|0xC4,              ctrlg,          /* Home */
X	SPEC|0xD4,              gotobob,        /* ^Home */
X	SPEC|0xC5,              filesave,       /* Execute */
X	SPEC|0xD5,              ctrlg,          /* ^Execute */
X	SPEC|0xC6,              insfile,        /* Insert */
X	SPEC|0xD6,              ctrlg,          /* ^Insert */
X	SPEC|0xC7,              forwdel,        /* Delete */
X	SPEC|0xD7,              killregion,     /* ^Delete */
X	SPEC|0xC8,              backpage,       /* Previous */
X	SPEC|0xD8,              prevwind,       /* ^Previous */
X	SPEC|0xC9,              forwpage,       /* Next */
X	SPEC|0xD9,              nextwind,       /* ^Next */
X	SPEC|0xCB,              ctrlg,          /* Erase */
X	SPEC|0xDB,              ctrlg,          /* ^Erase */
X	SPEC|0xDC,              ctrlg,          /* ^Tab */
X	SPEC|0xCD,              ctrlg,          /* BackTab */
X	SPEC|0xDD,              ctrlg,          /* ^BackTab */
X	SPEC|0x80,              ctrlg,          /* Indent */
X	SPEC|0x90,              ctrlg,          /* ^Indent */
X	SPEC|0x81,              ctrlg,          /* Page */
X	SPEC|0x91,              ctrlg,          /* ^Page */
X	SPEC|0x82,              ctrlg,          /* Center */
X	SPEC|0x92,              ctrlg,          /* ^Center */
X	SPEC|0x83,              ctrlg,          /* DecTab */
X	SPEC|0x93,              ctrlg,          /* ^DecTab */
X	SPEC|0x84,              ctrlg,          /* Format */
X	SPEC|0x94,              ctrlg,          /* ^Format */
X	SPEC|0x85,              ctrlg,          /* Merge */
X	SPEC|0x95,              ctrlg,          /* ^Merge */
X	SPEC|0x86,              setmark,        /* Note */
X	SPEC|0x96,              ctrlg,          /* ^Note */
X	SPEC|0x87,              ctrlg,          /* Stop */
X	SPEC|0x97,              ctrlg,          /* ^Stop */
X	SPEC|0x88,              forwsearch,     /* Srch */
X	SPEC|0x98,              backsearch,     /* ^Srch */
X	SPEC|0x89,              sreplace,       /* Replac */
X	SPEC|0x99,              qreplace,       /* ^Replac */
X	SPEC|0x8A,              ctrlg,          /* Copy */
X	SPEC|0x9A,              ctrlg,          /* ^Copy */
X	SPEC|0x8B,              ctrlg,          /* Move */
X	SPEC|0x9B,              ctrlg,          /* ^Move */
X	SPEC|0x8C,              namedcmd,       /* Command */
X	SPEC|0x9C,              spawn,          /* ^Command */
X	SPEC|0x8D,              ctrlg,          /* ^ */
X	SPEC|0x9D,              ctrlg,          /* ^^ */
X	SPEC|0x8E,              ctrlg,          /* Blank */
X	SPEC|0x9E,              ctrlg,          /* ^Blank */
X	SPEC|0x8F,              gotoline,       /* GoTo */
X	SPEC|0x9F,              usebuffer,      /* ^GoTo */
X#endif
X 
X	{0x7F,			backdel},
X	{0,			NULL}
X};
X
X#if RAINBOW
X
X#include "rainbow.h"
X
X/*
X * Mapping table from the LK201 function keys to the internal EMACS character.
X */
X
Xshort lk_map[][2] = {
X	Up_Key,                         CTRL+'P',
X	Down_Key,                       CTRL+'N',
X	Left_Key,                       CTRL+'B',
X	Right_Key,                      CTRL+'F',
X	Shift+Left_Key,                 META+'B',
X	Shift+Right_Key,                META+'F',
X	Control+Left_Key,               CTRL+'A',
X	Control+Right_Key,              CTRL+'E',
X	Prev_Scr_Key,                   META+'V',
X	Next_Scr_Key,                   CTRL+'V',
X	Shift+Up_Key,                   META+'<',
X	Shift+Down_Key,                 META+'>',
X	Cancel_Key,                     CTRL+'G',
X	Find_Key,                       CTRL+'S',
X	Shift+Find_Key,                 CTRL+'R',
X	Insert_Key,                     CTRL+'Y',
X	Options_Key,                    CTRL+'D',
X	Shift+Options_Key,              META+'D',
X	Remove_Key,                     CTRL+'W',
X	Shift+Remove_Key,               META+'W',
X	Select_Key,                     CTRL+'@',
X	Shift+Select_Key,               CTLX+CTRL+'X',
X	Interrupt_Key,                  CTRL+'U',
X	Keypad_PF2,                     META+'L',
X	Keypad_PF3,                     META+'C',
X	Keypad_PF4,                     META+'U',
X	Shift+Keypad_PF2,               CTLX+CTRL+'L',
X	Shift+Keypad_PF4,               CTLX+CTRL+'U',
X	Keypad_1,                       CTLX+'1',
X	Keypad_2,                       CTLX+'2',
X	Do_Key,                         CTLX+'E',
X	Keypad_4,                       CTLX+CTRL+'B',
X	Keypad_5,                       CTLX+'B',
X	Keypad_6,                       CTLX+'K',
X	Resume_Key,                     META+'!',
X	Control+Next_Scr_Key,           CTLX+'N',
X	Control+Prev_Scr_Key,           CTLX+'P',
X	Control+Up_Key,                 CTLX+CTRL+'P',
X	Control+Down_Key,               CTLX+CTRL+'N',
X	Help_Key,                       CTLX+'=',
X	Shift+Do_Key,                   CTLX+'(',
X	Control+Do_Key,                 CTLX+')',
X	Keypad_0,                       CTLX+'Z',
X	Shift+Keypad_0,                 CTLX+CTRL+'Z',
X	Main_Scr_Key,                   CTRL+'C',
X	Keypad_Enter,                   CTLX+'!',
X	Exit_Key,                       CTLX+CTRL+'C',
X	Shift+Exit_Key,                 CTRL+'Z'
X};
X
X#define lk_map_size     (sizeof(lk_map)/2)
X#endif
X
FRIDAY_NIGHT
echo es.2 completed!
: That's all folks!

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

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

[  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.  Lawrence 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 - edef.h
sed 's/^X//' > edef.h << 'FRIDAY_NIGHT'
X/*	EDEF:		Global variable definitions for
X			MicroEMACS 3.2
X
X			written by Dave G. Conroy
X			modified by Steve Wilhite, George Jones
X			greatly modified by Daniel Lawrence
X*/
X
X/* some global fuction declarations */
X
Xchar *malloc();
X
X#ifdef	maindef
X
X/* for MAIN.C */
X
X/* initialized global definitions */
X
Xint     fillcol = 72;                   /* Current fill column          */
Xshort   kbdm[NKBDM] = {CTLX|')'};       /* Macro                        */
Xchar    pat[NPAT];                      /* Search pattern		*/
Xchar	rpat[NPAT];			/* replacement pattern		*/
Xchar	sarg[NSTRING] = "";		/* string argument for line exec*/
Xint	eolexist = TRUE;		/* does clear to EOL exist	*/
Xint	revexist = FALSE;		/* does reverse video exist?	*/
Xchar	*modename[] = {			/* name of modes		*/
X	"WRAP", "CMODE", "SPELL", "EXACT", "VIEW", "OVER", "MAGIC"};
Xchar	modecode[] = "WCSEVOM";		/* letters to represent modes	*/
Xint	gmode = 0;			/* global editor mode		*/
Xint	gfcolor = 7;			/* global forgrnd color (white)	*/
Xint	gbcolor	= 0;			/* global backgrnd color (black)*/
Xint     sgarbf  = TRUE;                 /* TRUE if screen is garbage	*/
Xint     mpresf  = FALSE;                /* TRUE if message in last line */
Xint	clexec	= FALSE;		/* command line execution flag	*/
Xint	mstore	= FALSE;		/* storing text to macro flag	*/
Xstruct	BUFFER *bstore = NULL;		/* buffer to store macro text to*/
Xint     vtrow   = 0;                    /* Row location of SW cursor */
Xint     vtcol   = 0;                    /* Column location of SW cursor */
Xint     ttrow   = HUGE;                 /* Row location of HW cursor */
Xint     ttcol   = HUGE;                 /* Column location of HW cursor */
Xint	lbound	= 0;			/* leftmost column of current line
X					   being displayed */
Xint	metac = CTRL | '[';		/* current meta character */
Xint	ctlxc = CTRL | 'X';		/* current control X prefix char */
Xint	quotec = 0x11;			/* quote char during mlreply() */
Xchar	*cname[] = {			/* names of colors		*/
X	"BLACK", "RED", "GREEN", "YELLOW", "BLUE",
X	"MAGENTA", "CYAN", "WHITE"};
XKILL *kbufp  = NULL;		/* current kill buffer chunk pointer	*/
XKILL *kbufh  = NULL;		/* kill buffer header pointer		*/
Xint kused = KBLOCK;		/* # of bytes used in kill buffer	*/
XWINDOW *swindow = NULL;		/* saved window pointer			*/
X
X/* uninitialized global definitions */
X
Xint     currow;                 /* Cursor row                   */
Xint     curcol;                 /* Cursor column                */
Xint     thisflag;               /* Flags, this command          */
Xint     lastflag;               /* Flags, last command          */
Xint     curgoal;                /* Goal for C-P, C-N            */
XWINDOW  *curwp;                 /* Current window               */
XBUFFER  *curbp;                 /* Current buffer               */
XWINDOW  *wheadp;                /* Head of list of windows      */
XBUFFER  *bheadp;                /* Head of list of buffers      */
XBUFFER  *blistp;                /* Buffer for C-X C-B           */
Xshort   *kbdmip;                /* Input pointer for above      */
Xshort   *kbdmop;                /* Output pointer for above     */
X
XBUFFER  *bfind();               /* Lookup a buffer by name      */
XWINDOW  *wpopup();              /* Pop up window creation       */
XLINE    *lalloc();              /* Allocate a line              */
X
X#else
X
X/* for all the other .C files */
X
X/* initialized global external declarations */
X
Xextern  int     fillcol;                /* Fill column                  */
Xextern  short   kbdm[];                 /* Holds kayboard macro data    */
Xextern  char    pat[];                  /* Search pattern               */
Xextern	char	rpat[];			/* Replacement pattern		*/
Xextern	char	sarg[];			/* string argument for line exec*/
Xextern	int	eolexist;		/* does clear to EOL exist?	*/
Xextern	int	revexist;		/* does reverse video exist?	*/
Xextern	char *modename[];		/* text names of modes		*/
Xextern	char	modecode[];		/* letters to represent modes	*/
Xextern	KEYTAB keytab[];		/* key bind to functions table	*/
Xextern	NBIND names[];			/* name to function table	*/
Xextern	int	gmode;			/* global editor mode		*/
Xextern	int	gfcolor;		/* global forgrnd color (white)	*/
Xextern	int	gbcolor;		/* global backgrnd color (black)*/
Xextern  int     sgarbf;                 /* State of screen unknown      */
Xextern  int     mpresf;                 /* Stuff in message line        */
Xextern	int	clexec;			/* command line execution flag	*/
Xextern	int	mstore;			/* storing text to macro flag	*/
Xextern	struct	BUFFER *bstore;		/* buffer to store macro text to*/
Xextern	int     vtrow;                  /* Row location of SW cursor */
Xextern	int     vtcol;                  /* Column location of SW cursor */
Xextern	int     ttrow;                  /* Row location of HW cursor */
Xextern	int     ttcol;                  /* Column location of HW cursor */
Xextern	int	lbound;			/* leftmost column of current line
X					   being displayed */
Xextern	int	metac;			/* current meta character */
Xextern	int	ctlxc;			/* current control X prefix char */
Xextern	int	quotec;			/* quote char during mlreply() */
Xextern	char	*cname[];		/* names of colors		*/
Xextern KILL *kbufp;			/* current kill buffer chunk pointer */
Xextern KILL *kbufh;			/* kill buffer header pointer	*/
Xextern int kused;			/* # of bytes used in KB        */
Xextern WINDOW *swindow;			/* saved window pointer		*/
X
X/* initialized global external declarations */
X
Xextern  int     currow;                 /* Cursor row                   */
Xextern  int     curcol;                 /* Cursor column                */
Xextern  int     thisflag;               /* Flags, this command          */
Xextern  int     lastflag;               /* Flags, last command          */
Xextern  int     curgoal;                /* Goal for C-P, C-N            */
Xextern  WINDOW  *curwp;                 /* Current window               */
Xextern  BUFFER  *curbp;                 /* Current buffer               */
Xextern  WINDOW  *wheadp;                /* Head of list of windows      */
Xextern  BUFFER  *bheadp;                /* Head of list of buffers      */
Xextern  BUFFER  *blistp;                /* Buffer for C-X C-B           */
Xextern  short   *kbdmip;                /* Input pointer for above      */
Xextern  short   *kbdmop;                /* Output pointer for above     */
X
Xextern  BUFFER  *bfind();               /* Lookup a buffer by name      */
Xextern  WINDOW  *wpopup();              /* Pop up window creation       */
Xextern  LINE    *lalloc();              /* Allocate a line              */
X
X#endif
X
X/* terminal table defined only in TERM.C */
X
X#ifndef	termdef
Xextern  TERM    term;                   /* Terminal information.        */
X#endif
X
X
FRIDAY_NIGHT
echo extracting - efunc.h
sed 's/^X//' > efunc.h << 'FRIDAY_NIGHT'
X/*	EFUNC.H:	MicroEMACS function declarations and names
X
X		This file list all the C code functions used by MicroEMACS
X	and the names to use to bind keys to them. To add functions,
X	declare it here in both the extern function list and the name
X	binding table.
X
X*/
X
X/*	External function declarations		*/
X
Xextern  int     ctrlg();                /* Abort out of things          */
Xextern  int     quit();                 /* Quit                         */
Xextern  int     ctlxlp();               /* Begin macro                  */
Xextern  int     ctlxrp();               /* End macro                    */
Xextern  int     ctlxe();                /* Execute macro                */
Xextern  int     fileread();             /* Get a file, read only        */
Xextern  int     filefind();		/* Get a file, read write       */
Xextern  int     filewrite();            /* Write a file                 */
Xextern  int     filesave();             /* Save current file            */
Xextern  int     filename();             /* Adjust file name             */
Xextern  int     getccol();              /* Get current column           */
Xextern  int     gotobol();              /* Move to start of line        */
Xextern  int     forwchar();             /* Move forward by characters   */
Xextern  int     gotoeol();              /* Move to end of line          */
Xextern  int     backchar();             /* Move backward by characters  */
Xextern  int     forwline();             /* Move forward by lines        */
Xextern  int     backline();             /* Move backward by lines       */
Xextern  int     forwpage();             /* Move forward by pages        */
Xextern  int     backpage();             /* Move backward by pages       */
Xextern  int     gotobob();              /* Move to start of buffer      */
Xextern  int     gotoeob();              /* Move to end of buffer        */
Xextern  int     setfillcol();           /* Set fill column.             */
Xextern  int     setmark();              /* Set mark                     */
Xextern  int     swapmark();             /* Swap "." and mark            */
Xextern  int     forwsearch();           /* Search forward               */
Xextern  int     backsearch();           /* Search backwards             */
Xextern	int	sreplace();		/* search and replace		*/
Xextern	int	qreplace();		/* search and replace w/query	*/
Xextern  int     showcpos();             /* Show the cursor position     */
Xextern  int     nextwind();             /* Move to the next window      */
Xextern  int     prevwind();             /* Move to the previous window  */
Xextern  int     onlywind();             /* Make current window only one */
Xextern  int     splitwind();            /* Split current window         */
Xextern  int     mvdnwind();             /* Move window down             */
Xextern  int     mvupwind();             /* Move window up               */
Xextern  int     enlargewind();          /* Enlarge display window.      */
Xextern  int     shrinkwind();           /* Shrink window.               */
Xextern  int     listbuffers();          /* Display list of buffers      */
Xextern  int     usebuffer();            /* Switch a window to a buffer  */
Xextern  int     killbuffer();           /* Make a buffer go away.       */
Xextern  int     reposition();           /* Reposition window            */
Xextern  int     refresh();              /* Refresh the screen           */
Xextern  int     twiddle();              /* Twiddle characters           */
Xextern  int     tab();                  /* Insert tab                   */
Xextern  int     newline();              /* Insert CR-LF                 */
Xextern  int     indent();               /* Insert CR-LF, then indent    */
Xextern  int     openline();             /* Open up a blank line         */
Xextern  int     deblank();              /* Delete blank lines           */
Xextern  int     quote();                /* Insert literal               */
Xextern  int     backword();             /* Backup by words              */
Xextern  int     forwword();             /* Advance by words             */
Xextern  int     forwdel();              /* Forward delete               */
Xextern  int     backdel();              /* Backward delete              */
Xextern  int     killtext();             /* Kill forward                 */
Xextern  int     yank();                 /* Yank back from killbuffer.   */
Xextern  int     upperword();            /* Upper case word.             */
Xextern  int     lowerword();            /* Lower case word.             */
Xextern  int     upperregion();          /* Upper case region.           */
Xextern  int     lowerregion();          /* Lower case region.           */
Xextern  int     capword();              /* Initial capitalize word.     */
Xextern  int     delfword();             /* Delete forward word.         */
Xextern  int     delbword();             /* Delete backward word.        */
Xextern  int     killregion();           /* Kill region.                 */
Xextern  int     copyregion();           /* Copy region to kill buffer.  */
Xextern  int     spawncli();             /* Run CLI in a subjob.         */
Xextern  int     spawn();                /* Run a command in a subjob.   */
X#if	BSD
Xextern	int	bktoshell();		/* suspend emacs to parent shell*/
Xextern	int	rtfrmshell();		/* return from a suspended state*/
X#endif
Xextern  int     quickexit();            /* low keystroke style exit.    */
Xextern	int	setmode();		/* set an editor mode		*/
Xextern	int	delmode();		/* delete a mode		*/
Xextern	int	gotoline();		/* go to a numbered line	*/
Xextern	int	namebuffer();		/* rename the current buffer	*/
X#if	WORDPRO
Xextern	int	gotobop();		/* go to begining/paragraph	*/
Xextern	int	gotoeop();		/* go to end/paragraph		*/
Xextern	int	fillpara();		/* fill current paragraph	*/
X#endif
Xextern	int	help();			/* get the help file here	*/
Xextern	int	deskey();		/* describe a key's binding	*/
Xextern	int	viewfile();		/* find a file in view mode	*/
Xextern	int	insfile();		/* insert a file		*/
Xextern	int	scrnextup();		/* scroll next window back	*/
Xextern	int	scrnextdw();		/* scroll next window down	*/
Xextern	int	bindtokey();		/* bind a function to a key	*/
Xextern	int	unbindkey();		/* unbind a key's function	*/
Xextern	int	namedcmd();		/* execute named command	*/
Xextern	int	desbind();		/* describe bindings		*/
Xextern	int	execcmd();		/* execute a command line	*/
Xextern	int	execbuf();		/* exec commands from a buffer	*/
Xextern	int	execfile();		/* exec commands from a file	*/
Xextern	int	nextbuffer();		/* switch to the next buffer	*/
X#if	WORDPRO
Xextern	int	killpara();		/* kill the current paragraph	*/
X#endif
Xextern	int	setgmode();		/* set a global mode		*/
Xextern	int	delgmode();		/* delete a global mode		*/
Xextern	int	insspace();		/* insert a space forword	*/
Xextern	int	forwhunt();		/* hunt forward for next match	*/
Xextern	int	backhunt();		/* hunt backwards for next match*/
Xextern	int	pipe();			/* pipe command into buffer	*/
Xextern	int	filter();		/* filter buffer through dos	*/
Xextern	int	delwind();		/* delete the current window	*/
Xextern	int	cbuf1();		/* execute numbered comd buffer */
Xextern	int	cbuf2();
Xextern	int	cbuf3();
Xextern	int	cbuf4();
Xextern	int	cbuf5();
Xextern	int	cbuf6();
Xextern	int	cbuf7();
Xextern	int	cbuf8();
Xextern	int	cbuf9();
Xextern	int	cbuf10();
Xextern	int	cbuf11();
Xextern	int	cbuf12();
Xextern	int	cbuf13();
Xextern	int	cbuf14();
Xextern	int	cbuf15();
Xextern	int	cbuf16();
Xextern	int	cbuf17();
Xextern	int	cbuf18();
Xextern	int	cbuf19();
Xextern	int	cbuf20();
Xextern	int	cbuf21();
Xextern	int	cbuf22();
Xextern	int	cbuf23();
Xextern	int	cbuf24();
Xextern	int	cbuf25();
Xextern	int	cbuf26();
Xextern	int	cbuf27();
Xextern	int	cbuf28();
Xextern	int	cbuf29();
Xextern	int	cbuf30();
Xextern	int	cbuf31();
Xextern	int	cbuf32();
Xextern	int	cbuf33();
Xextern	int	cbuf34();
Xextern	int	cbuf35();
Xextern	int	cbuf36();
Xextern	int	cbuf37();
Xextern	int	cbuf38();
Xextern	int	cbuf39();
Xextern	int	cbuf40();
Xextern	int	storemac();		/* store text for macro		*/
Xextern	int	resize();		/* resize current window	*/
Xextern	int	clrmes();		/* clear the message line	*/
Xextern	int	meta();			/* meta prefix dummy function	*/
Xextern	int	cex();			/* ^X prefix dummy function	*/
Xextern	int	istring();		/* insert string in text	*/
Xextern	int	unmark();		/* unmark current buffer	*/
X#if	ISRCH
Xextern	int	fisearch();		/* forward incremental search	*/
Xextern	int	risearch();		/* reverse incremental search	*/
X#endif
X#if	WORDPRO
Xextern	int	wordcount();		/* count words in region	*/
X#endif
Xextern	int	savewnd();		/* save current window		*/
Xextern	int	restwnd();		/* restore current window	*/
Xextern	int	upscreen();		/* force screen update		*/
Xextern	int	writemsg();		/* write text on message line	*/
X
X/*	Name to function binding table
X
X		This table gives the names of all the bindable functions
X	end their C function address. These are used for the bind-to-key
X	function.
X*/
X
XNBIND	names[] = {
X	{"add-mode",			setmode},
X	{"add-global-mode",		setgmode},
X	{"backward-character",		backchar},
X	{"begin-macro",			ctlxlp},
X	{"begining-of-file",		gotobob},
X	{"begining-of-line",		gotobol},
X	{"bind-to-key",			bindtokey},
X	{"buffer-position",		showcpos},
X	{"case-region-lower",		lowerregion},
X	{"case-region-upper",		upperregion},
X	{"case-word-capitalize",	capword},
X	{"case-word-lower",		lowerword},
X	{"case-word-upper",		upperword},
X	{"change-file-name",		filename},
X	{"clear-and-redraw",		refresh},
X	{"clear-message-line",		clrmes},
X	{"copy-region",			copyregion},
X#if	WORDPRO
X	{"count-words",			wordcount},
X#endif
X	{"ctlx-prefix",			cex},
X	{"delete-blank-lines",		deblank},
X	{"delete-buffer",		killbuffer},
X	{"delete-mode",			delmode},
X	{"delete-global-mode",		delgmode},
X	{"delete-next-character",	forwdel},
X	{"delete-next-word",		delfword},
X	{"delete-other-windows",	onlywind},
X	{"delete-previous-character",	backdel},
X	{"delete-previous-word",	delbword},
X	{"delete-window",		delwind},
X	{"describe-bindings",		desbind},
X	{"describe-key",		deskey},
X	{"end-macro",			ctlxrp},
X	{"end-of-file",			gotoeob},
X	{"end-of-line",			gotoeol},
X	{"exchange-point-and-mark",	swapmark},
X	{"execute-buffer",		execbuf},
X	{"execute-command-line",	execcmd},
X	{"execute-file",		execfile},
X	{"execute-macro",		ctlxe},
X	{"execute-macro-1",		cbuf1},
X	{"execute-macro-2",		cbuf2},
X	{"execute-macro-3",		cbuf3},
X	{"execute-macro-4",		cbuf4},
X	{"execute-macro-5",		cbuf5},
X	{"execute-macro-6",		cbuf6},
X	{"execute-macro-7",		cbuf7},
X	{"execute-macro-8",		cbuf8},
X	{"execute-macro-9",		cbuf9},
X	{"execute-macro-10",		cbuf10},
X	{"execute-macro-11",		cbuf11},
X	{"execute-macro-12",		cbuf12},
X	{"execute-macro-13",		cbuf13},
X	{"execute-macro-14",		cbuf14},
X	{"execute-macro-15",		cbuf15},
X	{"execute-macro-16",		cbuf16},
X	{"execute-macro-17",		cbuf17},
X	{"execute-macro-18",		cbuf18},
X	{"execute-macro-19",		cbuf19},
X	{"execute-macro-20",		cbuf20},
X	{"execute-macro-21",		cbuf21},
X	{"execute-macro-22",		cbuf22},
X	{"execute-macro-23",		cbuf23},
X	{"execute-macro-24",		cbuf24},
X	{"execute-macro-25",		cbuf25},
X	{"execute-macro-26",		cbuf26},
X	{"execute-macro-27",		cbuf27},
X	{"execute-macro-28",		cbuf28},
X	{"execute-macro-29",		cbuf29},
X	{"execute-macro-30",		cbuf30},
X	{"execute-macro-31",		cbuf31},
X	{"execute-macro-32",		cbuf32},
X	{"execute-macro-33",		cbuf33},
X	{"execute-macro-34",		cbuf34},
X	{"execute-macro-35",		cbuf35},
X	{"execute-macro-36",		cbuf36},
X	{"execute-macro-37",		cbuf37},
X	{"execute-macro-38",		cbuf38},
X	{"execute-macro-39",		cbuf39},
X	{"execute-macro-40",		cbuf40},
X	{"execute-named-command",	namedcmd},
X	{"exit-emacs",			quit},
X#if	WORDPRO
X	{"fill-paragraph",		fillpara},
X#endif
X	{"filter-buffer",		filter},
X	{"find-file",			filefind},
X	{"forward-character",		forwchar},
X	{"goto-line",			gotoline},
X	{"grow-window",			enlargewind},
X	{"handle-tab",			tab},
X	{"hunt-forward",		forwhunt},
X	{"hunt-backward",		backhunt},
X	{"help",			help},
X	{"i-shell",			spawncli},
X#if	ISRCH
X	{"incremental-search",		fisearch},
X#endif
X	{"insert-file",			insfile},
X	{"insert-space",		insspace},
X	{"insert-string",		istring},
X#if	WORDPRO
X	{"kill-paragraph",		killpara},
X#endif
X	{"kill-region",			killregion},
X	{"kill-to-end-of-line",		killtext},
X	{"list-buffers",		listbuffers},
X	{"meta-prefix",			meta},
X	{"move-window-down",		mvdnwind},
X	{"move-window-up",		mvupwind},
X	{"name-buffer",			namebuffer},
X	{"newline",			newline},
X	{"newline-and-indent",		indent},
X	{"next-buffer",			nextbuffer},
X	{"next-line",			forwline},
X	{"next-page",			forwpage},
X#if	WORDPRO
X	{"next-paragraph",		gotoeop},
X#endif
X	{"next-window",			nextwind},
X	{"next-word",			forwword},
X	{"open-line",			openline},
X	{"pipe-command",		pipe},
X	{"previous-line",		backline},
X	{"previous-page",		backpage},
X#if	WORDPRO
X	{"previous-paragraph",		gotobop},
X#endif
X	{"previous-window",		prevwind},
X	{"previous-word",		backword},
X	{"query-replace-string",	qreplace},
X	{"quick-exit",			quickexit},
X	{"quote-character",		quote},
X	{"read-file",			fileread},
X	{"redraw-display",		reposition},
X	{"resize-window",		resize},
X	{"restore-window",		restwnd},
X	{"replace-string",		sreplace},
X#if	ISRCH
X	{"reverse-incremental-search",	risearch},
X#endif
X	{"save-file",			filesave},
X	{"save-window",			savewnd},
X	{"scroll-next-up",		scrnextup},
X	{"scroll-next-down",		scrnextdw},
X	{"search-forward",		forwsearch},
X	{"search-reverse",		backsearch},
X	{"select-buffer",		usebuffer},
X	{"set-fill-column",		setfillcol},
X	{"set-mark",			setmark},
X	{"shell-command",		spawn},
X	{"shrink-window",		shrinkwind},
X	{"split-current-window",	splitwind},
X	{"store-macro",			storemac},
X#if	BSD
X	{"suspend-emacs",		bktoshell},
X#endif
X	{"transpose-characters",	twiddle},
X	{"unbind-key",			unbindkey},
X	{"unmark-buffer",		unmark},
X	{"update-screen",		upscreen},
X	{"view-file",			viewfile},
X	{"write-file",			filewrite},
X	{"write-message",		writemsg},
X	{"yank",			yank},
X
X	{"",			NULL}
X};
FRIDAY_NIGHT
echo extracting - emacs.hlp
sed 's/^X//' > emacs.hlp << 'FRIDAY_NIGHT'
X=>		MicroEMACS 3.7 Help screens		(07/02/86)
X
X	M-  means to use the <ESC> key prior to using another key
X	^A  means to use the control key at the same time as the A key
X
X^V or [Pg Dn]     Scroll down		M-< or <HOME>	Begining of file
X^Z or [Pg Up]     Scroll up		M-> or <END>	End of file
X
X-----------------------------------------------------------------------
X=>		(1) MOVING THE CURSOR
X
X^F  Forward character   M-F    Forward word		Keypad arrows
X^B  Backward character  M-B    Backward word		are active!
X^A  Front of line	M-G    Goto a line
X^E  End of line		
X^N  Next line		M-N    Front of paragraph
X^P  Previous line	M-P    End of paragraph
X-----------------------------------------------------------------------
X=>		(2) DELETING & INSERTING
X
X<--             Delete previous character
X^D or <DELETE>  Delete next character
X^C or <INSERT>  Insert a space
XM-<--           Delete previous word
XM-D             Delete next word
X^K              Close (delete) to end of line
X-----------------------------------------------------------------------
X=>		(2a) MORE DELETING & INSERTING
X
X<RETURN>   Insert a newline             <TAB>  Advance to next tab stop
X^J         Insert a newline and indent  M-^W   Delete paragraph
X^O         Open (insert) line
X^W         Delete region between mark (set using M-<spacebar>) and cursor
XM-W        Copy region to kill buffer
X^X ^O      Delete blank lines around cursor
X-----------------------------------------------------------------------
X=>		(3) SEARCHING
X
X^S	Search forward from cursor position.
X^R	Reverse search from cursor position.
X^X S	Forward incremental search
X^X R	Reverse incremental search
X<ALT> S	Search for the next occurence of the last string (IBM-PC only)
X<ALT> R	Search for the last occurence of the last string (IBM-PC only)
X-----------------------------------------------------------------------
X=>		(4) REPLACING
X
XM-R   Replace all instances of first typed-in string with second
X          typed-in string.  End each string with ESC.
XM-^R  Replace with query.  Answer with:
X	^G  cancel			.   exit to entry point
X	!   replace the rest		Y    replace & continue
X	?   Get a list of options	N   no replacement & continue
X-----------------------------------------------------------------------
X=>		(5) CAPITALIZING & TRANSPOSING
X
XM-U	UPPERCASE word
XM-C	Capitalize word		^T	Transpose characters
XM-L	lowercase word
X^X ^L	lowercase region
X^X ^U	uppercase region
X^Q	Quote next entry, so that control codes may be entered into text
X-----------------------------------------------------------------------
X=>		(6) REGIONS & THE KILL BUFFER
X
XM-<spacebar>	set MARK at current position
X^X ^X		eXchange mark and cursor
X
XA REGION will then be continuously-defined as the area between the mark and
Xthe current cursor position.  The KILL BUFFER is the text which has been
Xmost recently saved or deleted.
X-----------------------------------------------------------------------
X=>		(7) COPYING AND MOVING
X
X^W  Delete (Wipe) region		M-W	copy region to KILL buffer
X^Y  Yankback save buffer at cursor
XGenerally, the procedure for copying or moving text is:
X    1)  Mark a REGION using M-<spacebar> at beginning and cursor at end.
X    2)  Delete it (with ^W) or copy it (with M-W) into the KILL buffer.
X    3)  Move the cursor to the desired location and yank it back (with ^Y).
X-----------------------------------------------------------------------
X=>		(8) MODES OF OPERATION
X^X M	Add mode in buffer              M-M    Add global mode
X^X ^M   Delete mode in buffer           M-^M   Delete global mode
XOVER		Replaces (overwrites) rather than inserts characters
XWRAP		Turns on word wrap (automatic carraige return).
XVIEW		Allows viewing file without insertion and deletion.
XCMODE		Automatic indenting for C program entry
XEXACT/MAGIC	Changes how search and replace commands work (see next page)
X-----------------------------------------------------------------------
X=>		(9) SEARCH AND REPLACE MODES
X
XEXACT	Uppper/lower case is not ignored in searches
XMAGIC   Regular pattern matching characters are active
X           ?   Matches any one character
X           *   Matches any sequence of characters
X	[EXACT MODE NOT READY YET ---- 6/5/86]
X
X-----------------------------------------------------------------------
X=>		(10) ON-SCREEN FORMATTING
X
X^X F		Set fill column
XMn-<tab>	Set tab spacing to n charecters between tabs stops
XM-Q		Format paragraph so that text lies between margins
X^X =		Position report -- displays line number, char count,
X                                   file size and character under cursor
XM-^C		Count words/lines/chars in marked region
X-----------------------------------------------------------------------
X=>		(11) MULTIPLE WINDOWS
X
XMany WINDOWS may be active at once on the screen.  All windows may show
Xdifferent parts of the same buffer, or each may display a different one.
X^X 2	Split the current window in two	^X O	Change to next window
X^X 0    delete current window           ^X P    Change to previous window
X^X 1	delete all other windows        M-^V    Page down next window
X                                  	M-^Z	Page up other window
X-----------------------------------------------------------------------
X=>		(12) CONTROLLING WINDOWS
X
X^X ^    Enlarge current window   M-<n> ^X W   Resize window to <n> lines
X^X ^Z   Shrink current window
X^X ^N   Move window down
X^X ^P   Move window up
XM-^L    Reposition window
X^L      Refresh the screen
X-----------------------------------------------------------------------
X=>		(13) MULTIPLE BUFFERS
XA BUFFER is a named area containing a document being edited.  Many buffers
Xmay be activated at once.
X^X B	Switch to another buffer.  <CR> = use just-previous buffer
X^X X	Switch to next buffer in buffer list
XM-^N    Change name of current buffer
X^X K	Delete a non-displayed buffer.
X^X ^B	Display buffer directory in a window
X-----------------------------------------------------------------------
X=>		(14) READING FROM DISK
X
X^X ^F	Find file; read into a new buffer created from filename.
X	(This is the usual way to begin editing a new file.)
X^X ^R	Read file into current buffer, erasing its previous contents.
X	No new buffer will be created.
X^X ^I	Insert file into current buffer at cursor's location.
X^X ^V	Find a file to make current in VIEW mode
X-----------------------------------------------------------------------
X=>		(15) SAVING TO DISK
X
X^X ^S	Save current buffer to disk
X^X ^W	Write current buffer to disk
X^X N    Change file name of current buffer
XM-Z	Write out all changed buffers and exit MicroEMACS
X
X
X-----------------------------------------------------------------------
X=>		(16) ACCESSING THE OPERATING SYSTEM
X
X^X !	Send one command to the operating system and return
X^X @	Pipe DOS command results to buffer
X^X #	Filter buffer through DOS filter program
X^X C	Start a new command processor under MicroEMACS
X^X D	Suspend MicroEMACS into the background (UNIX BSD4.2 only)
X^X ^C	Exit MicroEMACS
X-----------------------------------------------------------------------
X=>		(17) KEY BINDINGS AND COMMANDS
X
XM-K	Bind a key to a command
XM-^K	Unbind a key from a command
X^X ?	Describe command bound to a key
XM-X	Execute a named (and possibly unbound) command
X{Describe-bindings}
X	Display a list of all commands and key bindings to a buffer
X-----------------------------------------------------------------------
X=>		(18) COMMAND EXECUTION
XCommands can be specified as command lines in the form:
X	<optional repeat count> {command-name} <optional arguments>
X{Execute-command-line}	execute a typed in command line
X{Execute-buffer}	executes commands lines in a buffer
X{Execute-file}		executes command lines from a file
X{clear-message-line}	clears the message line during execution
X   M-~			clears the change flag for a buffer
X-----------------------------------------------------------------------
X=>		(19) MACRO EXECUTION
X
X^X (	Start recording keyboard macro
X^X )	Stop recording keyboard macro
X^X E	Execute keyboard macro
XM-<n> {store-macro}	Start recording named macro
X      [end]		Stop recording named macro
X{execute-macro-n}	Execute macro n (where n is from 1 to 20)
X-----------------------------------------------------------------------
X=>		(20) SPECIAL KEYS
X
X^G		Cancel current command and return to top level of processing.
X^U or		Universal repeat.  May be followed by an integer (default = 4)
XM-<digit>	and repeats the next command that many times.
XM-X		Execute a named (and possibly unbound) command
X
X
FRIDAY_NIGHT
echo extracting - emacs.key
sed 's/^X//' > emacs.key << 'FRIDAY_NIGHT'
X		Default Key Bindings for MicroEmacs 3.7		(06/05/86)
X		========================================
X
X ^A   Move to start of line           
X ^B   Move backward by characters     ESC B   Backup by words
X ^C   Insert space                    ESC C   Initial capitalize word
X ^D   Forward delete                  ESC D   Delete forward word
X ^E   Goto end of line                     
X ^F   Move forward by characters      ESC F   Advance by words
X ^G   Abort out of things             ESC G   Go to a line
X ^H   Backward delete                 
X ^I   Insert tab/Set tab stops
X ^J   Insert CR-LF, then indent                     
X ^K   Kill forward                    ESC K   Bind Key to function
X ^L   Refresh the screen              ESC L   Lower case word
X ^M   Insert CR-LF                    ESC M   Add global mode
X ^N   Move forward by lines           ESC N   Goto End paragraph
X ^O   Open up a blank line            
X ^P   Move backward by lines          ESC P   Goto Begining of paragraph
X ^Q   Insert literal                  ESC Q   Fill current paragraph
X ^R   Search backwards                ESC R   Search and replace
X ^S   Search forward
X ^T   Transpose characters                     
X ^U   Repeat command four times       ESC U   Upper case word
X ^V   Move forward by pages           ESC V   Move backward by pages
X ^W   Kill region                     ESC W   Copy region to kill buffer
X ^Y   Yank back from killbuffer       ESC X   Execute named command
X ^Z   Move backward by pages          ESC Z   Save all buffers and exit
X
X ESC ^C   Count words in region       ESC ~   Unmark current buffer
X ESC ^H   Delete backward word        ESC !   Reposition window
X ESC ^K   Unbind Key from function    ESC <   Move to start of buffer
X ESC ^L   Reposition window           ESC >   Move to end of buffer
X ESC ^M   Delete global mode          ESC .   Set mark
X ESC ^N   Rename current buffer       ESC space    Set mark
X ESC ^R   Search & replace w/query    ESC rubout   Delete backward word
X ESC ^V   Scroll next window down         rubout   Backward delete       
X ESC ^W   Delete Paragraph
X ESC ^Z   Scroll next window up
X
X ^X ?   Describe a key             ^X !   Run 1 command in a subjob
X ^X =   Show the cursor position   ^X @   Pipe DOS command to buffer
X ^X ^   Enlarge display window     ^X #   Filter buffer thru DOS filter
X ^X 0   Delete current window      ^X (   Begin macro
X ^X 1   Delete other windows       ^X )   End macro
X ^X 2   Split current window
X
X ^X ^B   Display buffer list       ^X B   Switch a window to a buffer
X ^X ^C   Exit MicroEMACS           ^X C   Start a new command processer
X                                   ^X D   Suspend MicroEMACS (BSD4.2 only)
X                                   ^X E   Execute macro
X ^X ^F   Find file                 ^X F   Set fill column
X ^X ^I   Insert file
X                                   ^X K   Delete buffer
X ^X ^L   Lower case region
X ^X ^M   Delete Mode               ^X M   Add a mode
X ^X ^N   Move window down          ^X N   Rename current filename
X ^X ^O   Delete blank lines        ^X O   Move to the next window
X ^X ^P   Move window up            ^X P   Move to the previous window
X ^X ^R   Get a file from disk      ^X R   Incremental reverse search
X ^X ^S   Save current file         ^X S   Incremental forward search
X ^X ^U   Upper case region
X ^X ^V   View file
X ^X ^W   Write a file to disk      ^X W   resize Window
X ^X ^X   Swap "." and mark         ^X X   Use next buffer
X ^X ^Z   Shrink window             ^X Z   Enlarge display window
X
XOnly under PCDOS:
X <ALT>-S Hunt forward        SHIFT <F1> - <F10>
X <ALT>-R Hunt backward           Execute macroes 1 - 10
X
XUnbound commands:
X=================
Xdescribe-bindings	pull the list of current bindings into a window
Xclear-message-line      clears the message line (for in macroes)
Xexecute-buffer		execute a buffer od command lines
Xexecute-command-line	execute a command line (n <command> <args>)
Xexecute-file		execute a file of command lines
Xexecute-named-command	execute a command by name (w/command completion)
Xexecute-macro-[1-20]	execute macroes 1 thru 20
Xhunt-forward		find next occurance of search string
Xhunt-backward		find last occurance of search string
X
XUsable Modes
X============
XWRAP     Lines going past right margin "wrap" to a new line
XVIEW     Read-Only mode where no modifications are allowed
XCMODE    Change behavior of some commands to work with C better
XEXACT    Exact case matching on search strings
XOVER     Overwrite typed characters instead of inserting them
XMAGIC    Use regular expresion matching in searches [NOT READY YET]
X
XWHITE/CYAN/MAGENTA/YELLOW/BLUE/RED/GREEN/BLACK	Sets foreground color
Xwhite/cyan/magenta/yellow/blue/red/green/black	Sets background color
FRIDAY_NIGHT
echo extracting - emacs.rc
sed 's/^X//' > emacs.rc << 'FRIDAY_NIGHT'
X;	EMACS.RC:	Startup file for MicroEMACS 3.4
X;
X;			This file is executed everytime the
X;			editor is entered
X
X;	***** Rebind the Function key group
X
Xbind-to-key execute-named-command	FN;
Xbind-to-key execute-file		FN<
Xbind-to-key hunt-forward		FN=
Xbind-to-key hunt-backward		FN>
Xbind-to-key next-window			FN?
Xbind-to-key execute-macro		FN@
Xbind-to-key find-file			FNA
Xbind-to-key view-file			FNB
Xbind-to-key save-file			FNC
Xbind-to-key exit-emacs			FND
X
X;	set screen colors
Xadd-global-mode "blue"
X
X;	Enter Help
X1 store-macro
X	help
X	8 resize-window
X	bind-to-key execute-macro-12 FNI
X	bind-to-key execute-macro-13 FNQ
X	bind-to-key execute-macro-11 FNT
X	add-mode "red"
X	begining-of-file
X	2 forward-character
X	clear-message-line
X[end]
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;	Exit Help
X11 store-macro
X	bind-to-key previous-page FNI
X	bind-to-key next-page FNQ
X	bind-to-key execute-macro-1 FNT
X	delete-window
X	clear-message-line
X[end]
X
X;	last help page
X12 store-macro
X	begining-of-line
X	search-reverse "=>"
X	1 redraw-display
X[end]
X
X;	next help page
X13 store-macro
X	begining-of-line
X	2 forward-character
X	search-forward "=>"
X	1 redraw-display
X[end]
X
X;	bring up the function key window
X
X	2 split-current-window
X	select-buffer "Function Keys"
X	add-mode "red"
X	2 resize-window
X	insert-string "F1 exec cmd    F2  exec file   F3 hunt       F4  back hunt     F5  next window"
X	newline
X	insert-string "F6 exec macro  F7  find file   F8 view file  F9  save file     F10 exit emacs"
X	begining-of-file
X	unmark-buffer
X	next-window
FRIDAY_NIGHT
echo es.3 completed!
: That's all folks!