Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!uwvax!oddjob!gargoyle!ihnp4!homxb!mtuxo!mtune!codas!ge-dab!ge-rtp!edison!toylnd!dca From: dca@toylnd.UUCP (David C. Albrecht) Newsgroups: comp.emacs Subject: Termcap mods for microemacs 3.8 Message-ID: <157@toylnd.UUCP> Date: Fri, 14-Aug-87 01:02:51 EDT Article-I.D.: toylnd.157 Posted: Fri Aug 14 01:02:51 1987 Date-Received: Sat, 22-Aug-87 10:57:22 EDT Distribution: na Organization: Dave & Anne in Charlottesville, VA Lines: 780 Keywords: MicroEmacs 3.8 #!/bin/sh # # The following is a posting for a set of mods to the distributed # microemacs 3.8i. It might be of interest to those like myself # who are running microemacs on UNIX based iron. It consists of # a set of hacks to input and tcap to provide support for input # as well as output. It binds the termcap kl = FNA, kr = FNB, # ku = FNC, kd = FND, kh = FNE, it also binds k0 through k9 to # FNF - FNO, l0 through l9 to FNP - FNY. # # Finally, you can put in your startup file: # # bind-to-key previous-line FNC # bind-to-key next-line FND # bind-to-key forward-character FNB # bind-to-key backward-character FNA # # and no matter what kind of terminal you use the cursor keys will work # (I admit it, I've always hated ^N ^P ^B ^F). # # I also added $term to the predefined variable list in the macros so # that you can access the TERM environment variable to determine if # you can make other bindings. It won't hurt to make bindings to # FNs that aren't supported by a particular terminal but if you # use a select set of terminals you can thereby provide a fancier # mapping. # # Not being a termcap guru I picked the entries from the man page that # seemed closest to being the kinds of things I wanted to bind to, # i.e. function keys and keypad. Note that in this implementation # the termcap bindings take precedence over any sequences you type # manually. I wouldn't expect this to be a problem but it is possible # that one of the k's or l's would steal a sequence you like to type normally. # # Well, I've done my hack for this month. Maybe some other crazy person # could see if they can use this stuff to make microemacs emulate edt :-). # # The following is mostly a bunch of diffs except for I included an entire # edef.h because I don't like duplicating declarations so I changed it to the # way I usually do things. # # Hope someone else finds this useful. # # David Albrecht # # echo 'Start of me3.8mods, part 01 of 01:' echo 'x - diffs' sed 's/^X//' > diffs << '/' Xdiff -bc unmod3.8/display.c me3.8/display.c X*** unmod3.8/display.c Wed Jul 29 23:45:41 1987 X--- me3.8/display.c Wed Jul 22 22:29:53 1987 X*************** X*** 44,49 X register int i; X register VIDEO *vp; X char *malloc(); X X TTopen(); /* open the screen */ X TTkopen(); /* open the keyboard */ X X--- 44,52 ----- X register int i; X register VIDEO *vp; X char *malloc(); X+ #if TERMCAP X+ char *kpinit; X+ #endif X X TTopen(); /* open the screen */ X TTkopen(); /* open the keyboard */ X*************** X*** 48,53 X TTopen(); /* open the screen */ X TTkopen(); /* open the keyboard */ X TTrev(FALSE); X vscreen = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *)); X X if (vscreen == NULL) X X--- 51,63 ----- X TTopen(); /* open the screen */ X TTkopen(); /* open the keyboard */ X TTrev(FALSE); X+ #if TERMCAP X+ if (kpinit = KS) { X+ while (*kpinit) { X+ TTputc(*(kpinit++)); X+ } X+ } X+ #endif X vscreen = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *)); X X if (vscreen == NULL) X*************** X*** 93,98 X */ X vttidy() X { X mlerase(); X movecursor(term.t_nrow, 0); X TTflush(); X X--- 103,112 ----- X */ X vttidy() X { X+ #if TERMCAP X+ char *kpreset; X+ #endif X+ X mlerase(); X movecursor(term.t_nrow, 0); X #if TERMCAP X*************** X*** 95,100 X { X mlerase(); X movecursor(term.t_nrow, 0); X TTflush(); X TTclose(); X TTkclose(); X X--- 109,121 ----- X X mlerase(); X movecursor(term.t_nrow, 0); X+ #if TERMCAP X+ if (kpreset = KE) { X+ while (*kpreset) { X+ TTputc(*(kpreset++)); X+ } X+ } X+ #endif X TTflush(); X TTclose(); X TTkclose(); Xdiff -bc unmod3.8/eval.c me3.8/eval.c X*** unmod3.8/eval.c Wed Jul 29 23:46:32 1987 X--- me3.8/eval.c Wed Jul 22 22:29:59 1987 X*************** X*** 163,168 X case EVPROGNAME:return(PROGNAME); X case EVSEED: return(itoa(seed)); X case EVDISINP: return(ltos(disinp)); X } X exit(-12); /* again, we should never get here */ X } X X--- 163,173 ----- X case EVPROGNAME:return(PROGNAME); X case EVSEED: return(itoa(seed)); X case EVDISINP: return(ltos(disinp)); X+ #if TERMCAP X+ case EVTERM: return(TERMTYPE); X+ #else X+ case EVTERM: return(""); X+ #endif X } X exit(-12); /* again, we should never get here */ X } Xdiff -bc unmod3.8/evar.h me3.8/evar.h X*** unmod3.8/evar.h Wed Jul 29 23:46:36 1987 X--- me3.8/evar.h Wed Jul 22 22:30:11 1987 X*************** X*** 42,47 X "progname", /* returns current prog name - "MicroEMACS" */ X "seed", /* current random number seed */ X "disinp", /* display command line input characters */ X }; X X #define NEVARS sizeof(envars) / sizeof(char *) X X--- 42,48 ----- X "progname", /* returns current prog name - "MicroEMACS" */ X "seed", /* current random number seed */ X "disinp", /* display command line input characters */ X+ "term", /* display terminal type */ X }; X X #define NEVARS sizeof(envars) / sizeof(char *) X*************** X*** 70,75 X #define EVPROGNAME 19 X #define EVSEED 20 X #define EVDISINP 21 X X /* list of recognized user functions */ X X X--- 71,77 ----- X #define EVPROGNAME 19 X #define EVSEED 20 X #define EVDISINP 21 X+ #define EVTERM 22 X X /* list of recognized user functions */ X Xdiff -bc unmod3.8/input.c me3.8/input.c X*** unmod3.8/input.c Wed Jul 29 23:47:23 1987 X--- me3.8/input.c Wed Jul 22 22:30:14 1987 X*************** X*** 6,11 X #include "estruct.h" X #include "edef.h" X X /* X * Ask a yes or no question in the message line. Return either TRUE, FALSE, or X * ABORT. The ABORT status is returned if the user bumps out of the question X X--- 6,15 ----- X #include "estruct.h" X #include "edef.h" X X+ #ifdef TERMCAP X+ static int tseq_putback = 0; X+ #endif X+ X /* X * Ask a yes or no question in the message line. Return either TRUE, FALSE, or X * ABORT. The ABORT status is returned if the user bumps out of the question X*************** X*** 345,350 X X { X int c; /* fetched keystroke */ X X /* get initial character */ X c = get1key(); X X--- 349,359 ----- X X { X int c; /* fetched keystroke */ X+ #if TERMCAP X+ register int tseqlen = 0; X+ register int **specpt; X+ static int tseq[6], *tseqnext; X+ #endif X X #if TERMCAP X if (!tseq_putback) { X*************** X*** 346,351 X { X int c; /* fetched keystroke */ X X /* get initial character */ X c = get1key(); X X X--- 355,362 ----- X static int tseq[6], *tseqnext; X #endif X X+ #if TERMCAP X+ if (!tseq_putback) { X /* get initial character */ X c = get1key(); X tseqnext = tseq; X*************** X*** 348,353 X X /* get initial character */ X c = get1key(); X X /* process META prefix */ X if (c == metac) { X X--- 359,408 ----- X if (!tseq_putback) { X /* get initial character */ X c = get1key(); X+ tseqnext = tseq; X+ while (1) { X+ *(tseqnext++) = c; X+ *tseqnext = 0; X+ tseqlen++; X+ specpt = specs; X+ while (specpt < &specs[MAX_SPECS]) { X+ if (*specpt) { X+ { register int *c1, *c2, i; X+ c1 = *specpt; X+ c2 = tseq; X+ i = tseqlen; X+ while (i-- && *(c1++) == *(c2++)); X+ if (i < 0) { X+ if (!*c1) { X+ return(SPEC | 'A' + (specpt - specs)); X+ } X+ else { X+ c = get1key(); X+ break; X+ } X+ } X+ } /* end register */ X+ } X+ specpt++; X+ } X+ if (specpt >= &specs[MAX_SPECS]) { X+ tseq_putback = tseqlen - 1; X+ if (tseq_putback) { X+ tseqnext = tseq; X+ c = *(tseqnext++); X+ } X+ break; X+ } X+ } X+ } X+ else { X+ c = *(tseqnext++); X+ tseq_putback--; X+ } X+ #else X+ /* get initial character */ X+ c = get1key(); X+ #endif X X /* process META prefix */ X if (c == metac) { X*************** X*** 351,356 X X /* process META prefix */ X if (c == metac) { X c = get1key(); X if (islower(c)) /* Force to upper */ X c ^= DIFCASE; X X--- 406,417 ----- X X /* process META prefix */ X if (c == metac) { X+ #if TERMCAP X+ if (tseq_putback) { X+ c = *(tseqnext++); X+ tseq_putback--; X+ } X+ else { X c = get1key(); X } X #else X*************** X*** 352,357 X /* process META prefix */ X if (c == metac) { X c = get1key(); X if (islower(c)) /* Force to upper */ X c ^= DIFCASE; X if (c>=0x00 && c<=0x1F) /* control key */ X X--- 413,422 ----- X } X else { X c = get1key(); X+ } X+ #else X+ c = get1key(); X+ #endif X if (islower(c)) /* Force to upper */ X c ^= DIFCASE; X if (c>=0x00 && c<=0x1F) /* control key */ X*************** X*** 361,366 X X /* process CTLX prefix */ X if (c == ctlxc) { X c = get1key(); X if (c>='a' && c<='z') /* Force to upper */ X c -= 0x20; X X--- 426,437 ----- X X /* process CTLX prefix */ X if (c == ctlxc) { X+ #if TERMCAP X+ if (tseq_putback) { X+ c = *(tseqnext++); X+ tseq_putback--; X+ } X+ else { X c = get1key(); X } X #else X*************** X*** 362,367 X /* process CTLX prefix */ X if (c == ctlxc) { X c = get1key(); X if (c>='a' && c<='z') /* Force to upper */ X c -= 0x20; X if (c>=0x00 && c<=0x1F) /* control key */ X X--- 433,442 ----- X } X else { X c = get1key(); X+ } X+ #else X+ c = get1key(); X+ #endif X if (c>='a' && c<='z') /* Force to upper */ X c -= 0x20; X if (c>=0x00 && c<=0x1F) /* control key */ Xdiff -bc unmod3.8/tcap.c me3.8/tcap.c X*** unmod3.8/tcap.c Wed Jul 29 23:48:58 1987 X--- me3.8/tcap.c Wed Jul 22 22:30:16 1987 X*************** X*** 75,81 X char *getenv(); X char *t, *p, *tgetstr(); X char tcbuf[1024]; X- char *tv_stype; X char err_str[72]; X X if ((tv_stype = getenv("TERM")) == NULL) X X--- 75,80 ----- X char *getenv(); X char *t, *p, *tgetstr(); X char tcbuf[1024]; X char err_str[72]; X X if ((TERMTYPE = getenv("TERM")) == NULL) X*************** X*** 78,84 X char *tv_stype; X char err_str[72]; X X! if ((tv_stype = getenv("TERM")) == NULL) X { X puts("Environment variable TERM not defined!"); X exit(1); X X--- 77,83 ----- X char tcbuf[1024]; X char err_str[72]; X X! if ((TERMTYPE = getenv("TERM")) == NULL) X { X puts("Environment variable TERM not defined!"); X exit(1); X*************** X*** 84,90 X exit(1); X } X X! if ((tgetent(tcbuf, tv_stype)) != 1) X { X sprintf(err_str, "Unknown terminal type %s!", tv_stype); X puts(err_str); X X--- 83,89 ----- X exit(1); X } X X! if ((tgetent(tcbuf, TERMTYPE)) != 1) X { X sprintf(err_str, "Unknown terminal type %s!", TERMTYPE); X puts(err_str); X*************** X*** 86,92 X X if ((tgetent(tcbuf, tv_stype)) != 1) X { X! sprintf(err_str, "Unknown terminal type %s!", tv_stype); X puts(err_str); X exit(1); X } X X--- 85,91 ----- X X if ((tgetent(tcbuf, TERMTYPE)) != 1) X { X! sprintf(err_str, "Unknown terminal type %s!", TERMTYPE); X puts(err_str); X exit(1); X } X*************** X*** 127,132 X if (CE == NULL) /* will we be able to use clear to EOL? */ X eolexist = FALSE; X X if (p >= &tcapbuf[TCAPSLEN]) X { X puts("Terminal description too big!\n"); X X--- 126,160 ----- X if (CE == NULL) /* will we be able to use clear to EOL? */ X eolexist = FALSE; X X+ KS = tgetstr("ks", &p); X+ KE = tgetstr("ke", &p); X+ X+ setkeypad("kl",KL,&p); X+ setkeypad("kr",KR,&p); X+ setkeypad("ku",KU,&p); X+ setkeypad("kd",KD,&p); X+ setkeypad("kh",KH,&p); X+ setkeypad("k0",K0,&p); X+ setkeypad("k1",K1,&p); X+ setkeypad("k2",K2,&p); X+ setkeypad("k3",K3,&p); X+ setkeypad("k4",K4,&p); X+ setkeypad("k5",K5,&p); X+ setkeypad("k6",K6,&p); X+ setkeypad("k7",K7,&p); X+ setkeypad("k8",K8,&p); X+ setkeypad("k9",K9,&p); X+ setkeypad("l0",L0,&p); X+ setkeypad("l1",L1,&p); X+ setkeypad("l2",L2,&p); X+ setkeypad("l3",L3,&p); X+ setkeypad("l4",L4,&p); X+ setkeypad("l5",L5,&p); X+ setkeypad("l6",L6,&p); X+ setkeypad("l7",L7,&p); X+ setkeypad("l8",L8,&p); X+ setkeypad("l9",L9,&p); X+ X if (p >= &tcapbuf[TCAPSLEN]) X { X puts("Terminal description too big!\n"); X*************** X*** 215,220 X tputs(str, n, ttputc); X } X X X #if FLABEL X fnclabel(f, n) /* label a function key */ X X--- 243,269 ----- X tputs(str, n, ttputc); X } X X+ X+ setkeypad(tcapstr, specno, p) X+ char *tcapstr; X+ int specno; X+ char **p; X+ { char *tgetstr(); X+ register char c, *str; X+ register int *inseq; X+ X+ str = tgetstr(tcapstr, p); X+ if (str) { X+ inseq = specs[specno] = (int *)malloc(sizeof(int) * (strlen(str)+1)); X+ while (c = *(str++)) { X+ if (c>=0x00 && c <=0x1F) X+ *(inseq++) = CTRL | (c+'@'); X+ else X+ *(inseq++) = c; X+ } X+ *(inseq) = 0; X+ } X+ } X X #if FLABEL X fnclabel(f, n) /* label a function key */ X / echo 'x - edef.h' sed 's/^X//' > edef.h << '/' 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(); Xchar *strcpy(); Xchar *strcat(); Xchar *strncpy(); Xchar *itoa(); Xchar *getval(); Xchar *gtenv(); Xchar *gtusr(); Xchar *gtfun(); Xchar *token(); Xchar *ltos(); Xchar *flook(); Xchar *mkupper(); Xchar *mklower(); Xunsigned int getckey(); X X#ifdef maindef X#define EXTERN X#define INIT(x) = x X#else X#define EXTERN extern X#define INIT(x) X#endif X X/* for MAIN.C */ X X/* initialized global definitions */ X XEXTERN int fillcol INIT(72); /* Current fill column */ XEXTERN short kbdm[NKBDM]; /* Macro */ XEXTERN char *execstr INIT(NULL); /* pointer to string to execute */ XEXTERN char golabel[NPAT] INIT(""); /* current line to go to */ XEXTERN int execlevel INIT(0); /* execution IF level */ XEXTERN int eolexist INIT(TRUE); /* does clear to EOL exist */ XEXTERN int revexist INIT(FALSE); /* does reverse video exist? */ XEXTERN int flickcode INIT(FALSE); /* do flicker supression? */ XEXTERN char *modename[] X#ifdef maindef X = { /* name of modes */ X "WRAP", "CMODE", "SPELL", "EXACT", "VIEW", "OVER", X "MAGIC", "CRYPT", "ASAVE"} X#endif X ; XEXTERN char modecode[] INIT("WCSEVOMYA"); /* letters to represent modes */ XEXTERN int gmode INIT(0); /* global editor mode */ XEXTERN int gfcolor INIT(7); /* global forgrnd color (white) */ XEXTERN int gbcolor INIT(0); /* global backgrnd color (black)*/ XEXTERN int gasave INIT(256); /* global ASAVE size */ XEXTERN int gacount INIT(256); /* count until next ASAVE */ XEXTERN int sgarbf INIT(TRUE); /* TRUE if screen is garbage */ XEXTERN int mpresf INIT(FALSE); /* TRUE if message in last line */ XEXTERN int clexec INIT(FALSE); /* command line execution flag */ XEXTERN int mstore INIT(FALSE); /* storing text to macro flag */ XEXTERN int discmd INIT(TRUE); /* display command flag */ XEXTERN int disinp INIT(TRUE); /* display input characters */ XEXTERN struct BUFFER *bstore INIT(NULL); /* buffer to store macro text to*/ XEXTERN int vtrow INIT(0); /* Row location of SW cursor */ XEXTERN int vtcol INIT(0); /* Column location of SW cursor */ XEXTERN int ttrow INIT(HUGE); /* Row location of HW cursor */ XEXTERN int ttcol INIT(HUGE); /* Column location of HW cursor */ XEXTERN int lbound INIT(0); /* leftmost column of current line X being displayed */ XEXTERN int taboff INIT(0); /* tab offset for display */ XEXTERN int metac INIT(CTRL | '['); /* current meta character */ XEXTERN int ctlxc INIT(CTRL | 'X'); /* current control X prefix char */ XEXTERN int reptc INIT(CTRL | 'U'); /* current universal repeat char */ XEXTERN int abortc INIT(CTRL | 'G'); /* current abort command char */ X XEXTERN int quotec INIT(0x11); /* quote char during mlreply() */ XEXTERN char *cname[] X#ifdef maindef X = { /* names of colors */ X "BLACK", "RED", "GREEN", "YELLOW", "BLUE", X "MAGENTA", "CYAN", "WHITE"} X#endif X ; XEXTERN KILL *kbufp INIT(NULL); /* current kill buffer chunk pointer */ XEXTERN KILL *kbufh INIT(NULL); /* kill buffer header pointer */ XEXTERN int kused INIT(KBLOCK); /* # of bytes used in kill buffer */ XEXTERN WINDOW *swindow INIT(NULL); /* saved window pointer */ XEXTERN int cryptflag INIT(FALSE); /* currently encrypting? */ XEXTERN short *kbdptr; /* current position in keyboard buf */ XEXTERN short *kbdend INIT(&kbdm[0]); /* ptr to end of the keyboard */ XEXTERN int kbdmode INIT(STOP); /* current keyboard macro mode */ XEXTERN int kbdrep INIT(0); /* number of repetitions */ XEXTERN int restflag INIT(FALSE); /* restricted use? */ XEXTERN int lastkey INIT(0); /* last keystoke */ XEXTERN int seed INIT(0); /* random number seed */ XEXTERN long envram INIT(0l); /* # of bytes current in use by malloc */ XEXTERN int macbug INIT(FALSE); /* macro debuging flag */ XEXTERN char errorm[] INIT("ERROR"); /* error literal */ XEXTERN char truem[] INIT("TRUE"); /* true literal */ XEXTERN char falsem[] INIT("FALSE"); /* false litereal */ XEXTERN int cmdstatus INIT(TRUE); /* last command status */ XEXTERN char palstr[49] INIT(""); /* palette string */ X X/* uninitialized global definitions */ 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 */ X XEXTERN BUFFER *bfind(); /* Lookup a buffer by name */ XEXTERN WINDOW *wpopup(); /* Pop up window creation */ XEXTERN LINE *lalloc(); /* Allocate a line */ XEXTERN char sres[NBUFN]; /* current screen resolution */ X XEXTERN char pat[NPAT]; /* Search pattern */ XEXTERN char tap[NPAT]; /* Reversed pattern array. */ XEXTERN char rpat[NPAT]; /* replacement pattern */ X X/* The variable matchlen holds the length of the matched X * string - used by the replace functions. X * The variable patmatch holds the string that satisfies X * the search command. X * The variables matchline and matchoff hold the line and X * offset position of the start of match. X */ XEXTERN unsigned int matchlen INIT(0); XEXTERN unsigned int mlenold INIT(0); XEXTERN char *patmatch INIT(NULL); XEXTERN LINE *matchline INIT(NULL); XEXTERN int matchoff INIT(0); X X#if MAGIC X/* X * The variable magical determines if there are actual X * metacharacters in the string - if not, then we don't X * have to use the slower MAGIC mode search functions. X */ XEXTERN short int magical INIT(FALSE); XEXTERN MC mcpat[NPAT]; /* the magic pattern */ XEXTERN MC tapcm[NPAT]; /* the reversed magic pattern */ X X#endif X X#if TERMCAP X XEXTERN char *TERMTYPE INIT(NULL); /* terminal name */ XEXTERN char *KS INIT(NULL); /* possible keypad enable */ XEXTERN char *KE INIT(NULL); /* possible keypad disable */ X X#define KL 0 /* keypad spec numbers */ X#define KR 1 X#define KU 2 X#define KD 3 X#define KH 4 X#define K0 5 X#define K1 6 X#define K2 7 X#define K3 8 X#define K4 9 X#define K5 10 X#define K6 11 X#define K7 12 X#define K8 13 X#define K9 14 X#define L0 15 X#define L1 16 X#define L2 17 X#define L3 18 X#define L4 19 X#define L5 20 X#define L6 21 X#define L7 22 X#define L8 23 X#define L9 24 X#define MAX_SPECS 25 XEXTERN int *specs[MAX_SPECS] X#ifdef maindef X ={ X NULL, NULL, NULL, NULL, NULL, X NULL, NULL, NULL, NULL, NULL, X NULL, NULL, NULL, NULL, NULL, X NULL, NULL, NULL, NULL, NULL, X NULL, NULL, NULL, NULL, NULL X } X#endif X ; X X#endif X X#ifndef maindef Xextern KEYTAB keytab[]; /* key bind to functions table */ Xextern NBIND names[]; /* name to function table */ X#endif X X/* terminal table defined only in TERM.C */ X X#ifndef termdef Xextern TERM term; /* Terminal information. */ X#endif X X X#undef EXTERN X#undef INIT / echo 'Part 01 of me3.8mods complete.' exit