home *** CD-ROM | disk | FTP | other *** search
- /*
- * This program is in public domain; written by Dave G. Conroy,
- * substantially modified by Moshe Braner, July 1986.
- * further additions by Dale Schumacher, December 1986.
- * further additions by Dale Schumacher and John Stanley, Sept 1987.
- *
- * Parts of this program:
- * copyright (C) 1986 by Moshe Braner.
- * copyright (C) 1986,1987 by Dale Schumacher.
- * copyright (C) 1987 by John Stanley.
- *
- * Permission is granted to copy and use this program,
- * provided that this copyright notice and the source
- * code for the program are included in each copy,
- * and that it is not sold for profit.
- *
- * This file contains the
- * main driving routine, and some
- * keyboard processing code, for the
- * MicroEMACS screen editor.
- */
-
- #include <stdio.h>
- #include "ed.h"
-
- #if VMS
- #include <ssdef.h>
- #define GOOD (SS$_NORMAL)
- #endif
-
- #if MSDOS
- #include <fcntl.h>
- #endif
-
- #ifndef GOOD
- #define GOOD 0
- #endif
-
- #define BASE 0 /* mb: states of the machine */
- #define ESC 1
- #define ARG 2
- #define EXEC 3
-
- /* NOTE: configurable variables defined the end of this file */
-
- #if AtST
- unsigned long _BLKSIZ = 32768; /* dal: dLibs Malloc() granularity */
- #endif
-
- char vsn[] = VSN; /* dal: version identification */
- int currow = 0; /* Working cursor row */
- int curcol = 0; /* Working cursor column */
- int thisflag = 0; /* Flags, this command */
- int lastflag = 0; /* Flags, last command */
- int curgoal = 0; /* Goal column */
- BUFFER *curbp = NULL; /* Current buffer */
- BUFFER *oldbp = NULL; /* mb: previous buffer */
- WINDOW *curwp = NULL; /* Current window */
- BUFFER *bheadp = NULL; /* BUFFER listhead */
- WINDOW *wheadp = NULL; /* WINDOW listhead */
- BUFFER *blistp = NULL; /* Buffer list BUFFER */
- BUFFER *bhelpp = NULL; /* Help screens BUFFER */
- BUFFER *bdirp = NULL; /* dal: Directory BUFFER */
- int kbdm[NKBDM]; /* Macro */
- int *kbdmip = NULL; /* Input for above */
- int *kbdmop = NULL; /* Output for above */
- char pat[NPAT]; /* Pattern */
-
- typedef struct
- {
- int k_code; /* Key code */
- int (*k_fp)(); /* Routine to handle it */
- }
- KEYTAB;
-
- extern int quit(); /* Quit */
- extern int ctlxlp(); /* Begin macro */
- extern int ctlxrp(); /* End macro */
- extern int ctlxe(); /* Execute macro */
- extern int fileread(); /* Get a file, read only */
- extern int filevisit(); /* Get a file, read write */
- extern int filewrite(); /* Write a file */
- extern int filesave(); /* Save current file */
- extern int filename(); /* Adjust file name */
- extern int getccol(); /* Get current column */
- extern int gotobol(); /* Move to start of line */
- extern int forwchar(); /* Move forward by characters */
- extern int gotoeol(); /* Move to end of line */
- extern int backchar(); /* Move backward by characters */
- extern int forwline(); /* Move forward by lines */
- extern int backline(); /* Move backward by lines */
- extern int forwpage(); /* Move forward by pages */
- extern int backpage(); /* Move backward by pages */
- extern int gotobob(); /* Move to start of buffer */
- extern int gotoeob(); /* Move to end of buffer */
- extern int setfillcol(); /* Set fill column. */
- extern int setlmargin(); /* mb: added */
- extern int reformat(); /* mb: added */
- extern int setmark(); /* Set mark */
- extern int swapmark(); /* Swap "." and mark */
- extern int forwsearch(); /* Search forward */
- extern int backsearch(); /* Search backwards */
- extern int showcpos(); /* Show the cursor position */
- extern int nextwind(); /* Move to the next window */
- extern int prevwind(); /* Move to the previous window */
- extern int onlywind(); /* Make current window only one */
- extern int splitwind(); /* Split current window */
- extern int mvdnwind(); /* Move window down */
- extern int mvupwind(); /* Move window up */
- extern int enlargewind(); /* Enlarge display window. */
- extern int listbuffers(); /* Display list of buffers */
- extern int usebuffer(); /* Switch a window to a buffer */
- extern int jumpbuffer(); /* dal: Jump to next buffer */
- extern int killbuffer(); /* Make a buffer go away. */
- extern int reposition(); /* Reposition window */
- extern int refresh(); /* Refresh the screen */
- extern int twiddle(); /* Twiddle characters */
- extern int ltwiddle(); /* Twiddle lines - mb: added */
- extern int tab(); /* Insert tab */
- extern int newline(); /* Insert CR-LF */
- extern int indent(); /* Insert CR-LF, then indent */
- extern int indtog(); /* dal: toggle autoindent */
- extern int ctrlm(); /* dal: newline()/indent() */
- extern int ctrlj(); /* dal: indent()/newline() */
- extern int openline(); /* Open up a blank line */
- extern int deblank(); /* Delete blank lines */
- extern int backword(); /* Backup by words */
- extern int forwword(); /* Advance by words */
- extern int forwdel(); /* Forward delete */
- extern int backdel(); /* Backward delete */
- extern int kill(); /* Kill forward */
- extern int yank(); /* Yank back from killbuffer. */
- extern int unyank(); /* mb: added */
- extern int upperword(); /* Upper case word */
- extern int lowerword(); /* Lower case word */
- extern int upperregion(); /* Upper case region */
- extern int lowerregion(); /* Lower case region */
- extern int capword(); /* Initial capitalize word */
- extern int delfword(); /* Delete forward word */
- extern int delbword(); /* Delete backward word */
- extern int killregion(); /* Kill region */
- extern int copyregion(); /* Copy region to kill buffer */
- extern int spawncli(); /* Run CLI in a subjob */
- extern int spawn1(); /* Run a command in a subjob */
- extern int quickexit(); /* low keystroke style exit */
- extern int wrapword(); /* mb: added the rest, */
- extern int help(); /* just in case */
- extern int forw_brace();
- extern int back_brace();
- extern int instog();
- extern int editog();
- extern int visitog();
- extern int gotolinum();
- extern int forwparag();
- extern int backparag();
- extern int renambuf();
- extern int page_nextw();
- extern int back_nextw();
- extern int flush_kbuf();
- extern int emacs_quit(); /* fwd ref */
- extern int _stop(); /* fwd ref */
- extern int ctrlg(); /* fwd ref */
- extern int undo(); /* fwd ref */
- extern int bkill(); /* fwd ref */
- extern int defmacro(); /* fwd ref */
- #if AtST
- extern int mousemode(); /* dal: fwd ref */
- extern int mfnleft(); /* dal: fwd ref */
- extern int mfnright(); /* dal: fwd ref */
- extern int dxmouse(); /* dal: added */
- extern int dymouse(); /* dal: added */
- #endif
- extern int save_cfg(); /* dal: fwd ref */
-
- /*
- * Command table.
- * This table is *roughly* in ASCII
- * order, left to right across the characters
- * of the command. This expains the funny
- * location of the control-X commands.
- */
- KEYTAB keytab[] =
- {
- CNTL|'@', _stop, /* dal: do nothing */
- CNTL|'A', gotobol,
- CNTL|'B', backchar,
- CNTL|'C', quit, /* mb: was C-X C-C */
- ED|CNTL|'D', forwdel,
- CNTL|'E', gotoeol,
- CNTL|'F', forwchar,
- CNTL|'G', undo,
- ED|CNTL|'H', backdel,
- ED|CNTL|0x3F, forwdel, /* mb: DELETE key */
- /* ED|CNTL|0x3F, backdel, - if you want DEL=BS */
- ED|CNTL|'I', tab,
- ED|CNTL|'J', ctrlj,
- ED|CNTL|'K', kill,
- CNTL|'L', refresh,
- ED|CNTL|'M', ctrlm,
- CNTL|'N', forwline,
- ED|CNTL|'O', openline,
- CNTL|'P', backline,
- #if V7
- /* skip these */
- #else
- CNTL|'S', forwsearch,
- #endif
- CNTL|'R', backsearch,
- ED|CNTL|'T', twiddle,
- CNTL|'V', forwpage,
- ED|CNTL|'W', killregion,
- ED|CNTL|'Y', yank,
- CNTL|'Z', quickexit, /* quick save and exit */
- CTLX|CNTL|'C', spawncli, /* Run CLI in subjob. */
- CTLX|CNTL|'E', editog, /* mb: added */
- CTLX|CNTL|'F', filename,
- CTLX|CNTL|'B', renambuf, /* mb: added */
- CTLX|CNTL|'R', fileread,
- #if V7
- /* skip */
- #else
- ED|CTLX|CNTL|'S', filesave,
- #endif
- CTLX|CNTL|'I', indtog, /* dal: added */
- ED|CTLX|CNTL|'T', ltwiddle, /* mb: added */
- CTLX|CNTL|'V', filevisit,
- ED|CTLX|CNTL|'W', filewrite,
- CTLX|CNTL|'X', swapmark,
- ED|CTLX|CNTL|'Y', unyank, /* mb: added */
- CTLX|CNTL|'Z', emacs_quit,
- CTLX|' ', setmark,
- CTLX|'?', listbuffers,
- CTLX|'!', spawn1,
- CTLX|'=', showcpos,
- CTLX|'(', ctlxlp,
- CTLX|')', ctlxrp,
- CTLX|'1', onlywind,
- CTLX|'2', splitwind,
- CTLX|'B', usebuffer,
- CTLX|'E', ctlxe,
- ED|CTLX|'F', reformat, /* mb: added */
- CTLX|'I', indtog, /* dal: added */
- CTLX|'J', jumpbuffer, /* dal: added */
- CTLX|'K', killbuffer,
- CTLX|'L', setlmargin, /* mb: added */
- CTLX|'M', defmacro, /* mb: added */
- CTLX|'N', nextwind,
- CTLX|'O', nextwind, /* mb: EMACS-like */
- CTLX|'P', prevwind,
- CTLX|'Q', visitog, /* mb: added */
- CTLX|'R', setfillcol,
- ED|CTLX|'S', filesave, /* mb: instead of ^X^S */
- CTLX|'V', page_nextw, /* mb: added */
- CTLX|'Y', flush_kbuf, /* dal: instead of META-Y */
- CTLX|'Z', back_nextw, /* mb: added */
- META|'!', reposition,
- #if VT100
- /* skip this - it clashes with function key codes */
- #else
- #if LK201
- /* skip */
- #else
- META|']', forw_brace, /* mb: added */
- META|'[', back_brace, /* mb: added */
- #endif
- #endif
- META|CNTL|'C', save_cfg, /* dal: added */
- META|')', forw_brace, /* mb: added */
- META|'}', forw_brace, /* mb: added */
- META|'{', back_brace, /* mb: added */
- META|'(', back_brace, /* mb: added */
- META|'.', setmark,
- META|' ', setmark,
- META|'>', gotoeob,
- META|'<', gotobob,
- META|'B', backword,
- META|'F', forwword,
- META|'G', gotolinum, /* mb: added */
- META|'I', instog, /* mb: added */
- META|'R', backsearch,
- META|'S', forwsearch,
- META|'V', backpage,
- META|'W', copyregion,
- #if AtST
- META|'M', mousemode, /* dal: added */
- META|'X', dxmouse, /* dal: added */
- META|'Y', dymouse, /* dal: added */
- #endif
-
- #if EXTRA
-
- ED|CTLX|CNTL|'L', lowerregion,
- CTLX|CNTL|'N', mvdnwind,
- ED|CTLX|CNTL|'O', deblank,
- CTLX|CNTL|'P', mvupwind,
- ED|CTLX|CNTL|'U', upperregion,
- CTLX|'^', enlargewind,
- ED|META|CNTL|'H', delbword,
- ED|META|'C', capword,
- ED|META|'D', delfword,
- ED|META|'L', lowerword,
- META|'N', forwparag, /* mb: added */
- META|'P', backparag, /* mb: added */
- ED|META|'U', upperword,
- ED|META|CNTL|0x3F, delbword,
-
- #endif /* EXTRA */
-
- /* JLS: 9/8/87 - Common keytable for MS-DOS and Atari ST */
- #if AtST|MSDOS /* mb: added */
-
- FUNC|0x4B, backchar, /* <-- */
- FUNC|SHFT|0x4B, backword,
- FUNC|META|0x4B, gotobol,
- FUNC|SHFT|0x73, gotobol,
- FUNC|0x4D, forwchar, /* --> */
- FUNC|SHFT|0x4D, forwword,
- FUNC|META|0x4D, gotoeol,
- FUNC|SHFT|0x74, gotoeol,
- FUNC|0x50, forwline,
- FUNC|0x48, backline,
- #if EXTRA
- FUNC|SHFT|0x50, mvdnwind,
- FUNC|ALT|SHFT|0x50, forwpage, /* dal: added, see ttgetc() */
- FUNC|META|0x50, forwparag,
- FUNC|SHFT|0x48, mvupwind,
- FUNC|ALT|SHFT|0x48, backpage, /* dal: added, see ttgetc() */
- FUNC|META|0x48, backparag,
- #endif
- FUNC|0x61, undo, /* Undo */
- FUNC|SHFT|0x61, flush_kbuf,
- ED|FUNC|0x53, forwdel, /* Del */
- ED|FUNC|SHFT|0x53, kill,
- ED|FUNC|0x0E, backdel, /* Backspace */
- ED|FUNC|SHFT|0x0E, bkill,
- #if EXTRA
- ED|FUNC|META|0x53, delfword, /* Delete */
- ED|FUNC|META|0x0E, delbword, /* Backspace */
- #endif
- #if MSDOS
- FUNC|'I', backpage, /* Pg Up */
- FUNC|'Q', forwpage, /* Pg Dn */
- FUNC|'O', jumpbuffer, /* End */
- #endif
- FUNC|'G', reposition, /* Clr/Home */
- FUNC|META|'G', gotobob, /* Esc-Home */
- FUNC|SHFT|0x77, gotoeob, /* Ctrl-Home */
- ED|FUNC|'R', openline, /* Insert */
- #if AtST
- FUNC|ALT|0x74, mfnleft, /* dal: Left mouse button */
- FUNC|ALT|0x75, mfnright, /* dal: Right mouse button */
- #endif
- #if EXTRA
- ED|FUNC|SHFT|0x52, deblank,
- #endif
- FUNC|0x3B, ctlxe, /* F1 */
- FUNC|SHFT|0x3B, defmacro,
- FUNC|0x3C, setmark, /* F2 */
- FUNC|SHFT|0x3C, swapmark,
- FUNC|0x3D, usebuffer, /* F3 */
- FUNC|SHFT|0x3D, filevisit,
- ED|FUNC|0x3E, fileread, /* F4 */
- FUNC|SHFT|0x3E, filewrite,
- ED|FUNC|0x3F, kill, /* F5 */
- ED|FUNC|SHFT|0x3F, killregion,
- ED|FUNC|0x40, yank, /* F6 */
- FUNC|SHFT|0x40, copyregion,
- FUNC|0x41, backsearch, /* F7 */
- FUNC|SHFT|0x41, back_brace,
- FUNC|0x42, forwsearch, /* F8 */
- FUNC|SHFT|0x42, forw_brace,
- FUNC|0x43, backpage, /* F9 */
- FUNC|SHFT|0x43, back_nextw,
- FUNC|0x44, forwpage, /* F10 */
- FUNC|SHFT|0x44, page_nextw,
- #if HELP
- FUNC|0x62, help, /* Help */
- #else
- FUNC|0x62, listbuffers,
- #endif
- FUNC|SHFT|0x62, listbuffers,
- /* Alt to act as Ctrl-X-Ctrl: */
- FUNC|SHFT|0x2E, spawncli, /* Alt-C */
- FUNC|SHFT|0x20, spawn1, /* Alt-D */
- FUNC|SHFT|0x12, editog, /* Alt-E */
- ED|FUNC|SHFT|0x14, ltwiddle, /* Alt-T */
- FUNC|SHFT|0x2D, swapmark, /* Alt-X */
- /* Alt to act as Ctrl-X: */
- FUNC|SHFT|0x83, showcpos,
- FUNC|SHFT|0x78, onlywind,
- FUNC|SHFT|0x79, splitwind,
- FUNC|SHFT|0x30, usebuffer,
- FUNC|SHFT|0x24, jumpbuffer, /* dal: Alt-J */
- ED|FUNC|SHFT|0x21, reformat,
- FUNC|SHFT|0x25, killbuffer,
- FUNC|SHFT|0x26, setlmargin,
- FUNC|SHFT|0x32, defmacro,
- FUNC|SHFT|0x31, nextwind,
- FUNC|SHFT|0x19, prevwind,
- FUNC|SHFT|0x13, setfillcol,
- FUNC|SHFT|0x10, visitog,
- ED|FUNC|SHFT|0x1F, filesave,
- FUNC|SHFT|0x2F, filevisit,
- /* Other Alt- functions: */
- FUNC|SHFT|0x22, gotolinum, /* Alt-G */
- FUNC|SHFT|0x17, instog, /* Alt-I */
- ED|FUNC|SHFT|0x11, filewrite, /* Alt-W */
- ED|FUNC|SHFT|0x18, openline, /* Alt-O */
- FUNC|SHFT|0x80, back_brace, /* Alt-( */
- FUNC|SHFT|0x81, forw_brace, /* Alt-) */
- #if EXTRA
- FUNC|SHFT|0x7D, enlargewind, /* Alt-^ */
- #endif
- /* Still available:
- FUNC|SHFT|0x23, Alt-H
- FUNC|SHFT|0x16, Alt-U
- FUNC|SHFT|0x15, Alt-Y
- FUNC|SHFT|0x2C, Alt-Z
- FUNC|SHFT|0x7A, Alt-3
- FUNC|SHFT|0x7B, Alt-4
- FUNC|SHFT|0x7C, Alt-5
- FUNC|SHFT|0x7E, Alt-7
- FUNC|SHFT|0x7F, Alt-8
- FUNC|SHFT|0x82, Alt '-'
- */
- #endif /* AtST */
-
- #if HELP /* mb: added */
- META|'?', help,
- META|CNTL|'[', help,
- #ifdef HELPCH
- HELPCH, help,
- #endif
- #endif /* HELP */
-
- 0, _stop
- };
-
- #define NKEYTAB (sizeof(keytab)/sizeof(keytab[0]))
-
- main(argc, argv) /* mb: completely rewritten */
- int argc;
- register char *argv[];
- {
- register int c;
- register int f = FALSE;
- register int n = 1;
- register int state;
- register char *p;
- register BUFFER *bp;
- char bname[NBUFN];
- char fname[NFILEN];
- int negarg;
- int view_only = FALSE;
- int wild = FALSE;
- BUFFER *b1 = NULL;
- char *wildcard();
-
- vtinit(); /* dal: do Displays 1st */
- kbdm[0] = CTLX | ')'; /* Empty macro */
- while(wild || --argc)
- {
- if(wild)
- {
- if(p = wildcard(NULL))
- p = strcpy(fname, p);
- else
- {
- wild = FALSE;
- continue;
- }
- }
- else
- {
- p = *++argv;
- if(strchr(p, '*') || strchr(p, '?'))
- {
- if(p = wildcard(p))
- {
- wild = TRUE;
- p = strcpy(fname, p);
- }
- else
- continue;
- }
- }
- if(*p == '-') /* command line switch */
- {
- p += 2;
- switch(tolower(*(p-1)))
- {
- case 'v':
- view_only = TRUE;
- break;
- case 'g':
- if(b1)
- gotolinum(TRUE, atoi(p));
- break;
- }
- }
- /*----------------------------------------------------------------------*/
- else if (b1 == NULL)
- {
- makename(bname, p); /* initial buffer name */
- edinit(bname); /* init buffers, etc. */
- update(); /* draw screen first */
- if(readin(p)==FIOFNF) /* file not found */
- {
- if(view_only)
- mlwrite("[%s not found]", p);
- else
- {
- mlwrite("[New file]");
- fullpath(curbp->b_fname, p);
- }
- }
- else
- fullpath(curbp->b_fname, p);
- if(view_only)
- curbp->b_flag &= ~BFEDIT;
- b1 = curbp;
- }
- else
- {
- makename(bname, p); /* derive buffer name */
- if((bp = bfind(bname, TRUE, BFEDIT)) == NULL)
- continue;
- gotobuf(bp);
- if(readin(p) != FIOEOF)
- {
- gotobuf(oldbp); /* switch back */
- freebuf(oldbp); /* now oldbp == bad */
- continue;
- }
- fullpath(bp->b_fname, p); /* dal: normalize */
- bp->b_flag &= ~(BFTEMP|BFCHG);
- if(view_only)
- bp->b_flag &= ~BFEDIT;
- }
- /*----------------------------------------------------------------------*/
- }
- if(b1 == NULL) /* no initial file */
- {
- strcpy(bname, "main");
- edinit(bname); /* init buffers, etc. */
- mlpending("Hit [%s] for help. [%s] reads a file.",
- (AtST ? "HELP" : "ESC-?"),
- (AtST|MSDOS ? "F4" : "^X^R"));
- }
- else
- gotobuf(b1);
-
- update(); /* draw screen */
- lastflag = 0; /* Fake last flags. */
- negarg = FALSE;
- f = FALSE;
- n = 1;
- update();
- c = getkey();
- mlerase();
- state = BASE;
-
- for(;;) /* main loop */
- {
- switch (state)
- {
-
- case BASE:
- if (c==(CNTL|'U'))
- {
- n = 4;
- mlwrite("arg: 4");
- c = getkey();
- state = ARG;
- break;
- }
- if (c == METACH)
- {
- c = getkey();
- state = ESC;
- break;
- }
- if (c == (CNTL|'X'))
- {
- c = getkey();
- if (c == (CNTL|'G')
- #if AtST
- || c == (FUNC|0x61)
- #endif
- ) /* Undo */
- {
- c = getkey();
- break;
- }
- if (c>='a' && c<='z')
- c -= 0x20; /* force upper case */
- c |= CTLX;
- }
- state = EXEC;
- break;
-
- case ESC:
- if (c=='-' || (c>='0' && c<='9'))
- {
- state = ARG;
- break;
- }
- #if VT100
- if (c=='[' || c=='O')
- {
- state = EXEC;
- c = escseq(c);
- if (! c)
- {
- c = getkey();
- state = BASE;
- }
- break;
- }
- #endif
- #if LK201
- if (c=='[' || c=='O')
- {
- state = EXEC;
- c = escseq(c);
- if (! c)
- {
- c = getkey();
- state = BASE;
- }
- break;
- }
- #endif
- if (c == (CNTL|'G')
- #if AtST
- || c == (FUNC|0x61)
- #endif
- ) /* Undo */
- {
- c = getkey();
- state = BASE;
- break;
- }
- if (c>='a' && c<='z')
- c -= 0x20; /* force upper case */
- c |= META;
- state = EXEC;
- break;
-
- case ARG:
- if (c == (CNTL|'U'))
- {
- n *= 4;
- }
- else if (c=='-' && f==FALSE)
- {
- negarg = TRUE;
- n = (-1);
- }
- else if (c==(CNTL|'H') || c==(CNTL|0x3F)
- #if AtST
- || c==(FUNC|0x0E) || c==(FUNC|0x53)
- #endif
- )
- {
- n /= 10;
- if (n == 0)
- negarg = FALSE;
- }
- else if (c == (FUNC|0x61)
- #if AtST
- || c == (CNTL|'G')
- #endif
- ) /* Undo */
- {
- f = FALSE;
- n = 1;
- mlwrite("[aborted]");
- update(); /* put cursor back */
- c = getkey();
- state = BASE;
- break;
- }
- else if (c>='0' && c<='9')
- {
- if (f == FALSE)
- {
- n = 0;
- f = TRUE;
- }
- n = 10*n + ((negarg) ? ('0'-c) : (c-'0'));
- }
- else
- {
- state = BASE;
- f = TRUE;
- break;
- }
- mlwrite("arg: %d",n);
- c = getkey();
- break;
-
- case EXEC:
- if (c == (CNTL|'Q') || c == (META|'Q'))
- {
- c = (*term.t_getchar)();
- c &= 0xFF;
- }
- #if AtST
- if (c == (FUNC|SHFT|0x1E)) /* Alt-A */
- {
- c = (*term.t_getchar)();
- c &= 0xFF;
- c |= 0x80; /* set MSB: alternate char set */
- }
- #endif
- if (kbdmip != NULL) /* Save macro strokes. */
- {
- if (c!=(CTLX|')') && kbdmip>&kbdm[NKBDM-6])
- {
- ctrlg(FALSE, 0);
- c = getkey();
- state = BASE;
- break;
- }
- if (f != FALSE)
- {
- *kbdmip++ = (CNTL|'U');
- *kbdmip++ = n;
- }
- *kbdmip++ = c;
- }
- execute(c, f, n); /* Do it, finally */
- f = FALSE;
- n = 1;
- negarg = FALSE;
- update(); /* Fix up the screen */
- c = getkey();
- if (mpresf != FALSE)
- {
- mlerase();
- }
- state = BASE;
- break;
-
- default:
- exit(0); /* bug if you're here */
- } /* end of switch */
- } /* end of for() */
- } /* end of main() */
-
- /*
- * 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, BFEDIT); /* First buffer */
- blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer */
- bhelpp = bfind("[Help]", TRUE, BFTEMP); /* Help screens buffer */
- bdirp = bfind("[Dir]", TRUE, BFTEMP); /* dal: Directory buffer*/
- wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */
- if(bp==NULL || wp==NULL || blistp==NULL || bhelpp==NULL || bdirp==NULL)
- exit(1);
- curbp = bp; /* Make this current */
- 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 = term.t_nrow-1; /* "-1" for mode line. */
- wp->w_force = 0;
- wp->w_flag = WFMODE|WFHARD; /* Full. */
- }
-
- #if VT100
- int escseq(c)
- register int c;
- {
- if (c == '[') /* Arrows and extras. */
- {
- c = (*term.t_getchar)();
- if (c == 'A')
- return (CNTL | 'P');
- if (c == 'B')
- return (CNTL | 'N');
- if (c == 'C')
- return (CNTL | 'F');
- if (c == 'D')
- return (CNTL | 'B');
- return (0);
- }
- if (c == 'O')
- {
- c = (*term.t_getchar)();
- if (c == 'P') /* PF1 */
- return (META | 'B');
- if (c == 'Q') /* PF2 */
- return (META | 'F');
- if (c == 'R') /* PF3 */
- return (META | '.');
- if (c == 'S') /* PF4 */
- return (CTLX | 'E');
- return (0);
- }
- }
- #endif
-
- #if LK201
- int escseq(c)
- register int c;
- {
- if (c == '[') /* Arrows and extras. */
- {
- c = (*term.t_getchar)();
- if (c == 'A')
- return (CNTL | 'P');
- if (c == 'B')
- return (CNTL | 'N');
- if (c == 'C')
- return (CNTL | 'F');
- if (c == 'D')
- return (CNTL | 'B');
- if (c>='0' && c<='9')
- {
- i = 0;
- do
- {
- i = 10*i + c - '0';
- c = (*term.t_getchar)();
- }
- while (c>='0' && c<='9');
- if (c=='~' && i<35 && (c=lkmap[i]))
- return (c);
- }
- return (0);
- }
- if (c == 'O')
- {
- c = (*term.t_getchar)();
- if (c == 'P') /* PF1 */
- return (META | 'B');
- if (c == 'Q') /* PF2 */
- return (META | 'F');
- if (c == 'R') /* PF3 */
- return (META | '.');
- if (c == 'S') /* PF4 */
- return (CTLX | 'E');
- return (0);
- }
- }
- #endif
-
- /*
- * This is the general command execution
- * routine. It handles the fake binding of all the
- * keys to "self-insert". It also clears out the "thisflag"
- * word, and arranges to move it to the "lastflag", so that
- * the next command can look at it. Return the status of
- * command.
- * mb: added the BFEDIT / ED stuff.
- */
- execute(c, f, n)
- register int c;
- {
- register KEYTAB *ktp;
- register int k;
- register int d;
- register int status;
-
- if ((c & 0xFF00) == 0)
- goto ascii;
- d = c;
- if (curbp->b_flag & BFEDIT)
- d |= ED;
- ktp = &keytab[0]; /* Look in key table. */
- while (ktp < &keytab[NKEYTAB])
- {
- k = ktp->k_code;
- if (k==c || k==d) /* mb: fit, ED| or not */
- {
- thisflag = 0;
- status = (*ktp->k_fp)(f, n);
- lastflag = thisflag;
- return (status);
- }
- ++ktp;
- }
- if (c != d)
- {
- #if GDEBUG
- mlwrite("No such command (code 0x%x)", c);
- #else
- mlwrite("No such command");
- #endif
- return (FALSE);
- }
- /* else fall thru to "view-only" message */
- ascii:
- if (! (curbp->b_flag & BFEDIT))
- {
- #if AtST
- mlwrite("View-only mode - Alt-E to edit");
- #else
- mlwrite("View-only mode - ^X^E to edit");
- #endif
- lastflag = 0;
- return(FALSE);
- }
-
- #ifdef NEVER /* moved and changed to act on ANY character... */
- /*
- * If a space was typed, fill column is defined, the argument is non-
- * negative, and we are now past fill column, perform word wrap.
- */
- if (c==' ' && fillcol>0 && n>=0 && getccol(FALSE)>fillcol)
- wrapword();
- #endif
- /* mb: skipped the ASCII check */
- if (n <= 0) /* Fenceposts. */
- {
- lastflag = 0;
- return (n<0 ? FALSE : TRUE);
- }
- thisflag = 0; /* For the future. */
- status = linsert(n, c, ovrstrk); /* mb: added param */
- lastflag = thisflag;
- if (fillcol>0 && n>=0 && getccol(FALSE)>fillcol)
- wrapword();
- return (status);
- lastflag = 0; /* Fake last flags. */
- return (FALSE);
- }
-
- indtog()
- /*
- * Toggle auto-indent mode. In auto-indent mode, ^M and ^J swap functions.
- */
- {
- mlwrite("[auto-indent %s]", (autoindent = !autoindent) ? "on" : "off");
- }
-
- /*
- * Read in a key. - mb: very much simplified.
- * Convert ctrl keys to the internal character set.
- */
- getkey()
- {
- register int c;
- register int t;
-
- c = (*term.t_getchar)();
- #ifdef CNTLCH
- if (c == CNTLCH) /* Apply C- prefix */
- {
- c = (*term.t_getchar)();
- c = toupper(c); /* Force to upper */
- c |= CNTL;
- }
- #endif
- /* control -> CNTL */
- t = c & 0x7F;
- if ((!(FUNC & c)) && ((t < 0x20) || (t == 0x7F)))
- c = CNTL | (c ^ 0x40);
- return (c);
- }
-
- /*
- * Fancy quit command, as implemented
- * by Norm. If the current buffer has changed
- * do a write current buffer and exit emacs,
- * otherwise simply exit.
- */
- quickexit(f, n)
- {
- if ((curbp->b_flag & BFCHG) != 0 /* Changed. */
- && (curbp->b_flag & BFTEMP) == 0) /* Real. */
- filesave(f, n);
- quit(f, n); /* conditionally quit */
- }
-
- /*
- * 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)
- {
- register int s;
-
- if (f != FALSE /* Argument forces it. */
- || anycb() == FALSE /* All buffers clean. */
- || (s=mlyesno("Discard changes")) == TRUE) /* User says OK. */
- {
- vttidy();
- exit(GOOD);
- }
- mlwrite("[aborted]");
- return (s);
- }
-
- /* mb: added */
- emacs_quit(f, n)
- {
- if (f)
- return(quickexit(FALSE, 1));
- else
- return(quit(f, n));
- }
-
- /*
- * Begin a keyboard macro.
- * Error if not at the top level
- * in keyboard processing. Set up
- * variables and return.
- */
- ctlxlp(f, n)
-
- {
- if (kbdmip!=NULL || kbdmop!=NULL)
- {
- mlwrite("Not now");
- return (FALSE);
- }
- mlwrite("[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)
- {
- if (kbdmip == NULL)
- {
- mlwrite("Not now");
- return (FALSE);
- }
- *(--kbdmip) = CTLX|')'; /* in case CTLX|'M' */
- mlwrite("[End macro]");
- kbdmip = NULL;
- return (TRUE);
- }
-
- /* mb: added.
- */
- defmacro(f, n)
- {
- if (kbdmip == NULL)
- return (ctlxlp(f, n));
- else
- return (ctlxrp(f, n));
- }
-
- /*
- * 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)
- {
- register int c;
- register int af;
- register int an;
- register int s;
-
- if (kbdmip!=NULL || kbdmop!=NULL)
- {
- mlwrite("Not now");
- return (FALSE);
- }
- if (n <= 0)
- return (TRUE);
- do
- {
- kbdmop = &kbdm[0];
- do
- {
- af = FALSE;
- an = 1;
- if ((c = *kbdmop++) == (CNTL|'U'))
- {
- af = TRUE;
- an = *kbdmop++;
- c = *kbdmop++;
- }
- s = TRUE;
- }
- while (c!=(CTLX|')') && (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.
- */
- _stop(f, n)
- {
- if (kbdmip != NULL)
- {
- kbdm[0] = (CTLX|')');
- kbdmip = NULL;
- }
- return (ABORT);
- }
-
- ctrlg(f, n)
- {
- mlwrite("[aborted]"); /* mb: instead of beep */
- return( _stop());
- }
-
- /* mb: added.
- */
- undo(f, n)
- {
- if ((lastflag&CFKILL)) /* If last command was Kill */
- return (yank(0, 1));
- if ((lastflag&CFYANK)) /* If last command was Yank */
- return (unyank(0, 1));
- if ((lastflag&CFSPLIT)) /* After help or buflist */
- return (onlywind(0, 1));
- if (kbdmip != NULL) /* Inside macro definition */
- return (ctrlg(f,n));
- else
- return (ABORT);
- }
-
- #if AtST
- /*
- * dal: added support for Atari mouse.
- */
- static int mfncut = FALSE;
-
- mousemode(f, n) /* switch between bound and cut/paste action */
- {
- mousef = !mousef;
- mlwrite("Mouse buttons now do %s functions",
- (mousef ? "bound" : "mark/cut/paste"));
- return(TRUE);
- }
-
- mfnleft(f, n) /* MARK mouse function */
- {
- mfncut = TRUE;
- return(setmark(f, n));
- }
-
- mfnright(f, n) /* CUT/PASTE mouse function */
- {
- if (mfncut)
- {
- mfncut = FALSE;
- if (curbp->b_flag & BFEDIT)
- return(killregion(f, n));
- else
- return(copyregion(f, n));
- }
- else
- {
- if (curbp->b_flag & BFEDIT)
- return(yank(f, n));
- else
- {
- mlwrite("View-only mode - Alt-E to edit");
- return(FALSE);
- }
- }
- }
- #endif /* AtST */
-
- /*
- * The following is code to handle the "clone" operation for saving
- * new default settings in an EMACS executable file.
- */
- #if AtST
- static char NAMEN[] = "EMACS.TTP";
- #define MODE_RWB (O_RDWR)
- #endif
- #if MSDOS
- static char NAMEN[] = "EMACS.EXE";
- #define MODE_RWB (O_RDWR|O_BINARY)
- #endif
-
- save_cfg()
- {
- register int c, n, h, i;
- register unsigned int bufsize;
- register char *buf, *p;
- register long ofst = (long)CFG_MSIZE;
-
- #if AtST
- unsigned long memavail();
- unsigned long space;
- #else
- unsigned int _memavl();
- #endif
- char *malloc();
-
- if(mlyesno("Clone MicroEMACS") != TRUE)
- return(FALSE);
-
- if((h = open(NAMEN, MODE_RWB)) < 0)
- {
- mlwrite("[Can't open %s]", NAMEN);
- return(FALSE);
- }
-
- #if AtST
- if ((space = memavail()) > 32000)
- space = 32000;
- if ((bufsize = (int)space) < 1024)
- #else
- if ((bufsize = _memavl()) < 1024)
- #endif
- {
- close(h);
- mlwrite("[Not enough memory to clone]");
- return(FALSE);
- }
-
- #if !AtST
- if (bufsize > 32000)
- bufsize = 32000;
- #endif
- buf = malloc(bufsize);
-
- c = cfg.magic[0];
-
- n = read(h, (p = buf), bufsize);
- while (n >= sizeof(cfg))
- {
- if ((c == *p) && !strcmp(p+1, cfg.magic+1))
- {
- lseek(h, ofst, SEEK_SET);
- i = cfgchng;
- cfgchng = TRUE;
- n = write(h, &cfg.value[0], CFG_VSIZE);
- close(h);
- free(buf);
- if (n != CFG_VSIZE)
- {
- cfgchng = i;
- mlwrite("[Write error during clone]");
- return(FALSE);
- }
- mlwrite("[Clone successful]");
- return(TRUE);
- }
- --n;
- ++p;
- ++ofst;
- if (n < sizeof(cfg))
- {
- memcpy(buf, p, (i = n));
- if ((n = read(h, buf+n, bufsize-n)) < 0)
- break;
- p = buf;
- n += i;
- }
- }
-
- mlwrite((n < 0)
- ? "[Read error during clone]"
- : "[Clone failed]");
- close(h);
- free(buf);
- return(FALSE);
- }
-
- /* dal: configurable variables */
- T_CFG cfg =
- {
- "\177cfg_data>\001\002\004\011__\377@\020\007<..-Dal/JLS",
- {
- FALSE, /* 00: ovrstrk */
- 0, /* 01: lmargin */
- 0, /* 02: fillcol */
- 8, /* 03: tabsize */
- FALSE, /* 04: mousef */
- 0, /* 05: mb_right */
- 0, /* 06: mb_left */
- 0x0704, /* 07: m_init.. */
- 0x0A06, /* 08: : */
- 0x0500, /* 09: : */
- FALSE, /* 10: autoindent */
- 0 /* 11: cfgchng */
- }
- };
-