[N-World Contents] [Book Contents] [Prev] [Next] [Index]

N·World is fully extensible, so you can develop your own extensions to the original source code. The N·World Developers Kit includes Franz Allegro Common Lisp (ACL), and Xemacs, industry standard tools for developing object oriented LISP code. This chapter describes:

To develop in the N·World environment, you should be familiar with ACL and CLOS (Common Lisp Object System). This chapter is not intended to teach you to program using LISP, nor to teach you to use Xemacs.


Getting Started

LISP extensions to N·World are edited and compiled using Xemacs. To begin editing new LISP code:

1. Launch Xemacs.

The exact procedure for launching Xemacs is dependent on how your system is configured. For more information, consult the documentation which came with your Lisp development tools.

2. (CLICK-L) on ACLfile>Run/Restart Common Lisp.

This loads and starts Lisp.

3. Specify a buffer.

In general, choose the default buffer:

(default *common-Lisp*)

4. Specify a UNIX host.

By default, the host is the machine where Xemacs is running.

5. Specify a Process Directory.

This is essentially a default directory.

6. Specify an image to load.

Type the path and filename of the image you want to load into the current buffer. To load N·World, type its path and filename as it is installed on your system. The default pathname used during installation is:

/usr/local/ngc/bin/nworld-3-0-0

The filename may be different on your system, depending upon which version of N·World is installed on your system.

7. Specify any image arguments.

Accept the default argument, debug t. This instructs Xemacs to provide you with a listener, or interactive prompt from which you can evaluate Lisp forms.

You're now ready to code your extensions and enhancements to N·World.


Using Xemacs

Xemacs is fully extensible, and Franz has taken advantage of this by adding a host of tools for creating Lisp code. These include facilities for compiling and debugging code, as well as for inspecting Lisp objects. Xemacs has excellent online documentation, and there are a number of excellent third-party references available as well.

Extending Xemacs

You can use emacs Lisp (a non-ANSI dialect of Lisp) to extend Xemacs in several ways, including adding new key bindings, adding new menu commands. Extensions to Xemacs are stored in files with the extension .el. The N·World Developers Kit includes two such files: nworld-emacs-std.el and nworld-site-init.el

The Xemacs Window

Figure 3.1 The Xemacs window.

Figure 3.1 illustrates the major features of the Xemacs windowing system. When you enter text in a window, you are modifying a buffer. You can display several buffers at any given moment, but you can only enter text into a single buffer at a time.

Basic Commands and Key Bindings

You issue Xemacs commands by pressing key-combinations, or by selecting items from the pull-down menus in the menu bar. Table 3.1 summarizes some of the important Xemacs window and buffer manipulation key bindings.

Table 3.1 Xemacs keybindings for manipulating windows and buffers.
Key Binding Function
(C-x k)

Kill buffer. Unsaved changes are lost.

(C-x n)

Show n windows

(C-X B)

Switch to buffer

(C-X C-B)

Switch to buffer with a hypertext list of available buffers.

(C-X S)

Save buffer to file

(C-X C-w)

Save buffer to different filename

(C-X c-F)

Open file

(C-x 0)

Hide a buffer

(C-M-x)

Compile a Lisp form

(C-c C-b)

Compile a Lisp buffer

(M-x shell)

Open a UNIX shell

(M-Sh-a)

Get arguments for a function

(M-.)

"Meta-dot", find source code for a function.

Keys: C=control, M=Meta (Alt), Sh=Shift

There are many more useful Xemacs key bindings. To obtain a complete list of these:

1. Select Help/List Key Bindings from the Xemacs menu bar

You can also type the corresponding key binding, (C-H B).

Note: In Xemacs notation, M refers to the Meta key, which is usually mapped to the ALT key on SGI keyboards. Xemacs key bindings are case sensitive. For example, M-C and M-c are not equivalent. The first is "Meta-Shift-c", and the second merely "Meta-c".


Creating Code

