home *** CD-ROM | disk | FTP | other *** search
- /*
- * Name: MicroEMACS
- * Mainline, macro commands.
- * Version: 29
- * Last edit: 05-Feb-86
- * By: rex::conroy
- * decvax!decwrl!dec-rhea!dec-rex!conroy
- */
- #include "def.h"
-
- int thisflag; /* Flags, this command */
- int lastflag; /* Flags, last command */
- int curgoal; /* Goal column */
- BUFFER *curbp; /* Current buffer */
- WINDOW *curwp; /* Current window */
- BUFFER *bheadp; /* BUFFER listhead */
- WINDOW *wheadp; /* WINDOW listhead */
- BUFFER *blistp; /* Buffer list BUFFER */
- short kbdm[NKBDM] = (KCTLX|')'); /* Macro */
- short *kbdmip; /* Input for above */
- short *kbdmop; /* Output for above */
- char pat[NPAT]; /* Pattern */
- SYMBOL *symbol[NSHASH]; /* Symbol table listhead. */
- SYMBOL *binding[NKEYS]; /* Key bindings. */
-
- main(argc, argv)
- char *argv[];
- {
- register int c;
- register int f;
- register int n;
- register int mflag;
- char bname[NBUFN];
-
- strcpy(bname, "main"); /* Get buffer name. */
- if (argc > 1)
- makename(bname, argv[1]);
- vtinit(); /* Virtual terminal. */
- edinit(bname); /* Buffers, windows. */
- keymapinit(); /* Symbols, bindings. */
- if (argc > 1) {
- update();
- readin(argv[1]);
- }
- lastflag = 0; /* Fake last flags. */
- loop:
- update(); /* Fix up the screen. */
- c = getkey();
- if (epresf != FALSE) {
- eerase();
- update();
- }
- f = FALSE;
- n = 1;
- if (c == (KCTRL|'U')) { /* ^U, start argument. */
- f = TRUE;
- n = 4;
- while ((c=getkey()) == (KCTRL|'U'))
- n *= 4;
- if ((c>='0' && c<='9') || c=='-') {
- if (c == '-') {
- n = 0;
- mflag = TRUE;
- } else {
- n = c - '0';
- mflag = FALSE;
- }
- while ((c=getkey())>='0' && c<='9')
- n = 10*n + c - '0';
- if (mflag != FALSE)
- n = -n;
- }
- }
- if (kbdmip != NULL) { /* Save macro strokes. */
- if (c!=(KCTLX|')') && kbdmip>&kbdm[NKBDM-6]) {
- ctrlg(FALSE, 0, KRANDOM);
- goto loop;
- }
- if (f != FALSE) {
- *kbdmip++ = (KCTRL|'U');
- *kbdmip++ = n;
- }
- *kbdmip++ = c;
- }
- execute(c, f, n); /* Do it. */
- goto loop;
- }
-
- /*
- * Command execution. Look up the binding in the the
- * binding array, and do what it says. Return a very bad status
- * if there is no binding, or if the symbol has a type that
- * is not usable (there is no way to get this into a symbol table
- * entry now). Also fiddle with the flags.
- */
- execute(c, f, n)
- {
- register SYMBOL *sp;
- register int status;
-
- if ((sp=binding[c]) != NULL) {
- thisflag = 0;
- status = (*sp->s_funcp)(f, n, c);
- lastflag = thisflag;
- return (status);
- }
- lastflag = 0;
- return (ABORT);
- }
-
- /*
- * Initialize all of the buffers
- * and windows. The buffer name is passed down as
- * an argument, because the main routine may have been
- * told to read in a file by default, and we want the
- * buffer name to be right.
- */
- edinit(bname)
- char bname[];
- {
- register BUFFER *bp;
- register WINDOW *wp;
-
- bp = bfind(bname, TRUE); /* Text buffer. */
- blistp = bcreate(""); /* Special list buffer. */
- wp = (WINDOW *) malloc(sizeof(WINDOW)); /* Initial window. */
- if (bp==NULL || wp==NULL || blistp==NULL)
- abort();
- curbp = bp; /* Current ones. */
- wheadp = wp;
- curwp = wp;
- wp->w_wndp = NULL; /* Initialize window. */
- wp->w_bufp = bp;
- bp->b_nwnd = 1; /* Displayed. */
- wp->w_linep = bp->b_linep;
- wp->w_dotp = bp->b_linep;
- wp->w_doto = 0;
- wp->w_markp = NULL;
- wp->w_marko = 0;
- wp->w_toprow = 0;
- wp->w_ntrows = nrow-2; /* 2 = mode, echo. */
- wp->w_force = 0;
- wp->w_flag = WFMODE|WFHARD; /* Full. */
- }
-
- /*
- * Fancy quit command, as implemented
- * by Jeff. If the current buffer has changed
- * do a write current buffer. Otherwise run a command
- * interpreter in a subjob. Two of these will get you
- * out. Bound to "C-Z".
- */
- jeffexit(f, n, k)
- {
- if ((curbp->b_flag&BFCHG) != 0) /* Changed. */
- return (filesave(f, n, KRANDOM));
- return (spawncli(f, n, KRANDOM)); /* Suspend. */
- }
-
- /*
- * Quit command. If an argument, always
- * quit. Otherwise confirm if a buffer has been
- * changed and not written out. Normally bound
- * to "C-X C-C".
- */
- quit(f, n, k)
- {
- register int s;
-
- if (f != FALSE /* Argument forces it. */
- || anycb() == FALSE /* All buffers clean. */
- || (s=eyesno("Quit")) == TRUE) { /* User says it's OK. */
- vttidy();
- exit(GOOD);
- }
- return (s);
- }
-
- /*
- * Begin a keyboard macro.
- * Error if not at the top level
- * in keyboard processing. Set up
- * variables and return.
- */
- ctlxlp(f, n, k)
- {
- if (kbdmip!=NULL || kbdmop!=NULL) {
- eprintf("Not now");
- return (FALSE);
- }
- eprintf("[Start macro]");
- kbdmip = &kbdm[0];
- return (TRUE);
- }
-
- /*
- * End keyboard macro. Check for
- * the same limit conditions as the
- * above routine. Set up the variables
- * and return to the caller.
- */
- ctlxrp(f, n, k)
- {
- if (kbdmip == NULL) {
- eprintf("Not now");
- return (FALSE);
- }
- eprintf("[End macro]");
- kbdmip = NULL;
- return (TRUE);
- }
-
- /*
- * Execute a macro.
- * The command argument is the
- * number of times to loop. Quit as
- * soon as a command gets an error.
- * Return TRUE if all ok, else
- * FALSE.
- */
- ctlxe(f, n, k)
- {
- register int c;
- register int af;
- register int an;
- register int s;
-
- if (kbdmip!=NULL || kbdmop!=NULL) {
- eprintf("Not now");
- return (FALSE);
- }
- if (n <= 0)
- return (TRUE);
- do {
- kbdmop = &kbdm[0];
- do {
- af = FALSE;
- an = 1;
- if ((c = *kbdmop++) == (KCTRL|'U')) {
- af = TRUE;
- an = *kbdmop++;
- c = *kbdmop++;
- }
- s = TRUE;
- } while (c!=(KCTLX|')') && (s=execute(c, af, an))==TRUE);
- kbdmop = NULL;
- } while (s==TRUE && --n);
- return (s);
- }
-
- /*
- * Abort.
- * Beep the beeper.
- * Kill off any keyboard macro,
- * etc., that is in progress.
- * Sometimes called as a routine,
- * to do general aborting of
- * stuff.
- */
- ctrlg(f, n, k)
- {
- ttbeep();
- if (kbdmip != NULL) {
- kbdm[0] = (KCTLX|')');
- kbdmip = NULL;
- }
- return (ABORT);
- }
-
- /*
- * Display the version. All this does
- * is copy the text in the external "version" array into
- * the message system, and call the message reading code.
- * Don't call display if there is an argument.
- */
- showversion(f, n, k)
- {
- register char **cpp;
- register char *cp;
-
- cpp = &version[0];
- while ((cp = *cpp++) != NULL) {
- if (writemsg(cp) == FALSE)
- return (FALSE);
- }
- if (f != FALSE) /* No display if arg. */
- return (TRUE);
- return (readmsg());
- }
-