		The emacs spread.frame device handler

			 Richard M. Heiberger


There are two variants in the usage of this emacs spread.frame device
handler.  Both use the same command file: S-spread.el.  One variant is
stand-alone.  The other works with S-mode.  Both are written in emacs
19.29 to use the comint.el package.  They will not work in emacs 18.

A. Stand-alone Usage

1. Create a .Data subdirectory in the directory you will be using, say
`myclass' and `myclass/.Data'.  Get into the dired buffer of the
directory `myclass'.  Any other buffer will cause the terminal to beep.


2. From the dired buffer enter (on my computer):
	M-x load-file <RET> /disk5/rmh/sprd3d/S-spread.el
Edit the pathname for your computer.  Any other buffer than the dired
buffer will cause the terminal to beep.  You will be prompted "S or
Splus? ".  "Splus" has been filled in as the default.  Edit the
command name if necessary, inserting a full pathname if appropriate,
then hit carriage return.

This leaves the window showing the .Registry buffer in Spread mode.  If
you previously had a .Registry in that directory, it appears in the
buffer.  If you have never used the spread.frame handler in that
directory, then a new .Registry has been created for you.

You also have a buffer called *Splus* (or *S*) in Inferior Spread mode
in which Splus (or S) is running.


   NOTES for Stand-alone Version

If you were previously running Splus in buffer *Splus* in Inferior Spread mode
and accidentally killed the Splus process (for example, with the q()
command), you are still using that buffer and the Splus process has been
restarted.  

If you have a buffer named *Splus* not associated with a process, for
example a file you are editing, emacs will use that buffer for the
Inferior Spread mode.

If you have a running Inferior Spread process, a shell process, or any
other process, in a buffer named *Splus*, the terminal will beep.



B. S-mode Usage

1. Create a .Data subdirectory in the directory you will be using, say
`myclass' and `myclass/.Data'.  Get into the dired buffer of the
directory `myclass' and start S-mode with M-x S.


2. From the *S* buffer that S-mode has started enter (on my computer):
	M-x load-file <RET> /disk5/rmh/sprd3d/S-spread.el
Edit the pathname for your computer.  Any other buffer than the *S* buffer
will cause the terminal to beep.

This leaves the window showing the .Registry buffer in Spread mode.
If you previously had a .Registry in that directory, it appears in the
buffer.  If you have never used the spread.frame handler in that
directory, then a new .Registry has been created for you.


   NOTES FOR BOTH VERSIONS

   S/Splus thinks it is in charge and does not know about emacs.  Emacs with
comint attempts to coordinate its timing with Splus by sending commands to
Splus with (comint-send-input) and waiting for their completion with
(accept-process-output).  If for any reason an out-of-date display of a
buffer appears, use ^Cv to bring up the current display.  If things
still look wrong, go to the *Splus* buffer and force a current display
with ^Cr. You will be requested to type the name of the object to be
displayed in the minibuffer.  All buffers displaying views of that
object, and the .Registry buffer will be updated.

Either usage of the spread.frame functions and the command file
S-spread.el works with S Version 3, S Version 4, or Splus 3.3.



3. Start working in the .Registry buffer.  Move to the macro section.
   a. Do "f" or [mouse-2] on the name of the spread.frame you want to see.
      Spread.frame names are listed in the macro section of the display.
   b. If no names appear, then you must add them.


4. To add more spread.frames, for example the "xy" spread.frame, where the
   "xy" spread.frame already exists in the .Data:
   
    a. Move to the *Splus* buffer. Enter "^Cr".
    b. The minibuffer will ask you for the name of a spread.frame.
    c. Enter the name of the object (for example xy (no quotes))
       or an expression for a 2-way rectangular slice (xy[,,2]) of a 3-way object.
    d. The "xy" spread.frame will appear in the buffer.


5. To add a three-way spread.frame to the display from the *Splus* buffer

    a. Create a 3-way array and make it a spread.frame:
	xs <- as.spread(array(1:12,dim=c(2,3,2)))
    b. Print it to the /tmp/spraxxxxx directory with:
	print.update.emacs.3d(xs)
    c. Move the cursor to the .Registry buffer.  Place the cursor on the
       .Registry entry and press RETURN twice.  The names for the slices
       will now appear in the **macro** section (if not, use ^Cv).
    d. Place the cursor on each of the slices' names and press f.
    e. The entire spread.frame can also be displayed by pressing "f"
       or [mouse-2] on its name.
       The window displaying the entire spread.frame is not active.
       Pressing RETURN will beep.
    f. The slices are active.  Pressing RETURN on a cell entry will update
       the entire spread.frame and the display of the slices.  Pressing RETURN
       on a macro keyword or a macro name in a slice buffer will activate the
       display and update of the macro for the entire spread.frame.


6. Move between spread.frames with ^X o.


7. To edit a spread.frame, place the cursor on a cell and press ENTER
   or [mouse-3].  The expression associated with the cell will be
   displayed in the mini-buffer.  Edit it and press ENTER.  The
   spread.frame in Splus will be updated, and all views of the object in
   emacs buffers will be updated.


8. To execute a macro, place the cursor on the macro name and enter ^Cc.
   Don't use print() or cat() in macros; sink() is in use.


The graphics device can be used for rectangular spread.frames, but does
not yet work with three-way spread.frames.
To use a graphics device for the spread.frame display (but no macros yet).


9. Open a graphics device: x11(), iris4d(), motif(), etc.


10. Add the names of the spread.frames to .Registry as described above.


11. To place a spread.frame in the graphics device, put the cursor on the
   spread.frame name in the **macro** listing in .Registry, and press ^Cp
   The minibuffer will display
	> xy <- print.text( xy )
   Press ENTER and the device will show the xy spread.frame.


12. To change a value in a spread.frame in the graphics device, put the
   cursor on the spread.frame name in the **macro** listing in .Registry,
   and press ^Cs
   The minibuffer will display
	> xy <- control.text( xy )
   Press ENTER, move the cursor into the graphics window, and click when the
   crosshair is on the cell you wish to change.  Place the cursor in the *Splus*
   buffer, move to the end of the buffer by pressing ESC > .  You will see
   the expression to be edited (prefixed with a ">") on the next to the last
   line.  Move the cursor to that line, edit the value, and press ENTER.
   The graphics window will be updated.


13. You can edit any emacs buffer spread.frame by switching to its
   buffer and pressing ENTER or [mouse-3] on the appropriate entry.  You
   can edit any spread.frame in the graphics device, by switching to the
   .Registry buffer, confirming that the spread.frame is in the graphics
   window (or putting it there with ^Cp), and then entering ^Cs on the
   macro name in the .Registry buffer that matches the spread.frame.


14. There is an additional feature in the spread.frame interface that
   is very useful for numerical rows or columns.  When the cursor is
   placed on the dimnames row or column, the entire column or row is made
   available in the mini-buffer.  Warning: expr() in the row or column
   will be evaluated and will no longer be expr().


15. Character data.  Character matrices work well as spread.frames.


16. Warning:  character or factor columns in data.frames.
    S likes to coerce character columns in data.frames to factors.
Updating an entire factor column, or an entire row containing factor
columns, may be dangerous because the revised values may not be in the
levels().  The entire column may be replaced with NA values.  Updating
of individual character values is fine in character arrays that are
not data.frames, or in data.frames where the length(expr(x)) ==
prod(dim(x)).  To get a character column into a data frame use
	my.frame$char <- character.value		# remains character
Using either
	my.frame[,"char"] <- character.value		# coerced to factor
	my.frame <- cbind(my.frame,character.value)	# coerced to factor
won't work.  Either of those forms coerces the values to factor.
