Subject: v08i020: The JOVE text editor, Part01/13 Newsgroups: mod.sources Approved: mirror!rs Submitted by: seismo!rochester!jpayne (Jonathan Payne) Mod.sources: Volume 8, Issue 20 Archive-name: jove/Part01 [ Thanks to Jonathan for his persistance and help in getting the latest version of JOVE to me for publication. --r$ ] #! /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 1 (of 13)." # Contents: Makefile Ovmakefile README abbrev.c ask.c buf.c case.c # ctype.h io.h doc MANIFEST PATH=/bin:/usr/bin:/usr/ucb; export PATH echo shar: extracting "'Makefile'" '(6943 characters)' if test -f 'Makefile' ; then echo shar: will not over-write existing file "'Makefile'" else sed 's/^X//' >Makefile <<'@//E*O*F Makefile//' 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# TMPDIR is where the tmp files get stored, usually /tmp or /tmp/jove. If X# your system does not remove subdirectories of /tmp on reboot (lots do X# remove them these days) then it makes sense to make TMPDIR be /tmp/jove. X# But if you want to recover buffers on system crashes, you should create a X# directory that doesn't get clearned upon reboot, and use that instead. X# You would probably want to clean out that directory periodically with X# /etc/cron. LIBDIR is for online documentation, the PORTSRV process, X# RECOVER, and the system-wide .joverc file. BINDIR is where to put the X# executables JOVE and TEACHJOVE. MANDIR is where the manual pages go for X# JOVE, RECOVER and TEACHJOVE. MANEXT is the extension for the man pages, X# e.g., jove.1 or jove.l or jove.m. X XDESTDIR = XTMPDIR = /tmp XLIBDIR = /u/jpayne/jovelib XBINDIR = /u/jpayne/bin XMANDIR = /u/jpayne/manl XMANEXT = l XSHELL = /bin/csh X X# These should all just be right if the above ones are. XJOVE = $(DESTDIR)$(BINDIR)/jove XRECOVER = $(DESTDIR)$(LIBDIR)/recover XTEACHJOVE = $(DESTDIR)$(BINDIR)/teachjove XJOVERC = $(DESTDIR)$(LIBDIR)/.joverc XCMDS.DOC = $(DESTDIR)$(LIBDIR)/cmds.doc XTEACH-JOVE = $(DESTDIR)$(LIBDIR)/teach-jove XPORTSRV = $(DESTDIR)$(LIBDIR)/portsrv XJOVEM = $(DESTDIR)$(MANDIR)/jove.$(MANEXT) XRECOVERM = $(DESTDIR)$(MANDIR)/recover.$(MANEXT) XTEACHJOVEM = $(DESTDIR)$(MANDIR)/teachjove.$(MANEXT) X X# Select the right libraries for your system. X# 2.9BSD: LIBS = -ltermcap -ljobs X# v7: LIBS = -ltermcap X# 4.1BSD: LIBS = -ltermcap -ljobs X# 4.2BSD: LIBS = -ltermcap X# 4.3BSD: LIBS = -ltermcap X# SysV Rel. 2: LIBS = -lcurses X XLIBS = -ltermcap X X# If you are not VMUNIX (vax running Berkeley Version 4), you must specify X# the -i flags (split I/D space) and maybe the -x option (for adb to work). X# 2.9BSD: LDFLAGS = -x -i X# v7: LDFLAGS = -x -i X# 4.1BSD: LDFLAGS = X# 4.2BSD: LDFLAGS = X# 4.3BSD: LDFLAGS = X# SysV Rel. 2: LDFLAGS = -Ml X XLDFLAGS = X XCFLAGS = -O X XOBJECTS = keymaps.o funcdefs.o abbrev.o ask.o buf.o c.o case.o ctype.o \ X delete.o disp.o extend.o fp.o fmt.o insert.o io.o iproc.o jove.o macros.o \ X malloc.o marks.o misc.o move.o paragraph.o proc.o re.o re1.o rec.o \ X scandir.o screen.o table.o term.o tune.o util.o vars.o version.o wind.o X XJOVESRC = funcdefs.c abbrev.c ask.c buf.c c.c case.c ctype.c \ X delete.c disp.c extend.c fp.c fmt.c insert.c io.c iproc.c \ X jove.c macros.c malloc.c marks.c misc.c move.c paragraph.c \ X proc.c re.c re1.c rec.c scandir.c screen.c table.c term.c util.c \ X vars.c version.c wind.c X XSOURCES = $(JOVESRC) portsrv.c recover.c setmaps.c teachjove.c X XHEADERS = ctype.h io.h jove.h re.h rec.h table.h temp.h termcap.h tune.h X XDOCS = doc/cmds.doc.nr doc/example.rc doc/jove.1 doc/jove.2 doc/jove.3 \ X doc/jove.4 doc/jove.5 doc/jove.nr doc/recover.nr doc/system.rc \ X doc/teach-jove doc/teachjove.nr doc/README X XBACKUPS = $(HEADERS) $(JOVESRC) iproc-pipes.c iproc-ptys.c \ X teachjove.c recover.c setmaps.c portsrv.c tune.template \ X Makefile Ovmakefile keymaps.txt README $(DOCS) X X Xall: xjove recover teachjove portsrv X Xxjove: $(OBJECTS) X $(CC) $(LDFLAGS) -o xjove $(OBJECTS) version.o $(LIBS) X @-size xjove X @-date X Xportsrv: portsrv.o X cc -o portsrv -n portsrv.o $(LIBS) X Xrecover: recover.o tune.o rec.h temp.h X cc -o recover -n recover.o tune.o $(LIBS) X Xteachjove: teachjove.o X cc -o teachjove -n teachjove.o $(LIBS) X Xsetmaps: setmaps.o funcdefs.c X cc -o setmaps setmaps.o X Xteachjove.o: teachjove.c /usr/include/sys/types.h /usr/include/sys/file.h X cc -c $(CFLAGS) -DTEACHJOVE=\"$(TEACH-JOVE)\" teachjove.c X Xsetmaps.o: funcdefs.c keymaps.txt X Xkeymaps.c: setmaps keymaps.txt X setmaps < keymaps.txt > keymaps.c X Xkeymaps.o: keymaps.c jove.h X Xtune.c: Makefile tune.template X @echo "/* Changes should be made in Makefile, not to this file! */" > tune.c X @echo "" >> tune.c X @sed -e 's;TMPDIR;$(TMPDIR);' \ X -e 's;LIBDIR;$(LIBDIR);' \ X -e 's;BINDIR;$(BINDIR);' \ X -e 's;SHELL;$(SHELL);' tune.template >> tune.c X Xinstall: $(DESTDIR)$(LIBDIR) $(TEACH-JOVE) $(CMDS.DOC) $(JOVERC) \ X $(PORTSRV) $(RECOVER) $(JOVE) $(TEACHJOVE) $(JOVEM) \ X $(RECOVERM) $(TEACHJOVEM) X X$(DESTDIR)$(LIBDIR): X -mkdir $(DESTDIR)$(LIBDIR) X X$(TEACH-JOVE): doc/teach-jove X install -c -m 644 doc/teach-jove $(TEACH-JOVE) X Xdoc/cmds.doc: doc/cmds.doc.nr doc/jove.4 doc/jove.5 X nroff doc/cmds.doc.nr doc/jove.4 doc/jove.5 > doc/cmds.doc X X$(CMDS.DOC): doc/cmds.doc X install -c -m 644 doc/cmds.doc $(CMDS.DOC) X X$(JOVERC): doc/system.rc X install -c -m 644 doc/system.rc $(JOVERC) X X$(PORTSRV): portsrv X install -c -s -m 755 portsrv $(PORTSRV) X X$(RECOVER): recover X install -c -s -m 755 recover $(RECOVER) X X$(JOVE): xjove X install -c -m 755 xjove $(JOVE) X X$(TEACHJOVE): teachjove X install -c -s -m 755 teachjove $(TEACHJOVE) X X$(JOVEM): doc/jove.nr X @sed -e 's;TMPDIR;$(TMPDIR);' \ X -e 's;LIBDIR;$(LIBDIR);' \ X -e 's;SHELL;$(SHELL);' doc/jove.nr > /tmp/jove.nr X install -m 644 /tmp/jove.nr $(JOVEM) X X$(RECOVERM): doc/recover.nr X @sed -e 's;TMPDIR;$(TMPDIR);' \ X -e 's;LIBDIR;$(LIBDIR);' \ X -e 's;SHELL;$(SHELL);' doc/recover.nr > /tmp/recover.nr X install -m 644 /tmp/recover.nr $(RECOVERM) X X$(TEACHJOVEM): doc/teachjove.nr X @sed -e 's;TMPDIR;$(TMPDIR);' \ X -e 's;LIBDIR;$(LIBDIR);' \ X -e 's;SHELL;$(SHELL);' doc/teachjove.nr > /tmp/teachjove.nr X install -m 644 /tmp/teachjove.nr $(TEACHJOVEM) X Xecho: X @echo $(C-FILES) $(HEADERS) X Xlint: X lint -n $(JOVESRC) tune.c keymaps.c X @echo Done X Xtags: X ctags -w $(JOVESRC) $(HEADERS) X Xciall: X ci $(BACKUPS) X Xcoall: X co $(BACKUPS) X Xjove.shar: X shar $(BACKUPS) > jove.shar X Xbackup: X tar cf backup $(BACKUPS) X Xtape-backup: X tar cbf 20 /dev/rmt0 $(BACKUPS) X Xrtape-backup: X rtar cbf 20 sen:/dev/rmt0 $(BACKUPS) X Xtouch: X touch $(OBJECTS) X Xclean: X rm -f a.out core *.o keymaps.c tune.c xjove portsrv recover setmaps \ X teachjove X X# This version only works under 4.3BSD X#depend: X# for i in ${SOURCES} ; do \ X# cc -M ${CFLAGS} $$i | awk ' { if ($$1 != prev) \ X# { if (rec != "") print rec; rec = $$0; prev = $$1; } \ X# else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \ X# else rec = rec " " $$2 } } \ X# END { print rec } ' >> makedep; done X# echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep X# echo '$$r makedep' >>eddep X# echo 'w' >>eddep X# cp Makefile Makefile.bak X# ed - Makefile < eddep X# rm eddep makedep X# echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile X# echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile X# echo '# see make depend above' >> Makefile X# X## DO NOT DELETE THIS LINE -- make depend uses it @//E*O*F Makefile// if test 6943 -ne "`wc -c <'Makefile'`"; then echo shar: error transmitting "'Makefile'" '(should have been 6943 characters)' fi fi # end of overwriting check echo shar: extracting "'Ovmakefile'" '(6718 characters)' if test -f 'Ovmakefile' ; then echo shar: will not over-write existing file "'Ovmakefile'" else sed 's/^X//' >Ovmakefile <<'@//E*O*F Ovmakefile//' 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# TMPDIR is where the tmp files get stored, usually /tmp or /tmp/jove. If X# your system does not remove subdirectories of /tmp on reboot (lots do X# remove them these days) then it makes sense to make TMPDIR be /tmp/jove. X# But if you want to recover buffers on system crashes, you should create a X# directory that doesn't get clearned upon reboot, and use that instead. X# You would probably want to clean out that directory periodically with X# /etc/cron. LIBDIR is for online documentation, the PORTSRV process, X# RECOVER, and the system-wide .joverc file. BINDIR is where to put the X# executables JOVE and TEACHJOVE. MANDIR is where the manual pages go for X# JOVE, RECOVER and TEACHJOVE. MANEXT is the extension for the man pages, X# e.g., jove.1 or jove.l or jove.m. X XDESTDIR = XTMPDIR = /tmp XLIBDIR = /usr/lib/jove XBINDIR = /bin XMANDIR = /usr/man/man1 XMANEXT = 1 XSHELL = /bin/csh X X# These should all just be right if the above ones are. XJOVE = $(DESTDIR)$(BINDIR)/jove XRECOVER = $(DESTDIR)$(LIBDIR)/recover XTEACHJOVE = $(DESTDIR)$(BINDIR)/teachjove XJOVERC = $(DESTDIR)$(LIBDIR)/.joverc XCMDS.DOC = $(DESTDIR)$(LIBDIR)/cmds.doc XTEACH-JOVE = $(DESTDIR)$(LIBDIR)/teach-jove XPORTSRV = $(DESTDIR)$(LIBDIR)/portsrv XJOVEM = $(DESTDIR)$(MANDIR)/jove.$(MANEXT) XRECOVERM = $(DESTDIR)$(MANDIR)/recover.$(MANEXT) XTEACHJOVEM = $(DESTDIR)$(MANDIR)/teachjove.$(MANEXT) X X# Select the right libraries for your system. X# 2.9BSD: LIBS = -ltermlib -ljobs X# v7: LIBS = -ltermlib X# 4.1BSD: LIBS = -ltermlib -ljobs X# 4.2BSD: LIBS = -ltermlib X# 4.3BSD: LIBS = -ltermlib X XOVLIBS = -lovtermcap -lovjobs XLIBS = -ltermcap -ljobs X X# If you are not VMUNIX (vax running Berkeley Version 4), you must specify X# the -i flags (split I/D space) and maybe the -x option (for adb to work). X# 2.9BSD: LDFLAGS = -x -i X# v7: LDFLAGS = -x -i X# 4.1BSD: LDFLAGS = X# 4.2BSD: LDFLAGS = X# 4.3BSD: LDFLAGS = X XLDFLAGS = -x -i X XCFLAGS = -O -V X XCOFLAGS = -rworking -q X XBASESEG = funcdefs.o keymaps.o ask.o buf.o ctype.o delete.o disp.o fmt.o fp.o \ X insert.o io.o jove.o malloc.o macros.o marks.o misc.o move.o re.o \ X screen.o table.o tune.o util.o vars.o version.o XOVLAY1 = abbrev.o rec.o paragraph.o XOVLAY2 = c.o wind.o XOVLAY3 = extend.o XOVLAY4 = iproc.o re1.o XOVLAY5 = proc.o scandir.o term.o case.o X XOBJECTS = $(BASESEG) $(OVLAY1) $(OVLAY2) $(OVLAY3) $(OVLAY4) $(OVLAY5) X XC-FILES = funcdefs.c abbrev.c ask.c buf.c c.c case.c ctype.c delete.c disp.c \ X extend.c fmt.c fp.c insert.c io.c iproc.c iproc-pipes.c iproc-ptys.c \ X jove.c macros.c malloc.c marks.c misc.c move.c paragraph.c proc.c \ X re.c re1.c rec.c scandir.c screen.c table.c term.c util.c vars.c version.c \ X wind.c X XH-FILES = ctype.h io.h jove.h re.h rec.h table.h temp.h termcap.h tune.h X XBACKUPS = $(C-FILES) $(H-FILES) $(DOCS) teachjove.c recover.c setmaps.c portsrv.c \ X tune.template Makefile Ovmakefile keymaps.txt README tags X XDOCS = doc/cmds.doc.nr doc/example.rc doc/jove.1 doc/jove.2 doc/jove.3 \ X doc/jove.4 doc/jove.nr doc/recover.nr doc/system.rc doc/teach-jove \ X doc/teachjove.nr doc/README X Xall: xjove recover teachjove portsrv X Xxjove: $(OBJECTS) X ld $(LDFLAGS) /lib/crt0.o \ X -Z $(OVLAY1) \ X -Z $(OVLAY2) \ X -Z $(OVLAY3) \ X -Z $(OVLAY4) \ X -Z $(OVLAY5) \ X -L $(BASESEG) \ X -o xjove $(OVLIBS) -lovc X checkobj xjove X @-size xjove X @-date X Xportsrv: portsrv.c X cc -o portsrv -n -O portsrv.c $(LIBS) X Xrecover: recover.c tune.o rec.h temp.h X cc -o recover -n -O recover.c tune.o -ljobs X Xteachjove: teachjove.c X cc -o teachjove -n -O -DTEACHJOVE=\"$(TEACH-JOVE)\" teachjove.c X Xsetmaps: setmaps.c funcdefs.c X cc -o setmaps setmaps.c X Xkeymaps.c: setmaps keymaps.txt X setmaps < keymaps.txt > keymaps.c X Xtune.c: Makefile tune.template X @echo "/* Changes should be made in Makefile, not to this file! */" > tune.c X @echo "" >> tune.c X @sed -e 's;TMPDIR;$(TMPDIR);' \ X -e 's;LIBDIR;$(LIBDIR);' \ X -e 's;BINDIR;$(BINDIR);' \ X -e 's;SHELL;$(SHELL);' tune.template >> tune.c X Xinstall: $(LIBDIR) $(TEACH-JOVE) $(CMDS.DOC) $(JOVERC) $(PORTSRV) $(RECOVER) \ X $(JOVE) $(TEACHJOVE) $(JOVEM) $(RECOVERM) $(TEACHJOVEM) X X$(DESTDIR)$(LIBDIR): X -mkdir (DESTDIR)$(LIBDIR) X X$(TEACH-JOVE): doc/teach-jove X install -c -m 644 doc/teach-jove $(TEACH-JOVE) X X$(CMDS.DOC): doc/cmds.doc X install -c -m 644 doc/cmds.doc $(CMDS.DOC) X X$(JOVERC): doc/system.rc X install -c -m 644 doc/system.rc $(JOVERC) X X$(PORTSRV): portsrv X install -c -m 755 portsrv $(PORTSRV) X X$(RECOVER): recover X install -c -m 755 recover $(RECOVER) X X$(JOVE): xjove X install -c -m 755 xjove $(JOVE) X X$(TEACHJOVE): teachjove X install -c -m 755 teachjove $(TEACHJOVE) X X$(JOVEM): doc/jove.nr X @sed -e 's;TMPDIR;$(TMPDIR);' \ X -e 's;LIBDIR;$(LIBDIR);' \ X -e 's;SHELL;$(SHELL);' doc/jove.nr > /tmp/jove.nr X install -m 644 /tmp/jove.nr $(JOVEM) X X$(RECOVERM): doc/recover.nr X @sed -e 's;TMPDIR;$(TMPDIR);' \ X -e 's;LIBDIR;$(LIBDIR);' \ X -e 's;SHELL;$(SHELL);' doc/recover.nr > /tmp/recover.nr X install -m 644 /tmp/recover.nr $(RECOVERM) X X$(TEACHJOVEM): doc/teachjove.nr X @sed -e 's;TMPDIR;$(TMPDIR);' \ X -e 's;LIBDIR;$(LIBDIR);' \ X -e 's;SHELL;$(SHELL);' doc/teachjove.nr > /tmp/teachjove.nr X install -m 644 /tmp/teachjove.nr $(TEACHJOVEM) X Xecho: X @echo $(C-FILES) $(H-FILES) X Xlint: X lint -x $(C-FILES) X echo Done X Xtags: X ctags -w $(C-FILES) $(H-FILES) X X Xjove.shar: X shar $(BACKUPS) doc/* > jove.shar X Xbackup: X tar cf backup $(BACKUPS) X Xtape-backup: X tar cbf 20 /dev/rmt0 $(BACKUPS) X Xclean: X rm -f a.out core $(OBJECTS) keymaps.c xjove \ X portsrv recover setmaps teachjove X X# abbrev.o: jove.h tune.h X# ask.o: jove.h tune.h X# buf.o: jove.h tune.h X# c.o: jove.h tune.h X# delete.o: jove.h tune.h X# disp.o: jove.h tune.h termcap.h X# extend.o: jove.h tune.h X# fmt.o: jove.h tune.h termcap.h X# funcdefs.o: jove.h tune.h X# insert.o: jove.h tune.h X# io.o: jove.h tune.h termcap.h temp.h X# iproc.o: jove.h tune.h X# jove.o: jove.h tune.h termcap.h X# macros.o: jove.h tune.h X# marks.o: jove.h tune.h X# misc.o: jove.h tune.h X# move.o: jove.h tune.h X# portsrv.o: jove.h tune.h X# proc.o: jove.h tune.h X# re.o: jove.h tune.h X# rec.o: jove.h tune.h temp.h rec.h X# recover.o: jove.h tune.h temp.h rec.h X# screen.o: jove.h tune.h temp.h termcap.h X# setmaps.o: jove.h tune.h X# term.o: jove.h tune.h X# tune.o: tune.h X# util.o: jove.h tune.h X# wind.o: jove.h tune.h termcap.h @//E*O*F Ovmakefile// if test 6718 -ne "`wc -c <'Ovmakefile'`"; then echo shar: error transmitting "'Ovmakefile'" '(should have been 6718 characters)' fi fi # end of overwriting check echo shar: extracting "'README'" '(8874 characters)' if test -f 'README' ; then echo shar: will not over-write existing file "'README'" else sed 's/^X//' >README <<'@//E*O*F README//' 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 XTo make JOVE edit Makefile to set the right directories for the binaries, Xonline documentation, the man pages, and the TMP files. (IMPORTANT! read Xthe Makefile carefully.) "tune.c" will be created from "tune.template" by XMAKE automatically, and it will use the directories you specified in the XMakefile. (NOTE: You should never edit tune.c directly because your Xchanges will be undone by the next make. If you want to make a change to a Xpart of tune.c that isn't a directory name, you should edit tune.template.) XNext you must edit "tune.h" selecting the compile time options you care Xabout. See below for a description of all the compile time options. You Xcan type "make" to compile XJOVE, PORTSRV (this is compiled but not used on X4.2+ systems), JOVE_RECOVER and TEACHJOVE. Test them out to see if they Xwork. If they do, type "make install" to install everything where it Xbelongs. X XHere are some things to consider for deciding where to put the tmp files. XTMPDIR is where the tmp files get stored, usually /tmp or /tmp/jove. If Xyour system does not remove subdirectories of /tmp on reboot (lots do Xremove them these days) then it makes sense to make TMPDIR be /tmp/jove. XBut if you want to recover buffers on system crashes, you should create a Xdirectory that doesn't get clearned upon reboot, and use that instead. XYou would probably want to clean out that directory periodically with X/etc/cron. X XFor the pdp11 version there is the Ovmakefile. This has only been tested Xon 2.9bsd. It works pretty well, actually, and it is possible to turn on Xall the compile time options with this version. X XBug reports: If you find bugs in JOVE I would appreciate hearing about Xthem. (My net address is at end of this message.) So, send me the bug Xreports. If the bug isn't already fixed, I will ask you to send me the Xfix. If you haven't found the bug, I may be able to, so don't wait until Xyou have found it. If you make improvements to JOVE and want them Xincorporated into the official version, send me a message explaining what Xthe change is, and I will decide whether I want to include it. If it is Xpossible for your change to be #ifdef'd in, that would be best, since I Xwant to avoid making JOVE huge. For instance, if it's a new package type Xthing (say, like word abbrev. mode, or something) then it would be best Xif that were a compile-time option. I will send out periodic updates to Xmod.sources. I will report all significant bug fixes there, and to Xnet.emacs as well. X XHere's a list of the compile time options and what they mean: X XABBREV - Enables word-abbrev-mode which again is nice for paper writers. X XBACKUPFILES - This enables backing up files on write. I guess lots of X people like this feature. It enables the feature but you X can still control whether files are backed up with the X make-backup-files variable. X XBIFF - This enables turning on and off BIFF so your screen doesn't X get messed up with messages from BIFF. X XBSD4_2 - Obviously, if you're a Berkeley 4.2 system. X XBSD4_3 - If you're running a Berkeley 4.3 (or very late 4.2) system. X This will automatically define BSD4_2, also. X XCHDIR - This enables the directory commands; PUSHD, POPD, DIRS and X CD. These simulate the csh commands I think exactly. As X a side-effect, absolute pathnames are enabled, which means X JOVE parses filenames for "." and ".." and all that to get X at what you REALLY mean. It's nicer when this is enabled, X but not essential. X XCMT_FMT - This enables code to format and indent C comments. X XID_CHAR - Enables support for Insert/Delete character on terminals X that have those capabilites. Couple of problems with this code: X it's large, takes up lots of I space which is a problem for the X smaller computers (pdp11). Also, it isn't particularly smart X and sometimes does really stupid things. It sometimes uses X insert/delete character when simply redrawing would have been X faster. And if you look at code you'll understand why I don't X like it all that much. X XIPROCS - Nice feature which lets you run interactive UNIX commands in X windows. In particular, there is a an i-shell command built X in which starts up an interactive shell in a window. This works X only on systems with JOB_CONTROL since it relies on the fancy X signal mechanism. X XJOB_CONTROL - Versions of UNIX that have the job control facility. X Berkeley 2.9 system, and the 4.1-3 systems I know have X job stopping, so if you're one of those, define X this. The reason MENLO_JCL is defined when JOB_CONTROL X is that the 2.9 signal.h file only defines all of the job X stopping signals only when MENLO_JCL is defined. X XLISP - Enables Lisp Mode. This includes code to indent "properly" X for Lisp code and new routines to move over s-expressions. X You probably won't want (or need) this on PDP-11's. X XLSRHS - This is for the Lincoln-Sudbury Regional High School version X of jove, which is where JOVE originated. X XMY_MALLOC - Use the older version of malloc that is more memory efficient X for the VAX. This is MUCH more efficient than the VAX one. X The VAX version seems to place more importance on the speed X of the allocation than the amount of memory it uses. Make your X choice ... JOVE hardly ever calls malloc, anyway, relatively X speaking, since it allocates lines in big chunks. NOTE: This X seems not to work on suns. X XPIPEPROCS - If NOT defined, JOVE will use the Berkeley pseudo-ttys when X doing interactive processes. This is infinitely better, X since you get job control and all that stuff on i-shells. X If defined, the portsrv program will have to be made, and X everything will be done using pipes. X XRESHAPING - This is for BRL or Berkeley 4.3 systems. It's not something I X dealt with so I can't really describe it. Got something to do X with reshaping the windows that UNIX knows about. When you try X to reshape one of those windows, it sends some signal which JOVE X catches and uses to resize its windows. X XSPELL - Enables the spell-buffer and parse-spelling-errors commands. X They are nice especially if you have lots of paper writers. X XWIRED_TERMS - Include compiled-in hard-wired code for certain terminals, X like the Concept 100. If you don't have these terminals, X you probably don't need this (but no point in taking it X out unless you're low on space). X XTo make macro files compatible between machines with different byte order I Xuse the ntohl() and htonl() calls that are supplied with (as far as I know) X4.2 systems. If you're not running 4.2 a bunch of macros will be defined Xautomatically in macros.c. From Dave Curry: X The "#if" gets all the identifiers of backwards (left-endian) X machines, the "#else" handles normal (right-endian) X machines.... Just add some remark in the READ_ME for people X porting to machines other than the Vax or PDP-11 which are X left-endian. X X"doc/system.rc" and "doc/example.rc" are jove initialization files. X"system.rc" is the "system" rc file here at UoR, and it gets ready every Xtime JOVE starts up FOR EVERYONE. ("make install" should copy the Xsystem-wide .joverc to the right place automatically.) After that JOVE Xreads an initialization file in the user's home directory, and "example.rc" Xis mine. X XThe files "jove.[12345]" in DOC are the official JOVE manual. I got Xpermission from Richard Stallman to use his manual for the original EMACS, Xmodifying it where necessary for JOVE. Lots of work was done by Brian XHarvey on this manual. X XThere are man pages for jove, recover and teachjove. Teachjove is for Xpeople who have never used EMACS style editors. It is an interactive Xtutorial, THE tutorial written by Stallman for the original EMACS, only Xslightly modified for JOVE in the appropriate places. The man pages are Xcompletely up to date, thanks to me. X XThanks to Jay Fenlason at Berkeley for writing the original pty code. X XThanks to Dave Curry at Purdue for putting in tons of time and effort Xinto getting JOVE ready. It just wouldn't be working without his help. X XThanks to Jeff Mc Carrell at Berkeley for finding bugs and adding features. X X(Thanks to Brian Harvey for teaching me about linked lists ...) X XGood luck, have fun. X Jonathan Payne (jpayne@rochester until '88) @//E*O*F README// if test 8874 -ne "`wc -c <'README'`"; then echo shar: error transmitting "'README'" '(should have been 8874 characters)' fi fi # end of overwriting check echo shar: extracting "'abbrev.c'" '(5740 characters)' if test -f 'abbrev.c' ; then echo shar: will not over-write existing file "'abbrev.c'" else sed 's/^X//' >abbrev.c <<'@//E*O*F abbrev.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 X#ifdef ABBREV X X#include "io.h" X#include "ctype.h" X X#define HASHSIZE 20 X Xstruct abbrev { X unsigned int a_hash; X char *a_abbrev, X *a_phrase; X struct abbrev *a_next; X data_obj *a_cmdhook; X}; X X#define GLOBAL NMAJORS Xstatic struct abbrev *A_tables[NMAJORS + 1][HASHSIZE] = {0}; X Xint AutoCaseAbbrev = 1; X Xstatic unsigned int Xhash(a) Xregister char *a; X{ X register unsigned int hashval = 0; X register int c; X X while (c = *a++) X hashval = (hashval << 2) + c; X X return hashval; X} X Xstatic Xdef_abbrev(table) Xstruct abbrev *table[HASHSIZE]; X{ X char abbrev[100], X phrase[100]; X X strcpy(abbrev, ask((char *) 0, "abbrev: ")); X strcpy(phrase, ask((char *) 0, "abbrev: %s phrase: ", abbrev)); X define(table, abbrev, phrase); X} X Xstatic struct abbrev * Xlookup(table, abbrev) Xregister struct abbrev *table[HASHSIZE]; Xregister char *abbrev; X{ X register struct abbrev *ap; X unsigned int h; X X h = hash(abbrev); X for (ap = table[h % HASHSIZE]; ap; ap = ap->a_next) X if (ap->a_hash == h && strcmp(ap->a_abbrev, abbrev) == 0) X break; X return ap; X} X Xstatic Xdefine(table, abbrev, phrase) Xregister struct abbrev *table[HASHSIZE]; Xchar *abbrev, X *phrase; X{ X register struct abbrev *ap; X X ap = lookup(table, abbrev); X if (ap == 0) { X register unsigned int h = hash(abbrev); X X ap = (struct abbrev *) emalloc(sizeof *ap); X ap->a_hash = h; X ap->a_abbrev = copystr(abbrev); X h %= HASHSIZE; X ap->a_next = table[h]; X ap->a_cmdhook = 0; X table[h] = ap; X } else X free(ap->a_phrase); X ap->a_phrase = copystr(phrase); X} X XAbbrevExpand() X{ X Bufpos point; X char wordbuf[100]; X register char *wp = wordbuf, X *cp; X register int c; X int UC_count = 0; X struct abbrev *ap; X X DOTsave(&point); X exp = 1; X WITH_TABLE(curbuf->b_major) X BackWord(); X while (curchar < point.p_char && ismword(c = linebuf[curchar])) { X if (AutoCaseAbbrev) { X if (isupper(c)) { X UC_count++; X c = tolower(c); X } X } X X *wp++ = c; X curchar++; X } X *wp = '\0'; X END_TABLE(); X X if ((ap = lookup(A_tables[curbuf->b_major], wordbuf)) == 0 && X (ap = lookup(A_tables[GLOBAL], wordbuf)) == 0) { X SetDot(&point); X return; X } X DoTimes(DelPChar(), (wp - wordbuf)); X X for (cp = ap->a_phrase; c = *cp; ) { X if (AutoCaseAbbrev) { X Insert(islower(c) && UC_count && X (cp == ap->a_phrase || (UC_count > 1 && (*(cp - 1) == ' '))) ? X toupper(c) : c); X } X else { X Insert(c); X } X cp++; X } X X if (ap->a_cmdhook != 0) X ExecCmd(ap->a_cmdhook); X} X Xstatic char *mode_names[NMAJORS + 1] = { X "Fundamental", X "Text Mode", X "C Mode", X#ifdef LISP X "Lisp Mode", X#endif X "Global" X}; X Xstatic Xsave_abbrevs(file) Xchar *file; X{ X File *fp; X struct abbrev *ap, X **tp; X char buf[LBSIZE]; X int i, X count = 0; X X fp = open_file(file, buf, F_WRITE, COMPLAIN, QUIET); X for (i = 0; i <= GLOBAL; i++) { X fprintf(fp, "------%s abbrevs------\n", mode_names[i]); X for (tp = A_tables[i]; tp < &A_tables[i][HASHSIZE]; tp++) X for (ap = *tp; ap; ap = ap->a_next) { X fprintf(fp, "%s:%s\n", X ap->a_abbrev, X ap->a_phrase); X count++; X } X } X f_close(fp); X add_mess(" %d written.", count); X} X Xstatic Xrest_abbrevs(file) Xchar *file; X{ X int eof = 0, X mode = -1, /* Will be ++'d immediately */ X lnum = 0; X char *phrase_p; X File *fp; X char buf[LBSIZE]; X X fp = open_file(file, buf, F_READ, COMPLAIN, QUIET); X while (mode <= GLOBAL) { X eof = f_gets(fp, genbuf, LBSIZE); X if (eof || genbuf[0] == '\0') X break; X lnum++; X if (strncmp(genbuf, "------", 6) == 0) { X mode++; X continue; X } X if (mode == -1) Xfmterr: complain("Abbrev. format error, line %d.", file, lnum); X phrase_p = index(genbuf, ':'); X if (phrase_p == 0) X goto fmterr; X *phrase_p++ = '\0'; /* Null terminate the abbrev. */ X define(A_tables[mode], genbuf, phrase_p); X } X f_close(fp); X message(NullStr); X} X XDefGAbbrev() X{ X def_abbrev(A_tables[GLOBAL]); X} X XDefMAbbrev() X{ X def_abbrev(A_tables[curbuf->b_major]); X} X XSaveAbbrevs() X{ X char filebuf[FILESIZE]; X X save_abbrevs(ask_file((char *) 0, (char *) 0, filebuf)); X} X XRestAbbrevs() X{ X char filebuf[FILESIZE]; X X rest_abbrevs(ask_file((char *) 0, (char *) 0, filebuf)); X} X XEditAbbrevs() X{ X char *tname = "jove_wam.$$$", X *EditName = "Abbreviation Edit"; X Buffer *obuf = curbuf, X *ebuf; X X if (ebuf = buf_exists(EditName)) { X if (ebuf->b_type != B_SCRATCH) X confirm("Over-write buffer %b?", ebuf); X } X SetBuf(ebuf = do_select(curwind, EditName)); X ebuf->b_type = B_SCRATCH; X initlist(ebuf); X /* Empty buffer. Save the definitions to a tmp file X and read them into this buffer so we can edit them. */ X save_abbrevs(tname); X read_file(tname, NO); X message("[Edit definitions and then type C-X C-C]"); X Recur(); /* We edit them ... now */ X /* RESetBuf in case we deleted the buffer while we were editing. */ X SetBuf(ebuf = do_select(curwind, EditName)); X if (IsModified(ebuf)) { X SetBuf(ebuf); X file_write(tname, 0); X rest_abbrevs(tname); X unmodify(); X } X (void) unlink(tname); X SetBuf(do_select(curwind, obuf->b_name)); X} X XBindMtoW() X{ X struct abbrev *ap; X char *word; X data_obj *hook; X X word = ask((char *) 0, "Word: "); X X if ((ap = lookup(A_tables[curbuf->b_major], word)) == 0 && X (ap = lookup(A_tables[GLOBAL], word)) == 0) X complain("%s: unknown abbrev.", word); X X hook = findmac("Macro: "); X if (hook == 0) X complain("[Undefined macro]"); X ap->a_cmdhook = hook; X} X X#endif ABBREV @//E*O*F abbrev.c// if test 5740 -ne "`wc -c <'abbrev.c'`"; then echo shar: error transmitting "'abbrev.c'" '(should have been 5740 characters)' fi fi # end of overwriting check echo shar: extracting "'ask.c'" '(9258 characters)' if test -f 'ask.c' ; then echo shar: will not over-write existing file "'ask.c'" else sed 's/^X//' >ask.c <<'@//E*O*F ask.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 "termcap.h" X#include "ctype.h" X#include X#include X X#ifdef F_COMPLETION X# include X#endif X Xint Asking = NO; Xchar Minibuf[LBSIZE]; Xprivate Line *CurAskPtr = 0; /* points at some line in mini-buffer */ Xprivate Buffer *AskBuffer = 0; /* Askbuffer points to actual structure */ X X/* The way the mini-buffer works is this: The first line of the mini-buffer X is where the user does his stuff. The rest of the buffer contains X strings that the user often wants to use, for instance, file names, or X common search strings, etc. If he types C-N or C-P while in ask(), we X bump the point up or down a line and extract the contents (we make sure X is somewhere in the mini-buffer). */ X Xstatic Buffer * Xget_minibuf() X{ X if (AskBuffer) { /* make sure ut still exists */ X register Buffer *b; X X for (b = world; b != 0; b = b->b_next) X if (b == AskBuffer) X return b; X } X AskBuffer = do_select((Window *) 0, "*minibuf*"); X AskBuffer->b_type = B_SCRATCH; X return AskBuffer; X} X X/* Add a string to the mini-buffer. */ X Xminib_add(str, movedown) Xchar *str; X{ X register Buffer *saveb = curbuf; X X SetBuf(get_minibuf()); X LineInsert(1); X ins_str(str, NO); X if (movedown) X CurAskPtr = curline; X SetBuf(saveb); X} X Xstatic char * Xreal_ask(delim, d_proc, def, prompt) Xchar *delim, X *def, X *prompt; Xint (*d_proc)(); X{ X static int InAsk = 0; X jmp_buf savejmp; X int c, X prompt_len; X Buffer *saveb = curbuf; X int abort = 0, X no_typed = 0; X data_obj *push_cmd = LastCmd; X int o_exp = exp, X o_exp_p = exp_p; X X if (InAsk) X complain((char *) 0); X push_env(savejmp); X InAsk++; X SetBuf(get_minibuf()); X if (!inlist(AskBuffer->b_first, CurAskPtr)) X CurAskPtr = curline; X prompt_len = strlen(prompt); X ToFirst(); /* Beginning of buffer. */ X linebuf[0] = '\0'; X modify(); X makedirty(curline); X X if (setjmp(mainjmp)) X if (InJoverc) { /* this is a kludge */ X abort++; X goto cleanup; X } X X for (;;) { X exp = 1; X exp_p = NO; X last_cmd = this_cmd; X init_strokes(); Xcont: s_mess("%s%s", prompt, linebuf); X Asking = curchar + prompt_len; X c = getch(); X if ((c == EOF) || index(delim, c)) { X if (d_proc == 0 || (*d_proc)(c) == 0) X goto cleanup; X } else switch (c) { X case CTL(G): X message("[Aborted]"); X abort++; X goto cleanup; X X case CTL(N): X case CTL(P): X if (CurAskPtr != 0) { X int n = (c == CTL(P) ? -exp : exp); X X CurAskPtr = next_line(CurAskPtr, n); X if (CurAskPtr == curbuf->b_first && CurAskPtr->l_next != 0) X CurAskPtr = CurAskPtr->l_next; X (void) ltobuf(CurAskPtr, linebuf); X modify(); X makedirty(curline); X Eol(); X this_cmd = 0; X } X break; X X case CTL(R): X if (def) X ins_str(def, NO); X else X rbell(); X break; X X default: X dispatch(c); X break; X } X if (curbuf != AskBuffer) X SetBuf(AskBuffer); X if (curline != curbuf->b_first) { X CurAskPtr = curline; X curline = curbuf->b_first; /* with whatever is in linebuf */ X } X if (this_cmd == ARG_CMD) X goto cont; X } Xcleanup: X pop_env(savejmp); X X LastCmd = push_cmd; X exp_p = o_exp_p; X exp = o_exp; X no_typed = (linebuf[0] == '\0'); X strcpy(Minibuf, linebuf); X SetBuf(saveb); X InAsk = Asking = Interactive = NO; X if (!abort) { X if (!charp()) { X Placur(ILI, 0); X flusho(); X } X if (no_typed) X return 0; X } else X complain(mesgbuf); X return Minibuf; X} X X/* VARARGS2 */ X Xchar * Xask(def, fmt, va_alist) Xchar *def, X *fmt; Xva_dcl X{ X char prompt[128]; X char *ans; X va_list ap; X X va_start(ap); X format(prompt, sizeof prompt, fmt, ap); X va_end(ap); X ans = real_ask("\r\n", (int (*)()) 0, def, prompt); X if (ans == 0) { /* Typed nothing. */ X if (def == 0) X complain("[No default]"); X return def; X } X return ans; X} X X/* VARARGS1 */ X Xchar * Xdo_ask(delim, d_proc, def, fmt, va_alist) Xchar *delim, X *def, X *fmt; Xint (*d_proc)(); Xva_dcl X{ X char prompt[128]; X va_list ap; X X va_start(ap); X format(prompt, sizeof prompt, fmt, ap); X va_end(ap); X return real_ask(delim, d_proc, def, prompt); X} X X/* VARARGS2 */ X Xyes_or_no_p(fmt, va_alist) Xchar *fmt; Xva_dcl X{ X char prompt[128]; X int c; X va_list ap; X X va_start(ap); X format(prompt, sizeof prompt, fmt, ap); X va_end(ap); X for (;;) { X message(prompt); X Asking = strlen(prompt); /* so redisplay works */ X c = getch(); X Asking = NO; X switch (Upper(c)) { X case 'Y': X return YES; X X case 'N': X return NO; X X case CTL(G): X complain("[Aborted]"); X X default: X add_mess("[Type Y or N]"); X SitFor(10); X } X } X /* NOTREACHED */ X} X X#ifdef F_COMPLETION Xstatic char *fc_filebase; Xchar BadExtensions[128] = ".o"; X Xstatic Xbad_extension(name, bads) Xchar *name, X *bads; X{ X char *ip; X int namelen = strlen(name), X ext_len, X stop = 0; X X do { X if (ip = index(bads, ' ')) X *ip = 0; X else { X ip = bads + strlen(bads); X stop++; X } X if ((ext_len = ip - bads) == 0) X continue; X if ((ext_len < namelen) && X (strcmp(&name[namelen - ext_len], bads) == 0)) X return YES; X } while ((bads = ip + 1), !stop); X return NO; X} X Xf_match(file) Xchar *file; X{ X int len = strlen(fc_filebase); X X return ((len == 0) || X (strncmp(file, fc_filebase, strlen(fc_filebase)) == 0)); X} X Xstatic Xisdir(name) Xchar *name; X{ X struct stat stbuf; X char filebuf[FILESIZE]; X X PathParse(name, filebuf); X return ((stat(filebuf, &stbuf) != -1) && X (stbuf.st_mode & S_IFDIR) == S_IFDIR); X} X Xstatic Xfill_in(dir_vec, n) Xregister char **dir_vec; X{ X int minmatch = 0, X numfound = 0, X lastmatch = -1, X i, X the_same = TRUE, /* After filling in, are we the same X as when we were called? */ X is_ntdir; /* Is Newly Typed Directory name */ X char bads[128]; X X for (i = 0; i < n; i++) { X strcpy(bads, BadExtensions); X /* bad_extension() is destructive */ X if (bad_extension(dir_vec[i], bads)) X continue; X if (numfound) X minmatch = min(minmatch, X numcomp(dir_vec[lastmatch], dir_vec[i])); X else X minmatch = strlen(dir_vec[i]); X lastmatch = i; X numfound++; X } X /* Ugh. Beware--this is hard to get right in a reasonable X manner. Please excuse this code--it's past my bedtime. */ X if (numfound == 0) { X rbell(); X return; X } X Eol(); X if (minmatch > strlen(fc_filebase)) { X the_same = FALSE; X null_ncpy(fc_filebase, dir_vec[lastmatch], minmatch); X Eol(); X makedirty(curline); X } X is_ntdir = ((numfound == 1) && X (curchar > 0) && X (linebuf[curchar - 1] != '/') && X (isdir(linebuf))); X if (the_same && !is_ntdir) { X add_mess(n == 1 ? " [Unique]" : " [Ambiguous]"); X SitFor(7); X } X if (is_ntdir) X Insert('/'); X} X Xextern int alphacomp(); X X/* called from do_ask() when one of "\r\n ?" is typed. Does the right X thing, depending on which. */ X Xstatic Xf_complete(c) X{ X char dir[FILESIZE], X **dir_vec; X int nentries, X i; X X if (c == CR || c == LF) X return 0; /* tells ask to return now */ X if ((fc_filebase = rindex(linebuf, '/')) != 0) { X char tmp[FILESIZE]; X X null_ncpy(tmp, linebuf, (++fc_filebase - linebuf)); X if (tmp[0] == '\0') X strcpy(tmp, "/"); X PathParse(tmp, dir); X } else { X fc_filebase = linebuf; X strcpy(dir, "."); X } X if ((nentries = scandir(dir, &dir_vec, f_match, alphacomp)) == -1) { X add_mess(" [Unknown directory: %s]", dir); X SitFor(7); X return 1; X } X if (nentries == 0) { X add_mess(" [No match]"); X SitFor(7); X } else if (c == ' ' || c == '\t') X fill_in(dir_vec, nentries); X else { X /* we're a '?' */ X int maxlen = 0, X ncols, X col, X lines, X linespercol; X X TOstart("Completion", FALSE); /* false means newline only on request */ X Typeout("(! means file will not be chosen unless typed explicitly)"); X Typeout((char *) 0); X Typeout("Possible completions (in %s):", dir); X Typeout((char *) 0); X X for (i = 0; i < nentries; i++) X maxlen = max(strlen(dir_vec[i]), maxlen); X maxlen += 4; /* pad each column with at least 4 spaces */ X ncols = (CO - 2) / maxlen; X linespercol = 1 + (nentries / ncols); X X for (lines = 0; lines < linespercol; lines++) { X for (col = 0; col < ncols; col++) { X int isbad, X which; X char bads[128]; X X which = (col * linespercol) + lines; X if (which >= nentries) X break; X strcpy(bads, BadExtensions); X isbad = bad_extension(dir_vec[which], bads); X Typeout("%s%-*s", isbad ? "!" : NullStr, X maxlen - isbad, dir_vec[which]); X } X Typeout((char *) 0); X } X TOstop(); X } X freedir(&dir_vec, nentries); X return 1; X} X X#endif X Xchar * Xask_file(prmt, def, buf) Xchar *prmt, X *def, X *buf; X{ X char *ans, X prompt[128], X *pretty_name = pr_name(def); X X if (prmt) X sprintf(prompt, prmt); X else { X if (def != 0 && *def != '\0') X sprintf(prompt, ": %f (default %s) ", pretty_name); X else X sprintf(prompt, ProcFmt); X } X#ifdef F_COMPLETION X ans = real_ask("\r\n \t?", f_complete, pretty_name, prompt); X if (ans == 0 && (ans = pretty_name) == 0) X complain("[No default file name]"); X#else X ans = ask(pretty_name, prompt); X#endif X PathParse(ans, buf); X X return buf; X} @//E*O*F ask.c// if test 9258 -ne "`wc -c <'ask.c'`"; then echo shar: error transmitting "'ask.c'" '(should have been 9258 characters)' fi fi # end of overwriting check echo shar: extracting "'buf.c'" '(11056 characters)' if test -f 'buf.c' ; then echo shar: will not over-write existing file "'buf.c'" else sed 's/^X//' >buf.c <<'@//E*O*F buf.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/* Contains commands that deal with creating, selecting, killing and X listing buffers, and buffer modes, and find-file, etc. */ X X#include "jove.h" X X#include X Xchar *Mainbuf = "Main", X *NoName = "Sans un nom!"; X XBuffer *world = 0, /* First in the list */ X *curbuf = 0, X *lastbuf = 0; /* Last buffer we were in so we have a default X buffer during a select buffer. */ X X/* Toggle BIT in the current buffer's minor mode flags. If argument is X supplied, a positive one always turns on the mode and zero argument X always turns it off. */ X XTogMinor(bit) X{ X if (exp_p) { X if (exp == 0) X curbuf->b_minor &= ~bit; X else X curbuf->b_minor |= bit; X } else X curbuf->b_minor ^= bit; X UpdModLine++; X} X X/* Creates a new buffer, links it at the end of the buffer chain, and X returns it. */ X Xstatic Buffer * Xbuf_alloc() X{ X register Buffer *b, X *lastbp; X X lastbp = 0; X for (b = world; b != 0; lastbp = b, b = b->b_next) X ; X X b = (Buffer *) emalloc(sizeof (Buffer)); X if (lastbp) X lastbp->b_next = b; X else X world = b; X b->b_first = 0; X b->b_next = 0; X X return b; X} X X/* Makes a buffer and initializes it. Obsolete. Used to take two X arguments, a buffer name and a file name. */ X Xstatic Buffer * Xmak_buf() X{ X register Buffer *newb; X register int i; X X newb = buf_alloc(); X newb->b_fname = 0; X newb->b_name = NoName; X set_ino(newb); X newb->b_marks = 0; X newb->b_themark = 0; /* Index into markring */ X /* No marks yet */ X for (i = 0; i < NMARKS; i++) X newb->b_markring[i] = 0; X newb->b_modified = 0; X newb->b_type = B_FILE; /* File until proven SCRATCH */ X newb->b_ntbf = 0; X newb->b_minor = 0; X newb->b_major = TEXT; X newb->b_first = 0; X newb->b_keybinds = 0; X#ifdef IPROCS X newb->b_process = 0; X#endif X initlist(newb); X X return newb; X} X XReNamBuf() X{ X register char *new = 0, X *prompt = ProcFmt, X *second = "%s already exists; new name? "; X X for (;;) { X new = ask((char *) 0, prompt, new); X if (!buf_exists(new)) X break; X prompt = second; X } X setbname(curbuf, new); X} X XFindFile() X{ X register char *name; X char fnamebuf[FILESIZE]; X X name = ask_file((char *) 0, curbuf->b_fname, fnamebuf); X SetABuf(curbuf); X SetBuf(do_find(curwind, name, 0)); X} X Xstatic Xmkbuflist(bnamp) Xregister char **bnamp; X{ X register Buffer *b; X X for (b = world; b != 0; b = b->b_next) X if (b->b_name != 0) X *bnamp++ = b->b_name; X *bnamp = 0; X} X Xchar * Xask_buf(def) XBuffer *def; X{ X char *bnames[100]; X register char *bname; X register int offset; X char prompt[100]; X X if (def != 0 && def->b_name != 0) X sprintf(prompt, ": %f (default %s) ", def->b_name); X else X sprintf(prompt, ProcFmt); X mkbuflist(bnames); X offset = complete(bnames, prompt, RET_STATE); X if (offset == EOF) X complain((char *) 0); X if (offset == ORIGINAL) X bname = Minibuf; X else if (offset == NULLSTRING) { X if (def) X bname = def->b_name; X else X complain((char *) 0); X } else if (offset < 0) X complain((char *) 0); X else X bname = bnames[offset]; X X return bname; X} X XBufSelect() X{ X register char *bname; X X bname = ask_buf(lastbuf); X SetABuf(curbuf); X SetBuf(do_select(curwind, bname)); X} X Xstatic Xdefb_wind(b) Xregister Buffer *b; X{ X register Window *w = fwind; X char *alt; X X if (lastbuf == b || lastbuf == 0) { X lastbuf = 0; X alt = (b->b_next != 0) ? b->b_next->b_name : Mainbuf; X } else X alt = lastbuf->b_name; X X do { X if (w->w_bufp == b) { X if (one_windp()) X (void) do_select(w, alt); X else { X register Window *save = w->w_next; X X del_wind(w); X w = save->w_prev; X } X } X w = w->w_next; X } while (w != fwind); X} X XBuffer * XgetNMbuf() X{ X register Buffer *delbuf; X register char *bname; X X bname = ask_buf(curbuf); X if ((delbuf = buf_exists(bname)) == 0) X complain("[No such buffer]"); X if (delbuf->b_modified) X confirm("%s modified, are you sure? ", bname); X return delbuf; X} X XBufErase() X{ X register Buffer *delbuf; X X if (delbuf = getNMbuf()) { X initlist(delbuf); X delbuf->b_modified = 0; X } X} X Xstatic Xkill_buf(delbuf) Xregister Buffer *delbuf; X{ X register Buffer *b, X *lastb = 0; X extern Buffer *perr_buf; X X#ifdef IPROCS X pbuftiedp(delbuf); /* check for lingering processes */ X#endif X for (b = world; b != 0; lastb = b, b = b->b_next) X if (b == delbuf) X break; X if (lastb) X lastb->b_next = delbuf->b_next; X else X world = delbuf->b_next; X X#define okay_free(ptr) if (ptr) free(ptr) X X lfreelist(delbuf->b_first); X okay_free(delbuf->b_name); X okay_free(delbuf->b_fname); X free((char *) delbuf); X X if (delbuf == lastbuf) X SetABuf(curbuf); X if (perr_buf == delbuf) { X ErrFree(); X perr_buf = 0; X } X defb_wind(delbuf); X if (curbuf == delbuf) X SetBuf(curwind->w_bufp); X} X X/* offer to kill some buffers */ X XKillSome() X{ X register Buffer *b, X *next; X Buffer *oldb; X register char *y_or_n; X X for (b = world; b != 0; b = next) { X next = b->b_next; X if (yes_or_no_p("Kill %s? ", b->b_name) == NO) X continue; X if (IsModified(b)) { X y_or_n = ask("No", "%s modified; should I save it? ", b->b_name); X if (Upper(*y_or_n) == 'Y') { X oldb = curbuf; X SetBuf(b); X SaveFile(); X SetBuf(oldb); X } X } X kill_buf(b); X } X} X XBufKill() X{ X Buffer *b; X X if ((b = getNMbuf()) == 0) X return; X kill_buf(b); X} X Xstatic char * Xline_cnt(b, buf) Xregister Buffer *b; Xchar *buf; X{ X register int nlines = 0; X register Line *lp; X X for (lp = b->b_first; lp != 0; lp = lp->l_next, nlines++) X ; X sprintf(buf, "%d", nlines); X return buf; X} X Xstatic char *TypeNames[] = { X 0, X "Scratch", X "File", X "Process", X}; X XBufList() X{ X register char *format = "%-2s %-5s %-11s %-1s %-*s %-s"; X register Buffer *b; X int bcount = 1, /* To give each buffer a number */ X buf_width = 11; X char nbuf[10]; X X for (b = world; b != 0; b = b->b_next) X buf_width = max(buf_width, strlen(b->b_name)); X X TOstart("Buffer list", TRUE); /* true means auto-newline */ X X Typeout("(* means buffer needs saving)"); X Typeout("(+ means file hasn't been read yet)"); X Typeout(NullStr); X Typeout(format, "NO", "Lines", "Type", NullStr, buf_width, "Name", "File"); X Typeout(format, "--", "-----", "----", NullStr, buf_width, "----", "----"); X for (b = world; b != 0; b = b->b_next) { X Typeout(format, itoa(bcount++), X line_cnt(b, nbuf), X TypeNames[b->b_type], X IsModified(b) ? "*" : X b->b_ntbf ? "+" : NullStr, X buf_width, X /* For the * (variable length field) */ X b->b_name, X filename(b)); X X if (TOabort) X break; X } X TOstop(); X} X Xbufname(b) Xregister Buffer *b; X{ X char tmp[100], X *cp; X int try = 1; X X if (b->b_fname == 0) X complain("[No file name]"); X cp = basename(b->b_fname); X strcpy(tmp, cp); X while (buf_exists(tmp)) { X sprintf(tmp, "%s.%d", cp, try); X try++; X } X setbname(b, tmp); X} X Xinitlist(b) Xregister Buffer *b; X{ X lfreelist(b->b_first); X b->b_first = b->b_dot = b->b_last = 0; X (void) listput(b, b->b_first); X X SavLine(b->b_dot, NullStr); X b->b_char = 0; X AllMarkSet(b, b->b_dot, 0); X if (b == curbuf) X getDOT(); X} X X/* Returns pointer to buffer with name NAME, or if NAME is a string of digits X returns the buffer whose number equals those digits. Otherwise, returns X 0. */ X XBuffer * Xbuf_exists(name) Xregister char *name; X{ X register Buffer *bp; X register int n; X X if (name == 0) X return 0; X X for (bp = world; bp != 0; bp = bp->b_next) X if (strcmp(bp->b_name, name) == 0) X return bp; X X /* Doesn't match any names. Try for a buffer number... */ X X if ((n = chr_to_int(name, 10, 1)) > 0) { X for (bp = world; n > 1; bp = bp->b_next) { X if (bp == 0) X break; X --n; X } X return bp; X } X X return 0; X} X X/* Returns buffer pointer with a file name NAME, if one exists. Stat's the X file and compares inodes, in case NAME is a link, as well as the actual X characters that make up the file name. */ X XBuffer * Xfile_exists(name) Xregister char *name; X{ X struct stat stbuf; X register struct stat *s = &stbuf; X register Buffer *b = 0; X char fnamebuf[FILESIZE]; X X if (name) { X PathParse(name, fnamebuf); X if (stat(fnamebuf, s) == -1) X s->st_ino = 0; X for (b = world; b != 0; b = b->b_next) { X if ((b->b_ino != 0 && b->b_ino == s->st_ino) || X (strcmp(b->b_fname, fnamebuf) == 0)) X break; X } X } X return b; X} X Xchar * Xralloc(obj, size) Xregister char *obj; X{ X register char *new; X X if (obj) X new = realloc(obj, (unsigned) size); X if (new == 0 || !obj) X new = emalloc(size); X return new; X} X Xsetbname(b, name) Xregister Buffer *b; Xregister char *name; X{ X UpdModLine++; /* Kludge ... but speeds things up considerably */ X if (name) { X if (b->b_name == NoName) X b->b_name = 0; X b->b_name = ralloc(b->b_name, strlen(name) + 1); X strcpy(b->b_name, name); X } else X b->b_name = 0; X} X Xsetfname(b, name) Xregister Buffer *b; Xregister char *name; X{ X char wholename[FILESIZE], X oldname[FILESIZE], X *oldptr = oldname; X Buffer *save = curbuf; X X SetBuf(b); X UpdModLine++; /* Kludge ... but speeds things up considerably */ X if (b->b_fname == 0) X oldptr = 0; X else X strcpy(oldname, b->b_fname); X if (name) { X PathParse(name, wholename); X curbuf->b_fname = ralloc(curbuf->b_fname, strlen(wholename) + 1); X strcpy(curbuf->b_fname, wholename); X } else X b->b_fname = 0; X DoAutoExec(curbuf->b_fname, oldptr); X curbuf->b_mtime = curbuf->b_ino = 0; /* until they're known. */ X SetBuf(save); X} X Xset_ino(b) Xregister Buffer *b; X{ X struct stat stbuf; X X if (b->b_fname == 0 || stat(b->b_fname, &stbuf) == -1) { X b->b_ino = 0; X b->b_mtime = 0; X } else { X b->b_ino = stbuf.st_ino; X b->b_mtime = stbuf.st_mtime; X } X} X X/* Find the file `fname' into buf and put in in window `w' */ X XBuffer * Xdo_find(w, fname, force) Xregister Window *w; Xregister char *fname; X{ X register Buffer *b; X X b = file_exists(fname); X if (b == 0) { X b = mak_buf(); X setfname(b, fname); X bufname(b); X set_ino(b); X b->b_ntbf = 1; X if (force) { X Buffer *oldb = curbuf; X X SetBuf(b); /* this'll read the file */ X SetBuf(oldb); X } X } X X if (w) X tiewind(w, b); X return b; X} X X/* set alternate buffer */ X XSetABuf(b) XBuffer *b; X{ X if (b != 0) X lastbuf = b; X} X XSetBuf(newbuf) Xregister Buffer *newbuf; X{ X register Buffer *oldb = curbuf; X X if (newbuf == curbuf || newbuf == 0) X return; X X lsave(); X curbuf = newbuf; X curline = newbuf->b_dot; X curchar = newbuf->b_char; X getDOT(); X /* Do the read now ... */ X if (curbuf->b_ntbf) X read_file(curbuf->b_fname, 0); X X#ifdef IPROCS X if (oldb != 0 && ((oldb->b_process == 0) != (curbuf->b_process == 0))) { X if (curbuf->b_process) X PushPBs(); /* Push process bindings */ X else if (oldb->b_process) X PopPBs(); X } X#endif X} X XBuffer * Xdo_select(w, name) Xregister Window *w; Xregister char *name; X{ X register Buffer *new; X X if ((new = buf_exists(name)) == 0) { X new = mak_buf(); X setfname(new, (char *) 0); X setbname(new, name); X } X if (w) X tiewind(w, new); X return new; X} @//E*O*F buf.c// if test 11056 -ne "`wc -c <'buf.c'`"; then echo shar: error transmitting "'buf.c'" '(should have been 11056 characters)' fi fi # end of overwriting check echo shar: extracting "'case.c'" '(2610 characters)' if test -f 'case.c' ; then echo shar: will not over-write existing file "'case.c'" else sed 's/^X//' >case.c <<'@//E*O*F case.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 XCapChar() X{ X register int num, X restore = 0; X Bufpos b; X X DOTsave(&b); X X if (exp < 0) { X restore++; X exp = -exp; X num = exp; X BackChar(); /* Cap previous EXP chars */ X } else X num = exp; X X exp = 1; /* So all the commands are done once */ X X while (num--) { X if (upper(&linebuf[curchar])) { X modify(); X makedirty(curline); X } X if (eolp()) { X if (curline->l_next == 0) X break; X SetLine(curline->l_next); X } X else X curchar++; X } X if (restore) X SetDot(&b); X} X XCapWord() X{ X register int num, X restore = 0; X Bufpos b; X X DOTsave(&b); X X if (exp < 0) { X restore++; X exp = -exp; X num = exp; X BackWord(); /* Cap previous EXP words */ X } else X num = exp; X X exp = 1; /* So all the commands are done once */ X X while (num--) { X to_word(1); /* Go to the beginning of the next word. */ X if (eobp()) X break; X if (upper(&linebuf[curchar])) { X modify(); X makedirty(curline); X } X curchar++; X while (!eolp() && isword(linebuf[curchar])) { X if (lower(&linebuf[curchar])) { X modify(); X makedirty(curline); X } X curchar++; X } X } X if (restore) X SetDot(&b); X} X Xcase_word(up) X{ X Bufpos before; X X DOTsave(&before); X ForWord(); /* This'll go backward if negative argument. */ X case_reg(before.p_line, before.p_char, curline, curchar, up); X} X Xstatic Xupper(c) Xregister char *c; X{ X if (islower(*c)) { X *c -= ' '; X return 1; X } X return 0; X} X Xstatic Xlower(c) Xregister char *c; X{ X if (isupper(*c)) { X *c += ' '; X return 1; X } X return 0; X} X Xcase_reg(line1, char1, line2, char2, up) XLine *line1, X *line2; Xint char1; X{ X (void) fixorder(&line1, &char1, &line2, &char2); X DotTo(line1, char1); X X exp = 1; X for (;;) { X if (curline == line2 && curchar == char2) X break; X if (!eolp()) X if ((up) ? upper(&linebuf[curchar]) : lower(&linebuf[curchar])) { X makedirty(curline); X modify(); X } X ForChar(); X } X} X XCasRegLower() X{ X CaseReg(0); X} X XCasRegUpper() X{ X CaseReg(1); X} X XCaseReg(up) X{ X register Mark *mp = CurMark(); X Bufpos savedot; X X DOTsave(&savedot); X case_reg(curline, curchar, mp->m_line, mp->m_char, up); X SetDot(&savedot); X} X XUppWord() X{ X case_word(1); X} X XLowWord() X{ X case_word(0); X} @//E*O*F case.c// if test 2610 -ne "`wc -c <'case.c'`"; then echo shar: error transmitting "'case.c'" '(should have been 2610 characters)' fi fi # end of overwriting check echo shar: extracting "'ctype.h'" '(1476 characters)' if test -f 'ctype.h' ; then echo shar: will not over-write existing file "'ctype.h'" else sed 's/^X//' >ctype.h <<'@//E*O*F ctype.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 code in this file was snarfed from ctype.h and modified for JOVE. */ X X#define _U 01 X#define _L 02 X#define _N 04 X#define _P 010 X#define _C 020 X#define _W 040 X#define _Op 0100 X#define _Cl 0200 X Xextern int SyntaxTable; X#define iswhite(c) (isspace(c)) X#define isword(c) ((CharTable[SyntaxTable])[c]&(_W)) X#define isalpha(c) ((CharTable[SyntaxTable])[c]&(_U|_L)) X#define isupper(c) ((CharTable[SyntaxTable])[c]&_U) X#define islower(c) ((CharTable[SyntaxTable])[c]&_L) X#define isdigit(c) ((CharTable[SyntaxTable])[c]&_N) X#define isspace(c) (c == ' ' || c == '\t') X#define ispunct(c) ((CharTable[SyntaxTable])[c]&_P) X#define toupper(c) ((c)&~040) X#define tolower(c) ((c)|040) X#define toascii(c) ((c)&0177) X#define isctrl(c) ((CharTable[0][c&0177])&_C) X#define isopenp(c) ((CharTable[0][c&0177])&_Op) X#define isclosep(c) ((CharTable[0][c&0177])&_Cl) X#define has_syntax(c,s) ((CharTable[SyntaxTable][c&0177])&s) X#define WITH_TABLE(x) \ X{ \ X int push = SyntaxTable; \ X SyntaxTable = x; X X#define END_TABLE() \ X SyntaxTable = push; \ X} @//E*O*F ctype.h// if test 1476 -ne "`wc -c <'ctype.h'`"; then echo shar: error transmitting "'ctype.h'" '(should have been 1476 characters)' fi fi # end of overwriting check echo shar: extracting "'io.h'" '(1336 characters)' if test -f 'io.h' ; then echo shar: will not over-write existing file "'io.h'" else sed 's/^X//' >io.h <<'@//E*O*F io.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 putchar(c) putc(c, stdout) X#define putc(c, fp) (--(fp)->f_cnt >= 0 ? (*(fp)->f_ptr++ = (c)) : _flush((c), fp)) X#define getc(fp) (((--(fp)->f_cnt < 0) ? filbuf(fp) : *(fp)->f_ptr++)) X Xtypedef struct { X int f_cnt, /* number of characters left in buffer */ X f_bufsize, /* size of what f_base points to */ X f_fd, /* fildes */ X f_flags; /* various flags */ X char *f_ptr, /* current offset */ X *f_base; /* pointer to base */ X char *f_name; /* name of open file */ X} File; X X#define F_READ 01 X#define F_WRITE 02 X#define F_APPEND 04 X#define F_MODE(x) (x&07) X#define F_EOF 010 X#define F_STRING 020 X#define F_ERR 040 X#define F_LOCKED 0100 /* don't close this file upon error */ X#define F_MYBUF 0200 /* f_alloc allocated the buffer, so X f_close knows to free it up */ X Xextern long io_chars; Xextern int io_lines; X Xextern File X *stdout, X X *open_file(), X *fd_open(), X *f_open(); @//E*O*F io.h// if test 1336 -ne "`wc -c <'io.h'`"; then echo shar: error transmitting "'io.h'" '(should have been 1336 characters)' fi fi # end of overwriting check if test ! -d 'doc' ; then echo shar: creating directory "'doc'" mkdir 'doc' fi echo shar: extracting "'MANIFEST'" '(2126 characters)' if test -f 'MANIFEST' ; then echo shar: will not over-write existing file "'MANIFEST'" else sed 's/^X//' >MANIFEST <<'@//E*O*F MANIFEST//' X File Name Kit # Description X----------------------------------------------------------- X MANIFEST 1 This shipping list X Makefile 1 X Ovmakefile 1 X README 1 X abbrev.c 1 X ask.c 1 X buf.c 1 X c.c 2 X case.c 1 X ctype.c 2 X ctype.h 1 X delete.c 2 X disp.c 2 X doc 1 X doc/README 8 X doc/cmds.doc.nr 2 X doc/example.rc 8 X doc/jove.1 9 X doc/jove.2 10 X doc/jove.3 8 X doc/jove.4 11 X doc/jove.5 12 X doc/jove.nr 9 X doc/recover.nr 10 X doc/system.rc 8 X doc/teach-jove 13 X doc/teachjove.nr 8 X extend.c 3 X fmt.c 2 X fp.c 3 X funcdefs.c 3 X insert.c 3 X io.c 4 X io.h 1 X iproc-pipes.c 4 X iproc-ptys.c 4 X iproc.c 4 X jove.c 5 X jove.h 5 X keymaps.txt 4 X macros.c 5 X malloc.c 5 X marks.c 5 X misc.c 6 X move.c 6 X paragraph.c 6 X portsrv.c 6 X proc.c 6 X re.c 7 X re.h 2 X re1.c 6 X rec.c 4 X rec.h 2 X recover.c 7 X scandir.c 7 X screen.c 7 X setmaps.c 5 X table.c 3 X table.h 6 X teachjove.c 7 X temp.h 8 X term.c 8 X termcap.h 8 X tune.h 8 X tune.template 7 X util.c 8 X vars.c 8 X version.c 7 X wind.c 8 @//E*O*F MANIFEST// if test 2126 -ne "`wc -c <'MANIFEST'`"; then echo shar: error transmitting "'MANIFEST'" '(should have been 2126 characters)' fi fi # end of overwriting check echo shar: "End of archive 1 (of 13)." cp /dev/null ark1isdone 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