[comp.editors] Simple Editor

ant@mks.com (Anthony Howe) (05/30/91)

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 <filename>	

where <filename> 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 <curses.h>
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<g)while(p<g)*--h= *--g;if(h<=p)while(h<p)*g++= *h++;p=h;}
Xchar*M(s)char*s;{while(b<(s=s-h?s:g)&&*--s!='\n');return b<s?s+1:b;}
Xchar*N(s)char*s;{while((s=s-g?s:h)<c&&*s++!='\n');return s<c?s:c;}
XA(){for(i=0,p=p-g?p:h;p<c&&*p!='\n'&&i<x;i+= *p-'\t'?1:8-(i&7),R());}
XL(){p=h-p?p:g;b<p&&--p;--y;}R(){p=p-g?p:h;p<c&&++p;}U(){p=M(M(p)-1);A();--y;}
XD(){p=N(p);A();}H(){p=M(p);}E(){p=N(p);L();}
XB(){while(!Z(*p)&&b<p)L();while(Z(*p)&&b<p)L();}
XJ(){m=p=M(M(n)-1);while(y--)p=N(p);A();n=c;}
XK(){for(i=d;--i;m=M(M(m)-1),p=M(M(p)-1));A();}
XW(){while(!Z(*p)&&p<c)R();while(Z(*p)&&p<c)R();}
XI(){V();while((a=getch())-'\f'){if(a-'\b')h-g&&(*g++=a-'\r'?a:'\n');
Xelse b<g&&--g;Y();}}X(){V();p=h<c?++h:p;}
XF(){p=b;V();write(i=creat(f,MODE),h,(int)(c-h));close(i);}
X(*z[])()={L,D,U,R,B,J,K,W,H,E,S,T,I,X,F,P,Q,V};
XY(){if(p<m)m=M(p);if(n<=p||++y==d)for(m=N(p),i=m-c?d:d-2;i--;m=M(M(m)-1));
Xmove(0,0);for(i=a=0,n=m;;){n=n-g?n:h;n-p||(y=i,x=a);if(d<=i||c<=n)break;
X*n-'\r'&&(addch(*n),a+= *n-'\t'?1:8-(a&7));if(*n++=='\n'||COLS<=a)++i,a=0;}
Xclrtobot();++i<d&&mvaddstr(i,0,"<< EOF >>");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<b?b:g,close(i);while(q){Y();
Xfor(a=getch(),i=0;k[i]&&a!=k[i];++i);(*z[i])();}endwin();return 0;}
---end---
-- 
ant@mks.com                                                   Anthony C Howe 
Mortice Kern Systems Inc. 35 King St. N., Waterloo, Ontario, Canada, N2J 6W9
"Fate favors fools, small children, and ships named Enterprise" - Riker

lewis@bnrmtl.bnr.ca (Pierre LEWis) (05/30/91)

|> What you'll find below is my simple VI-like full screen editor.

Incredible, I would not have thought it possible (a usable editor in 1.5
Kbytes! probably close to 3 orders of magnitude less than emacs).  So now
we all have the simple Unix editor people keep wanting.  It compiles on my
Sparc and what I tried worked, but I'll probably stick to my current
editor.  Still, I'm keeping the source...

By the way, what is IOCCC?

--
Pierre LEWIS    +1 514 765 8207
Internet:       bnrmtl!lewis@Larry.McRCIM.McGill.EDU

Lubarsky's law of cybernetic entomology:  There is always one more bug!

ant@mks.com (Anthony Howe) (05/31/91)

> |> What you'll find below is my simple VI-like full screen editor.
> 
> Incredible, I would not have thought it possible (a usable editor in 1.5
> Kbytes! probably close to 3 orders of magnitude less than emacs).  So now
> we all have the simple Unix editor people keep wanting.  It compiles on my
> Sparc and what I tried worked, but I'll probably stick to my current
> editor.  Still, I'm keeping the source...

Thank you, and others for the praise.  I'm glad the editor was well
received by most.  I'm even happier that it work (first go?) on your
machine.  

If not, drop me a note as to why and what you did to make it work.

Again thanks to every who sent me a note and especially to Joseph H. Allen
for writing the Editor 101 and Gap Buffer articles, and to Stephen Trier for
writing the Editor 102 article. 

> By the way, what is IOCCC?

The I.nternational O.fuscated C C.ode C.ontest is an informal contest
now in it's eight year.  There are no prizes other than fame or flames :)
for writing the smallest, dirtiest, and down right sneakiest pieces of code.

All the entries must do something interesting and they have different
catagories for judging.  Some past greats have been Tetris with built-in
mini-CURSES, uncompress, and a BASIC interpreter.  Below is an
extract of 1991 Rules that should give a better idea.  Watch comp.lang.c 
or comp.sources.unix for posting of the results.  The contest opens some 
time around March/April each year (this is my first time entering).

----
8th International Obfuscated C Code Contest Rules

	Obfuscate:  tr.v.  -cated, -cating, -cates.  1. a.  To render obscure.
		b.  To darken.  2. To confuse:  his emotions obfuscated his
		judgment.  [LLat. obfuscare, to darken : ob(intensive) +
		Lat. fuscare, to darken < fuscus, dark.] -obfuscation n.
		obfuscatory adj.

GOALS OF THE CONTEST:

    * To write the most Obscure/Obfuscated C program under the rules below.
    * To show what should NOT be done in C programs.
    * To provide a safe forum for poor C code.  :-)

RULES:

    1) Your source MUST be 1536 bytes or less, and it must be a complete
       program, not just a subroutine.

[..entry specification deleted..]

ANNOUNCEMENT OF WINNERS:

    * First announcement will likely be at the Summer 91 Usenix conference.

    * Winning entries will be posted in mid June 1991 to 
      comp.sources.unix as well as news groups where these rules 
      were posted.  (depending on the judges work load)
    
    * Winning entries will be deposited into the uunet archives.

    * An article containing the winning entries will be published
      in a future issue of the "Micro/Systems Journal".

    * Winners receive international fame and flames!  :-)


JUDGING:

    Awards will be given to the best entry in a number of categories.
    The actual category list will vary depending on the types of entries
    we receive.  As a guide, consider using the following:

	* The best small one line program
	* The strangest source layout
	* The most useful obfuscated program
	* The most creatively obfuscated program
	* Best obfuscated entry smaller than 256 bytes
	* Best obfuscated entry smaller than 1024 bytes
	* Best abuse of ANSI
	* Worse abuse of the rules (no abuse of entry format please!)
	* <anything else so strange that it deserves an award>

	[and last few years emphasis on portability]
---
-- 
ant@mks.com                                                   Anthony C Howe 
Mortice Kern Systems Inc. 35 King St. N., Waterloo, Ontario, Canada, N2J 6W9
"Fate favors fools, small children, and ships named Enterprise" - Riker

gallen@apollo.hp.com (Gary Allen) (06/05/91)

In article <1991May30.130945.4341@mks.com> ant@mks.com (Anthony Howe) writes:
......
>scheme that was discussed in the this group in the Editor 101 and
>102 articles.
......
>[net90]	"Editor 101/102" articles from comp.editors
......

Any possibility of getting a copy of these articles?
Thanks.

Gary Allen
Apollo Computer
Chelmsford, MA
gallen@apollo.HP.COM