Vile 02/17 - vi feel-alike (multi-window)
Paul Fox
pgf at cayman.COM
Sat Jun 8 08:09:10 AEST 1991
#!/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,"<sp>")) {
X c |= ' ';
X } else if (!strcmp(k,"<tab>")) {
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 <SPACE> 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 <stdio.h>
#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; i<ntext; ++i)
X lputc(lp, i, text[i]);
X bp->b_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 <stdio.h>
#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 at cayman.com, (617)494-1999
Cayman Systems, 26 Landsdowne St., Cambridge, MA 02139
More information about the Alt.sources
mailing list