Subject: v08i027: The JOVE text editor, Part08/13 Newsgroups: mod.sources Approved: mirror!rs Submitted by: seismo!rochester!jpayne (Jonathan Payne) Mod.sources: Volume 8, Issue 27 Archive-name: jove/Part08 #! /bin/sh # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # If all goes well, you will see the message "End of archive 8 (of 13)." # Contents: temp.h term.c termcap.h tune.h util.c vars.c wind.c # doc/README doc/example.rc doc/jove.3 doc/system.rc # doc/teachjove.nr PATH=/bin:/usr/bin:/usr/ucb; export PATH echo shar: extracting "'temp.h'" '(3368 characters)' if test -f 'temp.h' ; then echo shar: will not over-write existing file "'temp.h'" else sed 's/^X//' >temp.h <<'@//E*O*F temp.h//' X/************************************************************************ X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * X * provided to you without charge, and with no warranty. You may give * X * away copies of JOVE, including sources, provided that this notice is * X * included in all the files. * X ************************************************************************/ X X/* The tmp file is indexed in chunks of CH_SIZE characters. CH_SIZE is X (1 << CH_BITS). New lines are added to the end of the tmp file. The X file is not garbage collected because that would be too painful. As a X result, commands like Yank and Kill are really easy; basically all we X do is make copies of the disk addresses of the lines (as opposed to X the contents). So, putline(buf) writes BUF to the disk and returns a X new disk address. Getline(addr, buf) is the opposite of putline(). X f_getputl(line, fp) reads from open FP directly into the tmp file (into X the buffer cache (see below)) and stores the address in LINE. This is X used during read_file to minimize compying. X X Lines do NOT cross block bounderies in the tmp file so that accessing X the contents of lines can be much faster. Pointers to offsets into X disk buffers are returned instead of copying the contents into local X arrays and then using them. This cuts down on the amount of copying a X great deal, at the expense of less efficiency. The lower bit of disk X addresses is used for marking lines as needing redisplay done. X X There is a buffer cache of NBUF buffers (64 on !SMALL machines and the X 3 on small ones). The blocks are stored in LRU order and each block X is also stored in a hash table by block #. When a block is requested X it can quickly be looked up in the hash table. If it's not there the X LRU block is assigned the new block #. If it finds that the LRU block X is dirty (i.e., has pending IO) it syncs the WHOLE tmp file, i.e., X does all the pending writes. This works much better on floppy disk X systems, like the IBM PC, if the blocks are sorted before sync'ing. */ X X#ifdef SMALL X# define CH_BITS 4 X# if BUFSIZ == 512 X# define MAX_BLOCKS 1024 X# else X# define MAX_BLOCKS 512 X# endif X#else X# define CH_BITS 0 X# define MAX_BLOCKS 4096 /* basically unlimited */ X#endif SMALL X X#if BUFSIZ == 512 X# define BNO_SHIFT (9 - CH_BITS) X#else X# define BNO_SHIFT (10 - CH_BITS) X#endif X X/* CH_SIZE is how big each chunk is. For each 1 the DFree pointer X is incremented we extend the tmp file by CH_SIZE characters. X CH_PBLOCK is the # of chunks per block. RND_MASK is used to mask X off the lower order bits of the daddr to round down to the beginning X of a block. OFF_MASK masks off the higher order bits so we can get X at the offset into the disk buffer. X X NOTE: It's pretty important that these numbers be multiples of X 2. Be careful if you change things. */ X X#define CH_SIZE (1 << CH_BITS) X#define CH_PBLOCK (BUFSIZ / CH_SIZE) X#define RND_MASK (CH_PBLOCK - 1) X#define OFF_MASK (BUFSIZ - 1) X#define BNO_MASK (MAX_BLOCKS - 1) X#define blk_round(daddr) (daddr & ~RND_MASK) X#define forward_block(daddr) (daddr + CH_PBLOCK) X#define daddr_to_bno(daddr) ((daddr >> BNO_SHIFT) & BNO_MASK) X#define daddr_to_off(daddr) ((daddr << CH_BITS) & OFF_MASK) @//E*O*F temp.h// if test 3368 -ne "`wc -c <'temp.h'`"; then echo shar: error transmitting "'temp.h'" '(should have been 3368 characters)' fi fi # end of overwriting check echo shar: extracting "'term.c'" '(3672 characters)' if test -f 'term.c' ; then echo shar: will not over-write existing file "'term.c'" else sed 's/^X//' >term.c <<'@//E*O*F term.c//' X/************************************************************************ X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * X * provided to you without charge, and with no warranty. You may give * X * away copies of JOVE, including sources, provided that this notice is * X * included in all the files. * X ************************************************************************/ X X#include "jove.h" X#include X#ifdef SYSV X# include X#else X# include X#endif SYSV X X#ifdef IPROCS X# include X#endif X X/* Termcap definitions */ X Xchar *UP, X *CS, X *SO, X *SE, X *CM, X *CL, X *CE, X *HO, X *AL, X *DL, X *VS, X *VE, X *KS, X *KE, X *TI, X *TE, X *IC, X *DC, X *IM, X *EI, X *LL, X *BC, X *M_IC, /* Insert char with arg */ X *M_DC, /* Delete char with arg */ X *M_AL, /* Insert line with arg */ X *M_DL, /* Delete line with arg */ X *SF, /* Scroll forward */ X *SR, X *SP, /* Send Cursor Position */ X#ifdef LSRHS X *RS, /* Reverse video start */ X *RE, /* Reverse end */ X#endif X *VB, X *IP, /* insert pad after character inserted */ X *lPC; X Xint LI, X ILI, /* Internal lines, i.e., 23 of LI is 24. */ X CO, X X UL, X MI, X SG, /* number of magic cookies left by SO and SE */ X XS, /* whether standout is braindamaged */ X X TABS, X UPlen, X HOlen, X LLlen; X X#ifdef SYSV /* release 2, at least */ Xchar PC ; X#else Xextern char PC; X#endif SYSV X Xstatic char tspace[256]; X X/* The ordering of ts and meas must agree !! */ X#ifdef LSRHS Xstatic char *ts="vsvealdlspcssosecmclcehoupbcicimdceillsfsrvbksketiteALDLICDCrsrepcip"; Xstatic char **meas[] = { X &VS, &VE, &AL, &DL, &SP, &CS, &SO, &SE, X &CM, &CL, &CE, &HO, &UP, &BC, &IC, &IM, X &DC, &EI, &LL, &SF, &SR, &VB, &KS, &KE, X &TI, &TE, &M_AL, &M_DL, &M_IC, &M_DC, X &RS, &RE, &lPC, &IP, 0 X}; X#else Xstatic char *ts="vsvealdlspcssosecmclcehoupbcicimdceillsfsrvbksketiteALDLICDCpcip"; Xstatic char **meas[] = { X &VS, &VE, &AL, &DL, &SP, &CS, &SO, &SE, X &CM, &CL, &CE, &HO, &UP, &BC, &IC, &IM, X &DC, &EI, &LL, &SF, &SR, &VB, &KS, &KE, X &TI, &TE, &M_AL, &M_DL, &M_IC, &M_DC, X &lPC, &IP, 0 X}; X#endif X Xstatic Xgets(buf) Xchar *buf; X{ X buf[read(0, buf, 12) - 1] = 0; X} X X/* VARARGS1 */ X Xstatic XTermError(fmt, a) Xchar *fmt; X{ X printf(fmt, a); X _exit(1); X} X XgetTERM() X{ X char *getenv(), *tgetstr() ; X char termbuf[13], X *termname = 0, X *termp = tspace, X tbuff[2048]; /* Good grief! */ X int i; X X termname = getenv("TERM"); X if (termname == 0) { X putstr("Enter terminal name: "); X gets(termbuf); X if (termbuf[0] == 0) X TermError(NullStr); X X termname = termbuf; X } X X if (tgetent(tbuff, termname) < 1) X TermError("[\"%s\" unknown terminal type?]", termname); X X if ((CO = tgetnum("co")) == -1) X TermError("columns?"); X X if ((LI = tgetnum("li")) == -1) X TermError("lines?"); X X if ((SG = tgetnum("sg")) == -1) X SG = 0; /* Used for mode line only */ X X if ((XS = tgetflag("xs")) == -1) X XS = 0; /* Used for mode line only */ X X for (i = 0; meas[i]; i++) { X *(meas[i]) = (char *) tgetstr(ts, &termp); X ts += 2; X } X if (lPC) X PC = *lPC; X if (XS) X SO = SE = 0; X X if (CS && !SR) X CS = SR = SF = 0; X X if (CS && !SF) X SF = "\n"; X X if (IM && (*IM == 0)) X IM = 0; X else X MI = tgetflag("mi"); X X UL = tgetflag("ul"); X X#ifdef LSRHS /* We, at the high school, are the only ones who X do SO right in termcap, but unfortunately the X right SO doesn't look as good with modelines. */ X if (RS) X SO = RS; X if (RE) X SE = RE; X /* I only ever use SO for the modeline anyway. */ X X/* SO is really BOLDFACE! Why is LS always right and the rest of the X world wrong? */ X#endif X#ifdef ID_CHAR X disp_opt_init(); X#endif X if (CanScroll = ((AL && DL) || CS)) X IDline_setup(termname); X} X @//E*O*F term.c// if test 3672 -ne "`wc -c <'term.c'`"; then echo shar: error transmitting "'term.c'" '(should have been 3672 characters)' fi fi # end of overwriting check echo shar: extracting "'termcap.h'" '(1965 characters)' if test -f 'termcap.h' ; then echo shar: will not over-write existing file "'termcap.h'" else sed 's/^X//' >termcap.h <<'@//E*O*F termcap.h//' X/************************************************************************ X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * X * provided to you without charge, and with no warranty. You may give * X * away copies of JOVE, including sources, provided that this notice is * X * included in all the files. * X ************************************************************************/ X X/* Termcap definitions */ X Xextern char X *UP, /* Scroll reverse, or up */ X *CS, /* If on vt100 */ X *SO, /* Start standout */ X *SE, /* End standout */ X *CM, /* The cursor motion string */ X *CL, /* Clear screen */ X *CE, /* Clear to end of line */ X *HO, /* Home cursor */ X *AL, /* Addline (insert line) */ X *DL, /* Delete line */ X *VS, /* Visual start */ X *VE, /* Visual end */ X *KS, /* Keypad mode start */ X *KE, /* Keypad mode end */ X *TI, /* Cursor addressing start */ X *TE, /* Cursor addressing end */ X *IC, /* Insert char */ X *DC, /* Delete char */ X *IM, /* Insert mode */ X *EI, /* End insert mode */ X *LL, /* Last line, first column */ X *M_IC, /* Insert char with arg */ X *M_DC, /* Delete char with arg */ X *M_AL, /* Insert line with arg */ X *M_DL, /* Delete line with arg */ X *SF, /* Scroll forward */ X *SR, /* Scroll reverse */ X *SP, /* Send cursor position */ X#ifdef LSRHS X *RS, /* reverse video start */ X *RE, /* reverse video end */ X#endif X *VB, /* visible bell */ X *IP, /* insert pad after character inserted */ X *lPC; X Xextern int X LI, /* number of lines */ X ILI, /* number of internal lines */ X CO, /* number of columns */ X X UL, /* underscores don't replace chars already on screen */ X MI, /* okay to move while in insert mode */ X SG, /* number of magic cookies left by SO and SE */ X X TABS, /* whether we are in tabs mode */ X UPlen, /* length of the UP string */ X HOlen, /* length of Home string */ X LLlen; /* length of lower string */ X Xextern char X PC, X *BC; /* back space */ X Xextern short ospeed; @//E*O*F termcap.h// if test 1965 -ne "`wc -c <'termcap.h'`"; then echo shar: error transmitting "'termcap.h'" '(should have been 1965 characters)' fi fi # end of overwriting check echo shar: extracting "'tune.h'" '(3598 characters)' if test -f 'tune.h' ; then echo shar: will not over-write existing file "'tune.h'" else sed 's/^X//' >tune.h <<'@//E*O*F tune.h//' X/************************************************************************ X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * X * provided to you without charge, and with no warranty. You may give * X * away copies of JOVE, including sources, provided that this notice is * X * included in all the files. * X ************************************************************************/ X X#define TUNED /* don't touch this */ X X/*#define LSRHS /* if this is Lincoln-Sudbury Regional High School */ X/*#define MSDOS /* if this is MSDOS */ X#define BSD4_2 /* Berkeley 4.2 BSD */ X/*#define BSD4_3 /* Berkeley 4.3 BSD */ X/*#define SYSV /* for (System III/System V) UNIX systems */ X#ifdef BSD4_3 X# ifndef BSD4_2 X# define BSD4_2 /* 4.3 is 4.2 only different. */ X# endif X#endif X X X#ifdef MSDOS X# define SMALL X#else /* assume we're UNIX or something */ X# if vax || sel || sun || pyr || mc68000 || tahoe || iAPX286 X# define VMUNIX /* Virtual Memory UNIX */ X# define BUFSIZ 1024 X# if iAPX286 X# define NBUF 48 X# else X# define NBUF 64 /* number of disk buffers */ X# endif iAPX286 X# else X# define SMALL X# define BUFSIZ 512 /* or 1024 */ X# define NBUF 3 X# endif X# X/* # define LOAD_AV /* Use the load average for various commands. X# Do not define this if you lack a load average X# system call and kmem is read protected. */ X# X# define JOB_CONTROL /* if you have job stopping */ X# X# ifdef JOB_CONTROL X# define MENLO_JCL X# define IPROCS /* Interactive processes only work with JOB_CONTROL. */ X# endif X# X# define SUBPROCS /* only on UNIX systems (NOT INCORPORATED YET) */ X#endif MSDOS X X#ifdef SMALL X typedef short disk_line; X#else X# if iAPX286 X typedef long disk_line; X# else X typedef int disk_line; X# endif iAPX286 X#endif SMALL X X#ifndef SMALL X# define ABBREV /* word abbreviation mode */ X# define BACKUPFILES /* enable the backup files code */ X# ifndef MSDOS X# define BIFF /* if you have biff (or the equivalent) */ X# define F_COMPLETION /* filename completion */ X# define CHDIR /* cd command and absolute pathnames */ X# define KILL0 /* kill(pid, 0) returns 0 if proc exists */ X# define SPELL /* spell words and buffer commands */ X# define ID_CHAR /* include code to IDchar */ X# define WIRED_TERMS /* include code for wired terminals */ X# define ANSICODES /* extra commands that process ANSI codes */ X# endif X# define LISP /* include the code for Lisp Mode */ X# define CMT_FMT /* include the comment formatting routines */ X#endif SMALL X X#if !sun && !iAPX286 X# define MY_MALLOC /* use more memory efficient malloc (not on suns) */ X#endif X X#define DFLT_MODE 0666 /* file will be created with this mode */ X X#ifdef BSD4_3 X# define RESHAPING /* enable windows to handle reshaping */ X#endif X X#ifdef BSD4_2 /* byte_copy(from, to, len) */ X# define byte_copy bcopy /* use fast assembler version */ X#endif X X#ifdef IPROCS X# ifdef BSD4_2 X# define INPUT_SIG SIGIO X# else X# define PIPEPROCS /* do it with pipes */ X# define INPUT_SIG SIGTINT X# endif X#endif X X#ifdef SYSV X# define byte_copy(s2, s1, n) memcpy(s1, s2, n) X# define bzero(s, n) memset(s, 0, n) X# define index strchr X# define rindex strrchr X#endif X X/* These are here since they define things in tune.c. If you add things to X tune.c, add them here too, if necessary. */ X X#ifndef NOEXTERNS Xextern char X TmpFilePath[128], X *d_tempfile, X *p_tempfile, X *Recover, X *CmdDb, X *Joverc, X X#ifdef PIPEPROCS X *Portsrv, X#endif X X Shell[], X ShFlags[]; X#endif NOEXTERNS @//E*O*F tune.h// if test 3598 -ne "`wc -c <'tune.h'`"; then echo shar: error transmitting "'tune.h'" '(should have been 3598 characters)' fi fi # end of overwriting check echo shar: extracting "'util.c'" '(13431 characters)' if test -f 'util.c' ; then echo shar: will not over-write existing file "'util.c'" else sed 's/^X//' >util.c <<'@//E*O*F util.c//' X/************************************************************************ X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * X * provided to you without charge, and with no warranty. You may give * X * away copies of JOVE, including sources, provided that this notice is * X * included in all the files. * X ************************************************************************/ X X#include "jove.h" X#include "ctype.h" X#include X#include X X#ifdef SYSV /* release 2, at least */ Xshort ospeed ; X#endif X Xstruct cmd * XFindCmd(proc) Xregister int (*proc)(); X{ X register struct cmd *cp; X X for (cp = commands; cp->Name; cp++) X if (cp->c_proc == proc) X return cp; X return 0; X} X Xint Interactive; /* True when we invoke with the command handler? */ Xchar *ProcFmt = ": %f "; X XExecCmd(cp) Xdata_obj *cp; X{ X LastCmd = cp; X if (cp->Type & MAJOR_MODE) X SetMajor((cp->Type >> 8)); X else if (cp->Type & MINOR_MODE) X TogMinor((cp->Type >> 8)); X else switch (cp->Type&TYPEMASK) { X case MACRO: X do_macro((struct macro *) cp); X break; X X case FUNCTION: X { X struct cmd *cmd = (struct cmd *) cp; X X if (cmd->c_proc) X (*cmd->c_proc)(); X } X } X} X XLine * Xlastline(lp) Xregister Line *lp; X{ X while (lp->l_next) X lp = lp->l_next; X return lp; X} X XUpper(c) Xregister int c; X{ X return (islower(c) ? toupper(c) : c); X} X Xint alarmed = 0; X Xchar key_strokes[100]; Xstatic char *key_p = key_strokes; X Xinit_strokes() X{ X key_strokes[0] = 0; X key_p = key_strokes; X} X Xadd_stroke(c) X{ X if (key_p + 5 > &key_strokes[(sizeof key_strokes) - 1]) X key_p = key_strokes; X sprintf(key_p, "%p ", c); X key_p += strlen(key_p); X} X Xslowpoke() X{ X alarmed++; X f_mess(key_strokes); X} X X#ifdef BSD4_2 X# define N_SEC 1 /* will be precisely 1 second on 4.2 */ X#else X# define N_SEC 2 /* but from 0 to 2 seconds otherwise */ X#endif X Xwaitchar() X{ X#ifdef EUNICE X return getch(); X#endif X unsigned int old_time; X int c; X int (*oldproc)(); X X alarmed = 0; X oldproc = signal(SIGALRM, slowpoke); X X if ((old_time = alarm((unsigned) N_SEC)) == 0) X old_time = UpdFreq; X c = getch(); X (void) alarm(old_time); X (void) signal(SIGALRM, oldproc); X X return c; X} X X/* dir > 0 means forward; else means backward. */ X Xchar * XStrIndex(dir, buf, charpos, what) Xchar *buf, X what; X{ X char *cp = &buf[charpos], X c; X X if (dir > 0) { X while (c = *cp++) X if (c == what) X return (cp - 1); X } else { X while (cp >= buf && (c = *cp--)) X if (c == what) X return (cp + 1); X } X return 0; X} X Xblnkp(buf) Xregister char *buf; X{ X register char c; X X while ((c = *buf++) && (c == ' ' || c == '\t')) X ; X return c == 0; /* It's zero if we got to the end of the Line */ X} X XLine * Xnext_line(line, num) Xregister Line *line; Xregister int num; X{ X if (num < 0) X return prev_line(line, -num); X if (line) X while (--num >= 0 && line->l_next != 0) X line = line->l_next; X return line; X} X XLine * Xprev_line(line, num) Xregister Line *line; Xregister int num; X{ X if (num < 0) X return next_line(line, -num); X if (line) X while (--num >= 0 && line->l_prev != 0) X line = line->l_prev; X return line; X} X XDotTo(line, col) XLine *line; X{ X Bufpos bp; X X bp.p_line = line; X bp.p_char = col; X SetDot(&bp); X} X X/* If bp->p_line is != current line, then save current line. Then set dot X to bp->p_line, and if they weren't equal get that line into linebuf. */ X XSetDot(bp) Xregister Bufpos *bp; X{ X register int notequal; X X if (bp == 0) X return; X X notequal = bp->p_line != curline; X if (notequal) X lsave(); X if (bp->p_line) X curline = bp->p_line; X curchar = bp->p_char; X if (notequal) X getDOT(); X} X XToLast() X{ X SetLine(curbuf->b_last); X Eol(); X} X Xint MarkThresh = 22; /* Average screen size ... */ Xstatic int line_diff; X XLineDist(nextp, endp) Xregister Line *nextp, X *endp; X{ X (void) inorder(nextp, 0, endp, 0); X return line_diff; X} X Xinorder(nextp, char1, endp, char2) Xregister Line *nextp, X *endp; X{ X int count = 0; X register Line *prevp = nextp; X X line_diff = 0; X if (nextp == endp) X return char1 < char2; X X while (nextp || prevp) { X if (nextp == endp || prevp == endp) X break; X if (nextp) X nextp = nextp->l_next; X if (prevp) X prevp = prevp->l_prev; X count++; X } X if (nextp == 0 && prevp == 0) X return -1; X line_diff = count; X X return nextp == endp; X} X XPushPntp(line) Xregister Line *line; X{ X exp_p = NO; X if (LineDist(curline, line) >= MarkThresh) X SetMark(); X} X XToFirst() X{ X SetLine(curbuf->b_first); X} X Xlength(line) XLine *line; X{ X return strlen(lcontents(line)); X}; X Xto_word(dir) Xregister int dir; X{ X register char c; X X if (dir > 0) { X while ((c = linebuf[curchar]) != 0 && !isword(c)) X curchar++; X if (eolp()) { X if (curline->l_next == 0) X return; X SetLine(curline->l_next); X to_word(dir); X return; X } X } else { X while (!bolp() && (c = linebuf[curchar - 1], !isword(c))) X --curchar; X if (bolp()) { X if (curline->l_prev == 0) X return; X SetLine(curline->l_prev); X Eol(); X to_word(dir); X } X } X} X X/* Are there any modified buffers? Allp means include B_PROCESS X buffers in the check. */ X XModBufs(allp) X{ X register Buffer *b; X X for (b = world; b != 0; b = b->b_next) { X if (b->b_type == B_SCRATCH) X continue; X if ((b->b_type == B_FILE || allp) && IsModified(b)) X return 1; X } X return 0; X} X Xchar * Xfilename(b) Xregister Buffer *b; X{ X return b->b_fname ? pr_name(b->b_fname) : "[No file]"; X} X Xchar * Xitoa(num) Xregister int num; X{ X static char line[15]; X X sprintf(line, "%d", num); X return line; X} X Xmin(a, b) Xregister int a, X b; X{ X return (a < b) ? a : b; X} X Xmax(a, b) Xregister int a, X b; X{ X return (a > b) ? a : b; X} X Xtiewind(w, bp) Xregister Window *w; Xregister Buffer *bp; X{ X int not_tied = (w->w_bufp != bp); X X UpdModLine++; /* Kludge ... but speeds things up considerably */ X w->w_line = bp->b_dot; X w->w_char = bp->b_char; X w->w_bufp = bp; X if (not_tied) X CalcWind(w); /* ah, this has been missing since the X beginning of time! */ X} X Xextern int Jr_Len; X Xchar * Xlcontents(line) Xregister Line *line; X{ X if (line == curline) X return linebuf; X else X return lbptr(line); X} X Xchar * Xltobuf(line, buf) XLine *line; Xchar *buf; X{ X if (line == curline) { X if (buf != linebuf) X strcpy(buf, linebuf); X Jr_Len = strlen(linebuf); X } else X getline(line->l_dline, buf); X return buf; X} X XDOTsave(buf) XBufpos *buf; X{ X buf->p_line = curline; X buf->p_char = curchar; X} X X/* Return none-zero if we had to rearrange the order. */ X Xfixorder(line1, char1, line2, char2) Xregister Line **line1, X **line2; Xregister int *char1, X *char2; X{ X Line *tline; X int tchar; X X if (inorder(*line1, *char1, *line2, *char2)) X return 0; X X tline = *line1; X tchar = *char1; X *line1 = *line2; X *char1 = *char2; X *line2 = tline; X *char2 = tchar; X X return 1; X} X Xinlist(first, what) Xregister Line *first, X *what; X{ X while (first) { X if (first == what) X return 1; X first = first->l_next; X } X return 0; X} X X/* Make `buf' modified and tell the redisplay code to update the modeline X if it will need to be changed. */ X Xint ModCount = 0; X Xmodify() X{ X extern int DOLsave; X X if (!curbuf->b_modified) X UpdModLine++; X curbuf->b_modified++; X DOLsave++; X if (!Asking) X ModCount++; X} X Xunmodify() X{ X if (curbuf->b_modified) X UpdModLine++; X curbuf->b_modified = 0; X} X Xnumcomp(s1, s2) Xregister char *s1, X *s2; X{ X register int count = 0; X X while (*s1 != 0 && *s1++ == *s2++) X count++; X return count; X} X Xchar * Xcopystr(str) Xchar *str; X{ X char *val = emalloc(strlen(str) + 1); X X strcpy(val, str); X return val; X} X X#ifndef byte_copy Xbyte_copy(from, to, count) Xregister char *from, X *to; Xregister int count; X{ X while (--count >= 0) X *to++ = *from++; X} X#endif X Xlen_error(flag) X{ X char *mesg = "[line too long]"; X X (flag == COMPLAIN) ? complain(mesg) : error(mesg); X} X X/* Insert num number of c's at offset atchar in a linebuf of LBSIZE */ X Xins_c(c, buf, atchar, num, max) Xchar c, *buf; X{ X register char *pp, *pp1; X register int len; X int numchars; /* Number of characters to copy forward */ X X if (num <= 0) X return; X len = atchar + strlen(&buf[atchar]); X if (len + num >= max) X len_error(COMPLAIN); X pp = &buf[len + 1]; /* + 1 so we can --pp (not pp--) */ X pp1 = &buf[len + num + 1]; X numchars = len - atchar; X while (numchars-- >= 0) X *--pp1 = *--pp; X pp = &buf[atchar]; X while (--num >= 0) X *pp++ = c; X} X XTwoBlank() X{ X register Line *next = curline->l_next; X X return ((next != 0) && X (*(lcontents(next)) == '\0') && X (next->l_next != 0) && X (*(lcontents(next->l_next)) == '\0')); X} X Xlinecopy(onto, atchar, from) Xregister char *onto, X *from; X{ X register char *endp = &onto[LBSIZE - 2]; X X onto += atchar; X X while (*onto = *from++) X if (onto++ >= endp) X len_error(ERROR); X} X Xchar * XIOerr(err, file) Xchar *err, *file; X{ X return sprint("Couldn't %s \"%s\".", err, file); X} X Xpclose(p) Xint *p; X{ X (void) close(p[0]); X (void) close(p[1]); X} X Xdopipe(p) Xint p[]; X{ X if (pipe(p) == -1) X complain("[Pipe failed]"); X} X X/* NOSTRICT */ X Xchar * Xemalloc(size) X{ X char *ptr; X X if (ptr = malloc((unsigned) size)) X return ptr; X /* Try garbage collecting lines */ X GCchunks(); X if (ptr = malloc((unsigned) size)) X return ptr; X /* Uh ... Oh screw it! */ X error("[Out of memory] "); X /* NOTREACHED */ X} X X/* Return the basename of file F. */ X Xchar * Xbasename(f) Xregister char *f; X{ X register char *cp; X X if (cp = rindex(f, '/')) X return cp + 1; X else X return f; X} X Xpush_env(savejmp) Xjmp_buf savejmp; X{ X byte_copy((char *) mainjmp, (char *) savejmp, sizeof (jmp_buf)); X} X Xpop_env(savejmp) Xjmp_buf savejmp; X{ X byte_copy((char *) savejmp, (char *) mainjmp, sizeof (jmp_buf)); X} X X#ifdef LOAD_AV X# ifdef BSD4_2 X# ifdef PURDUE_EE X Xget_la(dp) Xdouble *dp; X{ X *dp = (double) loadav(0) / 100.0; X} X X# else PURDUE_EE X X#include X Xstatic struct nlist nl[] = { X { "_avenrun" }, X#define X_AVENRUN 0 X { "" } X}; X Xget_la(dp) Xdouble *dp; X{ X double avenrun[3]; X static int kmem = 0; X X if (kmem == -1) { X *dp = 4.0; /* So shell commands will say "Chugging" */ X return; X } else if (kmem == 0) { X if ((kmem = open("/dev/kmem", 0)) == -1) { X f_mess("Can't open kmem for load average."); X *dp = 4.0; X return; X } X nlist("/vmunix", nl); X } X lseek(kmem, (long) nl[X_AVENRUN].n_value, 0); X read(kmem, (char *) avenrun, sizeof(avenrun)); X *dp = avenrun[0]; X} X X# endif PURDUE_EE X# else BSD4_2 X Xget_la(dp) Xdouble *dp; X{ X short avg[3]; X X gldav(avg); X *dp = (double) avg[0] / 256; X} X X# endif BSD4_2 X#endif LOAD_AV X X/* get the time buf, designated by *timep, from FROM to TO. */ Xchar * Xget_time(timep, buf, from, to) Xchar *buf; Xtime_t *timep; X{ X time_t now; X char *cp; X extern char *ctime(); X X if (timep != 0) X now = *timep; X else X (void) time(&now); X cp = ctime(&now) + from; X if (to == -1) X cp[strlen(cp) - 1] = '\0'; /* Get rid of \n */ X else X cp[to - from] = '\0'; X if (buf) { X strcpy(buf, cp); X return buf; X } else X return cp; X} X X/* Return length of null terminated string. */ X Xstrlen(s) Xregister char *s; X{ X register char *base = s + 1; /* Can you say kludge? */ X X while (*s++) X ; X return (s - base); X} X Xchar * Xindex(s, c) Xregister char *s; Xregister int c; X{ X register int c1; X X if (c != 0) X while (c1 = *s++) X if (c == c1) X return s - 1; X return 0; X} X Xstrcmp(s1, s2) Xregister char *s1, X *s2; X{ X if (!s1 || !s2) X return 1; /* Which is not zero ... */ X while (*s1 == *s2++) X if (*s1++ == '\0') X return 0; X return (*s1 - *--s2); X} X Xcasecmp(s1, s2) Xregister char *s1, X *s2; X{ X if (!s1 || !s2) X return 1; /* Which is not zero ... */ X while (*s1 == *s2++ || Upper(*s1) == Upper(s2[-1])) X if (*s1++ == '\0') X return 0; X return (*s1 - *--s2); X} X Xcasencmp(s1, s2, n) Xregister char *s1, X *s2; Xregister int n; X{ X if (!s1 || !s2) X return 1; /* Which is not zero ... */ X while (--n >= 0 && (*s1 == *s2++ || Upper(*s1) == Upper(s2[-1]))) X if (*s1++ == '\0') X return 0; X return ((n < 0) ? 0 : *s1 - *--s2); X} X Xnull_ncpy(to, from, n) Xchar *to, X *from; X{ X (void) strncpy(to, from, n); X to[n] = '\0'; X} X Xstrcpy(t, f) Xregister char *t, X *f; X{ X while (*t++ = *f++) X ; X} X X/* Tries to pause for delay/10 seconds OR until a character is typed X at the keyboard. This works well on BSD4_2 and not so well on the X rest. Returns 1 if it returned because of keyboard input, or 0 X otherwise. */ X XSitFor(delay) Xint delay; X{ X#ifdef BSD4_2 X#include X X struct timeval timer; X int readfds = 1, X writefds = 0, X exceptfds = 0; X X timer.tv_sec = (delay / 10); X timer.tv_usec = (delay % 10) * 100000; X X if (charp()) X return; X /* gross that I had to snarf this from getch() */ X if (!UpdMesg && !Asking) { /* Don't erase if we are asking */ X if (mesgbuf[0] && !errormsg) X message(NullStr); X } X redisplay(); X select(1, &readfds, &writefds, &exceptfds, &timer); X#else X static int cps[] = { X 0, X 5, X 7, X 11, X 13, X 15, X 20, X 30, X 60, X 120, X 180, X 240, X 480, X 960, X 1920, X 1920, X }; X register int nchars; X X if (charp()) X return; X nchars = (delay * cps[ospeed]) / 10; X redisplay(); X while ((--nchars > 0) && !InputPending) { X putchar(0); X if (OkayAbort) { X OkayAbort = 0; X InputPending = charp(); X } X } X#endif X} X Xsindex(pattern, string) Xregister char *pattern, X *string; X{ X register int len = strlen(pattern); X X while (*string != '\0') { X if (*pattern == *string && strncmp(pattern, string, len) == 0) X return TRUE; X string++; X } X return FALSE; X} X Xmake_argv(argv, ap) Xregister char *argv[]; Xva_list ap; X{ X register char *cp; X register int i = 0; X X argv[i++] = va_arg(ap, char *); X argv[i++] = basename(argv[0]); X while (cp = va_arg(ap, char *)) X argv[i++] = cp; X argv[i] = 0; X} @//E*O*F util.c// if test 13431 -ne "`wc -c <'util.c'`"; then echo shar: error transmitting "'util.c'" '(should have been 13431 characters)' fi fi # end of overwriting check echo shar: extracting "'vars.c'" '(3332 characters)' if test -f 'vars.c' ; then echo shar: will not over-write existing file "'vars.c'" else sed 's/^X//' >vars.c <<'@//E*O*F vars.c//' X/************************************************************************ X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * X * provided to you without charge, and with no warranty. You may give * X * away copies of JOVE, including sources, provided that this notice is * X * included in all the files. * X ************************************************************************/ X X#include "jove.h" X Xstruct variable variables[] = { X VARIABLE, "allow-^S-and-^Q", &OKXonXoff, V_BOOL|V_TTY_RESET, X VARIABLE, "allow-bad-filenames", &OkayBadChars, V_BOOL, X#ifdef ABBREV X VARIABLE, "auto-case-abbrev", &AutoCaseAbbrev, V_BOOL, X#endif X#ifdef F_COMPLETION X VARIABLE, "bad-filename-extensions", (int *) BadExtensions, V_STRING, X#endif X VARIABLE, "c-indentation-increment", &CIndIncrmt, V_BASE10, X VARIABLE, "case-ignore-search", &CaseIgnore, V_BOOL, X#ifdef CMT_FMT X VARIABLE, "comment-format", (int *) CmtFmt, V_STRING, X#endif X#ifdef BIFF X VARIABLE, "disable-biff", &BiffChk, V_BOOL, X#endif X VARIABLE, "error-window-size", &EWSize, V_BASE10, X VARIABLE, "file-creation-mode", &CreatMode, V_BASE8, X VARIABLE, "files-should-end-with-newline", &EndWNewline, V_BOOL, X VARIABLE, "internal-tabstop", &tabstop, V_BASE10|V_CLRSCREEN, X VARIABLE, "left-margin", &LMargin, V_BASE10, X VARIABLE, "mailbox", (int *) Mailbox, V_FILENAME, X VARIABLE, "mail-check-frequency", (int *) &MailInt, V_BASE10, X#ifdef BACKUPFILES X VARIABLE, "make-backup-files", &BkupOnWrite, V_BOOL, X#endif X VARIABLE, "mark-threshold", &MarkThresh, V_BASE10, X VARIABLE, "marks-should-float", &MarksShouldFloat, V_BOOL, X VARIABLE, "match-regular-expressions", &UseRE, V_BOOL, X VARIABLE, "meta-key", &MetaKey, V_BOOL|V_TTY_RESET, X VARIABLE, "mode-line", (int *) ModeFmt, V_STRING|V_MODELINE, X VARIABLE, "mode-line-should-standout", &BriteMode, V_BOOL|V_MODELINE, X VARIABLE, "paren-flash-delay", &PDelay, V_BASE10, X VARIABLE, "physical-tabstop", &phystab, V_BASE10|V_CLRSCREEN, X#ifdef IPROCS X VARIABLE, "process-prompt", (int *) proc_prompt, V_STRING, X#endif X VARIABLE, "interrupt-character", &IntChar, V_CHAR|V_TTY_RESET, X VARIABLE, "right-margin", &RMargin, V_BASE10, X VARIABLE, "scroll-step", &ScrollStep, V_BASE10, X VARIABLE, "search-exit-char", &SExitChar, V_CHAR, X VARIABLE, "send-typeout-to-buffer", &UseBuffers, V_BOOL, X VARIABLE, "shell", (int *) Shell, V_STRING, X VARIABLE, "shell-flags", (int *) ShFlags, V_STRING, X VARIABLE, "sync-frequency", &SyncFreq, V_BASE10, X VARIABLE, "tag-file", (int *) TagFile, V_FILENAME, X VARIABLE, "tmp-file-pathname", (int *) TmpFilePath, V_FILENAME, X VARIABLE, "update-time-frequency", &UpdFreq, V_BASE10, X#ifdef ID_CHAR X VARIABLE, "use-i/d-char", &UseIC, V_BOOL, X#endif X VARIABLE, "visible-bell", &VisBell, V_BOOL, X VARIABLE, "wrap-search", &WrapScan, V_BOOL, X VARIABLE, "write-files-on-make", &WtOnMk, V_BOOL, X VARIABLE, 0, 0, 0 X}; X Xdata_obj * Xfindvar(prompt) Xchar *prompt; X{ X static char *strings[(sizeof variables) / sizeof (struct variable)]; X static int beenhere = 0; X register int com; X X if (beenhere == 0) { X register char **strs = strings; X register struct variable *v = variables; X X beenhere = 1; X for (; v->Name; v++) X *strs++ = v->Name; X *strs = 0; X } X X if ((com = complete(strings, prompt, NOTHING)) < 0) X return 0; X return (data_obj *) &variables[com]; X} @//E*O*F vars.c// if test 3332 -ne "`wc -c <'vars.c'`"; then echo shar: error transmitting "'vars.c'" '(should have been 3332 characters)' fi fi # end of overwriting check echo shar: extracting "'wind.c'" '(8645 characters)' if test -f 'wind.c' ; then echo shar: will not over-write existing file "'wind.c'" else sed 's/^X//' >wind.c <<'@//E*O*F wind.c//' X/************************************************************************ X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * X * provided to you without charge, and with no warranty. You may give * X * away copies of JOVE, including sources, provided that this notice is * X * included in all the files. * X ************************************************************************/ X X/* This creates/deletes/divides/grows/shrinks windows. */ X X#include "jove.h" X#include "termcap.h" X Xstatic char onlyone[] = "You only have one window!", X toosmall[] = "Resulting window would be too small."; X XWindow *curwind, X *fwind = 0; X X/* First line in a Window */ X XFLine(w) Xregister Window *w; X{ X register Window *wp = fwind; X register int lineno = -1; X X do { X if (wp == w) X return lineno + 1; X lineno += wp->w_height; X wp = wp->w_next; X } while (wp != fwind); X complain("window?"); X /* NOTREACHED */ X} X X/* Delete `wp' from the screen. If it is the only window left X on the screen, then complain. It gives its body X to the next window if there is one, otherwise the previous X window gets the body. */ X Xdel_wind(wp) Xregister Window *wp; X{ X register Window *prev = wp->w_prev; X X if (one_windp()) X complain(onlyone); X X wp->w_prev->w_next = wp->w_next; X wp->w_next->w_prev = wp->w_prev; X X if (fwind == wp) { X fwind = wp->w_next; X fwind->w_height += wp->w_height; X /* Here try to do something intelligent for redisplay() */ X SetTop(fwind, prev_line(fwind->w_top, wp->w_height)); X if (curwind == wp) X SetWind(fwind); X } else { X prev->w_height += wp->w_height; X if (curwind == wp) X SetWind(prev); X } X free((char *) wp); X} X X/* Divide the window WP N times, or at least once. Complains if WP is too X small to be split into that many pieces. It returns the new window. */ X XWindow * Xdiv_wind(wp, n) Xregister Window *wp; X{ X register Window *new; X int amt; X X if (n < 1) X n = 1; X amt = wp->w_height / (n + 1); X if (amt < 2) X complain(toosmall); X X while (--n >= 0) { X new = (Window *) emalloc(sizeof (Window)); X new->w_flags = 0; X X new->w_height = amt; X wp->w_height -= amt; X X /* set the lines such that w_line is the center in X each Window */ X new->w_line = wp->w_line; X new->w_char = wp->w_char; X new->w_bufp = wp->w_bufp; X new->w_top = prev_line(new->w_line, HALF(new)); X X /* Link the new window into the list */ X new->w_prev = wp; X new->w_next = wp->w_next; X new->w_next->w_prev = new; X wp->w_next = new; X } X return new; X} X X/* Initialze the first window setting the bounds to the size of the X screen. There is no buffer with this window. See parse for the X setting of this window. */ X Xwinit() X{ X register Window *w; X X w = curwind = fwind = (Window *) emalloc(sizeof (Window)); X w->w_line = w->w_top = 0; X w->w_flags = 0; X w->w_char = 0; X w->w_next = w->w_prev = fwind; X w->w_height = ILI; X} X X/* Change to previous window. */ X XPrevWindow() X{ X register Window *new = curwind->w_prev; X X if (one_windp()) X complain(onlyone); X SetWind(new); X} X X/* Make NEW the current Window */ X XSetWind(new) Xregister Window *new; X{ X if (!Asking){ /* can you say kludge? */ X curwind->w_line = curline; X curwind->w_char = curchar; X curwind->w_bufp = curbuf; X } X if (new == curwind) X return; X SetBuf(new->w_bufp); X if (!inlist(new->w_bufp->b_first, new->w_line)) { X new->w_line = curline; X new->w_char = curchar; X } X DotTo(new->w_line, new->w_char); X if (curchar > strlen(linebuf)) X new->w_char = curchar = strlen(linebuf); X curwind = new; X} X X/* delete the current window if it isn't the only one left */ X XDelCurWindow() X{ X SetABuf(curwind->w_bufp); X del_wind(curwind); X} X X/* put the current line of `w' in the middle of the window */ X XCentWind(w) Xregister Window *w; X{ X SetTop(w, prev_line(w->w_line, HALF(w))); X} X Xint ScrollStep = 0; /* full scrolling */ X X/* Calculate the new topline of the window. If ScrollStep == 0 X it means we should center the current line in the window. */ X XCalcWind(w) Xregister Window *w; X{ X register int up; X Line *newtop; X X if (ScrollStep == 0) /* Means just center it */ X CentWind(w); X else { X up = inorder(w->w_line, 0, w->w_top, 0); X if (up == -1) { X CentWind(w); X return; X } X if (up) /* Dot is above the screen */ X newtop = prev_line(w->w_line, min(ScrollStep - 1, HALF(w))); X else X newtop = prev_line(w->w_line, (SIZE(w) - 1) - X min(ScrollStep - 1, HALF(w))); X if (LineDist(newtop, w->w_top) >= SIZE(w) - 1) X CentWind(w); X else X SetTop(w, newtop); X } X} X X/* This is bound to C-X 4 [BTF]. To make the screen stay the X same we have to remember various things, like the current X top line in the current window. It's sorta gross, but it's X necessary because of the way this is implemented (i.e., in X terms of do_find(), do_select() which manipulate the windows. */ XWindFind() X{ X register Buffer *obuf = curbuf, X *nbuf; X Line *ltop = curwind->w_top; X Bufpos savedot; X extern int X FindTag(), X BufSelect(), X FindFile(); X X DOTsave(&savedot); X X switch (waitchar()) { X case 't': X case 'T': X ExecCmd((data_obj *) FindCmd(FindTag)); X break; X X case 'b': X case 'B': X ExecCmd((data_obj *) FindCmd(BufSelect)); X break; X X case 'f': X case 'F': X ExecCmd((data_obj *) FindCmd(FindFile)); X break; X X default: X complain("T: find-tag, F: find-file, B: select-buffer."); X } X X nbuf = curbuf; X SetBuf(obuf); X SetDot(&savedot); X SetTop(curwind, ltop); /* there! it's as if we did nothing */ X X if (one_windp()) X (void) div_wind(curwind, 1); X X tiewind(curwind->w_next, nbuf); X SetWind(curwind->w_next); X} X X/* Go into one window mode by deleting all the other windows */ X XOneWindow() X{ X while (curwind->w_next != curwind) X del_wind(curwind->w_next); X} X XWindow * Xwindbp(bp) Xregister Buffer *bp; X{ X X register Window *wp = fwind; X X if (bp == 0) X return 0; X do { X if (wp->w_bufp == bp) X return wp; X wp = wp->w_next; X } while (wp != fwind); X return 0; X} X X/* Change window into the next window. Curwind becomes the new window. */ X XNextWindow() X{ X register Window *new = curwind->w_next; X X if (one_windp()) X complain(onlyone); X SetWind(new); X} X X/* Scroll the next Window */ X XPageNWind() X{ X if (one_windp()) X complain(onlyone); X NextWindow(); X NextPage(); X PrevWindow(); X} X XWindow * Xw_nam_typ(name, type) Xregister char *name; X{ X register Window *w; X register Buffer *b; X X b = buf_exists(name); X w = fwind; X if (b) do { X if (w->w_bufp == b) X return w; X } while ((w = w->w_next) != fwind); X X w = fwind; X do { X if (w->w_bufp->b_type == type) X return w; X } while ((w = w->w_next) != fwind); X X return 0; X} X X/* Put a window with the buffer `name' in it. Erase the buffer if X `clobber' is non-zero. */ X Xpop_wind(name, clobber, btype) Xregister char *name; X{ X register Window *wp; X register Buffer *newb; X X if (newb = buf_exists(name)) X btype = -1; /* if the buffer exists, don't change X it's type */ X if ((wp = w_nam_typ(name, btype)) == 0) { X if (one_windp()) X SetWind(div_wind(curwind, 1)); X else X PrevWindow(); X } else X SetWind(wp); X X newb = do_select((Window *) 0, name); X if (clobber) { X initlist(newb); X newb->b_modified = NO; X } X tiewind(curwind, newb); X if (btype != -1) X newb->b_type = btype; X SetBuf(newb); X} X XGrowWindow() X{ X WindSize(curwind, abs(exp)); X} X XShrWindow() X{ X WindSize(curwind, -abs(exp)); X} X X/* Change the size of the window by inc. First arg is the window, X second is the increment. */ X XWindSize(w, inc) Xregister Window *w; Xregister int inc; X{ X if (one_windp()) X complain(onlyone); X X if (inc == 0) X return; X else if (inc < 0) { /* Shrinking this Window. */ X if (w->w_height + inc < 2) X complain(toosmall); X w->w_height += inc; X w->w_prev->w_height -= inc; X } else /* Growing the window. */ X WindSize(w->w_next, -inc); X} X X/* Set the topline of the window, calculating its number in the buffer. X This is for numbering the lines only. */ X XSetTop(w, line) XWindow *w; Xregister Line *line; X{ X register Line *lp = w->w_bufp->b_first; X register int num = 0; X X w->w_top = line; X if (w->w_flags & W_NUMLINES) { X while (lp) { X num++; X if (line == lp) X break; X lp = lp->l_next; X } X w->w_topnum = num; X } X} X XWNumLines() X{ X curwind->w_flags ^= W_NUMLINES; X SetTop(curwind, curwind->w_top); X} X XWVisSpace() X{ X curwind->w_flags ^= W_VISSPACE; X ClAndRedraw(); X} X X/* Return the line number that `line' occupies in `windes' */ X Xin_window(windes, line) Xregister Window *windes; Xregister Line *line; X{ X register int i; X register Line *top = windes->w_top; X X for (i = 0; top && i < windes->w_height - 1; i++, top = top->l_next) X if (top == line) X return FLine(windes) + i; X return -1; X} X XSplitWind() X{ X SetWind(div_wind(curwind, exp_p ? (exp - 1) : 1)); X} @//E*O*F wind.c// if test 8645 -ne "`wc -c <'wind.c'`"; then echo shar: error transmitting "'wind.c'" '(should have been 8645 characters)' fi fi # end of overwriting check echo shar: extracting "'doc/README'" '(306 characters)' if test -f 'doc/README' ; then echo shar: will not over-write existing file "'doc/README'" else sed 's/^X//' >doc/README <<'@//E*O*F doc/README//' XTo create the jove manual (as opposed to the man pages) Xjust do "nroff -ms jove.[12345]" (or ditroff or troff). XThat should do the trick. The man pages will be installed Xautomatically by "make install" in the previous directory. XAnd the online/run-time documentation will be installed Xautomatically, too. @//E*O*F doc/README// if test 306 -ne "`wc -c <'doc/README'`"; then echo shar: error transmitting "'doc/README'" '(should have been 306 characters)' fi fi # end of overwriting check echo shar: extracting "'doc/example.rc'" '(715 characters)' if test -f 'doc/example.rc' ; then echo shar: will not over-write existing file "'doc/example.rc'" else sed 's/^X//' >doc/example.rc <<'@//E*O*F doc/example.rc//' Xif /ua/jonathan/src/jove/lib/isttytype iq120 X bind-to-key Prefix-1 \\ X bind-to-key set-mark ^[ X set allow-^S-and-^Q on Xendif Xif /ua/jonathan/src/jove/lib/modemp X set mode-line -%n %m "%f" %((%t%s%C%s%l)%) Xelse X set mode-line -%n- %["%f" %m [%b] %]%s%((%t%s%C%s%l)%)%s(%M) %e Xendif Xauto-execute-command show-match .*\.[ch]$ Xset comment-format /* %! %c%! */ Xset disable-biff on Xset match-regular-expressions on Xset use-i/d-char off Xbind-to-key backward-paragraph ^[[ Xbind-to-key current-error ^X^C Xbind-to-key exit-jove ^X^Z Xbind-to-key find-tag-at-point ^[^T Xbind-to-key grow-window ^Xg Xbind-to-key kill-s-expression ^[^K Xbind-to-key list-processes ^X^L Xbind-to-key scroll-down ^C Xbind-to-key shrink-window ^Xs @//E*O*F doc/example.rc// if test 715 -ne "`wc -c <'doc/example.rc'`"; then echo shar: error transmitting "'doc/example.rc'" '(should have been 715 characters)' fi fi # end of overwriting check echo shar: extracting "'doc/jove.3'" '(13444 characters)' if test -f 'doc/jove.3' ; then echo shar: will not over-write existing file "'doc/jove.3'" else sed 's/^X//' >doc/jove.3 <<'@//E*O*F doc/jove.3//' X.NH 1 XDirectory Handling X.XS \n(PN X\*(SN Directory Handling X.XE X.LP XTo save having to use absolute pathnames when you want to edit a nearby file X\s-2JOVE\s0 allows you to move around the X.UX Xfilesystem just as the c-shell does. XThese commands are: X.IP "cd dir" 15n XChange to the specified directory. X.IP "pushd [dir]" XLike \fIcd\fP, but save the old directory on the directory stack. XWith no directory argument, simply exchange the top two directories Xon the stack and \fIcd\fP to the new top. X.IP "popd" XTake the current directory off the stack and \fIcd\fP to the directory now Xat the top. X.IP "dirs" XDisplay the contents of the directory stack. X.LP XThe names and behavior of these commands were chosen to mimic those in the c-shell. X.NH 1 XEditing C Programs X.XS \n(PN X\*(SN Editing C Programs X.XE X.LP XThis section details the support provided by \s-2JOVE\s0 Xfor working on C programs. X.NH 2 XIndentation Commands X.XS \n(PN 5n X\*(SN Indentation Commands X.XE X.LP XTo save having to lay out C programs "by hand", \s-2JOVE\s0 Xhas an idea of the correct indentation of a line, Xbased on the surrounding context. XWhen you are in C Mode, \s-2JOVE\s0 treats tabs specially \(em Xtyping a tab at the beginning of a new line means "indent to Xthe right place". XClosing braces are also handled specially, and are indented Xto match the corresponding open brace. X.NH 2 XParenthesis and Brace Matching X.XS \n(PN 5n X\*(SN Parenthesis and Brace Matching X.XE X.LP XTo check that parentheses and braces match the way you think they do, Xturn on \fIShow Match\fP mode (ESC X show-match-mode). Then, whenever Xyou type a close brace or parenthesis, the cursor moves momentarily to Xthe matching opener, if it's currently visible. If it's not visible, X\s-2JOVE\s0 displays the line containing the matching opener on the message Xline. X.NH 2 XC Tags X.XS \n(PN 5n X\*(SN C Tags X.XE X.LP XOften when you are editing a C program, Xespecially someone else's code, Xyou see a function call and wonder what that function does. XYou then search for the function within the current file and if you're Xlucky find Xthe definition, finally returning to the original spot when you are done. XHowever, if are unlucky, the function turns out to be external X(defined in another file) and Xyou have to suspend the edit, X\fIgrep\fP for the function name in every .c that might contain it, Xand finally visit the appropriate file. X.LP XTo avoid this diversion or the need to remember which Xfunction is defined in which file, XBerkeley X.UX Xhas a program called \fIctags(1)\fP, which Xtakes a set of source files and looks for function Xdefinitions, producing a file called \fItags\fP as its output. X.LP X\s-2JOVE\s0 has a command called C-X T (\fIfind-tag\fP) Xthat prompts you for the name of a function (a \fItag\fP), looks up Xthe tag reference in the previously constructed tags file, Xthen visits the file containing that tag in a new buffer, Xwith point positioned at the definition of the function. XThere is another version of this command, namely \fIfind-tag-at-point\fP, Xthat uses the identifier at X.I point. X.LP XSo, when you've added new functions to a module, or moved some old Xones around, run the \fIctags\fP program to regenerate the \fItags\fP file. X\s-2JOVE\s0 looks in the file specified in the \fItag-file\fP variable. The Xdefault is "./tags", that is, the tag file in the current directory. If you Xwish to use an alternate tag file, you use C-U\ C-X\ T, and \s-2JOVE\s0 will Xprompt for a file name. If you find yourself specifying the same file again Xand again, you can set \fItag-file\fP to that file, and run X\fIfind-tag\fP with no numeric argument. X.LP XTo begin an editing session looking for a particular tag, use Xthe \fI\-t tag\fP command line option to \s-2JOVE\s0. XFor example, say you wanted to look at the file containing the tag X\fISkipChar\fP, you would invoke \s-2JOVE\s0 as: X.DS I X.I X% jove \-t SkipChar X.R X.DE X.NH 2 XCompiling Your Program X.XS \n(PN 5n X\*(SN Compiling Your Program X.XE X.LP XYou've typed in a program or altered an existing one and now you Xwant to run it through the compiler to check for errors. XTo save having to suspend the edit, Xrun the compiler, Xscribble down error messages, and then resume the edit, X\s-2JOVE\s0 allows you to compile your code while in the editor. XThis is done with the C-X C-E (\fIcompile-it\fP) command. XIf you run \fIcompile-it\fP with no argument Xit runs the X.UX X\fImake\fP Xprogram into a buffer; XIf you need a special command or want to pass arguments to \fImake\fP, Xrun \fIcompile-it\fP with any argument (C-U is good enough) and you Xwill be prompted for the command to execute. X.LP XIf any error messages are produced, they are treated specially by \s-2JOVE\s0. XThat treatment is the subject of the next section. X.NH 2 XError Message Parsing and Spelling Checking X.XS \n(PN X\*(SN Error Message Parsing X\*(SN Spelling Checking X.XE X.LP X\s-2JOVE\s0 knows how to interpret the error messages from many X.UX Xcommands; XIn particular, Xthe messages from \fIcc\fP, X\fIgrep\fP and \fIlint\fP can be understood. XAfter running the \fIcompile-it\fP command, Xthe \fIparse-errors\fP command is automatically executed, Xand any errors found are displayed in a new buffer. XThe files whose names are found in parsing the error messages are each Xbrought into \s-2JOVE\s0 buffers and the point is positioned at the first error Xin the first file. XThe commands \fIcurrent-error\fP, C-X C-N (\fInext-error\fP), and XC-X C-P (\fIprevious-error\fP) Xcan be used to traverse the list of errors. X.LP XIf you already have a file called X\fIerrs\fP containing, say, c compiler messages then you can get \s-2JOVE\s0 to interpret the messages by Xinvoking it as: X.DS I X.I X% jove \-p errs X.R X.DE X.LP X\s-2JOVE\s0 has a special mechanism for checking the the spelling of a document; XIt runs the X.UX Xspell program into a buffer. XYou then delete from this buffer all those words that are not spelling Xerrors and then \s-2JOVE\s0 runs the \fIparse-spelling-errors\fP command to Xyield a list of errors just as in the last section. X.NH 1 XSimple Customization X.XS \n(PN X\*(SN Simple Customization X.XE X.LP X.NH 2 XMajor Modes X.XS \n(PN 5n X\*(SN Major Modes X.XE X.LP XTo help with editing particular types of file, say a paper or a C program, X\s-2JOVE\s0 has several \fImajor modes\fP. XThese are as follows: X.NH 3 XText mode X.XS \n(PN 10n X\*(SN Text mode X.XE X.LP XThis is the default major mode. Nothing special is done. X.NH 3 XC mode X.XS \n(PN 10n X\*(SN C mode X.XE X.LP XThis mode affects the behavior of the tab and parentheses characters. XInstead of just inserting the tab, \s-2JOVE\s0 determines Xwhere the text "ought" to line up for the C language and tabs to that position Xinstead. The same thing happens with the close brace and close parenthesis; Xthey are tabbed to the "right" place and then inserted. XUsing the \fIauto-execute-command\fP command, you can make \s-2JOVE\s0 enter X\fIC Mode\fP whenever you edit a file whose name ends in \fI.c\fP. X.NH 3 XLisp mode X.XS \n(PN 10n X\*(SN Lisp mode X.XE X.LP XThis mode is analogous to \fIC Mode\fP, Xbut performs the indentation needed to lay out Lisp programs properly. XNote also the \fIgrind-s-expr\fP command that prettyprints an X\fIs-expression\fP and the \fIkill-mode-expression\fP command. X.NH 2 XMinor Modes X.XS \n(PN 5n X\*(SN Minor Modes X.XE X.LP XIn addition to the major modes, X\s-2JOVE\s0 has a set of minor modes. XThese are as follows: X.NH 3 XAuto Indent X.XS \n(PN 10n X\*(SN Auto Indent X.XE X.LP XIn this mode, X\s-2JOVE\s0 indents each line the same way as that above it. That is, Xthe Return key in this mode acts as the Linefeed key ordinarily does. X.NH 3 XShow Match X.XS \n(PN 10n X\*(SN Show Match X.XE X.LP XMove the cursor momentarily to the matching opening parenthesis when a closing Xparenthesis is typed. X.NH 3 XAuto Fill X.XS \n(PN 10n X\*(SN Auto Fill X.XE X.LP XIn \fIAuto Fill\fP mode, Xa newline is automatically inserted when the line length Xexceeds the right margin. XThis way, Xyou can type a whole paper without having to use the Return key. X.NH 3 XOver Write X.XS \n(PN 10n X\*(SN Over Write X.XE X.LP XIn this mode, Xany text typed in will replace the previous contents. X(The default is for new text to be inserted and "push" the old along.) XThis is useful for editing an already-formatted diagram in which you Xwant to change some things without moving other things around on the Xscreen. X.NH 3 XWord Abbrev X.XS \n(PN 10n X\*(SN Word Abbrev X.XE X.LP XIn this mode, every word you type is compared to a list of word Xabbreviations; whenever you type an abbreviation, it is replaced Xby the text that it abbreviates. XThis can save typing if a particular word or phrase must be entered Xmany times. XThe abbreviations and their expansions are held in a file that looks like: X.DS I Xabbrev:phrase X.DE XThis file can be set up in your \fI~/.\|joverc\fP with the \fIread-word-abbrev-file\fP command. XThen, whenever you are editing a buffer in \fIWord Abbrev\fP mode, X\s-2JOVE\s0 checks for the abbreviations you've given. XSee also the commands X\fIread-word-abbrev-file\fP, X\fIwrite-word-abbrev-file\fP, X\fIedit-word-abbrevs\fP, X\fIdefine-global-word-abbrev\fP, X\fIdefine-mode-word-abbrev\fP, Xand \fIbind-macro-to-word-abbrev\fP, Xand the variable \fIauto-case-abbrev\fP. X.NH 2 XVariables X.XS \n(PN 5n X\*(SN Variables X.XE X.LP X\s-2JOVE\s0 can be tailored to suit your needs by changing the Xvalues of variables. XA \s-2JOVE\s0 variable can be given a value with the \fIset\fP command, Xand its value displayed with the \fIprint\fP command. X.LP XThe variables \s-2JOVE\s0 understands are listed along with the commands Xin the alphabetical list at the end of this document. X.NH 2 XKey Re-binding X.XS \n(PN 5n X\*(SN Key Re-binding X.XE X.LP XMany of the commands built into \s-2JOVE\s0 are not bound to Xspecific keys. XThe command handler in X\s-2JOVE\s0 is used to invoke these commands and is activated Xby the \fIexecute-extended-command\fP command (ESC X). XWhen the name of a command typed in is unambiguous, Xthat command will be executed. XSince it is very slow to have Xto type in the name of each command every time it is needed, X\s-2JOVE\s0 makes it possible to \fIbind\fP commands to keys. XWhen a command is X\fIbound\fP to a key any future hits on that key will invoke that command. XAll the printing characters are initially bound to the Xcommand \fIself-insert\fP. XThus, typing any printing character causes it to be inserted into the text. XAny of the existing commands can be bound to any key. X(A \fIkey\fP may actually be a \fIcontrol character\fP Xor an \fIescape sequence\fP as explained previously under X\fICommand Input Conventions\fP). X.LP XSince there are more commands than there are keys, Xtwo keys are treated as \fIprefix\fP commands. XWhen a key bound to one of the prefix commands is typed, Xthe next character Xtyped is interpreted on the basis that it was preceded by one of the Xprefix keys. XInitially ^X and ESC are the prefix keys and Xmany of the built in commands are initially bound to these "two stroke" keys. X(For historical reasons, the Escape key is often referred to as "Meta"). X.NH 2 XKeyboard Macros X.XS \n(PN 5n X\*(SN Keyboard Macros X.XE X.LP XAlthough \s-2JOVE\s0 has many powerful commands, Xyou often find that you have a task that no individual command can do. X\s-2JOVE\s0 allows you to define your own commands from sequences Xof existing ones "by example"; XSuch a sequence is termed a \fImacro\fP. XThe procedure is as follows: XFirst you type the \fIstart-remembering\fP command, Xusually bound to C-X (. XNext you "perform" the commands which as they are being executed are Xalso Xremembered, which will constitute the body of the macro. XThen you give the \fIstop-remembering\fP command, usually bound to XC-X ). XYou now have a \fIkeyboard macro\fP. XTo run this command sequence again, Xuse the command \fIexecute-keyboard-macro\fP, usually bound to XC-X E. XYou may find this bothersome to type and re-type, Xso there is a way to bind the macro to a key. XFirst, Xyou must give the keyboard macro a name using the X\fIname-keyboard-macro\fP command. XThen the binding is made with the \fIbind-macro-to-key\fP command. XWe're still not finished because all this hard work will be lost Xif you leave \s-2JOVE\s0. XWhat you do is to save your macros into a file Xwith the \fIwrite-macros-to-file\fP command. XThere is a corresponding \fIread-macros-from-file\fP command to retrieve Xyour macros in the next editing session. X.NH 2 XInitialization Files X.XS \n(PN 5n X\*(SN Initialization Files X.XE X.LP XUsers will likely want to modify the default key bindings to their liking. XSince it would be quite annoying to have to set up the bindings Xeach time \s-2JOVE\s0 is started up, X\s-2JOVE\s0 has the ability to read in a "startup" file. XWhenever \s-2JOVE\s0 is started, Xit reads commands from the file \fI.\|joverc\fP in the user's home directory. XThese commands are read as Xif they were typed to the command handler (ESC X) during an edit. XThere can be only one command per line in the startup file. XIf there is a file \fI/usr/lib/jove/joverc\fP, Xthen this file will be read before the user's X.I .\|joverc Xfile. XThis can be used to set up a system-wide default startup mode for X\s-2JOVE\s0 Xthat is tailored to the needs of that system. X.LP XThe \fIsource\fP command can be used to read commands from a specified file Xat any time during an editing session, Xeven from inside the \fI.\|joverc\fP file. XThis means that a macro can be used to change the key bindings, Xe.g., to enter a mode, Xby reading from a specified file which contains all the necessary bindings. @//E*O*F doc/jove.3// if test 13444 -ne "`wc -c <'doc/jove.3'`"; then echo shar: error transmitting "'doc/jove.3'" '(should have been 13444 characters)' fi fi # end of overwriting check echo shar: extracting "'doc/system.rc'" '(377 characters)' if test -f 'doc/system.rc' ; then echo shar: will not over-write existing file "'doc/system.rc'" else sed 's/^X//' >doc/system.rc <<'@//E*O*F doc/system.rc//' Xauto-execute-command auto-fill-mode /tmp/Re\|/tmp/article Xauto-execute-command show-match .*\.[lchy]$\|.*\.lisp$\|.*\.scm$\|.*\.slisp Xauto-execute-command c-mode .*\.[chy]$ Xauto-execute-command lisp-mode .*\.l$\|.*\.lisp$\|.*\.scm$\|.*\.slisp Xbind-to-key pause-jove ^[S Xbind-to-key pause-jove ^[s Xprocess-bind-to-key interrupt-process ^C Xprocess-bind-to-key process-newline ^M @//E*O*F doc/system.rc// if test 377 -ne "`wc -c <'doc/system.rc'`"; then echo shar: error transmitting "'doc/system.rc'" '(should have been 377 characters)' fi fi # end of overwriting check echo shar: extracting "'doc/teachjove.nr'" '(726 characters)' if test -f 'doc/teachjove.nr' ; then echo shar: will not over-write existing file "'doc/teachjove.nr'" else sed 's/^X//' >doc/teachjove.nr <<'@//E*O*F doc/teachjove.nr//' X.hy 0 X.TH TEACHJOVE 1 "12 February 1986" X.ad X.SH NAME XTEACHJOVE - learn how to use the JOVE editor X.SH SYNOPSIS Xteachjove X.SH DESCRIPTION XTEACHJOVE is a simple program that calls up the JOVE editor on a special Xfile that is an interactive tutorial for the JOVE editor. Once in JOVE Xall you do is follow the instructions and by doing so you will learn all Xabout JOVE! NOTE: TEACHJOVE actually makes a copy of the tutorial in Xyour home directory; if you ever want to start over (if you trash the Xfile by accident) all you need to do is remove the file "~/teach-jove" Xand run teachjove again. X.SH FILES XLIBDIR/teach-jove -- THE special file. X.SH SEE ALSO XJOVE(1) - to learn about JOVE in general. X.fi X.SH AUTHOR XJonathan Payne @//E*O*F doc/teachjove.nr// if test 726 -ne "`wc -c <'doc/teachjove.nr'`"; then echo shar: error transmitting "'doc/teachjove.nr'" '(should have been 726 characters)' fi fi # end of overwriting check echo shar: "End of archive 8 (of 13)." cp /dev/null ark8isdone DONE=true for I in 1 2 3 4 5 6 7 8 9 10 11 12 13; do if test -f ark${I}isdone; then echo "You have run archive ${I}." else echo "You still need to run archive ${I}." DONE=false fi done case $DONE in true) echo "You have run all 13 archives." echo 'Now read the README and Makefile.' ;; esac ## End of shell archive. exit 0