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 /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 /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.