There are two primary ways of entering code in Lisp:

Entering Code in the Lisp Listener

Code entered in the Lisp listerner is evaluated right away. For example, if you type in a Lisp form which defines a function and then press return, that function is interpreted and integrated with the current Lisp image.

Entering Code in a Buffer

You can also type your forms into a buffer, which you can save to a file. This is how you should enter code you wish to save for later use. You can edit an existing file, or create a new file.

To edit an existing file:

1. Type (C-X C-F), or choose File>Open from the Xemacs menu.

Xemacs will prompt you in the minibuffer for a filename.

2. Enter the name of the file you wish to edit.

You can type the first few letters of a path or filename, then use the tab key to complete the name. If more than one path or filename matches the partial name you typed in, Xemacs provides a list of possible completions in a temporary buffer. (CLICK-L) on the directory or filename you want.

Figure 3.2 Completing File Names

3. To create a new file, enter a filename which does not correspond to an existing file.

Xemacs creates a buffer with the name you specify. The new file is actually created when you first save the buffer.

Saving Your Work

Occasionally, you'll want to save your work. To save your work to a file:

1. (CLICK-L) on File>Save As.

(you can also use the C-X C-W key binding.)

Xemacs will prompt you to enter a path and filename.

2. Type in a path and filename for your file.

For example, to save your code in your home directory, type:

~/MyLisp.lisp

Where to Save Your Source Code

Xemacs and ACL have no preferences about where you store your source code. However, you must store your code in the default source code directory to make use of the Compile Plugin extension to Xemacs provided with your development kit. This default directory for source code is

/usr/local/ngc/src/plugin

Xemacs Modes

Xemacs has several different editing modes which allow you to optimize the editing environment for each task. When you are writing Lisp code, you'll want to be sure that Xemacs knows to invoke Lisp mode whenever you open a Lisp file for editing. To ensure that Xemacs opens your Lisp files in Lisp mode, include a mode line at the top of your file.

1. (CLICK-L) on NGC>Mode Line>Update Mode Line

A Lisp mode line looks like this:

;;; -*- Mode: Common-Lisp; Package: USER; -*-

Your mode lines will look very much like this line, except that you may wish to specify a different package. For more information on packages, see "Packages," on page 2-3.

Finding a Function, Method, or Macro

You can search a Lisp image for defined functions, methods, or macros whose names contain all or part of a search string that you specify. For example, if you wanted to obtain a listing of functions whose names contained "mom", you would type the following at the lisp prompt:

USER(17): (apropos `mom)

and Lisp returns all the symbols which contain "mom"

GEOMETRY::*MAX-MOM-OBJECTS* value: 40

GEOMETRY::MAX-MOM-HEIGHT [function] (&OPTIONAL N-OBJECTS)

You can refine your search to a single package by including the package name after a colon:

USER(18): (apropos `mom :3d)

Getting the Argument List of a Function

Often, you'll want to see which arguments a function requires. You can use the Xemacs key binding (M-SHIFT-A) to return the argument list for a function. Xemacs prompts you to enter a function, method, or macro name in the minibuffer area at the bottom of the screen

Figure 3.3 Getting the Arguments for a Function.

If the cursor is in a Lisp form near a function name, Xemacs will offer that function as the default. This situation is illustrated in Figure 3.3. You can obtain the arguments of a different function by typing in it's name in the minibuffer window.

Getting the Source Code of a Function

Whey you're working with Lisp, you'll frequently want to review the source code for the functions, methods, and macros you encounter. The Xemacs key-combination (M-.) (spoken as "Meta-dot") will find the source code file for a given function, and open that file in a new buffer. Just position the cursor over the function name and press (M-.). You can also press (M-.) and then type a function name into the mini-buffer.

Note. Source code is only available for functions which you have defined and compiled. You cannot access Nichimen source code using (M-.). However, Nichimen Graphics will provide source code in some circumstances upon request. Contact Nichimen Graphics Customer Support for more information.

