                                  EEdit
                                  =====
                                  
Introduction
------------
You'll be asking yourself what is EEdit by now I'd imagine. It's a very
little program that was relatively hard to write, and basically it allows you
to edit files from the command line. Instead of the 'normal' way that this
might be done (using a full screen, single-tasking editor - eg pico), eedit
returns to the desktop and allows you to edit the file in the comfort of your
favourite editor (so long as you like Zap or StrongEd!).

This may not seem useful at first, but if you want to automatically start an
edit of a file from an Obey file or similar then this is likely to be the
only way you can do it (short of using the 'full screen' editors).


Usage
-----
It's very simple to use really. Just place EE inside your Library structure
(if you use a directory structure, then I suggest that 'Prog' or similar
would be a good category) and to edit a file type :
  *EE <file>

This will attempt to use whatever editors are currently present to edit the
file. If there are no editors capable of editing that type of file the
editing session will abort and you will return to the command line. To force
a file to be edited in as if it were another type, use :
  *EE -t <type> <file>

where <type> is a three digit hex number. If you wanted (for example) to edit
the !Boot.!Boot file on your computer you might use :
  *EE -t FFF Boot:!Boot

One in the editing session, saving or discarding the file will return you to
the command line with the file updated or unmodified (respectively). If you
run the command from within a TaskWindow the window will remain active,
awaiting a key press or the return of the data. You can use R to forcibly
return the data (updated) to the task, or A to abort. Escape will also abort
the session.

Note: It is not dangerous to close the taskwindow, or kill the EETask task
that starts as these will be trapped and dealt with accordingly.


Building EE into other programs
-------------------------------
Whilst it's quite obvious that you could start EE from within a command line
C program by using system("ee <file>"), I have written a small C library
which will allow you to start an external edit from within your C code. This
is currently used in GMail 1.19 to provide it's editor.

Note on desktop/taskwindow interaction
--------------------------------------
Whilst this is not the first program to be able to perform operations in the
desktop from the command line or from within a taskwindow, it is possibly the
most useful (aside, perhaps, from Java).

If anyone wishes to write a CLI program that can interact with the desktop
they might be interested to know how this can be achieved...

Firstly, you find out if you are inside a task or not by doing
'Wimp_Initialise'. This will return an error if you are in a task (which
might happen if you were being run from within a TaskWindow or another
application. You should record your task handle and also the fact that the
call failed or succeeded (so that you can closedown if you need to later).

It might be advisable to Wimp_AddMessages /if/ you were already in a task, as
otherwise you might never receive anything.

Then, you should check if you are in a TaskWindow using TaskWindow_TaskInfo.
You should now start the filter (more details below). If you are, you need to
display a message and read keys (INKEY style) until a 'flag' is set to say
you should exit. If you are not in a taskwindow, you should perform a
Wimp_Poll loop, checking for the same 'flag' being set. The loop should
respond to only the quit message, for which it might set the flag to mark.

On the flag being set you should exit your loop, stop the filter and perform
Wimp_CloseDown (if required), then return to whatever you were doing.

You should register the filter with the task you are in (not the handle you
got back from Wimp_Initialise as this may be invalid) - you can read this
using Wimp_ReadSysInfo. The filter should perform 'interesting' operations
after all polls (rather than at only null polls - as the task may have these
disabled; you'd need a PreFilter to turn them on if you wanted to do it that
way) [EEdit does not quite do this, but then nobody's perfect :-) ]. You
should trap the TW_Morite and Quit usermessages to remove your filter. If you
were in a taskwindow the program would never see anything, but would exit
safely because the filter would not be present, and if you were in the CLI
the filter would exit and then the program would receive the quit message
and similarly exit. You should NOT fault multiple removals of the filter -
use the X variant.

Obviously, you'd probably want to use a state system (as EEdit does) rather
than just flags to mark return conditions, but the general principle holds.
One other matter of note is that you /can/ have the filter in the same space
as the Task itself - there is no requirement to move the filter into RMA.
However, you must remember that a program like 'Empty Tasks' is very likely
to kill the desktop if it pages such a task out of memory. There is a simple
solution to this - don't do it :-)

Hopefully that will help people wishing to write similar code. For those mad
enough, the source code is included in JFPatch format.


Final comments
--------------
Remember, it is not an exercise in futility to simply try something that has
never been done. Rather than just using the incredible power of your
computer, try to push it. There's an advert on telly at the moment (which I
don't like) but the sentiment is good - 'Don't just immitate, innovate', so
try writing something that has never been done before. And if anyone else
writes another Address Book program and then expects people to pay for it
I'll scream ! This is not a PC market, guys (and gals), we're have an
incredibly powerful machine at our fingertips which is not being exploited.

Next time you see a program running slowly on your machine and you're
thinking 'Oh, it's ok because it's doing lots of work' please bare in mind
this little snippet - 

"Every time a character needs outputing to the screen it passes into the
'SWI' decoding routine, which passes it to the OS_WriteC routine, which
passes it through to WrchV which goes through all the routines hooked on to
that vector to the code to display it on the screen. These then take account
of the screen mode, graphics cursor activation, control codes, etc and displa
it (or redirect it to a file - a similarly complex procedure), then returns
back through the SWI routines (possibly performing callbacks) and then to the
caller. This occurs for every character. And if you use OS_WriteS rather than
OS_WriteC it simply calls OS_WriteC lots of times, going through the whole
thing for every character."

Anyone who has programmed that side of things will know this (as will anyone
who programmed the BBC as the principle is the same). The thing is that so
much is going on for a single character output and yet it is still fast. Type
*Help . and watch as the screen fills with flashing characters (actually
you'll have to hold down shift otherwise it'll stop!). If you're not
surprised by the speed (and I'll admit that I was once I thought about it),
then I'll remind you that I'm using an A5000. If that still doesn't surprise
you then, I'll tell you another little tale :

"Fonts in the Desktop is something people have tried to do for Pre-RPCs for a
long time with varying degrees of success. However, I know of only one person
who ever tried it the way I did (other than me, and I forget their name). By
redirecting the WrchV and checking all the system variables then producing a
font via Font_Paint rather than system character and returning to the
original caller."

What surprised me most was not the fact that it worked (although that did
quite a bit), but the speed of it. Even doing this ridiculous level of
patching the desktop /still/ isn't particularly slow; it's possible now to
see the Pinboard menu redraw, but let's remember that every character is now
passing through the Font manager and has a few calls to OS_Byte and similar
routines chucked in there for good measure. It takes about 1 seconds to
redraw my current Mode 31 screen (full pinboard and three Filer Windows) but
that's not much more than the normal time anyhow. There are some problems
with sprite redirection, but that's only to be expected.

Why am I telling you this ? You should remember everytime you see a program
running slowly that it's not just the complexity of what it does, but the way
it's been written. In my example I was writing assembler by hand, but if you
see a C program's insides you'll know how yuckily it's been written. Simple
things like strcpy followed by strlen can optimise to a single call in hand
written assembler. They may not take long, but it all adds up. Similarly
something like :
  for (i=0; i<strlen(x); i++) { ... }

Is so amazingly bad that it really needs some thinking about. I reckon that
that comes out at O(2n) for that single loop, when it could be O(n) with a
tiny bit of thought. Ok, so not everybody wants to write code that way, and
most would rather the code worked than spent hours/days getting it to be
fast, but /do/ bare this in mind when a company says it can't make a program
any faster - they may not be telling the complete truth :-)

<end of sermon!>


Contact
-------
If you want to contact me, I am emailable at gerph@innocent.com - this
address is likely to remain for the forseeable future.
