Newsgroups: comp.editors Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!zaphod.mps.ohio-state.edu!caen!news.cs.indiana.edu!maytag!mks.com!ant From: ant@mks.com (Anthony Howe) Subject: Simple Editor (IOCCC '91 Entry) Date: Thu, 30 May 91 13:09:45 GMT Message-ID: <1991May30.130945.4341@mks.com> Organization: Mortice Kern Systems, Waterloo, Ontario, CANADA Sender: ant@mks.com (Anthony Howe) I've been iching to post this for over a year now to this group, but had to wait till after the closing of entries for the International Obfuscated C Code Contest for this year. This code may or may not win, but it should prove interesting. What you'll find below is my simple VI-like full screen editor. Now before I get caught in the cross-fire of the VI vs Emacs war, remember that the *source* code has to be less than 1.5k or 1536 bytes to enter the IOCCC. The use of modes and VI-like keys made the code all that much smaller allowing me to add more commands like word movement. With a little careful unwrapping of the source, it should be *very* easy to configure the program to use CURSES' keypad(1) function and the KEY_xxxx macros to obtain use of all your favourite terminal function keys. I had experimental versions that did this. This code should also prove interesting since I use the Buffer Gap scheme that was discussed in the this group in the Editor 101 and 102 articles. All entries into the IOCCC must be in the public domain and so this means you can do what you like to it. Below is the entry exactly as I sent it off. You'll have to cut out the man page which follows the remarks: line and also cut out the source. Note that the leading X's in the source are part of the entry form not the code. ---header items--- name: Anthony C Howe org: Mortice Kern Systems Inc. 35 King St. N, Waterloo, On, Canada, N2J 2W9 email address: ant@mks.com or ..!watmath!mks!ant postal address: #CL-23, 268 Phillip St, Waterloo, On, Canada, N2L 6G9 environment: Interactive UNIX System V/386 Release 3.2 BSD Unix 4.3 Atari Mega ST using Sozobon C NEC Ultralite using WatCom C v7 Some PC 386 box using Turbo C v1.5 entry: 0 remarks: NAME ae Ant's Editor vIOCCC91 USAGE ae where is the text file to edit or create. DESCRIPTION << ae >> is a full screen, VI style text editor. The source should be portable to any environment that provides a K&R C compiler and a CURSES library. (Even EBCDIC machines provided the above two requirements are met.) Text files consists of lines of printable text or tab characters. A line can be of arbitary length and is delimited by either a newline or the end of file. Carriage return is mapped to newline on input and ignored on output. Tab stops are every eight columns. Non-printable characters may have unpredictable results depending on the implementation of CURSES. COMMANDS h j k l left, down, up, right cursor movement H J K L word left, page down, page up, word right [ ] beginning and end of line t b top and bottom of file i enter insert mode, formfeed to quit x delete character under the cursor W write buffer to file R refresh the screen Q quit EXIT STATUS 0 success 2 missing edit filename INSTALLATION Requires K&R C and a CURSES library for the given target machine. The file creation MODE should be set at compile time to 0600 for Unix systems, or 0 for the Atari ST and PC. The BUF size should be set at compile time to 32767. This value was used because the Sozobon C compiler for the Atari ST has 16 bit ints and a limit on the size of arrays & structures of 32k. Also the WatCom C compiler for the PC also has 16 bits ints. On machines that have 32 bit ints (most unix boxes), a larger value for BUF could be used. It is recommend that compact memory model be used on PC class machines. Small memory model may work too provided BUF is not too large. The character constants '\b', '\f', '\n', '\r', '\t' are used in order to provide more portable code, since the compiler should handle the translation of them into the native character set. Note that '\f' (formfeed) was used to exit insert mode because K&R C had no escape constant for the escape-key. Note that the "int " definition at the top of the source was for the benifit of Turbo C, which returns lots of warnings. WatCom C should return no warnings provided your curses.h has no NULL expression defined for functions. System V and BSD should also generate no warnings. The source should pass basic linting. The source still looks like a mess when passed through our C beautifier (your milleage may vary). My goals for this project were to learn and experiment with the Buffer Gap Scheme [Fin80][net90], write a useful and *portable* programme, and meet the requirements of the IOCCC. I initially planned to have a mini CURSES built-in like the IOCCC Tetris entry from a previous year, however this was not as portable as using a CURSES library with TERMINFO/TERMCAP support. REFERENCES [Fin80] Craig A. Finseth, "Theory and Practice of Text Editors or A Cookbook For An EMACS", TM-165, MIT Lab. for Computer Science [KeP81] Kernighan & Plauger, "Software Tools in Pascal", Addison-Wesley, 81, chapter 6 [Mil86] Eugene W. Myers & Webb Miller, "Row-replacement Algorithums for Screen Editors", TR 86-19, Dept. of Compter Science, U. of Arizona [MyM86] Eugene W. Myers & Webb Miller, "A simple row-replacement method", TR 86-28, Dept. of Compter Science, U. of Arizona [Mil87] Webb Miller, "A Software Tools Sampler", Prentice Hall, 87 ISBN 0-13-822305-X, chapter 5 [net90] "Editor 101/102" articles from comp.editors FILES ae.c Obfuscated source ae.man Manual page ---how to ANSI compile--- ---how to common compile--- X # SYS V X cc -DMODE=0600 -DBUF=32767 -o ae ae.c -lcurses X # BSD X #cc -DMODE=0600 -DBUF=32767 -o ae ae.c -lcurses -ltermcap X # ATARI ST X #cc -DMODE=0 -DBUF=32767 -o ae.ttp ae.c curses.a X # PC class X #wcl -mc -DMODE=0 -DBUF=32767 ae.c curses.lib ---program--- X#include X#define Z(x) (x==' '||x=='\t'||x=='\n') Xint a,d,i,q=1,x,y;char b[BUF],*c,*g=b,*h,*p=b,*m=b,*n,*f, Xk[]="hjklHJKL[]tbixWRQ";S(){p=b;}T(){p=c;}Q(){q=0;}P(){clear();Y();} XV(){if(p>");move(y,x);refresh();} Xmain(u,v)char**v;{h=n=c=b+BUF;if(u<2)return 2;initscr();d=LINES;raw(); Xnoecho();idlok(stdscr,1); Xif(0<(i=open(f= *++v,0)))g+=read(i,b,BUF),g=g