Object Oriented Programming Tools

N·World code is object-oriented. ACL provides several powerful tools for examining and navigating through the N·World class hierarchy. These tools are part of the ACL composer. To use them, you must launch the composer from within Xemacs.

Using the Window Inspector

The Lisp Window Inspector provides an powerful tool for inspecting Lisp classes and other objects. You can find out about superclasses, subclasses, instance slots, and methods, as well as many other attributes. For example, let's say you wanted to learn how to retrieve the coordinates of a point. You can inspect the point class, find the slot which holds coordinate values and the corresponding accessor function.

To use the Window Inspector:

1. (CLICK-L) on Composer>Start Composer in the ACL main menu.

2. Select CLOS>Inspect Class from the Composer menu

Lisp prompts you in the mini-buffer to enter the name of a class

3. Type in the name of the class you wish to inspect, followed by Enter.

The window inspector for that class (in this case, 3d:point) appears:

Figure 3.4 The ACL Window Inspector

The items in the window are hyperlinks which lead to greater detail about each item. (CLICK-L) on an item to inspect it more closely.

Coordinates looks like a likely slot where we might find a reader function for coordinates. (CLICK-L) on the slot listing to inspect it.

A new window appears, detailing the coordinates slot of class Locus..

Figure 3.5 Window Inspector window for class Locus

Generally speaking, 3d:locus-coordinates will return coordinates for any object which has the coordinates slot. The Window Inspector is described in more detail in the Allegro Composer Development Environment User Guide.


Compiling Your Code

You can compile Lisp forms in four basic ways with Xemacs.

Compiling a buffer compiles forms in that buffer and adds them to the current Lisp world. It provides a way to compile code and add it to the current Lisp world without compiling and loading a file. If you are running N·World as the current Lisp world, then any forms you compile in this manner will be added to N·World, allowing for quick and easy testing of code on-the-fly.

Compiling Individual Forms

You can compile individual forms from the Lisp listener or within a buffer. Just place the cursor within the form and type (M-Sh-X). Forms compiled in this fashion remain in the current world until redefined, or until you exit Lisp. If you want to save a form which you have compiled, you'll need to include it in a file and save it to disk.

Compiling a Buffer

1. (CLICK-L) on Compile>Other>Buffer from Xemacs' ACLfile menu.

This command compiles the current buffer, and adds any definitions it contains to the current Lisp world. You can also use the C-c C-b keybinding.

Forms compiled in this fashion exist for the duration of the current Lisp session, or until they are redefined by another compile.

Compiling to a File

You can compile your Lisp code directly to a .fasl file. This file can be loaded into a Lisp image, or loaded with N·World as a plug-in. To compile a buffer to a file:

1. Select ACLfile>Compile File from the Xemacs menu.

2. Enter a file name for the source file in the minibuffer.

You can compile your source code directly to a plugin, provided that you store your source code in the default plugin source code directory:

/usr/local/ngc/src/plugin.


Using the Debugger

The ACL debugger is a complex and powerful tool. This section is intended to provide only a brief of overview of this powerful tool, as well as some of the more commonly used debugging commands. To use the debugger effectively we recommend a careful reading of Chapter 5 in the Allegro Common Lisp User Guide.

The debugger and debugging commands are integrated with the ACL top level. As a result, debugging commands are always available. There is no need to launch or invoke the debugger.

Break Levels

Interaction with Lisp takes the form of a read-eval-print loop: Lisp reads input, evaluates it, and prints any returned values. When an error occurs, Lisp enters a break-level, which is a new read-eval-print loop. The current break level is displayed as part of the Lisp prompt, as shown in Figure 3.6

Figure 3.6 The Debugger Prompt

Moving Through Break Levels

When you find yourself in a break level, you can either execute debugger commands to try and resolve the error, or execute one of several commands to move between read-eval-print loops.

