Path: utzoo!utgpu!cs.utexas.edu!usc!rpi!think.com!cayman!pgf From: pgf@cayman.COM (Paul Fox) Newsgroups: alt.sources Subject: Vile 02/17 - vi feel-alike (multi-window) Message-ID: <4521@cayman.COM> Date: 7 Jun 91 22:09:10 GMT Organization: Cayman Systems Inc., Cambridge Ma Lines: 2159 Submitted-by: pgf@cayman.com Archive-name: Vile/part02 #!/bin/sh # this is vileshar.02 (part 2 of Vile) # do not concatenate these parts, unpack them in order with /bin/sh # file bind.c continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 2; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 echo 'x - continuing file bind.c' sed 's/^X//' << 'SHAR_EOF' >> 'bind.c' && X if (nptr->n_cmd == cfp) { X return(nptr->n_name); X } X } X return NULL; } X #if NEEDED /* translate a function pointer to its associated flags */ fnc2flags(func) CMDFUNC *cfp; /* ptr to the requested function to bind to */ { X register NTAB *nptr; /* pointer into the name binding table */ X X /* skim through the table, looking for a match */ X nptr = nametbl; X while (nptr->n_cmd != NULL) { X if (nptr->n_cmd == cfp) { X return nptr->n_flags; X } X ++nptr; X } X return NONE; } #endif X X /* engl2fnc: match name to a function in the names table X translate english name to function pointer X return any match or NULL if none X */ CMDFUNC * engl2fnc(fname) char *fname; /* name to attempt to match */ { X register NTAB *nptr; /* pointer to entry in name binding table */ X X /* scan through the table, returning any match */ X nptr = nametbl; X while (nptr->n_cmd != NULL) { X if (strcmp(fname, nptr->n_name) == 0) { X return nptr->n_cmd; X } X ++nptr; X } X return NULL; } X /* prc2kcod: translate printable code to 10 bit keycode */ int prc2kcod(k) char *k; /* name of key to translate to Command key form */ { X register int c; /* key sequence to return */ X X /* parse it up */ X c = 0; X X /* first, the CTLA prefix */ X if (*k == '^' && *(k+1) == toalpha(cntl_a) && *(k+2) == '-') { X c = CTLA; X k += 3; X } X X /* next the function prefix */ X if (*k == 'F' && *(k+1) == 'N' && *(k+2) == '-') { X c |= SPEC; X k += 3; X } X X /* control-x as well... (but not with FN) */ X if (*k == '^' && *(k+1) == toalpha(cntl_x) && X *(k+2) == '-' && !(c & SPEC)) { X c |= CTLX; X k += 3; X } X X /* a control char? */ X if (*k == '^' && *(k+1) != 0) { X ++k; X c |= *k; X if (islower(c)) c = toupper(c); X c = tocntrl(c); X } else if (!strcmp(k,"")) { X c |= ' '; X } else if (!strcmp(k,"")) { X c |= '\t'; X } else { X c |= *k; X } X return c; } X #if ! SMALLER X /* translate printable code (like "M-r") to english command name */ char * prc2engl(skey) /* string key name to binding name.... */ char *skey; /* name of keey to get binding for */ { X char *bindname; X X bindname = fnc2engl(kcod2fnc(prc2kcod(skey))); X if (bindname == NULL) X bindname = "ERROR"; X X return bindname; } #endif X /* get an english command name from the user. Command completion means X * that pressing a will attempt to complete an unfinished command X * name if it is unique. X */ char * kbd_engl() { X int status; X char *buf; X X X status = kbd_engl_stat(&buf); X if (status == SORTOFTRUE) /* something was tungetc'ed */ X (void)tgetc(); X if (status == TRUE) X return buf; X return NULL; } X /* *bufp only valid if return is TRUE */ kbd_engl_stat(bufp) char **bufp; { #if ST520 & LATTICE #define register #endif X register int c; X register int cpos; /* current column on screen output */ X register char *sp; /* pointer to string for output */ X register NTAB *nbp; /* first ptr to entry in name binding table */ X register NTAB *cnbp; /* current ptr to entry in name binding table */ X register NTAB *lnbp; /* last ptr to entry in name binding table */ X static char buf[NLINE]; /* buffer to hold tentative command name */ X X cpos = 0; X X *bufp = NULL; X X /* if we are executing a command line just get the next arg and return */ X if (clexec) { X if (macarg(buf) != TRUE) { X return FALSE; X } X *bufp = buf; X return TRUE; X } X X lineinput = TRUE; X X /* build a name string from the keyboard */ X while (TRUE) { X c = tgetc(); X X if (cpos == 0) { X if (isbackspace(c) || X c == kcod2key(abortc) || X c == kcod2key(killc) || X c == '\r' || X islinespecchar(c) ) { X tungetc(c); X return SORTOFTRUE; X } X } X X if (c == '\r') { X buf[cpos] = 0; X lineinput = FALSE; X *bufp = buf; X return TRUE; X X } else if (c == kcod2key(abortc)) { /* Bell, abort */ X buf[0] = '\0'; X lineinput = FALSE; X return FALSE; X X } else if (isbackspace(c)) { X TTputc('\b'); X TTputc(' '); X TTputc('\b'); X --ttcol; X --cpos; X TTflush(); X X } else if (c == kcod2key(killc)) { /* ^U, kill */ X while (cpos != 0) { X TTputc('\b'); X TTputc(' '); X TTputc('\b'); X --cpos; X --ttcol; X } X TTflush(); X tungetc(c); X return SORTOFTRUE; X X } /* else... */ /* the following mess causes the command to terminate if: X we've got a space X -or- X we're in the first few chars and we're switching from punctuation X to alphanumerics, or vice-versa. oh yeah -- '!' is considered X alphanumeric today. X All this allows things like: X : e# X : !ls X : q! X to work properly. X If we pass this "if" with c != ' ', then c is ungotten below, X so it can be picked up by the commands argument getter later. */ X else if (c == ' ' || (cpos > 0 && cpos < 3 && X ((!ispunct(c) && ispunct(buf[cpos-1])) || X ((c != '!' && ispunct(c)) && X (buf[cpos-1] == '!' || !ispunct(buf[cpos-1]))) ) X ) X ) { /* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ X /* attempt a completion */ X buf[cpos] = 0; /* terminate it for us */ X nbp = nametbl; /* scan for matches */ X while (nbp->n_cmd != NULL) { X if (strncmp(buf, nbp->n_name, strlen(buf)) == 0) { X /* a possible match! exact? no more than one? */ X if (strcmp(buf, nbp->n_name) == 0 || /* exact? */ X (nbp + 1)->n_cmd == NULL || X strncmp(buf, (nbp+1)->n_name, strlen(buf)) != 0) X { X /* exact or only one like it. print it */ X sp = nbp->n_name + cpos; X while (*sp) X TTputc(*sp++); X TTflush(); X if (c != ' ') /* put it back */ X tungetc(c); X lineinput = FALSE; X /* return nbp->n_name; */ X strncpy(buf,nbp->n_name,NLINE); X *bufp = buf; X return TRUE; X } else { /* << << << << << << << << << << << << << << << << << */ X /* try for a partial match against the list */ X X /* first scan down until we no longer match the current input */ X lnbp = (nbp + 1); X while ((lnbp+1)->n_cmd != NULL) { X if (strncmp(buf, (lnbp+1)->n_name, strlen(buf)) != 0) X break; X ++lnbp; X } X X /* and now, attempt to partial complete the string, char at a time */ X while (TRUE) { X /* add the next char in */ X buf[cpos] = nbp->n_name[cpos]; X X /* scan through the candidates */ X cnbp = nbp + 1; X while (cnbp <= lnbp) { X if (cnbp->n_name[cpos] != buf[cpos]) X goto onward; X ++cnbp; X } X X /* add the character */ X TTputc(buf[cpos++]); X } /* << << << << << << << << << << << << << << << << << */ X } X } X ++nbp; X } X X /* no match.....beep and onward */ X TTbeep(); onward:; X TTflush(); /* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ X } else { X if (cpos < NLINE-1 && isprint(c)) { X buf[cpos++] = c; X TTputc(c); X } X X ++ttcol; X TTflush(); X } X } } X SHAR_EOF echo 'File bind.c is complete' && chmod 0444 bind.c || echo 'restore of bind.c failed' Wc_c="`wc -c < 'bind.c'`" test 21479 -eq "$Wc_c" || echo 'bind.c: original size 21479, current size' "$Wc_c" # ============= buffer.c ============== echo 'x - extracting buffer.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'buffer.c' && /* 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 */ #include #include "estruct.h" #include "edef.h" X static lastlookup = -1; X /* c is either first character of a filename, or an index into buffer list */ char * hist_lookup(c) { X register BUFFER *bp; X static char buf[NBUFN]; X buf[0] = '\0'; X X if (curbp != bheadp) X mlwrite("BUG: hist_lookup: curbp != bheadp"); X X bp = curbp->b_bufp; /* always skip the current */ X while (bp != NULL) { X if (!(bp->b_flag & (BFINVS|BFSCRTCH)) && (--c == 0)) X break; X bp = bp->b_bufp; X } X if (bp) X return bp->b_bname; X return NULL; } X hist_show() { X int i; X char line[NLINE]; X BUFFER *bp; X X if (curbp != bheadp) X mlwrite("BUG: hist_show: curbp != bheadp"); X X strcpy(line,""); X for (i = 0, bp = curbp->b_bufp; i < 10 && bp != NULL; bp = bp->b_bufp) { X if (!(bp->b_flag & (BFINVS|BFSCRTCH))) { X strcat(line, " %d"); X if (bp->b_flag & BFCHG) X strcat(line, "* "); X else X strcat(line, " "); X strcat(line, bp->b_bname); X i++; X } X } X if (strcmp(line,"")) { X mlwrite(line,1,2,3,4,5,6,7,8,9,10); X return TRUE; X } else { X return FALSE; X } } X histbuff(f,n) { X register int thiscmd, c; X register BUFFER *bp; X char *bufn; X X if (curbp->b_bufp == NULL) { X TTbeep(); X mlwrite("No other buffers."); X return(FALSE); X } X X if (f == FALSE) { X hist_show(); X thiscmd = lastcmd; X c = kbd_seq(); X mlerase(); X if (c == thiscmd) { X c = 1; X } else if (isdigit(c)) { X c = c - '0'; X } else { X tungetc(c); X return FALSE; X } X } else { X c = n; X } X X bufn = hist_lookup(c); X if (bufn == NULL) { X TTbeep(); X mlwrite("No such buffer."); X return FALSE; X } X /* first assume its a buffer name, then a file name */ X if ((bp=bfind(bufn, NO_CREAT, 0)) == NULL) X return getfile(bufn,TRUE); X else { X return swbuffer(bp); X } } X altbuff(f,n) { X return(histbuff(TRUE,1)); } 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 */ usebuffer(f, n) { X register BUFFER *bp; X register int s; X char bufn[NBUFN]; X X bufn[0] = 0; X if ((s=mlreply("Use buffer: ", bufn, NBUFN)) != TRUE) X return s; X if ((bp=bfind(bufn, OK_CREAT, 0)) == NULL) X return FALSE; X return swbuffer(bp); } X nextbuffer(f, n) /* switch to the next buffer in the buffer list */ int f, n; /* default flag, numeric argument */ { X register BUFFER *bp; /* eligable buffer to switch to*/ X register BUFFER *stopatbp; /* eligable buffer to switch to*/ X X stopatbp = NULL; X while (stopatbp != bheadp) { X /* get the last buffer in the list */ X for (bp = bheadp; bp->b_bufp != stopatbp; bp = bp->b_bufp) X ; X /* if that one's invisible, back up and try again */ X if (bp->b_flag & BFINVS) X stopatbp = bp; X else X return swbuffer(bp); X } X /* we're back to the top -- they were all invisible */ X return swbuffer(stopatbp); X } X X swbuffer(bp) /* make buffer BP current */ register BUFFER *bp; { X register WINDOW *wp; X X if (curbp == bp) /* no switching to be done */ X return TRUE; X X if (curbp) { X /* if we'll have to take over this window, and it's the last */ X if (bp->b_nwnd == 0 && --curbp->b_nwnd == 0) { X undispbuff(curbp,curwp); X } X } X make_current(bp); X X /* get it already on the screen if possible */ X if (bp->b_nwnd > 0) { /* then it's on the screen somewhere */ X register WINDOW *wp; X int nw; X for (wp = wheadp, nw= 1; X wp->w_bufp != bp && wp->w_wndp != NULL; X nw++, wp = wp->w_wndp) X ; X if (!wp) X mlwrite("BUG: swbuffer: wp still NULL"); X curwp = wp; X upmode(); X return TRUE; X } X X /* oh well, suck it into this window */ 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_mkp = bp->b_markp; X curwp->w_mko = bp->b_marko; X curwp->w_ldmkp = bp->b_ldmkp; X curwp->w_ldmko = bp->b_ldmko; X curwp->w_sideways = bp->b_sideways; X } X if (bp->b_active != TRUE) { /* buffer not active yet*/ X /* read it in and activate it */ X (void)readin(bp->b_fname, TRUE, bp, TRUE); X curwp->w_dotp = lforw(bp->b_linep); X curwp->w_doto = 0; X bp->b_active = TRUE; X } #if NeWS X newsreportmodes() ; #endif X return TRUE; } X X undispbuff(bp,wp) register BUFFER *bp; register WINDOW *wp; { X /* get rid of it completely if it's a scratch buffer, X or it's empty and unmodified */ X if ( (bp->b_flag & BFSCRTCH) || ( !(bp->b_flag & BFCHG) && X lforw(bp->b_linep) == bp->b_linep ) ) { X (void)zotbuf(bp); X } else { /* otherwise just adjust it off the screen */ X bp->b_dotp = wp->w_dotp; X bp->b_doto = wp->w_doto; X bp->b_markp = wp->w_mkp; X bp->b_marko = wp->w_mko; X bp->b_ldmkp = wp->w_ldmkp; X bp->b_ldmko = wp->w_ldmko; X bp->b_sideways = wp->w_sideways; X } } X /* bring nbp to the top of the list, where curbp _always_ lives */ make_current(nbp) BUFFER *nbp; { X register BUFFER *bp; X X if (nbp == bheadp) { /* already at the head */ X curbp = bheadp; X return; X } X X /* remove nbp from the list */ X for (bp = bheadp; bp->b_bufp != nbp; bp = bp->b_bufp) X ; X bp->b_bufp = nbp->b_bufp; X X /* put it at the head */ X nbp->b_bufp = bheadp; X X bheadp = nbp; X curbp = nbp; } 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. X */ killbuffer(f, n) { X register BUFFER *bp; X register int s; X char bufn[NBUFN]; X X bufn[0] = 0; X if ((s=mlreply("Kill buffer: ", bufn, NBUFN)) != TRUE) X return(s); X if ((bp=bfind(bufn, NO_CREAT, 0)) == NULL) { /* Easy if unknown. */ X mlwrite("No such buffer"); X return FALSE; X } X if(bp->b_flag & BFINVS) /* Deal with special buffers */ X return (TRUE); /* by doing nothing. */ X s = zotbuf(bp); X if (s == TRUE) X mlwrite("Buffer %s gone", bufn); X return s; } X zotbuf(bp) /* kill the buffer pointed to by bp */ register BUFFER *bp; { 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 X lfree(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 namebuffer(f,n) /* Rename the current buffer */ int f, n; /* default Flag & Numeric arg */ { X register BUFFER *bp; /* pointer to scan through all buffers */ X static char bufn[NBUFN]; /* buffer to hold buffer name */ X char *prompt = "New name for buffer: "; X X /* prompt for and get the new buffer name */ ask: if (mlreply(prompt, 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 prompt = "That name's been used. New name: "; X goto ask; /* try again */ X } 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 /* create or find a window, and stick this buffer in it. when X done, we own the window and the buffer, but they are _not_ X necessarily curwp and curbp */ popupbuff(bp) BUFFER *bp; { X register WINDOW *wp; X X if (!curbp) { X curbp = bp; /* possibly at startup time */ X curwp->w_bufp = curbp; X ++curbp->b_nwnd; X } else if (bp->b_nwnd == 0) { /* Not on screen yet. */ X if ((wp = wpopup()) == NULL) X return FALSE; X if (--wp->w_bufp->b_nwnd == 0) X undispbuff(wp->w_bufp,wp); X wp->w_bufp = bp; X ++bp->b_nwnd; X } X wp = wheadp; X while (wp != NULL) { X if (wp->w_bufp == bp) { X wp->w_linep = lforw(bp->b_linep); X wp->w_dotp = lforw(bp->b_linep); X wp->w_doto = 0; X wp->w_mkp = NULL; X wp->w_mko = 0; X wp->w_ldmkp = NULL; X wp->w_ldmko = 0; X wp->w_sideways = 0; X wp->w_flag |= WFMODE|WFHARD; X X } X wp = wp->w_wndp; X } X return TRUE; } X /* X List all of the active buffers. First update the special X buffer that holds the list. Next make sure at least 1 X window is displaying the buffer list, splitting the screen X if this is what it takes. Lastly, repaint all of the X windows that are displaying the list. X A numeric argument forces it to list invisable buffers as X well. */ togglelistbuffers(f, n) { X register WINDOW *wp; X register BUFFER *bp; X int s; X X /* if it doesn't exist, create it */ X if ((bp = bfind("[List]", NO_CREAT, BFSCRTCH)) == NULL) X return listbuffers(f,n); X X /* if it does exist, delete the window, which in turn X will kill the BFSCRTCH buffer */ X wp = wheadp; X s = TRUE; X while (wp != NULL && s) { X if (wp->w_bufp == bp) { X s = delwp(wp); X break; X } X wp = wp->w_wndp; X } X return s; } X listbuffers(f, n) { X register BUFFER *bp; X register int s; X X /* create the buffer list buffer */ X bp = bfind("[List]", OK_CREAT, BFSCRTCH); X if (bp == NULL) X return FALSE; X X if ((s=bclear(bp)) != TRUE) /* clear old text (?) */ X return (s); X bp->b_flag |= BFSCRTCH; X s = makelist(f,bp); X if (!s || popupbuff(bp) == FALSE) { X mlwrite("[Sorry, can't list. ]"); X zotbuf(bp); X return (FALSE); X } X sprintf(bp->b_fname, " %s %s",prognam,version); X bp->b_flag &= ~BFCHG; /* Don't complain! */ X bp->b_active = TRUE; X X return TRUE; } X /* X * This routine rebuilds the X * text in the 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). Iflag X * indicates whether to list hidden buffers. X */ /* returns no. of lines in list */ int makelist(iflag,blistp) int iflag; /* list hidden buffer flag */ BUFFER *blistp; { 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 int nbuf = 0; /* no. of buffers */ X int nlines = 0; /* no. of lines in list */ X char b[10]; X char line[NFILEN+NBUFN+30]; X static char dashes[] = X "-------------------------------------------------"; X int footnote = FALSE; X X sprintf(line," %-*s %7s %-*s %s", X NUMMODES,"Modes","Size",NBUFN,"Buffer name","Contents"); X if(addline(blistp,line, -1) == FALSE) X return (FALSE); X nlines++; X X /* put some spaces into the separator line... */ X dashes[3] = dashes[NUMMODES+4] = dashes[NUMMODES+4+8] = X dashes[NUMMODES+4+8+NBUFN+1] = ' '; X if (addline(blistp,dashes, -1) == FALSE) X return (FALSE); X nlines++; X X bp = bheadp; /* For all buffers */ X X /* output the list of buffers */ X while (bp != NULL) { X /* skip invisible buffers and ourself if iflag is false */ X if (((bp->b_flag&(BFINVS|BFSCRTCH)) != 0) && (iflag != TRUE)) { X bp = bp->b_bufp; X continue; X } X X X cp1 = &line[0]; /* Start at left edge */ X /* output status of ACTIVE flag (has the file been read in? */ X if (bp->b_active == TRUE) { /* if activated */ X if ((bp->b_flag&BFCHG) != 0) { /* if changed */ X *cp1++ = 'm'; X footnote = TRUE; X } else { X *cp1++ = ' '; X } X } else { X *cp1++ = 'u'; X footnote = TRUE; X } X X sprintf(cp1,"%2d ",nbuf++); X X cp1 = &line[strlen(line)]; 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 sprintf(cp1,"%7ld %-*s %s",nbytes, X NBUFN, bp->b_bname, bp->b_fname); X if (addline(blistp,line,-1) == FALSE) X return (FALSE); X nlines++; X bp = bp->b_bufp; X } X X if (footnote == TRUE) { X if (addline(blistp, X "('m' means modified, 'u' means unread)",-1) X == FALSE) { X return FALSE; X } X nlines++; X } X X /* build line to report global mode settings */ X sprintf(line," "); X cp1 = &line[4]; 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, " are the global modes"); X if (addline(blistp,line,-1) == FALSE) X return(FALSE); X X sprintf(line," tabstop = %d; fillcol = %d", TABVAL, fillcol); X if (addline(blistp,line,-1) == FALSE) X return(FALSE); X X sprintf(line," lazy filename matching is %s", X (othmode & OTH_LAZY) ? "on":"off"); X if (addline(blistp,line,-1) == FALSE) X return(FALSE); X X nlines++; X X return (nlines); } X ltoa(buf, width, num) char buf[]; int width; long num; { 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 * The argument "text" points to X * a string. Append this line to the X * buffer. Handcraft the EOL X * on the end. Return TRUE if it worked and X * FALSE if you ran out of room. X */ addline(bp,text,len) register BUFFER *bp; char *text; int len; { X register LINE *lp; X register int i; X register int ntext; X X ntext = (len < 0) ? strlen(text) : len; X if ((lp=lalloc(ntext)) == NULL) X return (FALSE); X for (i=0; ib_linep->l_bp->l_fp = lp; /* Hook onto the end */ X lp->l_bp = bp->b_linep->l_bp; X bp->b_linep->l_bp = lp; X lp->l_fp = bp->b_linep; X if (bp->b_dotp == bp->b_linep) /* If "." is at the end */ X bp->b_dotp = lp; /* move it to new line */ X return (TRUE); } 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 */ anycb() { X register BUFFER *bp; X register int cnt = 0; X X bp = bheadp; X while (bp != NULL) { X if ((bp->b_flag&BFINVS)==0 && (bp->b_flag&BFCHG)!=0) X cnt++; X bp = bp->b_bufp; X } X return (cnt); } 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 OK_CREAT, create it. The "bflag" is X * the settings for the flags in in buffer. X */ BUFFER * bfind(bname, cflag, bflag) char *bname; { X register BUFFER *bp; X register LINE *lp; X register BUFFER *lastb = NULL; /* buffer to insert after */ X X bp = bheadp; X while (bp != NULL) { X if (strncmp(bname, bp->b_bname, NBUFN) == 0) X return (bp); X lastb = bp; X bp = bp->b_bufp; X } X if (cflag == NO_CREAT) /* don't create it */ X return NULL; X 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 X /* and set up the other buffer fields */ X bp->b_active = FALSE; X bp->b_dotp = lp; X bp->b_doto = 0; X bp->b_markp = NULL; X bp->b_marko = 0; X bp->b_ldmkp = NULL; X bp->b_ldmko = 0; X bp->b_nmmarks = NULL; X bp->b_flag = bflag; X bp->b_mode = gmode & ~(MDCMOD|MDDOS); /* handled in readin() */ X bp->b_nwnd = 0; X bp->b_sideways = 0; X bp->b_linep = lp; X strcpy(bp->b_fname, ""); X strcpy(bp->b_bname, bname); #if CRYPT X bp->b_key[0] = 0; #endif X bp->b_udstks[0] = bp->b_udstks[1] = NULL; X bp->b_udstkindx = 0; X bp->b_ulinep = NULL; X lp->l_fp = lp; X lp->l_bp = lp; X X /* append at the end */ X if (lastb) X lastb->b_bufp = bp; X else X bheadp = bp; X bp->b_bufp = NULL; X X return (bp); } 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 */ bclear(bp) register BUFFER *bp; { X register LINE *lp; X register int s; X X if ((bp->b_flag&(BFINVS|BFSCRTCH)) == 0 /* Not invisible or scratch */ X && (bp->b_flag&BFCHG) != 0 ) { /* Something changed */ X char ques[50]; X strcpy(ques,"Discard changes to "); X strcat(ques,bp->b_bname); X if (mlyesno(ques) != TRUE) X return FALSE; X } X bp->b_flag &= ~BFCHG; /* Not changed */ X freeundostacks(bp); /* do this before removing lines */ X while ((lp=lforw(bp->b_linep)) != bp->b_linep) { X lremove(bp,lp); X lfree(lp); X } 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 bp->b_ldmkp = NULL; /* Invalidate "mark" */ X bp->b_ldmko = 0; X if (bp->b_nmmarks != NULL) { /* free the named marks */ X free((char *)(bp->b_nmmarks)); X bp->b_nmmarks = NULL; X } X return (TRUE); } X unmark(f, n) /* unmark the current buffers change flag */ int f, n; /* unused command arguments */ { X curbp->b_flag &= ~BFCHG; X curwp->w_flag |= WFMODE; X return(TRUE); } SHAR_EOF chmod 0444 buffer.c || echo 'restore of buffer.c failed' Wc_c="`wc -c < 'buffer.c'`" test 20200 -eq "$Wc_c" || echo 'buffer.c: original size 20200, current size' "$Wc_c" # ============= buglist ============== echo 'x - extracting buglist (Text)' sed 's/^X//' << 'SHAR_EOF' > 'buglist' && X X (E means enhancement, L,M,H are low, medium, high priority) ---------------------- X H the gotoeop motion and regions interract wrongly. For instance, X using ^W} to write the rest of the paragraph to a file writes X the wrong number of characters. X H when reading the output of a shell command, it's far too slow -- should X read as much as possible, put it into the buffer, and _then_ update X [ This has been fixed for BSD -- other implementations not yet ] X M output doesn't flush properly after a shell escape X M longnames cause severe portability constraint -- does the shortnames X stuff take care of this? I can't test it... X M :k, to set a mark, won't work as ":ka" or ":kb". Must use ":k a" X M :set all should be made to work (fix help) X L formatregion sometimes appends a space to the last line, for instance X when a paragraph is reformatted X L dos-style is set even when file is majority unix-lines? X L why does file reading seem so slow? X L why is searching so slow? X L with two window displayed, hitting * twice makes one go away. X perhaps popup should _always_ split a window, rather than sometimes X taking over an existing one. but then we'd have to remember who we X split, so we could give the space back to the donor. X E patterns as addresses do not work, e.g. ":/str1/,/str2/d". They're X hard to parse the way things are set up right now. We could accumulate X the whole commandline, and then parse it, the way real vi does, but we'd X lose the "prompt and display last response" behavior. X E In vi, the join command is supposed to act either on a region (from X the command line, as in ":13,15j"), or it should take a simple X count, from vi mode, as in "3j". Right now vile _only_ does the X simple count form of the command. X E should add an option to support file locking, rather than the X current ifdef stuff -- but this is only useful if we match the X GNU locking protocol, which I'm not inclined to do X E Wow. the scrsearch functions could become region based -- as in "search for X the next occrence of the region", which would usually be a word. And X the ^A/ version could become "a/ (search for teh contents of buffer a), X if you know what I mean. X E need a "file newer than buffer" warning. Should stat the file, and X store it's mod time, compare to current when going back to that window, X after performing some shell command. e.g., if you're editing a file X that is created by a script you're testing, then you want to be warned X that the file is out of date after doing a test run of the script. X E should be able to refer to remote tags file, and have paths X contained there be relative to _its_ location, rather than the current X directory. X E add a command-line expansion character to be the list of files X mentioned in "tags" X E should there be a "significant-length" for tags? X E another mode, which will "!get -p" an SCCS or RCS file if X the clear-text file isn't found X E add _another_ mode, similar to the above, which will do a caseless X match against filenames mentioned in tags X E it would be nice if ^X!! reran the last command into [Output] X E add support for sh or C comments to formatregion() code X E why can't I kill a displayed buffer? simply bring up the previous. X E g should become a region command. Then it could take ranges, as X it should, and could also become an operator command. X E add C comments to CFENCE matching code X E add C ifdefs to CFENCE matching code X E adjust window size of popups based on length of buffer. currently X popups get half the window they're splitting, no matter what X E collapse command execution code to as few places as possible. X Its currently spread through main(), execute(), operator(), X docmd(), and usekreg(). X E mlreply line should ideally be a one line buffer, so editing X and history can be done on it. X E BSD interrupt processing is botched during a read() of the keyboard. X The read doesn't return -1 as it does under sysV (USG). X So you can bang on ^C all day and nothing will happen. X [I'm not sure this is true anymore -pgf] X E This editor does not virtualize buffers out to disk. It is quite X a memory hog. But isn't that what /dev/swap is for? But X seriously, I haven't even come close to testing it for X memory-full conditions. Some malloc() packages give 95% X warnings -- perhaps something like that should be done for X safety. X E to make the code shrink, could probably try to eliminate X sprintf and its brethren. mlwrite already does format X expansion, it could probably be turned into a doprnt-like X beast, and that used as a basis for our own sprintf,fprintf X How does one write [sfp]printf and doprnt using varargs? X E likewise for scanf X E marks should perhaps be linked onto lines. this would make a lot X of things a lot easier, since a mark would travel with the X line, instead of having to be moved when the line is X reallocated etc. the U line could be treated as a special X mark. The "copied" flag needed by undo could be a special X sort of mark as well. Implementation of the "tag stack" X would be aided by this as well. X E there is currently no way to change working directories -- it's X not clear whether that should be a global thing, or perhaps X a per-buffer notion. X E there is code (in imdying()) that attempts to save unwritten buffers X on hangups. It is fairly crude, having been written quickly X in self-defense during debugging. It should be examined and X fixed. X E :e and :n should be able to deal with multiple filenames resulting X from filename globbing. vi has this problem too. At least X vile lets you choose to choose the first such name. if should show X you the first name, so you know whether to accept it or not. X E ^W should erase word in input mode, and killc should erase line X in input mode. (but only back to where the input started, if it X started on this line. right now we have no record of that, hence X you can backspace past the insert point) X E All code should pass lint. This won't be easy... :-) X SHAR_EOF chmod 0444 buglist || echo 'restore of buglist failed' Wc_c="`wc -c < 'buglist'`" test 6009 -eq "$Wc_c" || echo 'buglist: original size 6009, current size' "$Wc_c" # ============= cmdtbl ============== echo 'x - extracting cmdtbl (Text)' sed 's/^X//' << 'SHAR_EOF' > 'cmdtbl' && X # This file contains all of the editor's command and key linkages. # # It should be processed by the "mktbls" program, which produces the # headers #included by main.c # # All that is necessary to add a new function to the editor is to add # an entry to this file, write the function, make sure it's in the # makefile, and rebuild. (This is not to be confused with adding a # new key binding, which can be done with the rebind command if it # was compiled in.) # # If you want to know which keyboard bindings are already taken, look # at nebind.h, after you build it. # # The entries are functions within the editor. They _must_ match the # functions' names. On the same line as the name is the set of flags # describing that function. # Also accompanying each function is a list of english names for the # command, in double quotes, and a list of keys bound to the command, # in single quotes. These are the default key bindings -- they can change # at runtime. English names must be all lowercase. # Any function, name, or key may be followed by a conditional, i.e. the # name of a preprocessor #define which must be defined non-zero for that # line to become part of the editor. If a function name is made conditional, # the names and keys listed with it will be conditional also. # The names and keys must be preceded by a tab character. # Blank lines must be completely empty. # For convenience only, this table is kept in roughly alphabetical order, # by first character of function name. # # For example, consider the following entry: # # somefunc ABS|MOTION BSD|DOS # "funkycom" # '^X-F' # 'FN-2' DOS # # This says that somefunc() is an absolute motion command, that it should # only be included in the editor if we're running BSD or DOS, that its # english name as one would type on the command line is "funkycom", and # that it is bound to ^X-F, and also to function key 2 under DOS. # # Function flags have the following meanings: # REDO means the dotcmd command recorder should be halted, so that # the command can be redone. # UNDO means the undo stacks should be cleared, in preparation for # an undoable command. # OPER means the command is an "operator", that is, it acts on a region # demarcated by the current cursor postion and the cursor position # following a subsequent motion command. # MOTION means this command moves dot, and specifically is compatible # with the operator commands. # FL only occurs with MOTION, means that if the motion is an argument # to an operator, the operation should affect Full Lines # ABS only occurs with MOTION, means that the motion is absolute, # i.e. not relative to the current postion or screen. It causes # the "lastdotmark", ldmark to be set to dot before the move # takes place. # GOAL signifies a motion that will attempt to retain the # current column postition after the motion. # GLOBOK says the function can follow a global command # (e.g. the 'd' in "g/pattern/d") # # This file was designed and constructed by Paul Fox for vile, (c)1990 # # The flags given in parentheses are "ex" flags, related to what # kind of line-range arguments the command can take. Not all are # currently used or implemented, but they were defined in the command # table for the Steve Kirkendall's elvis editor, so I included them # here for completeness. X altbuff NONE X "alternate-buffer" !FEWNAMES X '^^' append REDO|UNDO X "appendchar" !FEWNAMES X 'a' appendeol REDO|UNDO X "append-eol" !FEWNAMES X 'A' apro NONE APROP|REBIND X "apropos" backchar MOTION X "backward-character" !FEWNAMES X 'h' X '^H' backdelchar REDO|UNDO X "delete-previous-character" !FEWNAMES X 'X' backhunt ABS|MOTION !SMALLER X "hunt-backward" backhpage NONE X "previous-half-page" !FEWNAMES X '^U' backline GOAL|MOTION|FL X "previous-line" !FEWNAMES X 'k' backbline MOTION|FL X "previous-line-at-bol" !FEWNAMES X '-' backpage MOTION X "previous-page" !FEWNAMES X '^B' backword MOTION X "previous-word" !FEWNAMES X 'B' backviword MOTION X "previous-punc-word" !FEWNAMES X 'b' backsearch ABS|MOTION X "search-reverse" !FEWNAMES X '?' bcsrch MOTION X "backward-char-scan" !FEWNAMES X 'F' bcsrch_to MOTION X "backward-char-scan-to" !FEWNAMES X 'T' bindkey NONE REBIND X "bind-key" X "rebind-key" bktoshell NONE UNIX&&defined(SIGTSTP) X "suspend-emacs" !FEWNAMES X '^Z' cntl_xf NONE X "cntl_x-prefix" !FEWNAMES X '^X' chgchar REDO|UNDO X "change-char" !FEWNAMES X 's' chgline REDO|UNDO X "change-line" !FEWNAMES X 'S' chgtoeol REDO|UNDO X "change-to-end-of-line" !FEWNAMES X 'C' clrmes NONE X "clear-message-line" !FEWNAMES consearch ABS|MOTION X "continue-search" !FEWNAMES X 'n' opercopy OPER|(RANGE|EXTRA) X "copy" X "c" ctlxlp NONE X "begin-macro" !FEWNAMES X '^X-(' ctlxrp NONE X "end-macro" !FEWNAMES X '^X-)' ctlxe REDO X "execute-macro" !FEWNAMES X '^X-&' cbuf1 REDO X "execute-macro-1" !FEWNAMES X 'FN-1' TERMCAP cbuf2 REDO X "execute-macro-2" !FEWNAMES X 'FN-2' TERMCAP cbuf3 REDO X "execute-macro-3" !FEWNAMES X 'FN-3' TERMCAP cbuf4 REDO X "execute-macro-4" !FEWNAMES X 'FN-4' TERMCAP cbuf5 REDO X "execute-macro-5" !FEWNAMES X 'FN-5' TERMCAP cbuf6 REDO X "execute-macro-6" !FEWNAMES X 'FN-6' TERMCAP cbuf7 REDO X "execute-macro-7" !FEWNAMES X 'FN-7' TERMCAP cbuf8 REDO X "execute-macro-8" !FEWNAMES X 'FN-8' TERMCAP cbuf9 REDO X "execute-macro-9" !FEWNAMES X 'FN-9' TERMCAP cbuf10 REDO X "execute-macro-10" !FEWNAMES cbuf11 REDO !SMALLER X "execute-macro-11" !FEWNAMES cbuf12 REDO !SMALLER X "execute-macro-12" !FEWNAMES cbuf13 REDO !SMALLER X "execute-macro-13" !FEWNAMES cbuf14 REDO !SMALLER X "execute-macro-14" !FEWNAMES cbuf15 REDO !SMALLER X "execute-macro-15" !FEWNAMES cbuf16 REDO !SMALLER X "execute-macro-16" !FEWNAMES cbuf17 REDO !SMALLER X "execute-macro-17" !FEWNAMES cbuf18 REDO !SMALLER X "execute-macro-18" !FEWNAMES cbuf19 REDO !SMALLER X "execute-macro-19" !FEWNAMES cbuf20 REDO !SMALLER X "execute-macro-20" !FEWNAMES cbuf21 REDO !SMALLER X "execute-macro-21" !FEWNAMES cbuf22 REDO !SMALLER X "execute-macro-22" !FEWNAMES cbuf23 REDO !SMALLER X "execute-macro-23" !FEWNAMES cbuf24 REDO !SMALLER X "execute-macro-24" !FEWNAMES cbuf25 REDO !SMALLER X "execute-macro-25" !FEWNAMES cbuf26 REDO !SMALLER X "execute-macro-26" !FEWNAMES cbuf27 REDO !SMALLER X "execute-macro-27" !FEWNAMES cbuf28 REDO !SMALLER X "execute-macro-28" !FEWNAMES cbuf29 REDO !SMALLER X "execute-macro-29" !FEWNAMES cbuf30 REDO !SMALLER X "execute-macro-30" !FEWNAMES cbuf31 REDO !SMALLER X "execute-macro-31" !FEWNAMES cbuf32 REDO !SMALLER X "execute-macro-32" !FEWNAMES cbuf33 REDO !SMALLER X "execute-macro-33" !FEWNAMES cbuf34 REDO !SMALLER X "execute-macro-34" !FEWNAMES cbuf35 REDO !SMALLER X "execute-macro-35" !FEWNAMES cbuf36 REDO !SMALLER X "execute-macro-36" !FEWNAMES cbuf37 REDO !SMALLER X "execute-macro-37" !FEWNAMES cbuf38 REDO !SMALLER X "execute-macro-38" !FEWNAMES cbuf39 REDO !SMALLER X "execute-macro-39" !FEWNAMES cbuf40 REDO !SMALLER X "execute-macro-40" !FEWNAMES delwind NONE X "delete-window" !FEWNAMES X '^K' X '^X-0' deblank REDO|UNDO AEDIT X "delete-blank-lines" !FEWNAMES X '^A-o' delgmode NONE X "delete-global-mode" !FEWNAMES X "setgno" X "unsetg" delmode NONE|(EXRCOK|EXTRA) X "delete-mode" !FEWNAMES X "setno" X "unset" deltoeol REDO|UNDO X "delete-to-end-of-line" !FEWNAMES X 'D' desbind NONE REBIND X "describe-bindings" deskey NONE REBIND X "describe-key" detab REDO|UNDO AEDIT X "detab-line" !FEWNAMES X '^A- ' dotcmdplay NONE X "repeat-last-cmd" !FEWNAMES X '.' execbuf NONE !SMALLER X "execute-buffer" !FEWNAMES execcmd NONE NEVER X "execute-command-line" !FEWNAMES execfile NONE !SMALLER X "execute-file" !FEWNAMES execproc REDO PROC X "execute-procedure" !FEWNAMES X "run" enlargewind NONE X "grow-window" !FEWNAMES X 'V' entab REDO|UNDO AEDIT X "entab-line" !FEWNAMES X '^A-^I' esc NONE X "abort-command" !FEWNAMES X '^[' fcsrch MOTION X "forward-char-scan" !FEWNAMES X 'f' fcsrch_to MOTION X "forward-char-scan-to" !FEWNAMES X 't' filefind NONE|(BANG|FILE1|PLUS) X "e" X "E" X "edit-file" !FEWNAMES X "find-file" !FEWNAMES X '^X-e' filename NONE|(NAMEDF) X "change-file-name" !FEWNAMES X "f" X "file" X "filename" fileread NONE X "e!" X "replace-with-file" !FEWNAMES filesave NONE !SMALLER X "save-file" filewrite NONE # "w" # "W" X "write-file" !FEWNAMES filter REDO|UNDO X "|" X "filter-buffer" !FEWNAMES finderr NONE FINDERR X "find-next-error" !FEWNAMES X '^X-^X' firstnonwhite MOTION X "first-nonwhite" !FEWNAMES X '^' fisearch NONE ISRCH X "incremental-search" !FEWNAMES X '^X-S' flipchar REDO|UNDO X "flip-character" !FEWNAMES X '~' fnclabel NONE FLABEL X "label-function-key" !FEWNAMES X "label-fkey" forwdelchar REDO|UNDO X "delete-next-character" !FEWNAMES X 'x' forwhpage NONE X "next-half-page" !FEWNAMES X '^D' forwchar MOTION X "forward-character" !FEWNAMES X ' ' X 'l' forwpage MOTION X "next-page" !FEWNAMES X '^F' forwline GOAL|MOTION|FL X "next-line" !FEWNAMES X 'j' X '^J' forwbline MOTION|FL X "next-line-at-bol" !FEWNAMES X '+' X '^M' forwword MOTION X "next-word" !FEWNAMES X 'W' forwviword MOTION X "next-punc-word" !FEWNAMES X 'w' forwendw MOTION X "next-word-end" !FEWNAMES X 'E' forwviendw MOTION X "next-punc-word-end" !FEWNAMES X 'e' forwhunt ABS|MOTION !SMALLER X "hunt-forward" !FEWNAMES forwsearch ABS|MOTION X "search-forward" !FEWNAMES X '/' getfence ABS|MOTION CFENCE X "goto-matching-fence" !FEWNAMES X '%' globals NONE GLOBALS X "og" # this function is for internal use only, for the operator commands godotplus MOTION|FL X # this function is for internal use only, for ex commands gomark MOTION|FL|(RANGE) X gotobop ABS|MOTION WORDPRO X "previous-paragraph" !FEWNAMES X '{' gotoeop ABS|MOTION WORDPRO X "next-paragraph" !FEWNAMES X '}' gotobob ABS|MOTION !SMALLER X "beginning-of-file" !FEWNAMES gotoeob ABS|MOTION !SMALLER X "end-of-file" !FEWNAMES gotobol MOTION X "beginning-of-line" !FEWNAMES X '0' gotoeol MOTION|GOAL X "end-of-line" !FEWNAMES X '$' gotobos MOTION|FL X "beginning-of-screen" !FEWNAMES X 'H' gotomos MOTION|FL X "middle-of-screen" !FEWNAMES X 'M' gotoeos MOTION|FL X "end-of-screen" !FEWNAMES X 'L' gotobosec ABS|MOTION WORDPRO X "previous-section" !FEWNAMES X '[' gotoeosec ABS|MOTION WORDPRO X "next-section" !FEWNAMES X ']' gototag NONE|(BANG|WORD1) TAGS X "ta" X "tag" X "find-tag" !FEWNAMES X '^]' gotocol MOTION X "goto-column" !FEWNAMES X '|' gotoline ABS|MOTION|FL|(RANGE) X "goto-line" !FEWNAMES X 'G' # golinenmmark and goexactnmmark are special cases-- # no ABS even though they are absolute, since these are the commands # that maintain the last-dot-mark golinenmmark MOTION|FL X "goto-named-mark" !FEWNAMES # single quote -- can't use ''' X '\047' goexactnmmark MOTION X "goto-named-mark-exact" !FEWNAMES X '`' help NONE X "h" X "help" X '^A-h' X '^X-h' histbuff NONE X "historical-buffer" !FEWNAMES X '_' X "_" insert REDO|UNDO X "insertchar" !FEWNAMES X 'i' insertbol REDO|UNDO X "insert-bol" !FEWNAMES X 'I' insfiletop REDO|UNDO BEFORE X "R" X "insert-file-at-top" !FEWNAMES insfile REDO|UNDO|GLOBOK|(FROM|ZERO|NAMEDF) X "r" X "insert-file" !FEWNAMES X '^R' insspace REDO|UNDO !SMALLER X "insert-space" !FEWNAMES istring REDO|UNDO !SMALLER X "insert-string" join REDO|UNDO X "join-lines" !FEWNAMES X 'J' killbuffer NONE X "delete-buffer" !FEWNAMES X "kill-buffer" !FEWNAMES X "ki" showlength NONE X "buffer-length" !FEWNAMES X "=" lastnonwhite MOTION !SMALLER X "last-nonwhite" !FEWNAMES listbuffers NONE X "list-buffers" !FEWNAMES X '^A-*' lineputafter REDO|UNDO|GLOBOK|(FROM|ZERO|WORD1) X "put-as-lines-after" !FEWNAMES X "put" X '^X-p' lineputbefore REDO|UNDO|GLOBOK|(FROM|WORD1) X "put-as-lines-before" !FEWNAMES X "Put" X '^X-P' lineundo NONE X "undo-line-changes" !FEWNAMES X 'U' map NONE|(EXRCOK|BANG|EXTRA) X "map" cntl_af NONE X "cntl_a-prefix" X '^A' opermove OPER|(RANGE|EXTRA) X "move" X "m" mvdnnxtwind NONE X "move-next-window-down" !FEWNAMES X '^A-^E' mvupnxtwind NONE X "move-next-window-up" !FEWNAMES X '^A-^Y' mvdnwind GOAL X "move-window-down" !FEWNAMES X '^E' mvupwind GOAL X "move-window-up" !FEWNAMES X '^Y' mvrightwind GOAL X "move-window-right" !FEWNAMES X '^X-^R' mvleftwind GOAL X "move-window-left" !FEWNAMES X '^X-^L' nextbuffer NONE|(BANG|NAMEDFS) X "n" X "next-buffer" !FEWNAMES namebuffer NONE X "rename-buffer" newline REDO|UNDO !SMALLER X "newline" newlength NONE X "screen-rows" newwidth NONE X "screen-columns" nextwind NONE X "next-window" !FEWNAMES X '^N' nullproc NONE X "nop" !FEWNAMES X '^Q' X '^S' onamedcmd NONE X "execute-named-command-old" !FEWNAMES X '^A-:' namedcmd NONE X "execute-named-command" !FEWNAMES X ":" X ':' ex NONE|(BANG|FILE1) X "ex" operchg OPER|REDO|UNDO X "change-til" !FEWNAMES X 'c' operlinechg OPER|REDO|UNDO|(RANGE) X "change-lines-til" !FEWNAMES X "ch" X '^X-c' operdel OPER|REDO|UNDO X "delete-til" !FEWNAMES X 'd' operlinedel OPER|REDO|UNDO|GLOBOK|(RANGE+WORD1) X "delete-lines-til" !FEWNAMES X "d" X '^X-d' operfilter OPER|REDO|UNDO|(EXRCOK|RANGE|NAMEDFS|DFLNONE|NL) X "filter-til" !FEWNAMES X "!" X '!' operformat OPER|REDO|UNDO|(RANGE) WORDPRO X "format-til" !FEWNAMES X '^A-f' X '^A-j' operflip OPER|REDO|UNDO|GLOBOK|(RANGE) X "flip-til" !FEWNAMES X "~" X '^A-~' # RANGE commented out, since it's not done.... operglobals OPER|(/*RANGE|*/BANG|EXTRA|DFLALL) GLOBALS X "global" X "g" opervglobals OPER|(RANGE|BANG|EXTRA|DFLALL) GLOBALS X "vglobal" X "v" operlower OPER|REDO|UNDO|GLOBOK|(RANGE) X "lower-til" !FEWNAMES X "L" X '^A-l' operlist OPER|GLOBOK|(RANGE) GLOBALS X "list-lines-til" !FEWNAMES X "l" operprint OPER|GLOBOK|(RANGE) GLOBALS X "print-lines-til" !FEWNAMES X "p" operupper OPER|REDO|UNDO|GLOBOK|(RANGE) X "upper-til" !FEWNAMES X "U" X '^A-u' operlshift OPER|REDO|UNDO|GLOBOK|(RANGE) X "shift-left-til" !FEWNAMES X "<" X '<' operrshift OPER|REDO|UNDO|GLOBOK|(RANGE) X "shift-right-til" !FEWNAMES X ">" X '>' opersubst OPER|REDO|UNDO|GLOBOK|(RANGE|EXTRA) X "substitute" !FEWNAMES X "s" X '^X-s' operyank OPER X "yank-til" !FEWNAMES X 'y' operlineyank OPER|(RANGE|WORD1) X "yank-lines-til" !FEWNAMES X "y" X '^X-y' openup REDO|UNDO|(FROM) X "open-line-above" !FEWNAMES X "insert" X "i" X 'O' opendown REDO|UNDO|(FROM|ZERO) X "open-line-below" !FEWNAMES X "append" X "a" X 'o' operwrite OPER|(RANGE|BANG|FILE1|DFLALL) X "w" X "W" X "write-til" !FEWNAMES X '^W' overwrite REDO|UNDO X "overwrite" !FEWNAMES X 'R' onlywind NONE X "delete-other-windows" !FEWNAMES X '^O' X '^X-1' poswind NONE X "position-window" !FEWNAMES X 'z' prevwind NONE X "previous-window" !FEWNAMES X '^P' pipecmd NONE X "pipe-command" !FEWNAMES X '^X-!' putafter REDO|UNDO X "put-after" !FEWNAMES X 'p' putbefore REDO|UNDO X "put-before" !FEWNAMES X 'P' quit NONE|(BANG) X "q" X "Q" X "exit" X 'Q' X '^X-^C' quithard NONE X "q!" quickexit NONE|(BANG|NL) X "x" X "xit" X "quick-exit" !FEWNAMES X 'Z' quote REDO|UNDO X "quote-character" !FEWNAMES X '^V' refresh NONE X "clear-and-redraw" !FEWNAMES X '^L' reposition NONE !SMALLER X "redraw-display" rep_csrch MOTION X "repeat-char-scan" !FEWNAMES X ';' replacechar REDO|UNDO X "replace-character" !FEWNAMES X 'r' respawn NONE X "!!" X "rerun-shell-command" !FEWNAMES resize NONE !SMALLER X "resize-window" restwnd NONE !SMALLER X "restore-window" rev_csrch MOTION X "reverse-char-scan" !FEWNAMES X ',' risearch NONE ISRCH X "reverse-incremental-search" !FEWNAMES X '^X-R' revsearch ABS|MOTION X "reverse-search" !FEWNAMES X 'N' scrforwsearch ABS|MOTION X "screen-search-forward" !FEWNAMES X '^X-/' scrbacksearch ABS|MOTION X "screen-search-reverse" !FEWNAMES X '^X-?' scrsearchpat NONE X "screen-search-pattern-grab" !FEWNAMES X '^A-/' settab NONE X "handle-tab" !FEWNAMES X "set-tab" X '^X-t' spawncli NONE X "sh" X "shell" X "i-shell" !FEWNAMES savewnd NONE !SMALLER X "save-window" scrnextup NONE X "scroll-next-up" !FEWNAMES X '^A-^U' scrnextdw NONE X "scroll-next-down" !FEWNAMES X '^A-^D' setfillcol NONE X "set-fill-column" X '^X-f' setkey NONE CRYPT X "set-crypt-key" X '^X-X' setmode NONE|(EXRCOK|EXTRA) X "set" X "set-mode" !FEWNAMES setgmode NONE X "setg" X "set-global-mode" setnmmark NONE|(FROM+WORD1) X "set-named-mark" !FEWNAMES X "k" X 'm' setvar NONE !SMALLER X "setv" X "set-variable" setvmalloc NONE VMALLOC X "vmalloc" X '^X-v' showcpos NONE X "position" !FEWNAMES X '^G' X '^X-=' showmodes NONE X "modes" X "show-modes" X "setall" showgmodes NONE X "gmodes" X "show-global-modes" X "setgall" showversion NONE|(EXRCOK) X "version" shrinkwind NONE X "shrink-window" !FEWNAMES X 'v' source NONE|(EXRCOK|NAMEDF) X "source" spawn NONE # "!" X "shell-command" !FEWNAMES splitwind NONE X "split-current-window" !FEWNAMES X '^T' X '^X-2' storemac NONE X "store-macro" storeproc NONE PROC X "store-procedure" subst_again REDO|UNDO|GLOBOK|(RANGE|EXTRA) X "substitute-again" !FEWNAMES X "&" opertransf OPER|(RANGE+EXTRA) X "t" togglelistbuffers NONE X "*" X "toggle-buffer-list" !FEWNAMES X '*' trimline REDO|UNDO|GLOBOK X "trim-line" !FEWNAMES X "trim" X '^A-t' twiddle REDO|UNDO !SMALLER X "transpose-characters" !FEWNAMES unbindkey NONE REBIND X "unbind-key" undo NONE X "undo-change" !FEWNAMES X 'u' unarg NONE X "universal-argument" !FEWNAMES X 'K' unimpl NONE X "unimplemented-command" !FEWNAMES X '(' X ')' unmark NONE X "unmark-buffer" unmap NONE|(EXRCOK|BANG|EXTRA) X "unmap" untagpop NONE TAGS X "untag-pop" !FEWNAMES X '^X-^]' upscreen NONE !SMALLER X "update-screen" usebuffer NONE X "b" X "buffer" X "select-buffer" !FEWNAMES usekreg REDO X "use-named-kill-register" !FEWNAMES X '"' visual NONE X "visual" vglobals NONE GLOBALS X "ov" viewfile NONE X "view-file" writequit NONE|(NL) X "wq" X "Wq" X "WQ" X "write-file-and-quit" !FEWNAMES wrapword REDO|UNDO !SMALLER X "wrap-word" writemsg NONE !SMALLER X "write-message" yankline NONE X "yank-line" !FEWNAMES X 'Y' X SHAR_EOF chmod 0444 cmdtbl || echo 'restore of cmdtbl failed' Wc_c="`wc -c < 'cmdtbl'`" test 17753 -eq "$Wc_c" || echo 'cmdtbl: original size 17753, current size' "$Wc_c" # ============= crypt.c ============== echo 'x - extracting crypt.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'crypt.c' && /* Crypt: Encryption routines for MicroEMACS X written by Dana Hoggatt and Daniel Lawrence */ X #include #include "estruct.h" #include "edef.h" X #if CRYPT setkey(f, n) /* reset encryption key of current buffer */ X int f; /* default flag */ int n; /* numeric argument */ X { X register int status; /* return status */ X int odisinp; /* original vlaue of disinp */ X char key[NPAT]; /* new encryption string */ X X /* turn command input echo off */ X odisinp = disinp; X disinp = FALSE; X X /* get the string to use as an encrytion string */ X key[0] = 0; X status = mlreply("Encryption String: ", key, NPAT - 1); X disinp = odisinp; X if (status != TRUE) X return(status); X X /* and encrypt it */ X crypt((char *)NULL, 0); X crypt(key, strlen(key)); X X /* and save it off */ X strcpy(curbp->b_key, key); X mlwrite(" "); /* clear it off the bottom line */ X return(TRUE); } X /********** X * X * crypt - in place encryption/decryption of a buffer X * X * (C) Copyright 1986, Dana L. Hoggatt X * 1216, Beck Lane, Lafayette, IN X * X * When consulting directly with the author of this routine, X * please refer to this routine as the "DLH-POLY-86-B CIPHER". X * X * This routine was written for Dan Lawrence, for use in V3.8 of X * MicroEMACS, a public domain text/program editor. X * X * I kept the following goals in mind when preparing this function: X * X * 1. All printable characters were to be encrypted back X * into the printable range, control characters and X * high-bit characters were to remain unaffected. this X * way, encrypted would still be just as cheap to X * transmit down a 7-bit data path as they were before. X * X * 2. The encryption had to be portable. The encrypted SHAR_EOF true || echo 'restore of crypt.c failed' echo 'End of Vile part 2' echo 'File crypt.c is continued in part 3' echo 3 > _shar_seq_.tmp exit 0 -- paul fox, pgf@cayman.com, (617)494-1999 Cayman Systems, 26 Landsdowne St., Cambridge, MA 02139