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!