Table 2 Debugger commands (type at the Lisp prompt)
Command Effect
:reset

Returns to the top-level read-eval loop.

:pop n

Pops up to the specified level. Default value of n is 1.

:cont n

Restarts evaluation with the action specified in the continuation options list. Default value of n is 1.

:zoom :verbose

Provides a detailed listing of read-eval-print loops in frame stack, with values of arguments.

:error

Reprints error message and continuation options (if any) for the current break level.

:dn

Move down one level in the current evaluation stack

:up

Move up one level in the current evaluation stack.

:curr

Return the current form being evaluated.

:ed

Allows you to edit the function or symbol definition in the current break level.

Generally, :reset will break you out of any error and return you to the top-level.

Debugging and Multiprocessing

Allegro Common Lisp supports multiprocessing. If you are using multiprocessing, you'll want to take care when debugging code that the commands you type are being sent to the correct process. The process in which commands are typed is called the listener process, and the process which is being debugged is called the focussed process.

Table 3 Process management commands
Command Effect
:process

Lists current processes

:focus process

Shifts focus to the specified process. If no process is specified, returns current focussed process

:kill process

Kills specified process(es).

We strongly recommend that you read and understand Chapter 5 in the Allegro Common Lisp User's Guide.


Working with Plug-Ins

Once you've compiled and saved your code, you're ready to make it available for use in N-World. You do this by creating plugin files. Plug-ins are .fasl files containing code intended to add well-defined new functionality to N·World.

Storing Your Plug-ins

Although plug-ins in the default directory are automatically loaded when N·World loads, you may wish to consider storing your code in a separate subdirectory. Doing so will protect your code from being overwritten if you install a new version of N·World in the future.

For example, you might create a subdirectory under the plug-in directory:

/usr/local/ngc/plugin/ourplugins

Using Your Plug-ins

N·World loads patches and plug-ins in the following order at start-up:

1. Files in the default patch directory.

2. Files in the default plug-in directory.

3. Files specified in the .clinit.cl file in N·World's home directory.

4. Files specified in the .clinit.cl file in the user's home directory.

The .clinit.cl file can contain instructions for N·World to load plug-ins in certain directories. As a result, you can specify that a given plug-in be loaded:

Default Plug-in Directories

When N·World loads, .fasl files located in the default patch and plug-ins directories are loaded automatically.

The default patch and plug-in directory paths are:

Loading Plug-ins Every Time N·World Loads

To load specific plug-ins every time N·World loads:

1. Place all plug-ins you want to load in a single subdirectory.

Create a subdirectory you will use as your default plug-in directory. For example:

/usr/local/ngc/plugin/ourplugins

2. Edit the .clinit.cl file in the N·World home directory.

The default location for this file is:

/usr/local/ngc/bin/.clinit.cl

Loading Plug-ins in Specific Situations

You can configure individual user's .clinit.cl files to load only those plug-ins stored in specific directories. Doing so can help to reduce the overall amount of code loaded into memory when N·World executes.

To load user-specific plug-ins:

1. Place user-specific plug-ins in the appropriate directory.

You might develop a set of animation tools which you'll save in one subdirectory, and a set of development tools you'll save in a separate directory.

/usr/local/ngc/plugin/ourplugins/animation/

/usr/local/ngc/plugin/ourplugins/devo

2. Edit the .clinit.cl file in the user's home directory.

If this file does not exist, you will have to create it.

						(load-plugins "/usr/local/ngc/plugin/ourplugins/animation/" )

						(load "/usr/local/ngc/plugin/ourplugins/animation/aplugin.fasl")

Note. Plug-ins loaded after N·World's standard plug-ins and patches can redefine Lisp symbols present in these files. This may have the effect of disabling patches distributed by Nichimen Graphics.



[N-World Contents] [Book Contents] [Prev] [Next] [Index]

Another fine product from Nichimen documentation!

Copyright © 1996, Nichimen Graphics Corporation. All rights reserved.