aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2008-04-02 19:20:20 -0400
committerBrian Cully <bjc@kublai.com>2008-04-02 19:20:20 -0400
commitab10720260e2c184b319026da89f4dfd338500bb (patch)
treea692a27435da0296972e43b21b2f35762e720bfd
downloadmoxie-ab10720260e2c184b319026da89f4dfd338500bb.tar.gz
moxie-ab10720260e2c184b319026da89f4dfd338500bb.zip
Initial commit
-rw-r--r--English.lproj/Credits.rtf43
-rw-r--r--English.lproj/InfoPlist.stringsbin0 -> 482 bytes
-rw-r--r--English.lproj/LispREPL.nib/classes.nib18
-rw-r--r--English.lproj/LispREPL.nib/info.nib16
-rw-r--r--English.lproj/LispREPL.nib/keyedobjects.nibbin0 -> 4601 bytes
-rw-r--r--English.lproj/MainMenu.nib/classes.nib37
-rw-r--r--English.lproj/MainMenu.nib/info.nib22
-rw-r--r--English.lproj/MainMenu.nib/keyedobjects.nibbin0 -> 18996 bytes
-rw-r--r--English.lproj/Moxie Help/.svn/README.txt2
-rw-r--r--English.lproj/Moxie Help/.svn/empty-file0
-rw-r--r--English.lproj/Moxie Help/.svn/entries28
-rw-r--r--English.lproj/Moxie Help/.svn/format1
-rw-r--r--English.lproj/Moxie Help/.svn/prop-base/Moxie.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/.svn/props/Moxie.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/.svn/text-base/Moxie.html.svn-base18
-rw-r--r--English.lproj/Moxie Help/Moxie.html18
-rw-r--r--English.lproj/Moxie Help/images/.svn/README.txt2
-rw-r--r--English.lproj/Moxie Help/images/.svn/empty-file0
-rw-r--r--English.lproj/Moxie Help/images/.svn/entries31
-rw-r--r--English.lproj/Moxie Help/images/.svn/format1
-rw-r--r--English.lproj/Moxie Help/images/.svn/prop-base/Moxie.png.svn-base9
-rw-r--r--English.lproj/Moxie Help/images/.svn/prop-base/Moxie_small.png.svn-base9
-rw-r--r--English.lproj/Moxie Help/images/.svn/props/Moxie.png.svn-work9
-rw-r--r--English.lproj/Moxie Help/images/.svn/props/Moxie_small.png.svn-work9
-rw-r--r--English.lproj/Moxie Help/images/.svn/text-base/Moxie.png.svn-basebin0 -> 9137 bytes
-rw-r--r--English.lproj/Moxie Help/images/.svn/text-base/Moxie_small.png.svn-basebin0 -> 3145 bytes
-rw-r--r--English.lproj/Moxie Help/images/Moxie.pngbin0 -> 9137 bytes
-rw-r--r--English.lproj/Moxie Help/images/Moxie_small.pngbin0 -> 3145 bytes
-rw-r--r--English.lproj/Moxie Help/pages/.svn/README.txt2
-rw-r--r--English.lproj/Moxie Help/pages/.svn/empty-file0
-rw-r--r--English.lproj/Moxie Help/pages/.svn/entries112
-rw-r--r--English.lproj/Moxie Help/pages/.svn/format1
-rw-r--r--English.lproj/Moxie Help/pages/.svn/prop-base/bugs.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/prop-base/faq.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/prop-base/function-template.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/prop-base/glossary.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/prop-base/lisp-functions.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/prop-base/lisp-glossary.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/prop-base/navigation.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/prop-base/overview.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/prop-base/plugin.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/prop-base/todo.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/prop-base/whatsnew.html.svn-base5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/props/bugs.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/props/faq.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/props/function-template.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/props/glossary.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/props/lisp-functions.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/props/lisp-glossary.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/props/navigation.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/props/overview.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/props/plugin.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/props/todo.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/props/whatsnew.html.svn-work5
-rw-r--r--English.lproj/Moxie Help/pages/.svn/text-base/bugs.html.svn-base20
-rw-r--r--English.lproj/Moxie Help/pages/.svn/text-base/faq.html.svn-base81
-rw-r--r--English.lproj/Moxie Help/pages/.svn/text-base/function-template.html.svn-base30
-rw-r--r--English.lproj/Moxie Help/pages/.svn/text-base/glossary.html.svn-base27
-rw-r--r--English.lproj/Moxie Help/pages/.svn/text-base/lisp-functions.html.svn-base947
-rw-r--r--English.lproj/Moxie Help/pages/.svn/text-base/lisp-glossary.html.svn-base68
-rw-r--r--English.lproj/Moxie Help/pages/.svn/text-base/navigation.html.svn-base24
-rw-r--r--English.lproj/Moxie Help/pages/.svn/text-base/overview.html.svn-base36
-rw-r--r--English.lproj/Moxie Help/pages/.svn/text-base/plugin.html.svn-base203
-rw-r--r--English.lproj/Moxie Help/pages/.svn/text-base/todo.html.svn-base24
-rw-r--r--English.lproj/Moxie Help/pages/.svn/text-base/whatsnew.html.svn-base83
-rw-r--r--English.lproj/Moxie Help/pages/bugs.html20
-rw-r--r--English.lproj/Moxie Help/pages/faq.html81
-rw-r--r--English.lproj/Moxie Help/pages/function-template.html30
-rw-r--r--English.lproj/Moxie Help/pages/glossary.html27
-rw-r--r--English.lproj/Moxie Help/pages/lisp-functions.html947
-rw-r--r--English.lproj/Moxie Help/pages/lisp-glossary.html68
-rw-r--r--English.lproj/Moxie Help/pages/navigation.html24
-rw-r--r--English.lproj/Moxie Help/pages/overview.html36
-rw-r--r--English.lproj/Moxie Help/pages/plugin.html203
-rw-r--r--English.lproj/Moxie Help/pages/todo.html24
-rw-r--r--English.lproj/Moxie Help/pages/whatsnew.html83
-rw-r--r--English.lproj/Preferences.nib/classes.nib16
-rw-r--r--English.lproj/Preferences.nib/info.nib53
-rw-r--r--English.lproj/Preferences.nib/keyedobjects.nibbin0 -> 15397 bytes
-rw-r--r--English.lproj/SettingNames.strings10
-rw-r--r--English.lproj/World.nib/classes.nib27
-rw-r--r--English.lproj/World.nib/info.nib18
-rw-r--r--English.lproj/World.nib/keyedobjects.nibbin0 -> 9185 bytes
-rw-r--r--English.lproj/WorldSelector.nib/classes.nib12
-rw-r--r--English.lproj/WorldSelector.nib/info.nib16
-rw-r--r--English.lproj/WorldSelector.nib/keyedobjects.nibbin0 -> 5295 bytes
-rw-r--r--English.lproj/WorldSettings.nib/classes.nib17
-rw-r--r--English.lproj/WorldSettings.nib/info.nib16
-rw-r--r--English.lproj/WorldSettings.nib/keyedobjects.nibbin0 -> 20195 bytes
-rw-r--r--English.lproj/WorldSettings~.nib/classes.nib17
-rw-r--r--English.lproj/WorldSettings~.nib/info.nib16
-rw-r--r--English.lproj/WorldSettings~.nib/keyedobjects.nibbin0 -> 20195 bytes
-rw-r--r--English.lproj/World~.nib/classes.nib27
-rw-r--r--English.lproj/World~.nib/info.nib18
-rw-r--r--English.lproj/World~.nib/keyedobjects.nibbin0 -> 9155 bytes
-rw-r--r--Info.plist55
-rw-r--r--Lisp/asdf/LICENSE24
-rw-r--r--Lisp/asdf/README752
-rw-r--r--Lisp/asdf/asdf-install.lisp299
-rw-r--r--Lisp/asdf/asdf.lisp1104
-rw-r--r--Lisp/asdf/asdf.texinfo1220
-rw-r--r--Lisp/asdf/cclan-package.lisp5
-rw-r--r--Lisp/asdf/cclan.asd8
-rw-r--r--Lisp/asdf/cclan.lisp99
-rw-r--r--Lisp/asdf/debian/README.Debian14
-rw-r--r--Lisp/asdf/debian/changelog304
-rw-r--r--Lisp/asdf/debian/cl-asdf.postinst45
-rw-r--r--Lisp/asdf/debian/cl-cclan.postinst41
-rw-r--r--Lisp/asdf/debian/cl-cclan.prerm36
-rw-r--r--Lisp/asdf/debian/compat2
-rw-r--r--Lisp/asdf/debian/control26
-rw-r--r--Lisp/asdf/debian/copyright37
-rw-r--r--Lisp/asdf/debian/docs1
-rw-r--r--Lisp/asdf/debian/rules84
-rw-r--r--Lisp/asdf/test-mail1
-rw-r--r--Lisp/asdf/test/file1.lisp4
-rw-r--r--Lisp/asdf/test/file2.lisp2
-rw-r--r--Lisp/asdf/test/file3.lisp4
-rw-r--r--Lisp/asdf/test/file4.lisp2
-rw-r--r--Lisp/asdf/test/run-tests.sh39
-rw-r--r--Lisp/asdf/test/test1.asd12
-rw-r--r--Lisp/asdf/test/test1.script32
-rw-r--r--Lisp/asdf/test/test2.asd8
-rw-r--r--Lisp/asdf/test/test2.script19
-rw-r--r--Lisp/asdf/test/test2a.asd12
-rw-r--r--Lisp/asdf/test/test2b1.asd8
-rw-r--r--Lisp/asdf/test/test2b2.asd8
-rw-r--r--Lisp/asdf/test/test2b3.asd8
-rw-r--r--Lisp/asdf/test/test3.asd11
-rw-r--r--Lisp/asdf/test/test3.script23
-rw-r--r--Lisp/asdf/test/test4.script8
-rw-r--r--Lisp/asdf/test/wild-module.asd6
-rw-r--r--Lisp/asdf/test/wild-module.script7
-rw-r--r--Lisp/asdf/wild-modules.lisp38
-rwxr-xr-xLisp/build-lisp-image.sh30
-rwxr-xr-xLisp/clisp/clispbin0 -> 22336 bytes
-rw-r--r--Lisp/clisp/save-moxie-image.lisp5
-rw-r--r--Lisp/init-template.lisp3
-rw-r--r--Lisp/moxie/Map_Sym.txt1956
-rw-r--r--Lisp/moxie/Mop_Sym.txt128
-rw-r--r--Lisp/moxie/clhs-lookup.lisp148
-rw-r--r--Lisp/moxie/compat/compat-clisp.lib17
-rw-r--r--Lisp/moxie/compat/compat-clisp.lisp24
-rw-r--r--Lisp/moxie/compat/compat-openmcl.lisp59
-rw-r--r--Lisp/moxie/compat/compat-sbcl.faslbin0 -> 16205 bytes
-rw-r--r--Lisp/moxie/compat/compat-sbcl.lisp49
-rw-r--r--Lisp/moxie/default.faslbin0 -> 13599 bytes
-rw-r--r--Lisp/moxie/default.lisp63
-rw-r--r--Lisp/moxie/events.faslbin0 -> 26963 bytes
-rw-r--r--Lisp/moxie/events.lisp100
-rw-r--r--Lisp/moxie/hooks.lisp21
-rw-r--r--Lisp/moxie/moxie.asd34
-rw-r--r--Lisp/moxie/moxie.faslbin0 -> 41390 bytes
-rw-r--r--Lisp/moxie/moxie.lisp218
-rw-r--r--Lisp/moxie/package.faslbin0 -> 3386 bytes
-rw-r--r--Lisp/moxie/package.lisp21
-rw-r--r--Lisp/moxie/repl.faslbin0 -> 22375 bytes
-rw-r--r--Lisp/moxie/repl.lisp95
-rw-r--r--Lisp/moxie/repl.lisp.old87
-rw-r--r--Lisp/moxie/utils/bjc-utils.faslbin0 -> 41488 bytes
-rw-r--r--Lisp/moxie/utils/bjc-utils.lisp185
-rw-r--r--Lisp/moxie/world.faslbin0 -> 42872 bytes
-rw-r--r--Lisp/moxie/world.lisp120
-rwxr-xr-xLisp/openmcl/dppcclbin0 -> 488292 bytes
-rwxr-xr-xLisp/openmcl/openmcl42
-rw-r--r--Lisp/openmcl/save-moxie-image.lisp3
-rw-r--r--Lisp/sbcl/save-moxie-image.lisp3
-rwxr-xr-xLisp/sbcl/sbclbin0 -> 171284 bytes
-rwxr-xr-xLisp/startlisp46
-rw-r--r--LispREPL.h47
-rw-r--r--LispREPL.m318
-rw-r--r--LispREPLController.h60
-rw-r--r--LispREPLController.m847
-rw-r--r--LispSymbol.h30
-rw-r--r--LispSymbol.m136
-rw-r--r--Moxie.icnsbin0 -> 28862 bytes
-rw-r--r--Moxie.xcodeproj/bjc.mode11393
-rw-r--r--Moxie.xcodeproj/bjc.pbxuser1752
-rw-r--r--Moxie.xcodeproj/bjc.perspectivev31493
-rw-r--r--Moxie.xcodeproj/project.pbxproj876
-rw-r--r--MoxieWorld.icnsbin0 -> 57930 bytes
-rw-r--r--Moxie_Prefix.pch16
-rw-r--r--MxWorldSettings.h62
-rw-r--r--MxWorldSettings.m505
-rw-r--r--NSArray+LispExtensions.h13
-rw-r--r--NSArray+LispExtensions.m36
-rw-r--r--NSAttributedString+Moxie.h14
-rw-r--r--NSAttributedString+Moxie.m192
-rw-r--r--NSDictionary+LispExtensions.h15
-rw-r--r--NSDictionary+LispExtensions.m54
-rw-r--r--NSException+LiDebugging.m22
-rw-r--r--NSFileHandle+LispExtensions.h13
-rw-r--r--NSFileHandle+LispExtensions.m139
-rw-r--r--NSNumber+LispExtensions.h13
-rw-r--r--NSNumber+LispExtensions.m16
-rw-r--r--NSString+LispExtensions.h13
-rw-r--r--NSString+LispExtensions.m40
-rw-r--r--NSUserDefaults+Moxie.h52
-rw-r--r--NSUserDefaults+Moxie.m269
-rw-r--r--PlugIns/Ansi-Color.lisp145
-rw-r--r--PlugIns/Idle-Monster.lisp10
-rw-r--r--PlugIns/Logger.lisp73
-rw-r--r--PlugIns/MXP.lisp54
-rw-r--r--PlugIns/Numpad-Movement.lisp45
-rw-r--r--PlugIns/Sample-Plugin.lisp60
-rw-r--r--PlugIns/Telnet.lisp149
-rw-r--r--PreferencesController.h15
-rw-r--r--PreferencesController.m156
-rw-r--r--ScrollingTextView.h11
-rw-r--r--ScrollingTextView.m63
-rw-r--r--World.h79
-rw-r--r--World.m936
-rw-r--r--WorldController.h8
-rw-r--r--WorldController.m141
-rw-r--r--WorldSettingsController.h28
-rw-r--r--WorldSettingsController.m113
-rw-r--r--WorldStatusController.h10
-rw-r--r--WorldStatusController.m218
-rw-r--r--main.m14
-rw-r--r--version.plist16
220 files changed, 22502 insertions, 0 deletions
diff --git a/English.lproj/Credits.rtf b/English.lproj/Credits.rtf
new file mode 100644
index 0000000..a55871b
--- /dev/null
+++ b/English.lproj/Credits.rtf
@@ -0,0 +1,43 @@
+{\rtf1\mac\ansicpg10000\cocoartf102
+{\fonttbl\f0\fnil\fcharset77 Baskerville-Italic;\f1\fnil\fcharset77 Baskerville-Bold;\f2\fswiss\fcharset77 Optima-Bold;
+\f3\fswiss\fcharset77 Optima-Italic;\f4\fswiss\fcharset77 Optima-Regular;\f5\fnil\fcharset77 LucidaGrande;
+}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\i\fs24 \cf0 For Alanna, a human in a wizard's world.\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f1\i0\b \cf0 \
+
+\f2 Moxie includes CLISP:\
+
+\f3\i\b0 (see http://clisp.cons.org/)\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qr
+
+\f4\i0 \cf0 Copyright (c) Bruno Haible, Michael Stoll 1992, 1993\
+Copyright (c) Bruno Haible, Marcus Daniels 1994-1997\
+Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998\
+Copyright (c) Bruno Haible, Sam Steingold 1999-2000\
+Copyright (c) Sam Steingold, Bruno Haible 2001-2004\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f2\b \cf0 Moxie includes ASDF:\
+
+\f3\i\b0 (see http://www.cliki.net/asdf)
+\f2\i0\b \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qr
+
+\f4\b0 \cf0 Copyright \'a9 2001-2004 Daniel Barlow and contributors\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f5\fs28 \cf0 \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f2\b\fs24 \cf0 Moxie includes CL-PPCRE:\
+
+\f3\i\b0 (see http://www.cliki.net/cl-ppcre)
+\f2\i0\b \
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qr
+
+\f4\b0 \cf0 Copyright \'a9, Edi Weitz} \ No newline at end of file
diff --git a/English.lproj/InfoPlist.strings b/English.lproj/InfoPlist.strings
new file mode 100644
index 0000000..64f6f16
--- /dev/null
+++ b/English.lproj/InfoPlist.strings
Binary files differ
diff --git a/English.lproj/LispREPL.nib/classes.nib b/English.lproj/LispREPL.nib/classes.nib
new file mode 100644
index 0000000..1503745
--- /dev/null
+++ b/English.lproj/LispREPL.nib/classes.nib
@@ -0,0 +1,18 @@
+{
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ CLASS = LispREPLController;
+ LANGUAGE = ObjC;
+ OUTLETS = {theTextView = NSTextView; };
+ SUPERCLASS = NSWindowController;
+ },
+ {
+ CLASS = ScrollingTextView;
+ LANGUAGE = ObjC;
+ OUTLETS = {theResponder = NSResponder; };
+ SUPERCLASS = NSTextView;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/English.lproj/LispREPL.nib/info.nib b/English.lproj/LispREPL.nib/info.nib
new file mode 100644
index 0000000..16cf88d
--- /dev/null
+++ b/English.lproj/LispREPL.nib/info.nib
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>128 98 356 240 0 0 1600 1178 </string>
+ <key>IBFramework Version</key>
+ <string>364.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>7</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>7M34</string>
+</dict>
+</plist>
diff --git a/English.lproj/LispREPL.nib/keyedobjects.nib b/English.lproj/LispREPL.nib/keyedobjects.nib
new file mode 100644
index 0000000..9db0f0f
--- /dev/null
+++ b/English.lproj/LispREPL.nib/keyedobjects.nib
Binary files differ
diff --git a/English.lproj/MainMenu.nib/classes.nib b/English.lproj/MainMenu.nib/classes.nib
new file mode 100644
index 0000000..50662f9
--- /dev/null
+++ b/English.lproj/MainMenu.nib/classes.nib
@@ -0,0 +1,37 @@
+{
+ IBClasses = (
+ {
+ ACTIONS = {
+ showPreferencesWindow = id;
+ showWorldSettingsWindow = id;
+ showWorldStatusWindow = id;
+ };
+ CLASS = AppDelegate;
+ LANGUAGE = ObjC;
+ SUPERCLASS = NSObject;
+ },
+ {
+ ACTIONS = {
+ cycleDocumentWindows = id;
+ orderFrontStandardAboutPanel = id;
+ pasteWithFormatting = id;
+ };
+ CLASS = FirstResponder;
+ LANGUAGE = ObjC;
+ SUPERCLASS = NSObject;
+ },
+ {CLASS = MxTransparentScrollView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
+ {
+ ACTIONS = {
+ showLispREPLWindow = id;
+ showPreferencesWindow = id;
+ showWorldSettingsWindow = id;
+ showWorldStatusWindow = id;
+ };
+ CLASS = WorldController;
+ LANGUAGE = ObjC;
+ SUPERCLASS = NSDocumentController;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/English.lproj/MainMenu.nib/info.nib b/English.lproj/MainMenu.nib/info.nib
new file mode 100644
index 0000000..758c0df
--- /dev/null
+++ b/English.lproj/MainMenu.nib/info.nib
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>73 273 356 240 0 0 1600 1178 </string>
+ <key>IBEditorPositions</key>
+ <dict>
+ <key>29</key>
+ <string>13 690 316 44 0 0 1600 1178 </string>
+ </dict>
+ <key>IBFramework Version</key>
+ <string>364.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>29</integer>
+ <integer>270</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>7M34</string>
+</dict>
+</plist>
diff --git a/English.lproj/MainMenu.nib/keyedobjects.nib b/English.lproj/MainMenu.nib/keyedobjects.nib
new file mode 100644
index 0000000..3e6e00c
--- /dev/null
+++ b/English.lproj/MainMenu.nib/keyedobjects.nib
Binary files differ
diff --git a/English.lproj/Moxie Help/.svn/README.txt b/English.lproj/Moxie Help/.svn/README.txt
new file mode 100644
index 0000000..271a8ce
--- /dev/null
+++ b/English.lproj/Moxie Help/.svn/README.txt
@@ -0,0 +1,2 @@
+This is a Subversion working copy administrative directory.
+Visit http://subversion.tigris.org/ for more information.
diff --git a/English.lproj/Moxie Help/.svn/empty-file b/English.lproj/Moxie Help/.svn/empty-file
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/English.lproj/Moxie Help/.svn/empty-file
diff --git a/English.lproj/Moxie Help/.svn/entries b/English.lproj/Moxie Help/.svn/entries
new file mode 100644
index 0000000..96f9a9e
--- /dev/null
+++ b/English.lproj/Moxie Help/.svn/entries
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wc-entries
+ xmlns="svn:">
+<entry
+ committed-rev="20"
+ name=""
+ committed-date="2005-12-27T15:21:23.068810Z"
+ url="svn+ssh://coleridge/svn/Moxie/trunk/English.lproj/Moxie%20Help"
+ last-author="bjc"
+ kind="dir"
+ uuid="2641c99b-6c07-0410-920d-927397d2d5d0"
+ revision="47"/>
+<entry
+ name="pages"
+ kind="dir"/>
+<entry
+ committed-rev="20"
+ name="Moxie.html"
+ text-time="2005-12-23T23:28:45.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="16c8d066f7397d4a508adc024a58010a"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:54.000000Z"/>
+<entry
+ name="images"
+ kind="dir"/>
+</wc-entries>
diff --git a/English.lproj/Moxie Help/.svn/format b/English.lproj/Moxie Help/.svn/format
new file mode 100644
index 0000000..b8626c4
--- /dev/null
+++ b/English.lproj/Moxie Help/.svn/format
@@ -0,0 +1 @@
+4
diff --git a/English.lproj/Moxie Help/.svn/prop-base/Moxie.html.svn-base b/English.lproj/Moxie Help/.svn/prop-base/Moxie.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/.svn/prop-base/Moxie.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/.svn/props/Moxie.html.svn-work b/English.lproj/Moxie Help/.svn/props/Moxie.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/.svn/props/Moxie.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/.svn/text-base/Moxie.html.svn-base b/English.lproj/Moxie Help/.svn/text-base/Moxie.html.svn-base
new file mode 100644
index 0000000..7f04ac5
--- /dev/null
+++ b/English.lproj/Moxie Help/.svn/text-base/Moxie.html.svn-base
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Moxie Help</title>
+ <meta name="generator" content="Emacs!">
+ <meta name="AppleTitle" content="Moxie Help">
+ <meta name="AppleIcon" content="Moxie%20Help/images/Moxie_small.png">
+ <meta name="AppleFont" content="Lucida Grande,Helvetica">
+ <meta name="Description" content="Help for Moxie 0.1">
+ <meta name="keywords" content="Moxie Lisp REPL MUSH MUX MUD MOO">
+ </head>
+
+ <frameset cols="170,*" framespacing="0" border="0" frameborder="0" framespacing="0">
+ <frame name="navigationFrame" marginheight="0" marginwidth="0" scrolling="AUTO" src="pages/navigation.html">
+ <frame name="contentsFrame" marginheight="0" marginwidth="0" scrolling="AUTO" src="pages/overview.html">
+ </frameset>
+</html>
diff --git a/English.lproj/Moxie Help/Moxie.html b/English.lproj/Moxie Help/Moxie.html
new file mode 100644
index 0000000..7f04ac5
--- /dev/null
+++ b/English.lproj/Moxie Help/Moxie.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Moxie Help</title>
+ <meta name="generator" content="Emacs!">
+ <meta name="AppleTitle" content="Moxie Help">
+ <meta name="AppleIcon" content="Moxie%20Help/images/Moxie_small.png">
+ <meta name="AppleFont" content="Lucida Grande,Helvetica">
+ <meta name="Description" content="Help for Moxie 0.1">
+ <meta name="keywords" content="Moxie Lisp REPL MUSH MUX MUD MOO">
+ </head>
+
+ <frameset cols="170,*" framespacing="0" border="0" frameborder="0" framespacing="0">
+ <frame name="navigationFrame" marginheight="0" marginwidth="0" scrolling="AUTO" src="pages/navigation.html">
+ <frame name="contentsFrame" marginheight="0" marginwidth="0" scrolling="AUTO" src="pages/overview.html">
+ </frameset>
+</html>
diff --git a/English.lproj/Moxie Help/images/.svn/README.txt b/English.lproj/Moxie Help/images/.svn/README.txt
new file mode 100644
index 0000000..271a8ce
--- /dev/null
+++ b/English.lproj/Moxie Help/images/.svn/README.txt
@@ -0,0 +1,2 @@
+This is a Subversion working copy administrative directory.
+Visit http://subversion.tigris.org/ for more information.
diff --git a/English.lproj/Moxie Help/images/.svn/empty-file b/English.lproj/Moxie Help/images/.svn/empty-file
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/English.lproj/Moxie Help/images/.svn/empty-file
diff --git a/English.lproj/Moxie Help/images/.svn/entries b/English.lproj/Moxie Help/images/.svn/entries
new file mode 100644
index 0000000..764962c
--- /dev/null
+++ b/English.lproj/Moxie Help/images/.svn/entries
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wc-entries
+ xmlns="svn:">
+<entry
+ committed-rev="20"
+ name=""
+ committed-date="2005-12-27T15:21:23.068810Z"
+ url="svn+ssh://coleridge/svn/Moxie/trunk/English.lproj/Moxie%20Help/images"
+ last-author="bjc"
+ kind="dir"
+ uuid="2641c99b-6c07-0410-920d-927397d2d5d0"
+ revision="47"/>
+<entry
+ committed-rev="20"
+ name="Moxie.png"
+ text-time="2005-12-23T23:28:45.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="45ffa9775ecaedde832f59f85aff823c"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:54.000000Z"/>
+<entry
+ committed-rev="20"
+ name="Moxie_small.png"
+ text-time="2005-12-23T23:28:45.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="e569cf86d6902f830a70515f77d85d05"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:54.000000Z"/>
+</wc-entries>
diff --git a/English.lproj/Moxie Help/images/.svn/format b/English.lproj/Moxie Help/images/.svn/format
new file mode 100644
index 0000000..b8626c4
--- /dev/null
+++ b/English.lproj/Moxie Help/images/.svn/format
@@ -0,0 +1 @@
+4
diff --git a/English.lproj/Moxie Help/images/.svn/prop-base/Moxie.png.svn-base b/English.lproj/Moxie Help/images/.svn/prop-base/Moxie.png.svn-base
new file mode 100644
index 0000000..1c2f589
--- /dev/null
+++ b/English.lproj/Moxie Help/images/.svn/prop-base/Moxie.png.svn-base
@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 2
+Id
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/English.lproj/Moxie Help/images/.svn/prop-base/Moxie_small.png.svn-base b/English.lproj/Moxie Help/images/.svn/prop-base/Moxie_small.png.svn-base
new file mode 100644
index 0000000..1c2f589
--- /dev/null
+++ b/English.lproj/Moxie Help/images/.svn/prop-base/Moxie_small.png.svn-base
@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 2
+Id
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/English.lproj/Moxie Help/images/.svn/props/Moxie.png.svn-work b/English.lproj/Moxie Help/images/.svn/props/Moxie.png.svn-work
new file mode 100644
index 0000000..1c2f589
--- /dev/null
+++ b/English.lproj/Moxie Help/images/.svn/props/Moxie.png.svn-work
@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 2
+Id
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/English.lproj/Moxie Help/images/.svn/props/Moxie_small.png.svn-work b/English.lproj/Moxie Help/images/.svn/props/Moxie_small.png.svn-work
new file mode 100644
index 0000000..1c2f589
--- /dev/null
+++ b/English.lproj/Moxie Help/images/.svn/props/Moxie_small.png.svn-work
@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 2
+Id
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END
diff --git a/English.lproj/Moxie Help/images/.svn/text-base/Moxie.png.svn-base b/English.lproj/Moxie Help/images/.svn/text-base/Moxie.png.svn-base
new file mode 100644
index 0000000..cd5e2d4
--- /dev/null
+++ b/English.lproj/Moxie Help/images/.svn/text-base/Moxie.png.svn-base
Binary files differ
diff --git a/English.lproj/Moxie Help/images/.svn/text-base/Moxie_small.png.svn-base b/English.lproj/Moxie Help/images/.svn/text-base/Moxie_small.png.svn-base
new file mode 100644
index 0000000..5b07aa2
--- /dev/null
+++ b/English.lproj/Moxie Help/images/.svn/text-base/Moxie_small.png.svn-base
Binary files differ
diff --git a/English.lproj/Moxie Help/images/Moxie.png b/English.lproj/Moxie Help/images/Moxie.png
new file mode 100644
index 0000000..cd5e2d4
--- /dev/null
+++ b/English.lproj/Moxie Help/images/Moxie.png
Binary files differ
diff --git a/English.lproj/Moxie Help/images/Moxie_small.png b/English.lproj/Moxie Help/images/Moxie_small.png
new file mode 100644
index 0000000..5b07aa2
--- /dev/null
+++ b/English.lproj/Moxie Help/images/Moxie_small.png
Binary files differ
diff --git a/English.lproj/Moxie Help/pages/.svn/README.txt b/English.lproj/Moxie Help/pages/.svn/README.txt
new file mode 100644
index 0000000..271a8ce
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/README.txt
@@ -0,0 +1,2 @@
+This is a Subversion working copy administrative directory.
+Visit http://subversion.tigris.org/ for more information.
diff --git a/English.lproj/Moxie Help/pages/.svn/empty-file b/English.lproj/Moxie Help/pages/.svn/empty-file
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/empty-file
diff --git a/English.lproj/Moxie Help/pages/.svn/entries b/English.lproj/Moxie Help/pages/.svn/entries
new file mode 100644
index 0000000..564dfc4
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/entries
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wc-entries
+ xmlns="svn:">
+<entry
+ committed-rev="20"
+ name=""
+ committed-date="2005-12-27T15:21:23.068810Z"
+ url="svn+ssh://coleridge/svn/Moxie/trunk/English.lproj/Moxie%20Help/pages"
+ last-author="bjc"
+ kind="dir"
+ uuid="2641c99b-6c07-0410-920d-927397d2d5d0"
+ revision="47"/>
+<entry
+ committed-rev="20"
+ name="lisp-functions.html"
+ text-time="2005-12-23T23:28:43.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="a485095a82d3c831b544e09263f0e4bf"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:58.000000Z"/>
+<entry
+ committed-rev="20"
+ name="function-template.html"
+ text-time="2005-12-23T23:28:43.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="9eabe834fd9ad991f07290d4724b3142"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:57.000000Z"/>
+<entry
+ committed-rev="20"
+ name="plugin.html"
+ text-time="2005-12-23T23:28:43.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="688de8c0ce9d8eaa504fb5cc8b61cb50"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:59.000000Z"/>
+<entry
+ committed-rev="20"
+ name="navigation.html"
+ text-time="2005-12-23T23:28:43.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="4f4a317129a3ffd61e77f96e9492de72"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:58.000000Z"/>
+<entry
+ committed-rev="20"
+ name="bugs.html"
+ text-time="2005-12-23T23:28:43.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="d19c3585914c47587f83a4b6f4021401"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:57.000000Z"/>
+<entry
+ committed-rev="20"
+ name="whatsnew.html"
+ text-time="2005-12-23T23:28:43.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="96e631076fccdba18a44a07552e08bbe"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:59.000000Z"/>
+<entry
+ committed-rev="20"
+ name="glossary.html"
+ text-time="2005-12-23T23:28:43.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="acc70845ae51c8e3184bbde79cf33e93"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:58.000000Z"/>
+<entry
+ committed-rev="20"
+ name="todo.html"
+ text-time="2005-12-23T23:28:44.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="916a1c9889586af828188b6cc51de553"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:59.000000Z"/>
+<entry
+ committed-rev="20"
+ name="overview.html"
+ text-time="2005-12-23T23:28:44.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="8ff95b2bf74010bfd59bd13830a60799"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:59.000000Z"/>
+<entry
+ committed-rev="20"
+ name="faq.html"
+ text-time="2005-12-23T23:28:44.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="27624749cefddd3be4ebf30ef4e2697a"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:57.000000Z"/>
+<entry
+ committed-rev="20"
+ name="lisp-glossary.html"
+ text-time="2005-12-23T23:28:44.000000Z"
+ committed-date="2005-12-27T15:21:23.068810Z"
+ checksum="255c92563ea1a439ffdf37bc48987d17"
+ last-author="bjc"
+ kind="file"
+ prop-time="2005-12-27T01:33:58.000000Z"/>
+</wc-entries>
diff --git a/English.lproj/Moxie Help/pages/.svn/format b/English.lproj/Moxie Help/pages/.svn/format
new file mode 100644
index 0000000..b8626c4
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/format
@@ -0,0 +1 @@
+4
diff --git a/English.lproj/Moxie Help/pages/.svn/prop-base/bugs.html.svn-base b/English.lproj/Moxie Help/pages/.svn/prop-base/bugs.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/prop-base/bugs.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/prop-base/faq.html.svn-base b/English.lproj/Moxie Help/pages/.svn/prop-base/faq.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/prop-base/faq.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/prop-base/function-template.html.svn-base b/English.lproj/Moxie Help/pages/.svn/prop-base/function-template.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/prop-base/function-template.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/prop-base/glossary.html.svn-base b/English.lproj/Moxie Help/pages/.svn/prop-base/glossary.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/prop-base/glossary.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/prop-base/lisp-functions.html.svn-base b/English.lproj/Moxie Help/pages/.svn/prop-base/lisp-functions.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/prop-base/lisp-functions.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/prop-base/lisp-glossary.html.svn-base b/English.lproj/Moxie Help/pages/.svn/prop-base/lisp-glossary.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/prop-base/lisp-glossary.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/prop-base/navigation.html.svn-base b/English.lproj/Moxie Help/pages/.svn/prop-base/navigation.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/prop-base/navigation.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/prop-base/overview.html.svn-base b/English.lproj/Moxie Help/pages/.svn/prop-base/overview.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/prop-base/overview.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/prop-base/plugin.html.svn-base b/English.lproj/Moxie Help/pages/.svn/prop-base/plugin.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/prop-base/plugin.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/prop-base/todo.html.svn-base b/English.lproj/Moxie Help/pages/.svn/prop-base/todo.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/prop-base/todo.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/prop-base/whatsnew.html.svn-base b/English.lproj/Moxie Help/pages/.svn/prop-base/whatsnew.html.svn-base
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/prop-base/whatsnew.html.svn-base
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/props/bugs.html.svn-work b/English.lproj/Moxie Help/pages/.svn/props/bugs.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/props/bugs.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/props/faq.html.svn-work b/English.lproj/Moxie Help/pages/.svn/props/faq.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/props/faq.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/props/function-template.html.svn-work b/English.lproj/Moxie Help/pages/.svn/props/function-template.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/props/function-template.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/props/glossary.html.svn-work b/English.lproj/Moxie Help/pages/.svn/props/glossary.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/props/glossary.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/props/lisp-functions.html.svn-work b/English.lproj/Moxie Help/pages/.svn/props/lisp-functions.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/props/lisp-functions.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/props/lisp-glossary.html.svn-work b/English.lproj/Moxie Help/pages/.svn/props/lisp-glossary.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/props/lisp-glossary.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/props/navigation.html.svn-work b/English.lproj/Moxie Help/pages/.svn/props/navigation.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/props/navigation.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/props/overview.html.svn-work b/English.lproj/Moxie Help/pages/.svn/props/overview.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/props/overview.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/props/plugin.html.svn-work b/English.lproj/Moxie Help/pages/.svn/props/plugin.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/props/plugin.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/props/todo.html.svn-work b/English.lproj/Moxie Help/pages/.svn/props/todo.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/props/todo.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/props/whatsnew.html.svn-work b/English.lproj/Moxie Help/pages/.svn/props/whatsnew.html.svn-work
new file mode 100644
index 0000000..92c8ad7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/props/whatsnew.html.svn-work
@@ -0,0 +1,5 @@
+K 12
+svn:keywords
+V 2
+Id
+END
diff --git a/English.lproj/Moxie Help/pages/.svn/text-base/bugs.html.svn-base b/English.lproj/Moxie Help/pages/.svn/text-base/bugs.html.svn-base
new file mode 100644
index 0000000..b2a5fd5
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/text-base/bugs.html.svn-base
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Known Bugs</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>Known Bugs</h1>
+ <ul>
+ <li>The world selector will not raise the window you select if it's already the frontmost
+ Moxie window, even if Moxie is in the background (it comes next-to-top, for reasons I don't
+ at all understand).</li>
+ <li>Fonts get screwed up fairly frequently, especially when trying to set them via the font panel.</li>
+ <li>The "Choose" button for choosing the REPL font doesn't work at all.</li>
+ <li>Reading from standard-input in Lisp will hang Moxie.</li>
+ </ul>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/.svn/text-base/faq.html.svn-base b/English.lproj/Moxie Help/pages/.svn/text-base/faq.html.svn-base
new file mode 100644
index 0000000..a80cde3
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/text-base/faq.html.svn-base
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Frequently Asked Questions</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>Frequently Asked Questions</h1>
+
+ <dt><strong>How do I write a trigger, alias, or macro?</strong></dt>
+ <dd>
+ <p>First of all, Moxie makes no distinction between triggers, aliases, and macros. We
+ treat all of these things in the same way: as a <a href="plugin.html">plugin</a>.</p>
+
+ <p>All plugins are written in Common Lisp, so you'll have to have some grounding in
+ Lisp to do anything serious at the moment (although I have some ideas for simpler
+ interfaces for the non-programming-minded in the future). There are a few support
+ routines included in the MOXIE <a href="lisp-glossary.html#package">package</a> to
+ simplify common plugin tasks, such as triggers and aliases.</p>
+ </dd>
+
+ <dt><strong>LISP?! Why would you do that?</strong></dt>
+ <dd>
+ <p>Because I didn't want to have to write my own language for triggers, aliases, and
+ macros. No matter how much I worked on it, I wasn't going to get the kind of
+ programmability I wanted without embedding a full programming language.
+ I also think it's something of a waste of time to learn a new language just for the
+ purpose of programming a trigger in your MUX client.
+ </p>
+ <p>I could have just used AppleScript as the language of choice, and came very
+ close to doing so a number of times, but I had too much trouble trying to get
+ AS and ObjC talking as well as I'd liked, and, frankly, I don't consider it to
+ be full-featured enough.</p>
+ <p>So I chose to embed a language. There are, theoretically, a fair number
+ of popular languages I could have embedded, however, I chose Lisp for the
+ following reasons:
+ <ul>
+ <li>Real-time development. I feel that, in the scope of Moxie, having a fully
+ interactive development style is extremely useful. As far as I know, this
+ excludes PERL as a possibility.</li>
+ <li>Lisp has been ratified by ANSI, and is one of the few languages to do so. It
+ has a very large "library" that is standard from one lisp implementation to the
+ next, so as long as you've found code that's "Common Lisp" you've found code that
+ will work with Moxie.</li>
+ <li>Lisp is the second-oldest language still in use, after FORTRAN. While not
+ the largest consideration, it does guarantee that there's a fair amount of code
+ available for free in the world. Emacs, for example, has a huge amount of contributed
+ Emacs-Lisp code (which, while not common-lisp, is often easily ported).</li>
+ <li>And finally, because I can. I like Lisp, and I'm writing Moxie, so I get to pick.
+ "Give me real macros, or give me death!"</li>
+ </ul>
+ </p>
+ </dd>
+
+ <dt><strong>Where can I find more information on Lisp programming?</strong></dt>
+ <dd>
+ <p>There are a number of web sites devoted to Lisp programming. Below, I'll list a few
+ resources that should get you pointed in the right direction:
+ <ul>
+ <li><a href="lisp-glossary.html#cliki">CLiki's</a>
+ <a href="http://www.cliki.net/Online%20Tutorial" target="new">Online Tutorial</a> page
+ can get you started if you're completely new.</li>
+ <li><a href="http://www.paulgraham.com" target="new">Paul Graham</a> has a lot of
+ information on Lisp, including a free book for the more serious programmers.</li>
+ </ul>
+ </p>
+ </dd>
+
+ <dt><strong>What is the REPL?</strong></dt>
+ <dd>
+ <p>The <a href="lisp-glossary.html#repl">REPL</a> is your direct
+ interface to the Lisp sub-system. It is the key to fully interactive programming. Via
+ the REPL you can input Lisp commands directly and see the results - any Lisp will work
+ here, including function definitions. This allows you to write a function, test it, and
+ debug it, all without leaving the REPL, and with a much finer grain of control than with
+ a compile cycle.</p>
+ </dd>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/.svn/text-base/function-template.html.svn-base b/English.lproj/Moxie Help/pages/.svn/text-base/function-template.html.svn-base
new file mode 100644
index 0000000..da624de
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/text-base/function-template.html.svn-base
@@ -0,0 +1,30 @@
+ <hr>
+ <p><a id="NAME"><i>Function</i> <b>NAME</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>NAME</b> <i>ARG</i> => <i>RETURN-VALUE</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>ARG</i>---A <i>TYPE</i>.</p>
+ <p><i>RETURN-VALUE</i>---An <i>TYPE</i>.</p>
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>CODE</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#function">FUNCTION</a></b>
+ </p>
+
+ <p><b>Notes:</b> None</p>
diff --git a/English.lproj/Moxie Help/pages/.svn/text-base/glossary.html.svn-base b/English.lproj/Moxie Help/pages/.svn/text-base/glossary.html.svn-base
new file mode 100644
index 0000000..3606388
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/text-base/glossary.html.svn-base
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>
+ Glossary
+ </title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>
+ Glossary
+ </h1>
+ <ul>
+ <li>
+ <dt> <a id="mux">MUX</a> </dt>
+ <dd> A generic term meaning any of the variety of multi-user environments:
+ MUSH, MUD, MOO, etc.,.</dd>
+ </li>
+ <li>
+ <dt><a id="world">World</a></dt>
+ <dd>The file containing the preferences for a particular connection.</dd>
+ </li>
+ </ul>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/.svn/text-base/lisp-functions.html.svn-base b/English.lproj/Moxie Help/pages/.svn/text-base/lisp-functions.html.svn-base
new file mode 100644
index 0000000..a6091c7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/text-base/lisp-functions.html.svn-base
@@ -0,0 +1,947 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+
+
+<html lang="en">
+ <head>
+ <title>Lisp Functions</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>Moxie plugin functions</h1>
+ <p>These functions are all exported from the <code>MOXIE</code>
+ <a href="lisp-glossary.html#package">package</a>.
+ </p>
+ <p>
+ Contents:
+ <ul>
+ <li><a href="#world-var">world-var</a></li>
+ <li><a href="#add-hook">add-hook</a></li>
+ <li><a href="#remove-hook">remove-hook</a></li>
+ <li><a href="#run-hook">run-hook</a></li>
+ <li><a href="#add-keyword">add-keyword</a></li>
+ <li><a href="#remove-keyword">remove-keyword</a></li>
+ <li><a href="#add-keystroke-macro">add-keystroke-macro</a></li>
+ <li><a href="#remove-keystroke-macro">remove-keystroke-macro</a></li>
+ <li><a href="#send-to-mux">send-to-mux</a></li>
+ <li><a href="#print-to-world">print-to-world</a></li>
+ <li><a href="#set-status-buffer">set-status-buffer</a></li>
+ <li><a href="#enable-logging">enable-logging</a></li>
+ <li><a href="#disable-logging">disable-logging</a></li>
+ <li><a href="#make-attributed-string">make-attributed-string</a></li>
+<!--
+ We're going to lose these functions, in preference to a key/value
+ system.
+
+ <li><a href="#make-range">make-range</a></li>
+ <li><a href="#make-font">make-font</a></li>
+ <li><a href="#make-color">make-color</a></li>
+ <li><a href="#make-super">make-super</a></li>
+ <li><a href="#make-underline">make-underline</a></li>
+ <li><a href="#make-link">make-link</a></li> -->
+
+ <li><a href="#escape-mux-string">escape-mux-string</a></li>
+ <li><a href="#map-variables">map-variables</a></li>
+ </ul>
+ </p>
+
+ <hr>
+ <p><a id="world-var"><i>Function</i> <b>WORLD-VAR</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>world-var</b> <i>name</i> <code>&amp;optional</code> (<i>world-id</i> <i>*world*</i>) => <i>result</i>
+ </p>
+ <p>
+ (setf (<b>world-var</b> <i>name</i> <code>&amp;optional</code> (<i>world-id</i> *world*)) <i>new-value</i>)
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>name</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>result</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ <b>world-var</b> is used to associate <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_v.htm#value">values</a></i>, which are persistent throughout the application's lifetime, with <i>name</i> for a particular Moxie world, which has the unique identifier, <i>world-id</i>.
+ </p>
+ <p>
+ <b><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_setf_.htm#setf">setf</a></b> may be used with <b><a href="#world-var">world-var</a></b> to modify the <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_v.htm#value">values</a></i> associated with a given <i>name</i>, or to add a new entry.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (setf (world-var :foo 0) 'bar) => BAR
+ (world-var :foo 0) => BAR
+ (world-var :foo 1) => NIL
+ (setf (world-var :foo 1) 'YOW) => YOW
+ (world-var :foo 1) => YOW
+ (world-var :foo 0) => BAR</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="add-hook"><i>Function</i> <b>ADD-HOOK</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>add-hook</b> <i>function</i> <i>mode</i> => <i>hook-list</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>function</i>--a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i>.
+ <p><i>mode</i>---A <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keyword</a></i>.</p>
+ <p><i>hook-list</i>---A <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i> containing the active <i>functions</i> for <i>mode</i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p><b>add-hook</b> adds <i>function</i> to the list of functions to be run when
+ the hook <i>mode</i> is executed via <b>run-hook</b>.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>
+ (defun my-printer (string)
+ (let ((string (if (stringp string) string (car string))))
+ (concatenate 'string "TEST: " string))) => MY-PRINTER
+ (add-hook 'my-printer :output-from-server-hook) => (MY-PRINTER)
+ (run-hook :output-from-server-hook "foo") => "TEST: foo"
+ (defun 'do-nothing (&amp;rest args) nil) => DO-NOTHING
+ (add-hook 'do-nothing :output-from-server-hook) => (MY-PRINTER DO-NOTHING)
+ (run-hook :output-from-server-hook "foo") => "TEST: foo"</pre>
+ </p>
+
+ <p><b>Side Effects:</b></p>
+ <p><i>function</i> will be run by <b>run-hook</b> for <i>mode</i>.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#remove-hook">remove-hook</a></b>
+ <b><a href="#run-hook">run-hook</a></b>
+ </p>
+
+ <p><b>Notes:</b>
+ <p>If <i>function</i> is already on the hook list for <i>mode</i>, it will
+ not be added again.</p>
+
+ <hr>
+ <p><a id="remove-hook"><i>Function</i> <b>REMOVE-HOOK</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>remove-hook</b> <i>function</i> <i>mode</i> => <i>hook-list</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>function</i>--a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i>.
+ <p><i>mode</i>---A <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keyword</a></i>.</p>
+ <p><i>hook-list</i>---A <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i> containing the active <i>functions</i> for <i>mode</i>.</p>
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>
+ (remove-hook 'my-printer :output-from-server-hook) => NIL</pre></p>
+
+ <p><b>Side Effects:</b></p>
+ <p><i>function</i> is no longer called by <code>run-hook</code>.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#add-hook">add-hook</a></b>
+ <b><a href="#run-hook">run-hook</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ If <i>function</i> is not on the hook list for <i>mode</i>, the hook list is
+ returned without change. You can use this facility to get the current list
+ of <i>functions</i> for <i>mode</i> by removing <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_n.htm#nil">NIL</a> from the hook list.
+ </p>
+
+ <hr>
+ <p><a id="run-hook"><i>Function</i> <b>RUN-HOOK</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>run-hook</b> <i>mode</i> <code><i>&amp;optional</i></code> <i>arg</i>
+ => <i>result*</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>mode</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keyword</a></i>.</p>
+ <p><i>arg</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>results</i>---the <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_v.htm#value">values</a></i> returned by the last non-NIL terminating function.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_a.htm#apply">Applies</a> the
+ <i>functions</i> for <i>mode</i> to the <i>args</i>.
+ </p>
+ <p>
+ A hook-list acts as a filter, passing the output of one filter into the input of
+ the next. If a function on the hook-list returns <b>NIL</b>, it is treated in this iteration
+ as if it hadn't been on the hook-list in the first place. Thus, the only time
+ <b>run-hook</b> returns <b>NIL</b> is when every function on the hook-list returns
+ <b>NIL</b>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>
+ (run-hook :output-from-server-hook "Foobar!") => "TEST: Foobar!"</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b></p>
+ <p>
+ The hook list for <i>mode</i>. All the functions on the list are called, in
+ order. The last function which returns a non-nil value is used as the result
+ function.
+ </p>
+
+ <p><b>Exceptional Situations:</b></p>
+ <p>
+ If a <i>function</i> on the hook list for <i>mode</i> is not a function
+ designator, an error will be raised.
+ </p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#add-hook">add-hook</a></b>
+ <b><a href="#remove-hook">remove-hook</a></b>
+ </p>
+
+ <p><b>Notes:</b> None.</p>
+
+ <hr>
+ <p><a id="add-keyword"><i>Function</i> <b>ADD-KEYWORD</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>add-keyword</b> <i>function</i> <i>keyword</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>function</i>--a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i>.
+ <p><i>keyword</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>result</i>---the <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i> for <i>keyword</i>.</p>
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (defun my-keyword (args)
+ (format t "Keyword expander: ~S~%" args)) => MY-KEYWORD
+ (add-keyword 'my-keyword "foo") => MY-KEYWORD</pre></p>
+
+ <p><b>Side Effects:</b></p>
+ <p>
+ <i>keyword</i> is registered for keyword expansion.
+ </p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#remove-keyword">remove-keyword</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ The keyword expander compares keywords in a case insensitive fashion. So "FOO" and
+ "foo" are equivalent.
+ </p>
+
+ <hr>
+ <p><a id="remove-keyword"><i>Function</i> <b>REMOVE-KEYWORD</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>remove-keyword</b> <i>keyword</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>keyword</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>result</i>---the <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_t.htm#t">T</a> on successful removal. <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_n.htm#nil">NIL</a> otherwise.
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (remove-keyword "foo") => T
+ (remove-keyword "foo") => NIL</pre></p>
+
+ <p><b>Side Effects:</b></p>
+ <p>
+ <i>keyword</i> is no longer expanded by the keyword expander.
+ </p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#add-keyword">add-keyword</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ The keyword expander compares keywords in a case insensitive fashion. So "FOO" and
+ "foo" are equivalent.
+ </p>
+
+ <hr>
+ <p><a id="add-keystroke-macro"><i>Function</i> <b>ADD-KEYSTROKE-MACRO</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>add-keystroke-macro</b> <i>function</i> <i>keystroke</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>function</i>--a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i>.
+ <p><i>keystroke</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keyword</a></i>.</p>
+ <p><i>result</i>---the <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i> for <i>keyword</i>.</p>
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (defun my-keystroke-macro (keystroke)
+ (format t "Should expand keystroke ~S here.~%" keystroke)) => MY-KEYSTROKE-MACRO
+ (add-keystroke-macro 'my-keystroke-macro :f1) => MY-KEYSTROKE-MACRO</pre></p>
+
+ <p><b>Side Effects:</b></p>
+ <p>
+ <i>function</i> is called when <i>keystroke</i> is pressed.
+ </p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#remove-keystroke-macro">remove-keystroke-macro</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ Unlike most other functions defined here, keystrokes don't do anything by default.
+ This means that in order to achieve some user-visible result, you'll have to use
+ the lower level functions <b>print-to-world</b>, or <b>send-to-mux</b>..
+ </p>
+ <p><b>This format is likely to change very soon!</b></p>
+ <p>
+ Keystrokes, currently, are <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keywords</a></i> with the following format:
+ <pre>
+ keystroke := :[&lt;modifier&gt;-]*&lt;keycode&gt;
+ modifier := cmd|opt|ctrl|shift|numpad
+ keycode := &lt;fkey&gt;|character
+ fkey := f1 .. fn .. f35</pre>
+ So, hitting 8 on the number pad, while the command key is down yields the keyword: <code>:cmd-numpad-8</code>
+ </p>
+
+ <hr>
+ <p><a id="remove-keystroke-macro"><i>Function</i> <b>REMOVE-KEYSTROKE-MACRO</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>remove-keystroke-macro</b> <i>keystroke</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>keystroke</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keyword</a></i>.</p>
+ <p><i>result</i>---<a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_t.htm#t">T</a>, if the keystroke was previously registered, <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_t.htm#nil">NIL</a> otherwise.</p>
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (remove-keystroke-macro :f1) => T
+ (remove-keystroke-macro :f1) => NIL</pre></p>
+
+ <p><b>Side Effects:</b></p>
+ <p>
+ <i>keystroke</i> no longer triggers a function call.
+ </p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#add-keystroke-macro">add-keystroke-macro</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p><b>This format is likely to change very soon!</b></p>
+ <p>
+ Keystrokes, currently, are <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keywords</a></i> with the following format:
+ <pre>
+ keystroke := :[&lt;modifier&gt;-]*&lt;keycode&gt;
+ modifier := cmd|opt|ctrl|shift|numpad
+ keycode := &lt;fkey&gt;|character
+ fkey := f1 .. fn .. f35</pre>
+ So, hitting 8 on the number pad, while the command key is down yields the keyword: <code>:cmd-numpad-8</code>
+ </p>
+
+ <hr>
+ <p><a id="send-to-mux"><i>Function</i> <b>SEND-TO-MUX</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>send-to-mux</b> <i>world-id</i> <i>string</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ This is the low-level function to send data to the MUX server associated with
+ <i>world-id</i>. Currently, you can only send a string command, which will be
+ interpreted by the MUX directly. This may change in the future to allow for
+ attributed strings.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (send-to-mux *world* (format nil "Wauug!~%"))</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#print-to-world">print-to-world</a></b>
+ <b><a href="#set-status-buffer">set-status-buffer</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="print-to-world"><i>Function</i> <b>PRINT-TO-WORLD</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>print-to-world</b> <i>world-id</i> <i>arg</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ This is the low-level function to send data to the Moxie's world output view
+ associated with <i>world-id</i>. You can send either a normal string or an
+ attributed string for printing.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (print-to-world *world* (format nil "Wauug!~%"))</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#send-to-mux">send-to-mux</a></b>
+ <b><a href="#set-status-buffer">set-status-buffer</a></b>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="set-status-buffer"><i>Function</i> <b>SET-STATUS-BUFFER</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>set-status-buffer</b> <i>world-id</i> <i>string</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Sets the status buffer of the window associated with <i>world-id</i> to <i>string</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (set-status-buffer *world* "Hello, world!")</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#send-to-mux">send-to-mux</a></b>
+ <b><a href="#print-to-world">print-to-world</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="enable-logging"><i>Function</i> <b>ENABLE-LOGGING</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>enable-logging</b> <i>world-id</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Enables logging for the world associated with <i>world-id</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (enable-logging *world*)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#disable-logging">disable-logging</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="disable-logging"><i>Function</i> <b>DISABLE-LOGGING</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>disable-logging</b> <i>world-id</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Disables logging for the world associated with <i>world-id</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (disable-logging *world*)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#enable-logging">enable-logging</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="make-attributed-string"><i>Function</i> <b>MAKE-ATTRIBUTED-STRING</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-attributed-string</b> <i>string</i> <code>&amp;rest</code> <i>attribute*</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>attributes</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a string with attributes applied to it. This allows you to change various display properties of the string, such as the color, font, and style.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>
+ (make-attributed-string "Wauug!" (make-range 0 (length "Wauug!"))
+ (make-color 100 100 100)
+ (make-underline 1)) => ("Wauug!" ((:RANGE 0 6)
+ (:COLOR 100 100 100)
+ (:UNDERLINE 1)))</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ The only hook, currently, which can use attributed strings is <code>:output-from-server-hook</code>, which calls on <code>print-to-world</code> to display results. Those are the only places within Moxie to which you should be sending attributed strings.
+ </p>
+
+ <hr>
+ <p><a id="make-range"><i>Function</i> <b>MAKE-RANGE</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-range</b> <i>index</i> <i>length</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>index</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_b.htm#bounding_index_designator">bounding index designator</a></i>.
+ <p><i>length</i>---a non-negative <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i>.
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a <i>range</i> object from <i>index</i> for a <i>length</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-range 0 (length "Wauug!")) => (:RANGE 0 6)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ This function is likely to go away in the future as the attributed string mechansism gets cleaned up.
+ </p>
+
+ <hr>
+ <p><a id="make-font"><i>Function</i> <b>MAKE-FONT</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-font</b> <i>name</i> <i>size</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>name</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>size</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/t_real.htm#real">real</a></i>.
+ </p>
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a <i>font</i> object. The font is located by <i>name</i> and is <i>size</i> points high.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-font "apple-monaco" 12.0) => (:FONT "apple-monaco" 12.0)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <hr>
+ <p><a id="make-color"><i>Function</i> <b>MAKE-COLOR</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-color</b> <i>red-value</i> <i>green-value</i> <i>blue-value</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>red-value</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i> between 0 and 255.
+ <p><i>green-value</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i> between 0 and 255.
+ <p><i>blue-value</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i> between 0 and 255.
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a <i>color</i> object with the specified values for red, green, and blue.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-color 100 100 100) => (:COLOR 100 100 100)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <hr>
+ <p><a id="make-super"><i>Function</i> <b>MAKE-SUPER</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-super</b> <i>level</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>level</i>---a non-negative <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i>.
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a <i>superscript</i> attribute at the specified <i>level</i>. At level 0, the text is inline with normally attributed text, at each level above 0, the text moves higher and becomes smaller, denoting a superscript.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-super 1) => (:SUPER 1)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <hr>
+ <p><a id="make-underline"><i>Function</i> <b>MAKE-UNDERLINE</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-underline</b> <i>level</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>level</i>---a non-negative <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i>.
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates an <i>underline</i> attribute with <i>level</i> number of underline strokes.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-underline 1) => (:UNDERLINE 1)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <hr>
+ <p><a id="make-link"><i>Function</i> <b>MAKE-LINK</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-link</b> <i>url</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>url</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a <i>link</i> attribute, pointing to <i>url</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-link "http://www.spork.org/") => (:LINK "http://www.spork.org/")</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ </p>
+
+ <hr>
+ <p><a id="escape-mux-string"><i>Function</i> <b>ESCAPE-MUX-STRING</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>escape-mux-string</b> <i>string</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ This function is used to create pre-formatted strings for a MUX. MUXes normally ignore sequences of white space, and error on newlines, ignoring tab markins except as their capacity for white space. You can get around this by injecting %r, %t, and %b for newlines, tab characters, and white space, respectively. This function does that for you.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (escape-mux-string "xyzzy plugh") => "xyzzy%bplugh"</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ This function may only be useful for MUSHes. If your MUX escapes strings differently than a MUSH, then you will need a new function.
+ </p>
+
+ <hr>
+ <p><a id="map-variables"><i>Function</i> <b>MAP-VARIABLES</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>map-variables</b> <i>string</i> <i>variable-list</i>=> <i>result-string</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>variable-list</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i> containing the variable substitutions for <i>string</i>.
+ <p><i>result-string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ <b>map-variables</b> returns a <i>string</i> composed by substituting patterns of
+ the form $<i>number</i>$ from <i>string</i> with those places in <i>variable-list</i>.
+ So, <code>$1$</code> refers to the first position (<i>i.e., car</i>) of the list
+ <i>variable-list</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>
+ (map-variables "one: $1$ two: $2$ three: $3$" '(1 2 3)) => "one: 1 two: 2 three: 3"</pre></p>
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/.svn/text-base/lisp-glossary.html.svn-base b/English.lproj/Moxie Help/pages/.svn/text-base/lisp-glossary.html.svn-base
new file mode 100644
index 0000000..6f64434
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/text-base/lisp-glossary.html.svn-base
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Lisp Glossary</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>Lisp Glossary</h1>
+
+ <dt><strong><a id="asdf">ASDF</a></strong></dt>
+ <dd><p><em>(abbrev, "Another System Definition Facility"</em> A way to
+ package a lisp bundle together. See the <a href="#cliki">CLiki</a>
+ <a href="http://www.cliki.net/asdf" target="new">page</a> for further
+ details.</p></dd>
+
+ <dt><strong><a id="bjc-utils">bjc-utils</a></strong></dt>
+ <dd><p>A collection of utilities the author (bjc) finds useful, and so,
+ in order to facilitate his hacking, he has also included within
+ Moxie.</p></dd>
+
+ <dt><strong><a id="clhs">CLHS</a></strong></dt>
+ <dd><p><em>(abbrev, "Common Lisp HyperSpec")</em> The authoritative
+ reference for the ANSI ratified Common Lisp.<p>
+
+ <p>You may find a version of the HyperSpec online at:
+ <a href="http://www.lispworks.com/reference/HyperSpec/index.html"
+ target="new">
+ LispWorks</a></p></dd>
+
+ <dt><strong><a id="cliki">CLiki</a></strong></dt>
+ <dd><p><em>(from "Common Lisp" and "Wiki")</em> A Wiki devoted to
+ Common Lisp.</p>
+
+ <p>See <a href="http://www.cliki.net/" target="new">http://www.cliki.net/</a></p></dd>
+
+ <dt><strong><a id="cl-ppcre">CL-PPCRE</a></strong></dt>
+ <dd><p><em>(abbrev, "Common Lisp Portable Perl Compatible Regular Expression")</em>
+ A Lisp <a href="#package">package</a> with functions to parse and match
+ with PERL-style Regular Expressions.</p>
+
+ <p>See the <a href="#cliki">CLiki</a>
+ <a href="http://www.cliki.net/cl-ppcre" target="new">page</a> for
+ further details.</p></dd>
+
+ <dt><strong><a id="ecl">ECL</a></strong></dt>
+ <dd><p><em>(abbrev, "Embeddable Common Lisp")</em> Moxie uses ECL for
+ its lisp sub-system. More information on ECL can be found on the
+ <a href="http://ecls.sourceforge.net/" target="new">SourceForge
+ project page</a></p></dd>
+
+ <dt><strong><a id="package">package</a></strong></dt>
+ <dd><p>Packages are a kind of lisp "library". See the <a href="#clhs">CLHS</a>
+ <a href="http://www.lispworks.com/reference/HyperSpec/Body/11_.htm"
+ target="new">Chapter 11.</a></p></dd>
+
+ <dt><strong><a id="repl">REPL</a></strong></dt>
+ <dd><p><em>(abbrev, "Read, Eval, Print Loop")</em> The main loop responsible
+ for accepting user input, evaluating the input, and printing the results
+ of that evaluation. The REPL is often used synonymously with
+ <a href="#toplevel">"top level."</a></p></dd>
+
+ <dt><strong><a id="toplevel">Top Level</a></strong></dt>
+ <dd><p>The top-most <a href="#repl">REPL</a>. It is the first loop instantiated
+ by the lisp sub-system, from which everything else is evaluated.</p></dd>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/.svn/text-base/navigation.html.svn-base b/English.lproj/Moxie Help/pages/.svn/text-base/navigation.html.svn-base
new file mode 100644
index 0000000..b639388
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/text-base/navigation.html.svn-base
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+ <title>Navigation</title>
+ <meta name="generator" content="Emacs!">
+</head>
+
+<body>
+ <center><img src="../images/Moxie.png" alt="" width="128" height="128"></center>
+ <ul>
+ <li><a href="overview.html" target="contentsFrame">Overview</a></li>
+ <li><a href="faq.html" target="contentsFrame">Frequently Asked Questions</a></li>
+ <li><a href="plugin.html" target="contentsFrame">Plugin System</a></li>
+ <ul>
+ <li><a href="lisp-functions.html" target="contentsFrame">Plugin Dictionary</a></li>
+ </ul>
+ <li><a href="whatsnew.html" target="contentsFrame">What's new</a></li>
+ <li><a href="bugs.html" target="contentsFrame">Known Bugs</a></li>
+ <li><a href="todo.html" target="contentsFrame">To Do</a></li>
+ <li><a href="http://www.kublai.com/~shmit/software/Moxie/" target="new">Website</a></li>
+ </ul>
+</body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/.svn/text-base/overview.html.svn-base b/English.lproj/Moxie Help/pages/.svn/text-base/overview.html.svn-base
new file mode 100644
index 0000000..a32bb6c
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/text-base/overview.html.svn-base
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Overview</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>Overview</h1>
+ <p>Moxie is a client for <a href="glossary.html#mux">MUX</a> systems. Some of its
+ notable features are:</p>
+
+ <ul>
+ <li>ANSI color support is supplied via a plug in.</li>
+ <li>It has trigger, alias, and macro support via the <a href="plugin.html">plugin</a> sub-system.</li>
+ <li>Lisp-based plugin system, instead of a custom scripting language, so you can write
+ any kind of plug in you can imagine.</li>
+ <li>Transparent windows.</li>
+ <li>Command History via the CMD-Up/Down arrows. This also works in the Lisp REPL.</li>
+ <li>MUX-formatted pasting, which translates whitespace to %r, %t, %b as appropriate.</li>
+ <li>Auto-login to servers.</li>
+ <li>Startup worlds allow you to auto-open worlds when Moxie starts up.</li>
+ <li>Logging of sessions to plain-text files.</li>
+ <li>An innovative "World Selector" which allows you to switch between worlds very
+ quickly, shows status (New Activity, Connected, Disconnected), allowing for:</li>
+ <li>Clean and simple tab-less design, hearkening back to older MacOS days.</li>
+ </ul>
+
+ <p>You can create sessions ("<a href="glossary.html#world">Worlds</a>" in Moxie)
+ which contain all your preferences for a given world, as well as configure
+ global preferences (such as what worlds to start up when Moxie launches).</p>
+
+ <p>If you want to learn more about any of this, click a topic on the left.</p>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/.svn/text-base/plugin.html.svn-base b/English.lproj/Moxie Help/pages/.svn/text-base/plugin.html.svn-base
new file mode 100644
index 0000000..1f048c1
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/text-base/plugin.html.svn-base
@@ -0,0 +1,203 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Plugin Lifestyle</title>
+ <meta name="generator" content="BBEdit 6.5">
+ </head>
+
+ <body>
+ <h1><a id="intro">Introduction</a></h1>
+ <h2>Or: The worlds of MUXing are varied, so why shouldn't my viewer be?</h2>
+ <p>
+ Most MUXes are built off very similar codebases and design patters, but
+ within those similar roots are an infinite and varied number of worlds.
+ </p>
+ <p>
+ In order to cope with the almost maddening variety in MUXing,
+ programmatically, you have to develop some kind of programming language.
+ For instance, TinyFugue's trigger's are a simple programming language.
+ </p>
+ <p>
+ So, to allow for the largest amount of flexibility in Moxie, Moxie
+ includes a full programming language. While inventing one specifically
+ for Moxie would certainly be the norm, it is not something that should
+ be valued highly. In fact, by using a standard language, you get a lot
+ of benefits of useably free code-base.
+ </p>
+ <p>
+ So, Moxie includes an <a href="http://clisp.cons.org/">embedded lisp
+ interpreter</a>. This gives you the full power of the Lisp language from
+ within your plugin code. What kind of things you write, and how you want to
+ interact with Moxie and your MUX are limited only by your imagination.
+ </p>
+ <p>
+ This does mean you'll have to learn Lisp - at least a little - in order
+ to write any plugins for Moxie, although I will endeavour to keep things
+ as simple as possible throughout this document.
+ </p>
+
+ <h1><a id="quickstart">Quick Start</a></h1>
+ <h2>Or: Just Gimme the Code, and I'll Come Back When I Need You.</h2>
+ <p>
+ The simplest plugins are keyword expansions: when you type
+ "/foobar baz" into Moxie, it will try to trigger keyword expansion for
+ the keyword "foobar".
+ </p>
+ <p>
+ To register a keyword expander, you first have to write the code
+ for the expander, then register it with the keyword expansion hook.
+ all the functions referenced here are exported from the MOXIE
+ <a href="lisp-glossary.html#package">package</a>.
+ </p>
+ <p>
+ First, we'll create a package for our test plugin, and use the moxie
+ <a href="lisp-glossary.html#package">package</a>, as well as the
+ <a href="lisp-glossary.html#bjc-utils">bjc-utils</a> package.
+ </p>
+ <pre>
+ (defpackage test-plugin
+ (:use :cl :cl-user :moxie :bjc-utils))
+ (in-package :test-plugin)
+ </pre>
+ <p>
+ Then we define our expander function. We just want to take a name off
+ of the argument line, and page them with "hello!". For the sake of
+ debugging, we also want to print out what we got as the argument
+ to the lisp <a href="lisp-glossary.html#repl">REPL</a>:
+ </p>
+ <pre>
+ (defun foobar-handler (string)
+ (format t "foobar-handler got: ~A~%" string)
+ (map-variables "page $1$ = hello!"
+ (split string #\Space)))
+ </pre>
+ <p>
+ The function we've defined returns the string from the map-variables
+ command. This return value is what's sent to the MUX. If we don't want
+ to send anything to the MUX you can return an empty string ("") or
+ nil.
+ </p>
+ <p>
+ Now that we have the function defined, we want to register it with
+ the keyword expansion hook:
+ </p>
+ <pre>
+ (add-keyword 'foobar-handler "foobar")
+ </pre>
+ <p>
+ To test this, first bring up the REPL window so we can see what's
+ being printed out by the function as it runs. To do this, select
+ "Lisp REPL" from the "Window" menu.
+ </p>
+ <p>
+ Now, in Moxie, type "/foobar me", and, assuming you're connected
+ to a MUX, you should get a page from yourself saying, "hello!".
+ In the REPL window, however, you'll see:
+ </p>
+ <pre>
+ foobar-handler got: me
+ </pre>
+ <p>
+ Which means the handler received the string "me" as the argument
+ string.
+ </p>
+ <p>
+ If you're curious how the functions map-variables and split work,
+ in the REPL, type "(documentation 'map-variables 'function)" to view
+ their documentation.
+ </p>
+ <p>
+ There are other pre-defined triggers that work in a similar fashion.
+ There is a list of them in the moxie.lisp file in the
+ <a href="#app-source">resources directory</a>.
+ </p>
+
+ <h1><a id="app-predefs">Appendix: Pre-defined variables and triggers</a></h1>
+ <p>
+ Moxie uses a set of pre-defined symbols to communicate with the lisp
+ sub-system. Below is a table of symbols, what type they are, and what
+ they do.
+ </p>
+ <table border=1>
+ <tr>
+ <td>Name</td>
+ <td>Type</td>
+ <td>Description</td>
+ </tr>
+ <tr>
+ <td>moxie::*moxie-result-stream*</td>
+ <td>stream</td>
+ <td>The stream for communicating with Moxie.</td>
+ </tr>
+ <tr>
+ <td>moxie::*world*</td>
+ <td>object</td>
+ <td>The currently active world-id. This may be 0, if a world hasn't called into
+ the plugin system.</td>
+ </tr>
+ <tr>
+ <td>moxie::eval-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to send data from the REPL window to the
+ lisp plugin system.</td>
+ </tr>
+ <tr>
+ <td>moxie::input-to-server-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to send data to the lisp plugins after receiving
+ something from the input line.</td>
+ </tr>
+ <tr>
+ <td>moxie::output-from-server-hook</td>
+ <td>function</td>
+ <td>Used by Moxie when data is received from the MUX for display
+ on the screen.</td>
+ </tr>
+ <tr>
+ <td>moxie::keystroke-hook</td>
+ <td>function</td>
+ <td>Used by Moxie when a registered keystroke is pressed to call into its
+ function</td>
+ </tr>
+ <tr>
+ <td>moxie::world-opened-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to tell the plugin system a new world has opened.</td>
+ </tr>
+ <tr>
+ <td>moxie::world-closed-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to tell the plugin system a world has closed.</td>
+ </tr>
+ <tr>
+ <td>moxie::start-logging-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to tell the plugin system it wishes to log transcripts.</td>
+ </tr>
+ <tr>
+ <td>moxie::stop-logging-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to tell the plugin system it no longer wishes to log.</td>
+ </tr>
+ </table>
+
+ <h1><a id="app-source">Appendix: Sample source code</a></h1>
+ <p>
+ You can find definitions for all the built in functions in the Application
+ bundle: <code>Contents/Resources/*.lisp</code>. The file <code>startlisp</code>
+ parses the file <code>init-template.lisp</code> and starts the lisp with the parsed
+ file, loading the rest of the plug in system with it.
+ </p>
+ <p>
+ There are certain hooks in <code>tpl.lisp</code> which the application calls. You
+ can have a look at them, and even change them if you want, but don't
+ rename them or Moxie won't work anymore.
+ </p>
+ <p>
+ Also included in the Application Plug-Ins directory are a few pre-supplied plug ins
+ which you can use as an example. This includes the default logger, numpad movement macros,
+ and ANSI color support.
+ </p>
+ </body>
+</html
diff --git a/English.lproj/Moxie Help/pages/.svn/text-base/todo.html.svn-base b/English.lproj/Moxie Help/pages/.svn/text-base/todo.html.svn-base
new file mode 100644
index 0000000..4a413de
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/text-base/todo.html.svn-base
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>To Do</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>To Do</h1>
+
+ <ul>
+ <li>Parenthesis highlighting in the REPL. Programming lisp without this is a
+ complete pain for larger functions.</li>
+ <li>Create a better attributed string mechanism for Plug Ins. The current system
+ works, but is ugly.</li>
+ <li>Tab completion and indentation in the REPL.</li>
+ <li>Symbol lookup in the CLHS from the REPL.</li>
+ <li>Complete documentation.</li>
+ <li>Clean up the attributed string interface w/regards to hooks. Having to
+ conditionally extract the string is very annoying.</li>
+ </ul>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/.svn/text-base/whatsnew.html.svn-base b/English.lproj/Moxie Help/pages/.svn/text-base/whatsnew.html.svn-base
new file mode 100644
index 0000000..b990505
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/.svn/text-base/whatsnew.html.svn-base
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>What's New</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>What's new</h1>
+ <h3>Since 0.4</h3>
+ <ul>
+ <li>A timer hook now fires every second. You can attach to it by adding
+ a function to <code>:timer-hook</code>.</li>
+ <li>Telnet DONT and WONT are handled properly now.</li>
+ <li>The lisp image includes ASDF and CL-PPCRE, so startup times should be faster
+ if you use CL-PPCRE in your plugins.</li>
+ </ul>
+
+ <h3>Since 0.3</h3>
+ <ul>
+ <li>ANSI color support is now supplied via a built-in plug in.</li>
+ <li>You can send a lone enter key press.</li>
+ <li>Telnet protocol support.</li>
+ <li>You can clear your screen from the plug in interface now. For convenience,
+ the command "/clear" will clear your screen, as well as the <code>clear</code>
+ key on the numeric keypad.</li>
+ <li>Numpad keybindings have been added via a plug in.</li>
+ <li>Hooks use the results of the previous hook in a mode if applicable now, to
+ allow for multiple levels of filter feeding off of each other. This does complicate
+ things a little more, but it also allows hooks to play nice with each other.</li>
+ <li>Hooks no longer set arbitrary keywords. Those have been replaced by special
+ variables which will do the right thing, and greatly simplify plugin code.</li>
+ <li>Attributed strings changed. You can now set multiple attributes across multiple
+ ranges of the string.</li>
+ </ul>
+
+ <h3>Since 0.2:</h3>
+ <ul>
+ <li>Moxie now scans for plugins in ~/Library/Moxie, and the usual variations
+ thereof for Network, Local, and System directories.</li>
+ <li>There's a new package, CLHS-LOOKUP, which will lookup symbols in the CLHS.</li>
+ <li>The world view is no longer cleared when reconnecting.</li>
+ <li>Lisp is now initialized at startup time.</li>
+ <li>The Lisp system is no longer embedded. You can use any CL system you wish
+ now. The communications channels have become asynchronous, as well. The lisp
+ system should never hang Moxie again, although it is still required for its
+ functioning. You can now also use the built-in debugging features of whichever
+ lisp you choose.</li>
+ <li>CLISP is now included as the default lisp implementation. You can get more
+ information on CLISP at <a href="http://clisp.cons.org/">the website.</a></li>
+ <li>Logging has been moved into a plugin. You can now enable and disable it
+ from within plugins, and for convenience, the command "/log [filename]" in
+ a Moxie window will enable logging to FILENAME, if it exists, otherwise it
+ will toggle logging to the current log file.</li>
+ <li>The plug in system now defines "keystroke macros" which run when individual
+ keys are pressed. See the plug in documentation for further details.</li>
+ <li>Logging can be enabled and disabled from the plug in system.</li>
+ <li>The status buffer (the text field next to the lag indicator) can now
+ be set from the plug in system.</li>
+ <li>World-local variables are now available in the plug in system via the
+ <code>world-var</code> function. These variables differ depending upon
+ which world is calling into the plug in, and can be used to keep state
+ information. See the plug in documentation for further information.</li>
+ <li>CL-PPCRE moved into the PlugIns directory.</li>
+ <li>Plug in documentation updated for all exported functions.</li>
+ </ul>
+
+ <h3>Since 0.1:</h3>
+ <ul>
+ <li>Plugin System is here. The plugins are written in Lisp thanks to
+ <a href="http://ecls.sourceforge.net/" target="new">ECL.</a>
+ <a href="http://www.cliki.net/asdf" target="new">ASDF</a> and
+ <a href="http://www.cliki.net/cl-ppcre" target="new">CL-PPCRE</a> are
+ also included. See the help file for details.</li>
+
+ <li>Help is now available in the standard place. It's pretty empty at
+ the moment, but includes some pointers on how to get started with the
+ plugin system. There is also a sample plugin provided in the application
+ bundle, in the "PlugIns" directory.</li>
+ </ul>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/bugs.html b/English.lproj/Moxie Help/pages/bugs.html
new file mode 100644
index 0000000..b2a5fd5
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/bugs.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Known Bugs</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>Known Bugs</h1>
+ <ul>
+ <li>The world selector will not raise the window you select if it's already the frontmost
+ Moxie window, even if Moxie is in the background (it comes next-to-top, for reasons I don't
+ at all understand).</li>
+ <li>Fonts get screwed up fairly frequently, especially when trying to set them via the font panel.</li>
+ <li>The "Choose" button for choosing the REPL font doesn't work at all.</li>
+ <li>Reading from standard-input in Lisp will hang Moxie.</li>
+ </ul>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/faq.html b/English.lproj/Moxie Help/pages/faq.html
new file mode 100644
index 0000000..a80cde3
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/faq.html
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Frequently Asked Questions</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>Frequently Asked Questions</h1>
+
+ <dt><strong>How do I write a trigger, alias, or macro?</strong></dt>
+ <dd>
+ <p>First of all, Moxie makes no distinction between triggers, aliases, and macros. We
+ treat all of these things in the same way: as a <a href="plugin.html">plugin</a>.</p>
+
+ <p>All plugins are written in Common Lisp, so you'll have to have some grounding in
+ Lisp to do anything serious at the moment (although I have some ideas for simpler
+ interfaces for the non-programming-minded in the future). There are a few support
+ routines included in the MOXIE <a href="lisp-glossary.html#package">package</a> to
+ simplify common plugin tasks, such as triggers and aliases.</p>
+ </dd>
+
+ <dt><strong>LISP?! Why would you do that?</strong></dt>
+ <dd>
+ <p>Because I didn't want to have to write my own language for triggers, aliases, and
+ macros. No matter how much I worked on it, I wasn't going to get the kind of
+ programmability I wanted without embedding a full programming language.
+ I also think it's something of a waste of time to learn a new language just for the
+ purpose of programming a trigger in your MUX client.
+ </p>
+ <p>I could have just used AppleScript as the language of choice, and came very
+ close to doing so a number of times, but I had too much trouble trying to get
+ AS and ObjC talking as well as I'd liked, and, frankly, I don't consider it to
+ be full-featured enough.</p>
+ <p>So I chose to embed a language. There are, theoretically, a fair number
+ of popular languages I could have embedded, however, I chose Lisp for the
+ following reasons:
+ <ul>
+ <li>Real-time development. I feel that, in the scope of Moxie, having a fully
+ interactive development style is extremely useful. As far as I know, this
+ excludes PERL as a possibility.</li>
+ <li>Lisp has been ratified by ANSI, and is one of the few languages to do so. It
+ has a very large "library" that is standard from one lisp implementation to the
+ next, so as long as you've found code that's "Common Lisp" you've found code that
+ will work with Moxie.</li>
+ <li>Lisp is the second-oldest language still in use, after FORTRAN. While not
+ the largest consideration, it does guarantee that there's a fair amount of code
+ available for free in the world. Emacs, for example, has a huge amount of contributed
+ Emacs-Lisp code (which, while not common-lisp, is often easily ported).</li>
+ <li>And finally, because I can. I like Lisp, and I'm writing Moxie, so I get to pick.
+ "Give me real macros, or give me death!"</li>
+ </ul>
+ </p>
+ </dd>
+
+ <dt><strong>Where can I find more information on Lisp programming?</strong></dt>
+ <dd>
+ <p>There are a number of web sites devoted to Lisp programming. Below, I'll list a few
+ resources that should get you pointed in the right direction:
+ <ul>
+ <li><a href="lisp-glossary.html#cliki">CLiki's</a>
+ <a href="http://www.cliki.net/Online%20Tutorial" target="new">Online Tutorial</a> page
+ can get you started if you're completely new.</li>
+ <li><a href="http://www.paulgraham.com" target="new">Paul Graham</a> has a lot of
+ information on Lisp, including a free book for the more serious programmers.</li>
+ </ul>
+ </p>
+ </dd>
+
+ <dt><strong>What is the REPL?</strong></dt>
+ <dd>
+ <p>The <a href="lisp-glossary.html#repl">REPL</a> is your direct
+ interface to the Lisp sub-system. It is the key to fully interactive programming. Via
+ the REPL you can input Lisp commands directly and see the results - any Lisp will work
+ here, including function definitions. This allows you to write a function, test it, and
+ debug it, all without leaving the REPL, and with a much finer grain of control than with
+ a compile cycle.</p>
+ </dd>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/function-template.html b/English.lproj/Moxie Help/pages/function-template.html
new file mode 100644
index 0000000..da624de
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/function-template.html
@@ -0,0 +1,30 @@
+ <hr>
+ <p><a id="NAME"><i>Function</i> <b>NAME</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>NAME</b> <i>ARG</i> => <i>RETURN-VALUE</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>ARG</i>---A <i>TYPE</i>.</p>
+ <p><i>RETURN-VALUE</i>---An <i>TYPE</i>.</p>
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>CODE</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#function">FUNCTION</a></b>
+ </p>
+
+ <p><b>Notes:</b> None</p>
diff --git a/English.lproj/Moxie Help/pages/glossary.html b/English.lproj/Moxie Help/pages/glossary.html
new file mode 100644
index 0000000..3606388
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/glossary.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>
+ Glossary
+ </title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>
+ Glossary
+ </h1>
+ <ul>
+ <li>
+ <dt> <a id="mux">MUX</a> </dt>
+ <dd> A generic term meaning any of the variety of multi-user environments:
+ MUSH, MUD, MOO, etc.,.</dd>
+ </li>
+ <li>
+ <dt><a id="world">World</a></dt>
+ <dd>The file containing the preferences for a particular connection.</dd>
+ </li>
+ </ul>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/lisp-functions.html b/English.lproj/Moxie Help/pages/lisp-functions.html
new file mode 100644
index 0000000..a6091c7
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/lisp-functions.html
@@ -0,0 +1,947 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+
+
+<html lang="en">
+ <head>
+ <title>Lisp Functions</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>Moxie plugin functions</h1>
+ <p>These functions are all exported from the <code>MOXIE</code>
+ <a href="lisp-glossary.html#package">package</a>.
+ </p>
+ <p>
+ Contents:
+ <ul>
+ <li><a href="#world-var">world-var</a></li>
+ <li><a href="#add-hook">add-hook</a></li>
+ <li><a href="#remove-hook">remove-hook</a></li>
+ <li><a href="#run-hook">run-hook</a></li>
+ <li><a href="#add-keyword">add-keyword</a></li>
+ <li><a href="#remove-keyword">remove-keyword</a></li>
+ <li><a href="#add-keystroke-macro">add-keystroke-macro</a></li>
+ <li><a href="#remove-keystroke-macro">remove-keystroke-macro</a></li>
+ <li><a href="#send-to-mux">send-to-mux</a></li>
+ <li><a href="#print-to-world">print-to-world</a></li>
+ <li><a href="#set-status-buffer">set-status-buffer</a></li>
+ <li><a href="#enable-logging">enable-logging</a></li>
+ <li><a href="#disable-logging">disable-logging</a></li>
+ <li><a href="#make-attributed-string">make-attributed-string</a></li>
+<!--
+ We're going to lose these functions, in preference to a key/value
+ system.
+
+ <li><a href="#make-range">make-range</a></li>
+ <li><a href="#make-font">make-font</a></li>
+ <li><a href="#make-color">make-color</a></li>
+ <li><a href="#make-super">make-super</a></li>
+ <li><a href="#make-underline">make-underline</a></li>
+ <li><a href="#make-link">make-link</a></li> -->
+
+ <li><a href="#escape-mux-string">escape-mux-string</a></li>
+ <li><a href="#map-variables">map-variables</a></li>
+ </ul>
+ </p>
+
+ <hr>
+ <p><a id="world-var"><i>Function</i> <b>WORLD-VAR</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>world-var</b> <i>name</i> <code>&amp;optional</code> (<i>world-id</i> <i>*world*</i>) => <i>result</i>
+ </p>
+ <p>
+ (setf (<b>world-var</b> <i>name</i> <code>&amp;optional</code> (<i>world-id</i> *world*)) <i>new-value</i>)
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>name</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>result</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ <b>world-var</b> is used to associate <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_v.htm#value">values</a></i>, which are persistent throughout the application's lifetime, with <i>name</i> for a particular Moxie world, which has the unique identifier, <i>world-id</i>.
+ </p>
+ <p>
+ <b><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_setf_.htm#setf">setf</a></b> may be used with <b><a href="#world-var">world-var</a></b> to modify the <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_v.htm#value">values</a></i> associated with a given <i>name</i>, or to add a new entry.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (setf (world-var :foo 0) 'bar) => BAR
+ (world-var :foo 0) => BAR
+ (world-var :foo 1) => NIL
+ (setf (world-var :foo 1) 'YOW) => YOW
+ (world-var :foo 1) => YOW
+ (world-var :foo 0) => BAR</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="add-hook"><i>Function</i> <b>ADD-HOOK</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>add-hook</b> <i>function</i> <i>mode</i> => <i>hook-list</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>function</i>--a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i>.
+ <p><i>mode</i>---A <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keyword</a></i>.</p>
+ <p><i>hook-list</i>---A <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i> containing the active <i>functions</i> for <i>mode</i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p><b>add-hook</b> adds <i>function</i> to the list of functions to be run when
+ the hook <i>mode</i> is executed via <b>run-hook</b>.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>
+ (defun my-printer (string)
+ (let ((string (if (stringp string) string (car string))))
+ (concatenate 'string "TEST: " string))) => MY-PRINTER
+ (add-hook 'my-printer :output-from-server-hook) => (MY-PRINTER)
+ (run-hook :output-from-server-hook "foo") => "TEST: foo"
+ (defun 'do-nothing (&amp;rest args) nil) => DO-NOTHING
+ (add-hook 'do-nothing :output-from-server-hook) => (MY-PRINTER DO-NOTHING)
+ (run-hook :output-from-server-hook "foo") => "TEST: foo"</pre>
+ </p>
+
+ <p><b>Side Effects:</b></p>
+ <p><i>function</i> will be run by <b>run-hook</b> for <i>mode</i>.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#remove-hook">remove-hook</a></b>
+ <b><a href="#run-hook">run-hook</a></b>
+ </p>
+
+ <p><b>Notes:</b>
+ <p>If <i>function</i> is already on the hook list for <i>mode</i>, it will
+ not be added again.</p>
+
+ <hr>
+ <p><a id="remove-hook"><i>Function</i> <b>REMOVE-HOOK</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>remove-hook</b> <i>function</i> <i>mode</i> => <i>hook-list</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>function</i>--a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i>.
+ <p><i>mode</i>---A <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keyword</a></i>.</p>
+ <p><i>hook-list</i>---A <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i> containing the active <i>functions</i> for <i>mode</i>.</p>
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>
+ (remove-hook 'my-printer :output-from-server-hook) => NIL</pre></p>
+
+ <p><b>Side Effects:</b></p>
+ <p><i>function</i> is no longer called by <code>run-hook</code>.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#add-hook">add-hook</a></b>
+ <b><a href="#run-hook">run-hook</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ If <i>function</i> is not on the hook list for <i>mode</i>, the hook list is
+ returned without change. You can use this facility to get the current list
+ of <i>functions</i> for <i>mode</i> by removing <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_n.htm#nil">NIL</a> from the hook list.
+ </p>
+
+ <hr>
+ <p><a id="run-hook"><i>Function</i> <b>RUN-HOOK</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>run-hook</b> <i>mode</i> <code><i>&amp;optional</i></code> <i>arg</i>
+ => <i>result*</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>mode</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keyword</a></i>.</p>
+ <p><i>arg</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>results</i>---the <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_v.htm#value">values</a></i> returned by the last non-NIL terminating function.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_a.htm#apply">Applies</a> the
+ <i>functions</i> for <i>mode</i> to the <i>args</i>.
+ </p>
+ <p>
+ A hook-list acts as a filter, passing the output of one filter into the input of
+ the next. If a function on the hook-list returns <b>NIL</b>, it is treated in this iteration
+ as if it hadn't been on the hook-list in the first place. Thus, the only time
+ <b>run-hook</b> returns <b>NIL</b> is when every function on the hook-list returns
+ <b>NIL</b>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>
+ (run-hook :output-from-server-hook "Foobar!") => "TEST: Foobar!"</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b></p>
+ <p>
+ The hook list for <i>mode</i>. All the functions on the list are called, in
+ order. The last function which returns a non-nil value is used as the result
+ function.
+ </p>
+
+ <p><b>Exceptional Situations:</b></p>
+ <p>
+ If a <i>function</i> on the hook list for <i>mode</i> is not a function
+ designator, an error will be raised.
+ </p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#add-hook">add-hook</a></b>
+ <b><a href="#remove-hook">remove-hook</a></b>
+ </p>
+
+ <p><b>Notes:</b> None.</p>
+
+ <hr>
+ <p><a id="add-keyword"><i>Function</i> <b>ADD-KEYWORD</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>add-keyword</b> <i>function</i> <i>keyword</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>function</i>--a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i>.
+ <p><i>keyword</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>result</i>---the <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i> for <i>keyword</i>.</p>
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (defun my-keyword (args)
+ (format t "Keyword expander: ~S~%" args)) => MY-KEYWORD
+ (add-keyword 'my-keyword "foo") => MY-KEYWORD</pre></p>
+
+ <p><b>Side Effects:</b></p>
+ <p>
+ <i>keyword</i> is registered for keyword expansion.
+ </p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#remove-keyword">remove-keyword</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ The keyword expander compares keywords in a case insensitive fashion. So "FOO" and
+ "foo" are equivalent.
+ </p>
+
+ <hr>
+ <p><a id="remove-keyword"><i>Function</i> <b>REMOVE-KEYWORD</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>remove-keyword</b> <i>keyword</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>keyword</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>result</i>---the <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_t.htm#t">T</a> on successful removal. <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_n.htm#nil">NIL</a> otherwise.
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (remove-keyword "foo") => T
+ (remove-keyword "foo") => NIL</pre></p>
+
+ <p><b>Side Effects:</b></p>
+ <p>
+ <i>keyword</i> is no longer expanded by the keyword expander.
+ </p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#add-keyword">add-keyword</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ The keyword expander compares keywords in a case insensitive fashion. So "FOO" and
+ "foo" are equivalent.
+ </p>
+
+ <hr>
+ <p><a id="add-keystroke-macro"><i>Function</i> <b>ADD-KEYSTROKE-MACRO</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>add-keystroke-macro</b> <i>function</i> <i>keystroke</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>function</i>--a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i>.
+ <p><i>keystroke</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keyword</a></i>.</p>
+ <p><i>result</i>---the <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_f.htm#function_designator">function designator</a></i> for <i>keyword</i>.</p>
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (defun my-keystroke-macro (keystroke)
+ (format t "Should expand keystroke ~S here.~%" keystroke)) => MY-KEYSTROKE-MACRO
+ (add-keystroke-macro 'my-keystroke-macro :f1) => MY-KEYSTROKE-MACRO</pre></p>
+
+ <p><b>Side Effects:</b></p>
+ <p>
+ <i>function</i> is called when <i>keystroke</i> is pressed.
+ </p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#remove-keystroke-macro">remove-keystroke-macro</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ Unlike most other functions defined here, keystrokes don't do anything by default.
+ This means that in order to achieve some user-visible result, you'll have to use
+ the lower level functions <b>print-to-world</b>, or <b>send-to-mux</b>..
+ </p>
+ <p><b>This format is likely to change very soon!</b></p>
+ <p>
+ Keystrokes, currently, are <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keywords</a></i> with the following format:
+ <pre>
+ keystroke := :[&lt;modifier&gt;-]*&lt;keycode&gt;
+ modifier := cmd|opt|ctrl|shift|numpad
+ keycode := &lt;fkey&gt;|character
+ fkey := f1 .. fn .. f35</pre>
+ So, hitting 8 on the number pad, while the command key is down yields the keyword: <code>:cmd-numpad-8</code>
+ </p>
+
+ <hr>
+ <p><a id="remove-keystroke-macro"><i>Function</i> <b>REMOVE-KEYSTROKE-MACRO</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>remove-keystroke-macro</b> <i>keystroke</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>keystroke</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keyword</a></i>.</p>
+ <p><i>result</i>---<a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_t.htm#t">T</a>, if the keystroke was previously registered, <a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_t.htm#nil">NIL</a> otherwise.</p>
+ </p>
+
+ <p><b>Description:</b> None.</p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (remove-keystroke-macro :f1) => T
+ (remove-keystroke-macro :f1) => NIL</pre></p>
+
+ <p><b>Side Effects:</b></p>
+ <p>
+ <i>keystroke</i> no longer triggers a function call.
+ </p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#add-keystroke-macro">add-keystroke-macro</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p><b>This format is likely to change very soon!</b></p>
+ <p>
+ Keystrokes, currently, are <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_k.htm#keyword">keywords</a></i> with the following format:
+ <pre>
+ keystroke := :[&lt;modifier&gt;-]*&lt;keycode&gt;
+ modifier := cmd|opt|ctrl|shift|numpad
+ keycode := &lt;fkey&gt;|character
+ fkey := f1 .. fn .. f35</pre>
+ So, hitting 8 on the number pad, while the command key is down yields the keyword: <code>:cmd-numpad-8</code>
+ </p>
+
+ <hr>
+ <p><a id="send-to-mux"><i>Function</i> <b>SEND-TO-MUX</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>send-to-mux</b> <i>world-id</i> <i>string</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ This is the low-level function to send data to the MUX server associated with
+ <i>world-id</i>. Currently, you can only send a string command, which will be
+ interpreted by the MUX directly. This may change in the future to allow for
+ attributed strings.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (send-to-mux *world* (format nil "Wauug!~%"))</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#print-to-world">print-to-world</a></b>
+ <b><a href="#set-status-buffer">set-status-buffer</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="print-to-world"><i>Function</i> <b>PRINT-TO-WORLD</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>print-to-world</b> <i>world-id</i> <i>arg</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ This is the low-level function to send data to the Moxie's world output view
+ associated with <i>world-id</i>. You can send either a normal string or an
+ attributed string for printing.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (print-to-world *world* (format nil "Wauug!~%"))</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#send-to-mux">send-to-mux</a></b>
+ <b><a href="#set-status-buffer">set-status-buffer</a></b>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="set-status-buffer"><i>Function</i> <b>SET-STATUS-BUFFER</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>set-status-buffer</b> <i>world-id</i> <i>string</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Sets the status buffer of the window associated with <i>world-id</i> to <i>string</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (set-status-buffer *world* "Hello, world!")</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#send-to-mux">send-to-mux</a></b>
+ <b><a href="#print-to-world">print-to-world</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="enable-logging"><i>Function</i> <b>ENABLE-LOGGING</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>enable-logging</b> <i>world-id</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Enables logging for the world associated with <i>world-id</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (enable-logging *world*)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#disable-logging">disable-logging</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="disable-logging"><i>Function</i> <b>DISABLE-LOGGING</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>disable-logging</b> <i>world-id</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>world-id</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_o.htm#object">object</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Disables logging for the world associated with <i>world-id</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (disable-logging *world*)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#enable-logging">enable-logging</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ <i>world-id</i> is available as the <code>*world*</code> special variable.
+ </p>
+
+ <hr>
+ <p><a id="make-attributed-string"><i>Function</i> <b>MAKE-ATTRIBUTED-STRING</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-attributed-string</b> <i>string</i> <code>&amp;rest</code> <i>attribute*</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>attributes</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a string with attributes applied to it. This allows you to change various display properties of the string, such as the color, font, and style.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>
+ (make-attributed-string "Wauug!" (make-range 0 (length "Wauug!"))
+ (make-color 100 100 100)
+ (make-underline 1)) => ("Wauug!" ((:RANGE 0 6)
+ (:COLOR 100 100 100)
+ (:UNDERLINE 1)))</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ The only hook, currently, which can use attributed strings is <code>:output-from-server-hook</code>, which calls on <code>print-to-world</code> to display results. Those are the only places within Moxie to which you should be sending attributed strings.
+ </p>
+
+ <hr>
+ <p><a id="make-range"><i>Function</i> <b>MAKE-RANGE</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-range</b> <i>index</i> <i>length</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>index</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_b.htm#bounding_index_designator">bounding index designator</a></i>.
+ <p><i>length</i>---a non-negative <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i>.
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a <i>range</i> object from <i>index</i> for a <i>length</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-range 0 (length "Wauug!")) => (:RANGE 0 6)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ This function is likely to go away in the future as the attributed string mechansism gets cleaned up.
+ </p>
+
+ <hr>
+ <p><a id="make-font"><i>Function</i> <b>MAKE-FONT</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-font</b> <i>name</i> <i>size</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>name</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>size</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/t_real.htm#real">real</a></i>.
+ </p>
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a <i>font</i> object. The font is located by <i>name</i> and is <i>size</i> points high.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-font "apple-monaco" 12.0) => (:FONT "apple-monaco" 12.0)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <hr>
+ <p><a id="make-color"><i>Function</i> <b>MAKE-COLOR</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-color</b> <i>red-value</i> <i>green-value</i> <i>blue-value</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>red-value</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i> between 0 and 255.
+ <p><i>green-value</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i> between 0 and 255.
+ <p><i>blue-value</i>---an <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i> between 0 and 255.
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a <i>color</i> object with the specified values for red, green, and blue.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-color 100 100 100) => (:COLOR 100 100 100)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <hr>
+ <p><a id="make-super"><i>Function</i> <b>MAKE-SUPER</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-super</b> <i>level</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>level</i>---a non-negative <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i>.
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a <i>superscript</i> attribute at the specified <i>level</i>. At level 0, the text is inline with normally attributed text, at each level above 0, the text moves higher and becomes smaller, denoting a superscript.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-super 1) => (:SUPER 1)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <hr>
+ <p><a id="make-underline"><i>Function</i> <b>MAKE-UNDERLINE</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-underline</b> <i>level</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>level</i>---a non-negative <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_i.htm#integer">integer</a></i>.
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates an <i>underline</i> attribute with <i>level</i> number of underline strokes.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-underline 1) => (:UNDERLINE 1)</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-link">make-link</a></b>
+ </p>
+
+ <hr>
+ <p><a id="make-link"><i>Function</i> <b>MAKE-LINK</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>make-link</b> <i>url</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>url</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ Creates a <i>link</i> attribute, pointing to <i>url</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (make-link "http://www.spork.org/") => (:LINK "http://www.spork.org/")</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>See Also:</b></p>
+ <p>
+ <b><a href="#make-attributed-string">make-attributed-string</a></b>
+ <b><a href="#make-range">make-range</a></b>
+ <b><a href="#make-font">make-font</a></b>
+ <b><a href="#make-color">make-color</a></b>
+ <b><a href="#make-super">make-super</a></b>
+ <b><a href="#make-underline">make-underline</a></b>
+ </p>
+
+ <hr>
+ <p><a id="escape-mux-string"><i>Function</i> <b>ESCAPE-MUX-STRING</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>escape-mux-string</b> <i>string</i> => <i>result</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>result</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ This function is used to create pre-formatted strings for a MUX. MUXes normally ignore sequences of white space, and error on newlines, ignoring tab markins except as their capacity for white space. You can get around this by injecting %r, %t, and %b for newlines, tab characters, and white space, respectively. This function does that for you.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre> (escape-mux-string "xyzzy plugh") => "xyzzy%bplugh"</pre></p>
+
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+
+ <p><b>Notes:</b></p>
+ <p>
+ This function may only be useful for MUSHes. If your MUX escapes strings differently than a MUSH, then you will need a new function.
+ </p>
+
+ <hr>
+ <p><a id="map-variables"><i>Function</i> <b>MAP-VARIABLES</b></a></p>
+ <p><b>Syntax:</b></p>
+ <p>
+ <b>map-variables</b> <i>string</i> <i>variable-list</i>=> <i>result-string</i>
+ </p>
+
+ <p><b>Arguments and Values:</b></p>
+ <p>
+ <p><i>string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ <p><i>variable-list</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_l.htm#list">list</a></i> containing the variable substitutions for <i>string</i>.
+ <p><i>result-string</i>---a <i><a href="http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#string">string</a></i>.</p>
+ </p>
+
+ <p><b>Description:</b></p>
+ <p>
+ <b>map-variables</b> returns a <i>string</i> composed by substituting patterns of
+ the form $<i>number</i>$ from <i>string</i> with those places in <i>variable-list</i>.
+ So, <code>$1$</code> refers to the first position (<i>i.e., car</i>) of the list
+ <i>variable-list</i>.
+ </p>
+
+ <p><b>Examples:</b></p>
+ <p><pre>
+ (map-variables "one: $1$ two: $2$ three: $3$" '(1 2 3)) => "one: 1 two: 2 three: 3"</pre></p>
+ <p><b>Side Effects:</b> None.</p>
+
+ <p><b>Affected By:</b> None.</p>
+
+ <p><b>Exceptional Situations:</b> None</p>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/lisp-glossary.html b/English.lproj/Moxie Help/pages/lisp-glossary.html
new file mode 100644
index 0000000..6f64434
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/lisp-glossary.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Lisp Glossary</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>Lisp Glossary</h1>
+
+ <dt><strong><a id="asdf">ASDF</a></strong></dt>
+ <dd><p><em>(abbrev, "Another System Definition Facility"</em> A way to
+ package a lisp bundle together. See the <a href="#cliki">CLiki</a>
+ <a href="http://www.cliki.net/asdf" target="new">page</a> for further
+ details.</p></dd>
+
+ <dt><strong><a id="bjc-utils">bjc-utils</a></strong></dt>
+ <dd><p>A collection of utilities the author (bjc) finds useful, and so,
+ in order to facilitate his hacking, he has also included within
+ Moxie.</p></dd>
+
+ <dt><strong><a id="clhs">CLHS</a></strong></dt>
+ <dd><p><em>(abbrev, "Common Lisp HyperSpec")</em> The authoritative
+ reference for the ANSI ratified Common Lisp.<p>
+
+ <p>You may find a version of the HyperSpec online at:
+ <a href="http://www.lispworks.com/reference/HyperSpec/index.html"
+ target="new">
+ LispWorks</a></p></dd>
+
+ <dt><strong><a id="cliki">CLiki</a></strong></dt>
+ <dd><p><em>(from "Common Lisp" and "Wiki")</em> A Wiki devoted to
+ Common Lisp.</p>
+
+ <p>See <a href="http://www.cliki.net/" target="new">http://www.cliki.net/</a></p></dd>
+
+ <dt><strong><a id="cl-ppcre">CL-PPCRE</a></strong></dt>
+ <dd><p><em>(abbrev, "Common Lisp Portable Perl Compatible Regular Expression")</em>
+ A Lisp <a href="#package">package</a> with functions to parse and match
+ with PERL-style Regular Expressions.</p>
+
+ <p>See the <a href="#cliki">CLiki</a>
+ <a href="http://www.cliki.net/cl-ppcre" target="new">page</a> for
+ further details.</p></dd>
+
+ <dt><strong><a id="ecl">ECL</a></strong></dt>
+ <dd><p><em>(abbrev, "Embeddable Common Lisp")</em> Moxie uses ECL for
+ its lisp sub-system. More information on ECL can be found on the
+ <a href="http://ecls.sourceforge.net/" target="new">SourceForge
+ project page</a></p></dd>
+
+ <dt><strong><a id="package">package</a></strong></dt>
+ <dd><p>Packages are a kind of lisp "library". See the <a href="#clhs">CLHS</a>
+ <a href="http://www.lispworks.com/reference/HyperSpec/Body/11_.htm"
+ target="new">Chapter 11.</a></p></dd>
+
+ <dt><strong><a id="repl">REPL</a></strong></dt>
+ <dd><p><em>(abbrev, "Read, Eval, Print Loop")</em> The main loop responsible
+ for accepting user input, evaluating the input, and printing the results
+ of that evaluation. The REPL is often used synonymously with
+ <a href="#toplevel">"top level."</a></p></dd>
+
+ <dt><strong><a id="toplevel">Top Level</a></strong></dt>
+ <dd><p>The top-most <a href="#repl">REPL</a>. It is the first loop instantiated
+ by the lisp sub-system, from which everything else is evaluated.</p></dd>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/navigation.html b/English.lproj/Moxie Help/pages/navigation.html
new file mode 100644
index 0000000..b639388
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/navigation.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+<head>
+ <title>Navigation</title>
+ <meta name="generator" content="Emacs!">
+</head>
+
+<body>
+ <center><img src="../images/Moxie.png" alt="" width="128" height="128"></center>
+ <ul>
+ <li><a href="overview.html" target="contentsFrame">Overview</a></li>
+ <li><a href="faq.html" target="contentsFrame">Frequently Asked Questions</a></li>
+ <li><a href="plugin.html" target="contentsFrame">Plugin System</a></li>
+ <ul>
+ <li><a href="lisp-functions.html" target="contentsFrame">Plugin Dictionary</a></li>
+ </ul>
+ <li><a href="whatsnew.html" target="contentsFrame">What's new</a></li>
+ <li><a href="bugs.html" target="contentsFrame">Known Bugs</a></li>
+ <li><a href="todo.html" target="contentsFrame">To Do</a></li>
+ <li><a href="http://www.kublai.com/~shmit/software/Moxie/" target="new">Website</a></li>
+ </ul>
+</body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/overview.html b/English.lproj/Moxie Help/pages/overview.html
new file mode 100644
index 0000000..a32bb6c
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/overview.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Overview</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>Overview</h1>
+ <p>Moxie is a client for <a href="glossary.html#mux">MUX</a> systems. Some of its
+ notable features are:</p>
+
+ <ul>
+ <li>ANSI color support is supplied via a plug in.</li>
+ <li>It has trigger, alias, and macro support via the <a href="plugin.html">plugin</a> sub-system.</li>
+ <li>Lisp-based plugin system, instead of a custom scripting language, so you can write
+ any kind of plug in you can imagine.</li>
+ <li>Transparent windows.</li>
+ <li>Command History via the CMD-Up/Down arrows. This also works in the Lisp REPL.</li>
+ <li>MUX-formatted pasting, which translates whitespace to %r, %t, %b as appropriate.</li>
+ <li>Auto-login to servers.</li>
+ <li>Startup worlds allow you to auto-open worlds when Moxie starts up.</li>
+ <li>Logging of sessions to plain-text files.</li>
+ <li>An innovative "World Selector" which allows you to switch between worlds very
+ quickly, shows status (New Activity, Connected, Disconnected), allowing for:</li>
+ <li>Clean and simple tab-less design, hearkening back to older MacOS days.</li>
+ </ul>
+
+ <p>You can create sessions ("<a href="glossary.html#world">Worlds</a>" in Moxie)
+ which contain all your preferences for a given world, as well as configure
+ global preferences (such as what worlds to start up when Moxie launches).</p>
+
+ <p>If you want to learn more about any of this, click a topic on the left.</p>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/plugin.html b/English.lproj/Moxie Help/pages/plugin.html
new file mode 100644
index 0000000..1f048c1
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/plugin.html
@@ -0,0 +1,203 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Plugin Lifestyle</title>
+ <meta name="generator" content="BBEdit 6.5">
+ </head>
+
+ <body>
+ <h1><a id="intro">Introduction</a></h1>
+ <h2>Or: The worlds of MUXing are varied, so why shouldn't my viewer be?</h2>
+ <p>
+ Most MUXes are built off very similar codebases and design patters, but
+ within those similar roots are an infinite and varied number of worlds.
+ </p>
+ <p>
+ In order to cope with the almost maddening variety in MUXing,
+ programmatically, you have to develop some kind of programming language.
+ For instance, TinyFugue's trigger's are a simple programming language.
+ </p>
+ <p>
+ So, to allow for the largest amount of flexibility in Moxie, Moxie
+ includes a full programming language. While inventing one specifically
+ for Moxie would certainly be the norm, it is not something that should
+ be valued highly. In fact, by using a standard language, you get a lot
+ of benefits of useably free code-base.
+ </p>
+ <p>
+ So, Moxie includes an <a href="http://clisp.cons.org/">embedded lisp
+ interpreter</a>. This gives you the full power of the Lisp language from
+ within your plugin code. What kind of things you write, and how you want to
+ interact with Moxie and your MUX are limited only by your imagination.
+ </p>
+ <p>
+ This does mean you'll have to learn Lisp - at least a little - in order
+ to write any plugins for Moxie, although I will endeavour to keep things
+ as simple as possible throughout this document.
+ </p>
+
+ <h1><a id="quickstart">Quick Start</a></h1>
+ <h2>Or: Just Gimme the Code, and I'll Come Back When I Need You.</h2>
+ <p>
+ The simplest plugins are keyword expansions: when you type
+ "/foobar baz" into Moxie, it will try to trigger keyword expansion for
+ the keyword "foobar".
+ </p>
+ <p>
+ To register a keyword expander, you first have to write the code
+ for the expander, then register it with the keyword expansion hook.
+ all the functions referenced here are exported from the MOXIE
+ <a href="lisp-glossary.html#package">package</a>.
+ </p>
+ <p>
+ First, we'll create a package for our test plugin, and use the moxie
+ <a href="lisp-glossary.html#package">package</a>, as well as the
+ <a href="lisp-glossary.html#bjc-utils">bjc-utils</a> package.
+ </p>
+ <pre>
+ (defpackage test-plugin
+ (:use :cl :cl-user :moxie :bjc-utils))
+ (in-package :test-plugin)
+ </pre>
+ <p>
+ Then we define our expander function. We just want to take a name off
+ of the argument line, and page them with "hello!". For the sake of
+ debugging, we also want to print out what we got as the argument
+ to the lisp <a href="lisp-glossary.html#repl">REPL</a>:
+ </p>
+ <pre>
+ (defun foobar-handler (string)
+ (format t "foobar-handler got: ~A~%" string)
+ (map-variables "page $1$ = hello!"
+ (split string #\Space)))
+ </pre>
+ <p>
+ The function we've defined returns the string from the map-variables
+ command. This return value is what's sent to the MUX. If we don't want
+ to send anything to the MUX you can return an empty string ("") or
+ nil.
+ </p>
+ <p>
+ Now that we have the function defined, we want to register it with
+ the keyword expansion hook:
+ </p>
+ <pre>
+ (add-keyword 'foobar-handler "foobar")
+ </pre>
+ <p>
+ To test this, first bring up the REPL window so we can see what's
+ being printed out by the function as it runs. To do this, select
+ "Lisp REPL" from the "Window" menu.
+ </p>
+ <p>
+ Now, in Moxie, type "/foobar me", and, assuming you're connected
+ to a MUX, you should get a page from yourself saying, "hello!".
+ In the REPL window, however, you'll see:
+ </p>
+ <pre>
+ foobar-handler got: me
+ </pre>
+ <p>
+ Which means the handler received the string "me" as the argument
+ string.
+ </p>
+ <p>
+ If you're curious how the functions map-variables and split work,
+ in the REPL, type "(documentation 'map-variables 'function)" to view
+ their documentation.
+ </p>
+ <p>
+ There are other pre-defined triggers that work in a similar fashion.
+ There is a list of them in the moxie.lisp file in the
+ <a href="#app-source">resources directory</a>.
+ </p>
+
+ <h1><a id="app-predefs">Appendix: Pre-defined variables and triggers</a></h1>
+ <p>
+ Moxie uses a set of pre-defined symbols to communicate with the lisp
+ sub-system. Below is a table of symbols, what type they are, and what
+ they do.
+ </p>
+ <table border=1>
+ <tr>
+ <td>Name</td>
+ <td>Type</td>
+ <td>Description</td>
+ </tr>
+ <tr>
+ <td>moxie::*moxie-result-stream*</td>
+ <td>stream</td>
+ <td>The stream for communicating with Moxie.</td>
+ </tr>
+ <tr>
+ <td>moxie::*world*</td>
+ <td>object</td>
+ <td>The currently active world-id. This may be 0, if a world hasn't called into
+ the plugin system.</td>
+ </tr>
+ <tr>
+ <td>moxie::eval-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to send data from the REPL window to the
+ lisp plugin system.</td>
+ </tr>
+ <tr>
+ <td>moxie::input-to-server-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to send data to the lisp plugins after receiving
+ something from the input line.</td>
+ </tr>
+ <tr>
+ <td>moxie::output-from-server-hook</td>
+ <td>function</td>
+ <td>Used by Moxie when data is received from the MUX for display
+ on the screen.</td>
+ </tr>
+ <tr>
+ <td>moxie::keystroke-hook</td>
+ <td>function</td>
+ <td>Used by Moxie when a registered keystroke is pressed to call into its
+ function</td>
+ </tr>
+ <tr>
+ <td>moxie::world-opened-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to tell the plugin system a new world has opened.</td>
+ </tr>
+ <tr>
+ <td>moxie::world-closed-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to tell the plugin system a world has closed.</td>
+ </tr>
+ <tr>
+ <td>moxie::start-logging-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to tell the plugin system it wishes to log transcripts.</td>
+ </tr>
+ <tr>
+ <td>moxie::stop-logging-hook</td>
+ <td>function</td>
+ <td>Used by Moxie to tell the plugin system it no longer wishes to log.</td>
+ </tr>
+ </table>
+
+ <h1><a id="app-source">Appendix: Sample source code</a></h1>
+ <p>
+ You can find definitions for all the built in functions in the Application
+ bundle: <code>Contents/Resources/*.lisp</code>. The file <code>startlisp</code>
+ parses the file <code>init-template.lisp</code> and starts the lisp with the parsed
+ file, loading the rest of the plug in system with it.
+ </p>
+ <p>
+ There are certain hooks in <code>tpl.lisp</code> which the application calls. You
+ can have a look at them, and even change them if you want, but don't
+ rename them or Moxie won't work anymore.
+ </p>
+ <p>
+ Also included in the Application Plug-Ins directory are a few pre-supplied plug ins
+ which you can use as an example. This includes the default logger, numpad movement macros,
+ and ANSI color support.
+ </p>
+ </body>
+</html
diff --git a/English.lproj/Moxie Help/pages/todo.html b/English.lproj/Moxie Help/pages/todo.html
new file mode 100644
index 0000000..4a413de
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/todo.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>To Do</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>To Do</h1>
+
+ <ul>
+ <li>Parenthesis highlighting in the REPL. Programming lisp without this is a
+ complete pain for larger functions.</li>
+ <li>Create a better attributed string mechanism for Plug Ins. The current system
+ works, but is ugly.</li>
+ <li>Tab completion and indentation in the REPL.</li>
+ <li>Symbol lookup in the CLHS from the REPL.</li>
+ <li>Complete documentation.</li>
+ <li>Clean up the attributed string interface w/regards to hooks. Having to
+ conditionally extract the string is very annoying.</li>
+ </ul>
+ </body>
+</html>
diff --git a/English.lproj/Moxie Help/pages/whatsnew.html b/English.lproj/Moxie Help/pages/whatsnew.html
new file mode 100644
index 0000000..b990505
--- /dev/null
+++ b/English.lproj/Moxie Help/pages/whatsnew.html
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+<html lang="en">
+ <head>
+ <title>What's New</title>
+ <meta name="generator" content="Emacs!">
+ </head>
+
+ <body>
+ <h1>What's new</h1>
+ <h3>Since 0.4</h3>
+ <ul>
+ <li>A timer hook now fires every second. You can attach to it by adding
+ a function to <code>:timer-hook</code>.</li>
+ <li>Telnet DONT and WONT are handled properly now.</li>
+ <li>The lisp image includes ASDF and CL-PPCRE, so startup times should be faster
+ if you use CL-PPCRE in your plugins.</li>
+ </ul>
+
+ <h3>Since 0.3</h3>
+ <ul>
+ <li>ANSI color support is now supplied via a built-in plug in.</li>
+ <li>You can send a lone enter key press.</li>
+ <li>Telnet protocol support.</li>
+ <li>You can clear your screen from the plug in interface now. For convenience,
+ the command "/clear" will clear your screen, as well as the <code>clear</code>
+ key on the numeric keypad.</li>
+ <li>Numpad keybindings have been added via a plug in.</li>
+ <li>Hooks use the results of the previous hook in a mode if applicable now, to
+ allow for multiple levels of filter feeding off of each other. This does complicate
+ things a little more, but it also allows hooks to play nice with each other.</li>
+ <li>Hooks no longer set arbitrary keywords. Those have been replaced by special
+ variables which will do the right thing, and greatly simplify plugin code.</li>
+ <li>Attributed strings changed. You can now set multiple attributes across multiple
+ ranges of the string.</li>
+ </ul>
+
+ <h3>Since 0.2:</h3>
+ <ul>
+ <li>Moxie now scans for plugins in ~/Library/Moxie, and the usual variations
+ thereof for Network, Local, and System directories.</li>
+ <li>There's a new package, CLHS-LOOKUP, which will lookup symbols in the CLHS.</li>
+ <li>The world view is no longer cleared when reconnecting.</li>
+ <li>Lisp is now initialized at startup time.</li>
+ <li>The Lisp system is no longer embedded. You can use any CL system you wish
+ now. The communications channels have become asynchronous, as well. The lisp
+ system should never hang Moxie again, although it is still required for its
+ functioning. You can now also use the built-in debugging features of whichever
+ lisp you choose.</li>
+ <li>CLISP is now included as the default lisp implementation. You can get more
+ information on CLISP at <a href="http://clisp.cons.org/">the website.</a></li>
+ <li>Logging has been moved into a plugin. You can now enable and disable it
+ from within plugins, and for convenience, the command "/log [filename]" in
+ a Moxie window will enable logging to FILENAME, if it exists, otherwise it
+ will toggle logging to the current log file.</li>
+ <li>The plug in system now defines "keystroke macros" which run when individual
+ keys are pressed. See the plug in documentation for further details.</li>
+ <li>Logging can be enabled and disabled from the plug in system.</li>
+ <li>The status buffer (the text field next to the lag indicator) can now
+ be set from the plug in system.</li>
+ <li>World-local variables are now available in the plug in system via the
+ <code>world-var</code> function. These variables differ depending upon
+ which world is calling into the plug in, and can be used to keep state
+ information. See the plug in documentation for further information.</li>
+ <li>CL-PPCRE moved into the PlugIns directory.</li>
+ <li>Plug in documentation updated for all exported functions.</li>
+ </ul>
+
+ <h3>Since 0.1:</h3>
+ <ul>
+ <li>Plugin System is here. The plugins are written in Lisp thanks to
+ <a href="http://ecls.sourceforge.net/" target="new">ECL.</a>
+ <a href="http://www.cliki.net/asdf" target="new">ASDF</a> and
+ <a href="http://www.cliki.net/cl-ppcre" target="new">CL-PPCRE</a> are
+ also included. See the help file for details.</li>
+
+ <li>Help is now available in the standard place. It's pretty empty at
+ the moment, but includes some pointers on how to get started with the
+ plugin system. There is also a sample plugin provided in the application
+ bundle, in the "PlugIns" directory.</li>
+ </ul>
+ </body>
+</html>
diff --git a/English.lproj/Preferences.nib/classes.nib b/English.lproj/Preferences.nib/classes.nib
new file mode 100644
index 0000000..2bb3be6
--- /dev/null
+++ b/English.lproj/Preferences.nib/classes.nib
@@ -0,0 +1,16 @@
+{
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ ACTIONS = {addStartupWorld = id; removeStartupWorld = id; };
+ CLASS = PreferencesController;
+ LANGUAGE = ObjC;
+ OUTLETS = {
+ theStartupItemsController = NSArrayController;
+ theStartupItemsTableView = NSTableView;
+ };
+ SUPERCLASS = NSWindowController;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/English.lproj/Preferences.nib/info.nib b/English.lproj/Preferences.nib/info.nib
new file mode 100644
index 0000000..1caa62e
--- /dev/null
+++ b/English.lproj/Preferences.nib/info.nib
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>272 179 356 240 0 0 1024 746 </string>
+ <key>IBFramework Version</key>
+ <string>364.0</string>
+ <key>IBGroupedObjects</key>
+ <dict>
+ <key>0</key>
+ <array>
+ <string>9</string>
+ <string>21</string>
+ <string>23</string>
+ <string>12</string>
+ <string>14</string>
+ <string>13</string>
+ </array>
+ <key>3</key>
+ <array>
+ <string>75</string>
+ <string>78</string>
+ </array>
+ <key>4</key>
+ <array>
+ <string>167</string>
+ <string>168</string>
+ </array>
+ <key>6</key>
+ <array>
+ <string>170</string>
+ <string>169</string>
+ </array>
+ <key>7</key>
+ <array>
+ <string>84</string>
+ <string>85</string>
+ <string>86</string>
+ </array>
+ </dict>
+ <key>IBLastGroupID</key>
+ <string>9</string>
+ <key>IBOldestOS</key>
+ <integer>3</integer>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>20</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>7M34</string>
+</dict>
+</plist>
diff --git a/English.lproj/Preferences.nib/keyedobjects.nib b/English.lproj/Preferences.nib/keyedobjects.nib
new file mode 100644
index 0000000..af6e344
--- /dev/null
+++ b/English.lproj/Preferences.nib/keyedobjects.nib
Binary files differ
diff --git a/English.lproj/SettingNames.strings b/English.lproj/SettingNames.strings
new file mode 100644
index 0000000..3fa3bcf
--- /dev/null
+++ b/English.lproj/SettingNames.strings
@@ -0,0 +1,10 @@
+/* Used for the undo menu. */
+
+hostname = "Hostname";
+port = "Port";
+connectOnOpen = "Connect on Open";
+characterName = "Character Name";
+textColor = "Foreground Color";
+backgroundColor = "Background Color";
+font = "Font";
+loggingEnabled = "Logging Enabled"; \ No newline at end of file
diff --git a/English.lproj/World.nib/classes.nib b/English.lproj/World.nib/classes.nib
new file mode 100644
index 0000000..ed5f345
--- /dev/null
+++ b/English.lproj/World.nib/classes.nib
@@ -0,0 +1,27 @@
+{
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ CLASS = ScrollingTextView;
+ LANGUAGE = ObjC;
+ OUTLETS = {theResponder = NSResponder; };
+ SUPERCLASS = NSTextView;
+ },
+ {
+ ACTIONS = {close = id; open = id; };
+ CLASS = World;
+ LANGUAGE = ObjC;
+ OUTLETS = {
+ closeDelegate = id;
+ theConnectButton = NSButton;
+ theInputView = ScrollingTextView;
+ theOutputView = ScrollingTextView;
+ theProgressIndicator = NSProgressIndicator;
+ theRoomField = NSTextField;
+ theSplitView = NSSplitView;
+ };
+ SUPERCLASS = NSDocument;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/English.lproj/World.nib/info.nib b/English.lproj/World.nib/info.nib
new file mode 100644
index 0000000..5ca5fd0
--- /dev/null
+++ b/English.lproj/World.nib/info.nib
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>48 119 356 240 0 0 1280 1002 </string>
+ <key>IBFramework Version</key>
+ <string>443.0</string>
+ <key>IBOldestOS</key>
+ <integer>3</integer>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>5</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8J135</string>
+</dict>
+</plist>
diff --git a/English.lproj/World.nib/keyedobjects.nib b/English.lproj/World.nib/keyedobjects.nib
new file mode 100644
index 0000000..1f37fcb
--- /dev/null
+++ b/English.lproj/World.nib/keyedobjects.nib
Binary files differ
diff --git a/English.lproj/WorldSelector.nib/classes.nib b/English.lproj/WorldSelector.nib/classes.nib
new file mode 100644
index 0000000..376861b
--- /dev/null
+++ b/English.lproj/WorldSelector.nib/classes.nib
@@ -0,0 +1,12 @@
+{
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ CLASS = WorldStatusController;
+ LANGUAGE = ObjC;
+ OUTLETS = {theTableView = NSTableView; };
+ SUPERCLASS = NSWindowController;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/English.lproj/WorldSelector.nib/info.nib b/English.lproj/WorldSelector.nib/info.nib
new file mode 100644
index 0000000..38bfade
--- /dev/null
+++ b/English.lproj/WorldSelector.nib/info.nib
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>69 69 356 240 0 0 1600 1178 </string>
+ <key>IBFramework Version</key>
+ <string>349.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>12</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>7D26</string>
+</dict>
+</plist>
diff --git a/English.lproj/WorldSelector.nib/keyedobjects.nib b/English.lproj/WorldSelector.nib/keyedobjects.nib
new file mode 100644
index 0000000..b9bf135
--- /dev/null
+++ b/English.lproj/WorldSelector.nib/keyedobjects.nib
Binary files differ
diff --git a/English.lproj/WorldSettings.nib/classes.nib b/English.lproj/WorldSettings.nib/classes.nib
new file mode 100644
index 0000000..456e0f9
--- /dev/null
+++ b/English.lproj/WorldSettings.nib/classes.nib
@@ -0,0 +1,17 @@
+{
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ ACTIONS = {openLogDirectory = id; saveSettingsAsDefault = id; };
+ CLASS = WorldSettingsController;
+ LANGUAGE = ObjC;
+ OUTLETS = {
+ theHostSettingsTab = NSTabViewItem;
+ theSettingsController = NSObjectController;
+ theTabView = NSTabView;
+ };
+ SUPERCLASS = NSWindowController;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/English.lproj/WorldSettings.nib/info.nib b/English.lproj/WorldSettings.nib/info.nib
new file mode 100644
index 0000000..0dd122b
--- /dev/null
+++ b/English.lproj/WorldSettings.nib/info.nib
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>74 120 356 240 0 0 1600 1178 </string>
+ <key>IBFramework Version</key>
+ <string>443.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>5</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8F46</string>
+</dict>
+</plist>
diff --git a/English.lproj/WorldSettings.nib/keyedobjects.nib b/English.lproj/WorldSettings.nib/keyedobjects.nib
new file mode 100644
index 0000000..8d01021
--- /dev/null
+++ b/English.lproj/WorldSettings.nib/keyedobjects.nib
Binary files differ
diff --git a/English.lproj/WorldSettings~.nib/classes.nib b/English.lproj/WorldSettings~.nib/classes.nib
new file mode 100644
index 0000000..456e0f9
--- /dev/null
+++ b/English.lproj/WorldSettings~.nib/classes.nib
@@ -0,0 +1,17 @@
+{
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ ACTIONS = {openLogDirectory = id; saveSettingsAsDefault = id; };
+ CLASS = WorldSettingsController;
+ LANGUAGE = ObjC;
+ OUTLETS = {
+ theHostSettingsTab = NSTabViewItem;
+ theSettingsController = NSObjectController;
+ theTabView = NSTabView;
+ };
+ SUPERCLASS = NSWindowController;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/English.lproj/WorldSettings~.nib/info.nib b/English.lproj/WorldSettings~.nib/info.nib
new file mode 100644
index 0000000..0dd122b
--- /dev/null
+++ b/English.lproj/WorldSettings~.nib/info.nib
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>74 120 356 240 0 0 1600 1178 </string>
+ <key>IBFramework Version</key>
+ <string>443.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>5</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8F46</string>
+</dict>
+</plist>
diff --git a/English.lproj/WorldSettings~.nib/keyedobjects.nib b/English.lproj/WorldSettings~.nib/keyedobjects.nib
new file mode 100644
index 0000000..c18d17e
--- /dev/null
+++ b/English.lproj/WorldSettings~.nib/keyedobjects.nib
Binary files differ
diff --git a/English.lproj/World~.nib/classes.nib b/English.lproj/World~.nib/classes.nib
new file mode 100644
index 0000000..ed5f345
--- /dev/null
+++ b/English.lproj/World~.nib/classes.nib
@@ -0,0 +1,27 @@
+{
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ CLASS = ScrollingTextView;
+ LANGUAGE = ObjC;
+ OUTLETS = {theResponder = NSResponder; };
+ SUPERCLASS = NSTextView;
+ },
+ {
+ ACTIONS = {close = id; open = id; };
+ CLASS = World;
+ LANGUAGE = ObjC;
+ OUTLETS = {
+ closeDelegate = id;
+ theConnectButton = NSButton;
+ theInputView = ScrollingTextView;
+ theOutputView = ScrollingTextView;
+ theProgressIndicator = NSProgressIndicator;
+ theRoomField = NSTextField;
+ theSplitView = NSSplitView;
+ };
+ SUPERCLASS = NSDocument;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/English.lproj/World~.nib/info.nib b/English.lproj/World~.nib/info.nib
new file mode 100644
index 0000000..3b80e69
--- /dev/null
+++ b/English.lproj/World~.nib/info.nib
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>65 146 356 240 0 0 1600 1178 </string>
+ <key>IBFramework Version</key>
+ <string>443.0</string>
+ <key>IBOldestOS</key>
+ <integer>3</integer>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>5</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8F46</string>
+</dict>
+</plist>
diff --git a/English.lproj/World~.nib/keyedobjects.nib b/English.lproj/World~.nib/keyedobjects.nib
new file mode 100644
index 0000000..1ce300d
--- /dev/null
+++ b/English.lproj/World~.nib/keyedobjects.nib
Binary files differ
diff --git a/Info.plist b/Info.plist
new file mode 100644
index 0000000..c6f7d1d
--- /dev/null
+++ b/Info.plist
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>moxie</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>MoxieWorld.icns</string>
+ <key>CFBundleTypeMIMETypes</key>
+ <array>
+ <string>application/com.kublai.Moxie</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Moxie World</string>
+ <key>CFBundleTypeOSTypes</key>
+ <array>
+ <string>MOXI</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>NSDocumentClass</key>
+ <string>World</string>
+ </dict>
+ </array>
+ <key>CFBundleExecutable</key>
+ <string>Moxie</string>
+ <key>CFBundleHelpBookFolder</key>
+ <string>Moxie Help</string>
+ <key>CFBundleHelpBookName</key>
+ <string>Moxie Help</string>
+ <key>CFBundleIconFile</key>
+ <string>Moxie.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.kublai.Moxie</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>MOXI</string>
+ <key>CFBundleVersion</key>
+ <string>0-dev</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/Lisp/asdf/LICENSE b/Lisp/asdf/LICENSE
new file mode 100644
index 0000000..57b0a06
--- /dev/null
+++ b/Lisp/asdf/LICENSE
@@ -0,0 +1,24 @@
+
+(This is the MIT / X Consortium license as taken from
+ http://www.opensource.org/licenses/mit-license.html)
+
+Copyright (c) 2001, 2002 Daniel Barlow and contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Lisp/asdf/README b/Lisp/asdf/README
new file mode 100644
index 0000000..7243844
--- /dev/null
+++ b/Lisp/asdf/README
@@ -0,0 +1,752 @@
+$Id: README 20 2005-12-27 15:21:23Z bjc $ -*- Text -*-
+
+
+asdf: another system definition facility
+========================================
+
+* Getting the latest version
+
+0) Decide which version you want. HEAD is the newest version and
+usually OK, whereas RELEASE is for cautious people (e.g. who already
+have systems using asdf that they don't want broken), a slightly older
+version about which none of the HEAD users have complained.
+
+1) Check it out from sourceforge cCLan CVS:
+
+1a) cvs -d:pserver:anonymous@cvs.cclan.sourceforge.net:/cvsroot/cclan login
+ (no password: just press Enter)
+
+1a.1) cvs -z3 -d:pserver:anonymous@cvs.cclan.sourceforge.net:/cvsroot/cclan
+ co -r RELEASE asdf
+
+or for the bleeding edge, instead
+
+1a.2) cvs -z3 -d:pserver:anonymous@cvs.cclan.sourceforge.net:/cvsroot/cclan
+ co -A asdf
+
+If you are tracking the bleeding edge, you may want to subscribe to
+the cclan-commits mailing list (see
+<URL:http://sourceforge.net/mail/?group_id=28536>) to receive commit
+messages and diffs whenever changes are made.
+
+For more CVS information, look at http://sourceforge.net/cvs/?group_id=28536
+
+
+* Getting started
+
+- The single file asdf.lisp is all you need to use asdf normally. For
+maximum convenience you want to have it loaded whenever you start your
+Lisp implementation, by loading it from the startup script, or dumping
+a custom core, or something.
+
+- The variable asdf:*central-registry* is a list of system directory
+ designators. A system directory designator is a form which will be
+ evaluated whenever a system is to be found, and must evaluate to a
+ directory to look in. For example, you might have
+
+ (*default-pathname-defaults* "/home/me/cl/systems/"
+ "/usr/share/common-lisp/systems/")
+
+ (When we say "directory" here, we mean "designator for a pathname
+ with a supplied DIRECTORY component")
+
+ It is possible to customize the system definition file search.
+ That's considered advanced use, and covered later: search forward
+ for *system-definition-search-functions*
+
+- To compile and load a system 'foo', you need to (1) ensure that
+ foo.asd is in one of the directories in *central-registry* (a
+ symlink to the real location of foo.asd is preferred), (2) execute
+ ``(asdf:operate 'asdf:load-op 'foo)''
+
+ $ cd /home/me/cl/systems/
+ $ ln -s ~/src/foo/foo.asd .
+ $ lisp
+ * (asdf:operate 'asdf:load-op 'foo)
+
+- To write your own system definitions, look at the test systems in
+ test/ , and read the rest of this. Ignore systems/ which is old
+ and may go away when next I clean up
+
+- Syntax is similar to mk-defsystem 3 for straightforward systems, you
+ may only need to remove the :source-pathname option (and replace it
+ with :pathname if the asd file is not in the same place as the
+ system sources)
+
+- Join cclan-list@lists.sf.net for discussion, bug reports, questions, etc
+
+- cclan.asd and the source files listed therein contain useful extensions
+ for maintainers of systems in the cCLan. If this isn't you, you
+ don't need them - although you may want to look at them anyway
+
+- For systems that do complicated things (e.g. compiling C files to
+ load as foreign code), the packages in vn-cclan may provide some
+ guidance. db-sockets, for example, is known to do outlandish things
+ with preprocessors
+
+ http://ww.telent.net/cliki/vn-cclan
+
+
+
+* Concepts
+
+This system definition utility talks in terms of 'components' and
+'operations'.
+
+Components form systems: a component represents a source file, or a
+collection of components. A system is therefore a component,
+recursively formed of a tree of subcomponents.
+
+Operations are instantiated then performed on the nodes of a tree to
+do things like
+
+ - compile all its files
+ - load the files into a running lisp environment
+ - copy its source files somewhere else
+
+Operations can be invoked directly, or examined to see what their
+effects would be without performing them. There are a bunch of
+methods specialised on operation and component type which actually do
+the grunt work.
+
+asdf is extensible to new operations and to new component types. This
+allows the addition of behaviours: for example, a new component could
+be added for Java JAR archives, and methods specialised on
+compile-op added for it that would accomplish the relevant
+actions.
+
+* Inspiration
+
+** mk-defsystem (defsystem-3.x)
+
+We aim to solve basically the same problems as mk-defsystem does.
+However, our architecture for extensibility better exploits CL
+language features (and is documented), and we intend to be portable
+rather than just widely-ported. No slight on the mk-defsystem authors
+and maintainers is intended here; that implementation has the
+unenviable task of supporting non-ANSI implementations, which I
+propose to ignore.
+
+The surface defsystem syntax of asdf is more-or-less compatible with
+mk-defsystem
+
+The mk-defsystem code for topologically sorting a module's dependency
+list was very useful.
+
+** defsystem-4 proposal
+
+Marco and Peter's proposal for defsystem 4 served as the driver for
+many of the features in here. Notable differences are
+
+- we don't specify output files or output file extensions as part of
+ the system
+
+ If you want to find out what files an operation would create, ask
+ the operation
+
+- we don't deal with CL packages
+
+ If you want to compile in a particular package, use an in-package
+ form in that file (ilisp will like you more if you do this anyway)
+
+- there is no proposal here that defsystem does version control.
+
+ A system has a given version which can be used to check
+ dependencies, but that's all.
+
+The defsystem 4 proposal tends to look more at the external features,
+whereas this one centres on a protocol for system introspection.
+
+** kmp's "The Description of Large Systems", MIT AI Memu 801
+
+Available in updated-for-CL form on the web at
+http://world.std.com/~pitman/Papers/Large-Systems.html
+
+In our implementation we borrow kmp's overall PROCESS-OPTIONS and
+concept to deal with creating component trees from defsystem surface
+syntax. [ this is not true right now, though it used to be and
+probably will be again soon ]
+
+
+* The Objects
+
+** component
+
+*** Component Attributes
+
+**** A name (required)
+
+This is a string or a symbol. If a symbol, its name is taken and
+lowercased. The name must be a suitable value for the :name initarg
+to make-pathname in whatever filesystem the system is to be found.
+
+The lower-casing-symbols behaviour is unconventional, but was selected
+after some consideration. Observations suggest that the type of
+systems we want to support either have lowercase as customary case
+(Unix, Mac, windows) or silently convert lowercase to uppercase
+(lpns), so this makes more sense than attempting to use :case :common,
+which is reported not to work on some implementations
+
+**** a version identifier (optional)
+
+This is used by the test-system-version operation (see later).
+
+**** *features* required
+
+Traditionally defsystem users have used reader conditionals to include
+or exclude specific per-implementation files. This means that any
+single implementation cannot read the entire system, which becomes a
+problem if it doesn't wish to compile it, but instead for example to
+create an archive file containing all the sources, as it will omit to
+process the system-dependent sources for other systems.
+
+Each component in an asdf system may therefore specify features using
+the same syntax as #+ does, and it will (somehow) be ignored for
+certain operations unless the feature conditional matches
+
+**** dependencies on its siblings (optional but often necessary)
+
+There is an excitingly complicated relationship between the initarg
+and the method that you use to ask about dependencies
+
+Dependencies are between (operation component) pairs. In your
+initargs, you can say
+
+:in-order-to ((compile-op (load-op "a" "b") (compile-op "c"))
+ (load-op (load-op "foo")))
+
+- before performing compile-op on this component, we must perform
+load-op on "a" and "b", and compile-op on c, - before performing
+load-op, we have to load "foo"
+
+The syntax is approximately
+
+(this-op {(other-op required-components)}+)
+
+required-components := component-name
+ | (required-components required-components)
+
+component-name := string
+ | (:version string minimum-version-object)
+
+[ This is on a par with what ACL defsystem does. mk-defsystem is less
+general: it has an implied dependency
+
+ for all x, (load x) depends on (compile x)
+
+and using a :depends-on argument to say that b depends on a _actually_
+means that
+
+ (compile b) depends on (load a)
+
+This is insufficient for e.g. the McCLIM system, which requires that
+all the files are loaded before any of them can be compiled ]
+
+In asdf, the dependency information for a given component and
+operation can be queried using (component-depends-on operation
+component), which returns a list
+
+((load-op "a") (load-op "b") (compile-op "c") ...)
+
+component-depends-on can be subclassed for more specific
+component/operation types: these need to (call-next-method) and append
+the answer to their dependency, unless they have a good reason for
+completely overriding the default dependencies
+
+(If it weren't for CLISP, we'd be using a LIST method combination to
+do this transparently. But, we need to support CLISP. If you have
+the time for some CLISP hacking, I'm sure they'd welcome your fixes)
+
+**** a pathname
+
+This is optional and if absent will be inferred from name, type (the
+subclass of source-file), and the location of parent.
+
+The rules for this inference are:
+
+(for source-files)
+- the host is taken from the parent
+- pathname type is (source-file-type component system)
+- the pathname case option is :local
+- the pathname is merged against the parent
+
+(for modules)
+- the host is taken from the parent
+- the name and type are NIL
+- the directory is (:relative component-name)
+- the pathname case option is :local
+- the pathname is merged against the parent
+
+Note that the DEFSYSTEM operator (used to create a "top-level" system)
+does additional processing to set the filesystem location of the
+top component in that system. This is detailed elsewhere
+
+The answer to the frequently asked question "how do I create a system
+definition where all the source files have a .cl extension" is thus
+
+(defmethod source-file-type ((c cl-source-file) (s (eql (find-system 'my-sys))))
+ "cl")
+
+**** properties (optional)
+
+Packaging systems often require information about files or systems
+additional to that specified here. Programs that create vendor
+packages out of asdf systems therefore have to create "placeholder"
+information to satisfy these systems. Sometimes the creator of an
+asdf system may know the additional information and wish to provide it
+directly.
+
+(component-property component property-name) and associated setf method
+will allow the programmatic update of this information. Property
+names are compared as if by EQL, so use symbols or keywords or something
+
+** Subclasses of component
+
+*** 'source-file'
+
+A source file is any file that the system does not know how to
+generate from other components of the system.
+
+(Note that this is not necessarily the same thing as "a file
+containing data that is typically fed to a compiler". If a file is
+generated by some pre-processor stage (e.g. a ".h" file from ".h.in"
+by autoconf) then it is not, by this definition, a source file.
+Conversely, we might have a graphic file that cannot be automatically
+regenerated, or a proprietary shared library that we received as a
+binary: these do count as source files for our purposes. All
+suggestions for better terminology gratefully received)
+
+Subclasses of source-file exist for various languages.
+
+*** 'module', a collection of sub-components
+
+This has extra slots for
+
+ :components - the components contained in this module
+
+ :default-component-class - for child components which don't specify
+ their class explicitly
+
+ :if-component-dep-fails takes one of the values :fail, :try-next, :ignore
+ (default value is :fail). The other values can be used for implementing
+ conditional compilation based on implementation *features*, where
+ it is not necessary for all files in a module to be compiled
+
+The default operation knows how to traverse a module, so most
+operations will not need to provide methods specialised on modules.
+
+The module may be subclassed to represent components such as
+foreign-language linked libraries or archive files.
+
+*** system, subclasses module
+
+A system is a module with a few extra attributes for documentation
+purposes. In behaviour, it's usually identical.
+
+Users can create new classes for their systems: the default defsystem
+macro takes a :classs keyword argument.
+
+
+** operation
+
+An operation is instantiated whenever the user asks that an operation
+be performed, inspected, or etc. The operation object contains
+whatever state is relevant to this purpose (perhaps a list of visited
+nodes, for example) but primarily is a nice thing to specialise
+operation methods on and easier than having them all be EQL methods.
+
+There are no differences between standard operations and user-defined
+operations, except that the user is respectfully requested to keep his
+(or more importantly, our) package namespace clean
+
+*** invoking operations
+
+(operate operation system &rest keywords-args)
+
+keyword-args are passed to the make-instance call when creating the
+operation: valid keywords depend on the initargs that the operation is
+defined to accept. Note that dependencies may cause the operation to
+invoke other operations on the system or its components: the new
+operation will be created with the same initargs as the original one.
+
+oos is accepted as a synonym for operate
+
+*** standard operations
+
+**** feature-dependent-op
+
+This is not intended to be instantiated directly, but other operations
+may inherit from it. An instance of feature-dependent-op will ignore
+any components which have a `features' attribute, unless the feature
+combination it designates is satisfied by *features*
+
+See the earlier explanation about the component features attribute for
+more information
+
+**** compile-op &key proclamations
+
+If proclamations are supplied, they will be proclaimed. This is a
+good place to specify optimization settings
+
+When creating a new component, you should provide methods for this.
+
+If you invoke compile-op as a user, component dependencies often mean
+you may get some parts of the system loaded. This may not necessarily
+be the whole thing, though; for your own sanity it is recommended that
+you use load-op if you want to load a system.
+
+**** load-op &key proclamations
+
+The default methods for load-op compile files before loading them.
+For parity, your own methods on new component types should probably do
+so too
+
+**** load-source-op
+
+This method will load the source for the files in a module even if the
+source files have been compiled. Systems sometimes have knotty
+dependencies which require that sources are loaded before they can be
+compiled. This is how you do that.
+
+If you are creating a component type, you need to implement this
+operation - at least, where meaningful.
+
+**** test-system-version &key minimum
+
+Asks the system whether it satisfies a version requirement.
+
+The default method accepts a string, which is expected to contain of a
+number of integers separated by #\. characters. The method is not
+recursive. The component satisfies the version dependency if it has
+the same major number as required and each of its sub-versions is
+greater than or equal to the sub-version number required.
+
+(defun version-satisfies (x y)
+ (labels ((bigger (x y)
+ (cond ((not y) t)
+ ((not x) nil)
+ ((> (car x) (car y)) t)
+ ((= (car x) (car y))
+ (bigger (cdr x) (cdr y))))))
+ (and (= (car x) (car y))
+ (or (not (cdr y)) (bigger (cdr x) (cdr y))))))
+
+If that doesn't work for your system, you can override it. I hope
+yoyu have as much fun writing the new method as #lisp did
+reimplementing this one.
+
+*** Creating new operations
+
+subclass operation, provide methods for source-file for
+
+- output-files
+- perform
+ The perform method must call output-files to find out where to
+ put its files, because the user is allowed to override output-files
+ for local policy
+- explain
+- operation-done-p, if you don't like the default one
+
+* Writing system definitions
+
+** System designators
+
+System designators are strings or symbols and behave just like
+any other component names (including case conversion)
+
+** find-system
+
+Given a system designator, find-system finds an actual system - either
+in memory, or in a file on the disk. It funcalls each element in the
+*system-definition-search-functions* list, expecting a pathname to be
+returned.
+
+If a suitable file exists, it is loaded if
+
+- there is no system of that name in memory,
+- the file's last-modified time exceeds the last-modified time of the
+ system in memory
+
+When system definitions are loaded from .asd files, a new scratch
+package is created for them to load into, so that different systems do
+not overwrite each others operations. The user may also wish to (and
+is recommended to) include defpackage and in-package forms in his
+system definition files, however, so that they can be loaded manually
+if need be.
+
+For convenience in the normal case, and for backward compatibility
+with the spirit of mk-defsystem, the default contents of
+*system-definition-search-functions* is a function called
+sysdef-central-registry-search. This looks in each of the directories
+given by evaluating members of *central-registry*, for a file whose
+name is the name of the system and whose type is "asd". The first
+such file is returned, whether or not it turns out to actually define
+the appropriate system
+
+
+
+** Syntax
+
+Systems can always be constructed programmatically by instantiating
+components using make-instance. For most purposes, however, it is
+likely that people will want a static defystem form.
+
+asdf is based around the principle that components should not have to
+know defsystem syntax. That is, the initargs that a component accepts
+are not necessarily related to the defsystem form which creates it.
+
+A defsystem parser must implement a `defsystem' macro, which can
+be named for compatibility with whatever other system definition
+utility is being emulated. It should instantiate components in
+accordance with whatever language it accepts, and register the topmost
+component using REGISTER-SYSTEM
+
+*** Native syntax
+
+The native syntax is inspired by mk-defsystem, to the extent that it
+should be possible to take most straightforward mk- system definitions
+and run them with only light editing. For my convenience, this turns
+out to be basically the same as the initargs to the various
+components, with a few extensions for convenience
+
+system-definition := ( defsystem system-designator {option}* )
+
+option := :components component-list
+ | :pathname pathname
+ | :default-component-class
+ | :perform method-form
+ | :explain method-form
+ | :output-files method-form
+ | :operation-done-p method-form
+ | :depends-on ( {simple-component-name}* )
+ | :serial [ t | nil ]
+ | :in-order-to ( {dependency}+ )
+
+component-list := ( {component-def}* )
+
+component-def := simple-component-name
+ | ( component-type name {option}* )
+
+component-type := :module | :file | :system | other-component-type
+
+dependency := (dependent-op {requirement}+)
+requirement := (required-op {required-component}+)
+ | (feature feature-name)
+dependent-op := operation-name
+required-op := operation-name | feature
+
+For example
+
+(defsystem "foo"
+ :version "1.0"
+ :components ((:module "foo" :components ((:file "bar") (:file"baz")
+ (:file "quux"))
+ :perform (compile-op :after (op c)
+ (do-something c))
+ :explain (compile-op :after (op c)
+ (explain-something c)))
+ (:file "blah")))
+
+
+The method-form tokens need explaining: esentially,
+
+ :perform (compile-op :after (op c)
+ (do-something c))
+ :explain (compile-op :after (op c)
+ (explain-something c)))
+has the effect of
+
+(defmethod perform :after ((op compile-op) (c (eql ...)))
+ (do-something c))
+(defmethod explain :after ((op compile-op) (c (eql ...)))
+ (explain-something c))
+
+where ... is the component in question; note that although this also
+supports :before methods, they may not do what you want them to - a
+:before method on perform ((op compile-op) (c (eql ...))) will run
+after all the dependencies and sub-components have been processed, but
+before the component in question has been compiled.
+
+**** Serial dependencies
+
+If the `:serial t' option is specified for a module, asdf will add
+dependencies for each each child component, on all the children
+textually preceding it. This is done as if by :depends-on
+
+:components ((:file "a") (:file "b") (:file "c"))
+:serial t
+
+is equivalent to
+:components ((:file "a")
+ (:file "b" :depends-on ("a"))
+ (:file "c" :depends-on ("a" "b")))
+
+
+
+have all the
+
+**** Source location
+
+The :pathname option is optional in all cases for native-syntax
+systems, and in the usual case the user is recommended not to supply
+it. If it is not supplied for the top-level form, defsystem will set
+it from
+
+- The host/device/directory parts of *load-truename*, if it is bound
+- *default-pathname-defaults*, otherwise
+
+If a system is being redefined, the top-level pathname will be
+
+- changed, if explicitly supplied or obtained from *load-truename*
+- changed if it had previously been set from *default-pathname-defaults*
+- left as before, if it had previously been set from *load-truename*
+ and *load-truename* is not now bound
+
+These rules are designed so that (i) find-system will load a system
+from disk and have its pathname default to the right place, (ii)
+this pathname information will not be overwritten with
+*default-pathname-defaults* (which could be somewhere else altogether)
+if the user loads up the .asd file into his editor and
+interactively re-evaluates that form
+
+* Error handling
+
+It is an error to define a system incorrectly: an implementation may
+detect this and signal a generalised instance of
+SYSTEM-DEFINITION-ERROR
+
+Operations may go wrong (for example when source files contain
+errors). These are signalled using generalised instances of
+OPERATION-ERROR
+
+* Compilation error and warning handling
+
+ASDF checks for warnings and errors when a file is compiled. The
+variables *compile-file-warnings-behaviour* and
+*compile-file-errors-behavior* controls the handling of any such
+events. The valid values for these variables are :error, :warn, and
+:ignore.
+
+----------------------------------------------------------
+ TODO List
+----------------------------------------------------------
+
+* Outstanding spec questions, things to add
+
+** packaging systems
+
+*** manual page component?
+
+** style guide for .asd files
+
+You should either use keywords or be careful with the package that you
+evaluate defsystem forms in. Otherwise (defsystem partition ...)
+being read in the cl-user package will intern a cl-user:partition
+symbol, which will then collide with the partition:partition symbol.
+
+Actually there's a hairier packages problem to think about too.
+in-order-to is not a keyword: if you read defsystem forms in a package
+that doesn't use ASDF, odd things might happen
+
+** extending defsystem with new options
+
+You might not want to write a whole parser, but just to add options to
+the existing syntax. Reinstate parse-option or something akin
+
+** document all the error classes
+
+** what to do with compile-file failure
+
+Should check the primary return value from compile-file and see if
+that gets us any closer to a sensible error handling strategy
+
+** foreign files
+
+lift unix-dso stuff from db-sockets
+
+** Diagnostics
+
+A "dry run" of an operation can be made with the following form:
+
+(traverse (make-instance '<operation-name>)
+ (find-system <system-name>)
+ 'explain)
+
+This uses unexported symbols. What would be a nice interface for this
+functionality?
+
+** patches
+
+Sometimes one wants to
+
+
+* missing bits in implementation
+
+** all of the above
+** reuse the same scratch package whenever a system is reloaded from disk
+** rules for system pathname defaulting are not yet implemented properly
+** proclamations probably aren't
+** when a system is reloaded with fewer components than it previously
+ had, odd things happen
+
+we should do something inventive when processing a defsystem form,
+like take the list of kids and setf the slot to nil, then transfer
+children from old to new list as they're found
+
+** traverse may become a normal function
+
+If you're defining methods on traverse, speak up.
+
+
+** a lot of load-op methods can be rewritten to use input-files
+
+so should be.
+
+
+** (stuff that might happen later)
+
+*** david lichteblau's patch for symlink resolution?
+
+*** Propagation of the :force option. ``I notice that
+
+ (oos 'compile-op :araneida :force t)
+
+also forces compilation of every other system the :araneida system
+depends on. This is rarely useful to me; usually, when I want to force
+recompilation of something more than a single source file, I want to
+recompile only one system. So it would be more useful to have
+make-sub-operation refuse to propagate ":force t" to other systems, and
+propagate only something like ":force :recursively". ''
+
+Ideally what we actually want is some kind of criterion that says
+to which systems (and which operations) a :force switch will propagate.
+
+The problem is perhaps that 'force' is a pretty meaningless concept.
+How obvious is it that "load :force t" should force _compilation_?
+But we don't really have the right dependency setup for the user to
+compile :force t and expect it to work (files will not be loaded after
+compilation, so the compile environment for subsequent files will be
+emptier than it needs to be)
+
+What does the user actually want to do when he forces? Usually, for
+me, update for use with a new version of the lisp compiler. Perhaps
+for recovery when he suspects that something has gone wrong. Or else
+when he's changed compilation options or configuration in some way
+that's not reflected in the dependency graph.
+
+Other possible interface: have a 'revert' function akin to 'make clean'
+
+ (asdf:revert 'asdf:compile-op 'araneida)
+
+would delete any files produced by 'compile-op 'araneida. Of course, it
+wouldn't be able to do much about stuff in the image itself.
+
+How would this work?
+
+traverse
+
+There's a difference between a module's dependencies (peers) and its
+components (children). Perhaps there's a similar difference in
+operations? For example, (load "use") depends-on (load "macros") is a
+peer, whereas (load "use") depends-on (compile "use") is more of a
+`subservient' relationship.
diff --git a/Lisp/asdf/asdf-install.lisp b/Lisp/asdf/asdf-install.lisp
new file mode 100644
index 0000000..2bcd702
--- /dev/null
+++ b/Lisp/asdf/asdf-install.lisp
@@ -0,0 +1,299 @@
+#|| sh asdf-install.lisp will compile this file to an exe called asdf-install
+sbcl <<EOF
+(require 'sb-executable)
+(compile-file "asdf-install.lisp")
+(sb-executable:make-executable "asdf-install" *)
+EOF
+exit 0
+||#
+
+;;; Install an ASDF system or anything else that looks convincingly
+;;; like one, including updating symlink for all the toplevel .asd files it
+;;; contains
+
+;;; If the file $HOME/.asdf-install exists, it is loaded. This can be
+;;; used to override the default values of exported special variables
+;;; (see the defpackage form for details) - however, most of them are
+;;; sensible and/or taken from the environment anyway
+
+#||
+TODO:
+a) gpg signature checking would be better if it actually checked against
+a list of "trusted to write Lisp" keys, instead of just "trusted to be
+who they say they are"
+
+d) in sbcl 0.8.1 we'll have a run-program that knows about $PATH and so
+won't need to hardcode gpgpgpgp and tar locations.
+
+e) nice to have: resume half-done downloads instead of starting from scratch
+every time. but right now we're dealing in fairly small packages, this is not
+an immediate concern
+
+||#
+(in-package :cl-user)
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (require 'asdf)
+ (require 'sb-posix)
+ (require 'sb-executable)
+ (require 'sb-bsd-sockets))
+
+(defpackage :asdf-install
+ (:use "CL" "SB-EXT" "SB-BSD-SOCKETS")
+ (:export #:*proxy* #:*cclan-mirror* #:*sbcl-home*
+ #:*verify-gpg-signatures* #:*locations*))
+
+(defpackage :asdf-install-customize
+ (:use "CL" "SB-EXT" "SB-BSD-SOCKETS" "ASDF-INSTALL"))
+
+(in-package :asdf-install)
+
+(defvar *proxy* (posix-getenv "http_proxy"))
+(defvar *cclan-mirror*
+ (or (posix-getenv "CCLAN_MIRROR")
+ "http://ftp.linux.org.uk/pub/lisp/cclan/"))
+
+(defun directorify (name)
+ ;; input name may or may not have a training #\/, but we know we
+ ;; want a directory
+ (let ((path (pathname name)))
+ (if (pathname-name path)
+ (merge-pathnames
+ (make-pathname :directory `(:relative ,(pathname-name path))
+ :name "")
+ path)
+ path)))
+
+(defvar *sbcl-home* (directorify (posix-getenv "SBCL_HOME")))
+(defvar *dot-sbcl*
+ (merge-pathnames (make-pathname :directory '(:relative ".sbcl"))
+ (user-homedir-pathname)))
+
+(defvar *verify-gpg-signatures* t)
+
+(defvar *locations*
+ `((,(merge-pathnames "site/" *sbcl-home*)
+ ,(merge-pathnames "site-systems/" *sbcl-home*)
+ "System-wide install")
+ (,(merge-pathnames "site/" *dot-sbcl*)
+ ,(merge-pathnames "systems/" *dot-sbcl*)
+ "Personal installation")))
+
+(let* ((*package* (find-package :asdf-install-customize))
+ (file (probe-file (merge-pathnames
+ (make-pathname :name ".asdf-install")
+ (user-homedir-pathname)))))
+ (when file (load file)))
+
+(define-condition download-error (error)
+ ((url :initarg :url :reader download-url)
+ (response :initarg :response :reader download-response))
+ (:report (lambda (c s)
+ (format s "Server responded ~A for GET ~A"
+ (download-response c) (download-url c)))))
+
+(define-condition signature-error (error)
+ ((cause :initarg :cause :reader signature-error-cause))
+ (:report (lambda (c s)
+ (format s "Cannot verify package signature: ~A"
+ (signature-error-cause c)))))
+
+(defun url-host (url)
+ (assert (string-equal url "http://" :end1 7))
+ (let* ((port-start (position #\: url :start 7))
+ (host-end (min (or (position #\/ url :start 7) (length url))
+ (or port-start (length url)))))
+ (subseq url 7 host-end)))
+
+(defun url-port (url)
+ (assert (string-equal url "http://" :end1 7))
+ (let ((port-start (position #\: url :start 7)))
+ (if port-start (parse-integer url :start port-start :junk-allowed t) 80)))
+
+(defun url-connection (url)
+ (let ((s (make-instance 'inet-socket :type :stream :protocol :tcp))
+ (host (url-host url))
+ (port (url-port url)))
+ (socket-connect
+ s (car (host-ent-addresses (get-host-by-name (url-host (or *proxy* url)))))
+ (url-port (or *proxy* url)))
+ (let ((stream (socket-make-stream s :input t :output t :buffering :full)))
+ ;; we are exceedingly unportable about proper line-endings here.
+ ;; Anyone wishing to run this under non-SBCL should take especial care
+ (format stream "GET ~A HTTP/1.0~%Host: ~A~%Cookie: CCLAN-SITE=~A~%~%"
+ url host *cclan-mirror*)
+ (force-output stream)
+ (list
+ (let* ((l (read-line stream))
+ (space (position #\Space l)))
+ (parse-integer l :start (1+ space) :junk-allowed t))
+ (loop for line = (read-line stream nil nil)
+ until (or (null line) (eql (elt line 0) (code-char 13)))
+ collect
+ (let ((colon (position #\: line)))
+ (cons (intern (string-upcase (subseq line 0 colon)) :keyword)
+ (string-trim (list #\Space (code-char 13))
+ (subseq line (1+ colon))))))
+ stream))))
+
+(defun download (package-name-or-url file-name)
+ (let ((url
+ (if (= (mismatch package-name-or-url "http://") 7)
+ package-name-or-url
+ (format nil "http://www.cliki.net/~A?download"
+ package-name-or-url))))
+ (destructuring-bind (response headers stream)
+ (block got
+ (loop
+ (destructuring-bind (response headers stream) (url-connection url)
+ (unless (member response '(301 302))
+ (return-from got (list response headers stream)))
+ (close stream)
+ (setf url (cdr (assoc :location headers))))))
+ (if (>= response 400)
+ (error 'download-error :url url :response response))
+ (let ((length (parse-integer
+ (or (cdr (assoc :content-length headers)) "")
+ :junk-allowed t)))
+ (format t "Downloading ~A bytes from ~A ..."
+ (if length length "some unknown number of") url)
+ (force-output)
+ (with-open-file (o file-name :direction :output)
+ (if length
+ (let ((buf (make-array length
+ :element-type
+ (stream-element-type stream) )))
+ (read-sequence buf stream)
+ (write-sequence buf o))
+ (sb-executable:copy-stream stream o))))
+ (close stream)
+ (terpri)
+ ;; seems to have worked. let's try for a detached gpg signature too
+ (when *verify-gpg-signatures*
+ (verify-gpg-signature url file-name)))))
+
+(defun verify-gpg-signature (url file-name)
+ (destructuring-bind (response headers stream)
+ (url-connection (concatenate 'string url ".asc"))
+ (declare (ignore headers))
+ (unwind-protect
+ (if (= response 200)
+ ;; sadly, we can't pass the stream directly to run-program,
+ ;; because (at least in sbcl 0.8) that ignores existing buffered
+ ;; data and only reads new fresh data direct from the file
+ ;; descriptor
+ (let ((data (make-string (parse-integer
+ (cdr (assoc :content-length headers))
+ :junk-allowed t))))
+ (read-sequence data stream)
+ (let ((ret
+ (process-exit-code
+ (sb-ext:run-program "/usr/bin/gpg"
+ (list "--verify" "-"
+ (namestring file-name))
+ :output t
+ :input (make-string-input-stream data)
+ :wait t))))
+ (unless (zerop ret)
+ (error 'signature-error
+ :cause (make-condition
+ 'simple-error
+ :format-control "GPG returned exit status ~A"
+ :format-arguments (list ret))))))
+ (error 'signature-error
+ :cause
+ (make-condition
+ 'download-error :url (concatenate 'string url ".asc")
+ :response response)))
+ (close stream))))
+
+
+
+
+(defun where ()
+ (format t "Install where?~%")
+ (loop for (source system name) in *locations*
+ for i from 1
+ do (format t "~A) ~A: ~% System in ~A~% Files in ~A ~%"
+ i name system source))
+ (format t " --> ") (force-output)
+ (let ((response (read)))
+ (when (> response 0)
+ (elt *locations* (1- response)))))
+
+(defun install (source system packagename)
+ "Returns a list of asdf system names for installed asdf systems"
+ (ensure-directories-exist source )
+ (ensure-directories-exist system )
+ (let* ((tar
+ (with-output-to-string (o)
+ (or
+ (sb-ext:run-program "/bin/tar"
+ (list "-C" (namestring source)
+ "-xzvf" (namestring packagename))
+ :output o
+ :wait t)
+ (error "can't untar"))))
+ (dummy (princ tar))
+ (pos-slash (position #\/ tar))
+ (*default-pathname-defaults*
+ (merge-pathnames
+ (make-pathname :directory
+ `(:relative ,(subseq tar 0 pos-slash)))
+ source)))
+ (loop for asd in (directory
+ (make-pathname :name :wild :type "asd"))
+ do (let ((target (merge-pathnames
+ (make-pathname :name (pathname-name asd)
+ :type (pathname-type asd))
+ system)))
+ (when (probe-file target)
+ (sb-posix:unlink target))
+ (sb-posix:symlink asd target))
+ collect (pathname-name asd))))
+
+(defvar *temporary-files*)
+(defun temp-file-name (p)
+ (let* ((pos-slash (position #\/ p :from-end t))
+ (pos-dot (position #\. p :start (or pos-slash 0))))
+ (merge-pathnames
+ (make-pathname
+ :name (subseq p (if pos-slash (1+ pos-slash) 0) pos-dot)
+ :type "asdf-install-tmp"))))
+
+
+
+(defun run (&optional (packages (cdr *posix-argv*)))
+ (destructuring-bind (source system name) (where)
+ (labels ((one-iter (packages)
+ (dolist (asd
+ (loop for p in packages
+ unless (probe-file p)
+ do (let ((tmp (temp-file-name p)))
+ (pushnew tmp *temporary-files*)
+ (download p tmp)
+ (setf p tmp))
+ end
+ do (format t "Installing ~A in ~A,~A~%" p source system)
+ append (install source system p)))
+ (handler-case
+ (asdf:operate 'asdf:load-op asd)
+ (asdf:missing-dependency (c)
+ (format t "Downloading package ~A, required by ~A~%"
+ (asdf::missing-requires c)
+ (asdf:component-name (asdf::missing-required-by c)))
+ (one-iter (list
+ (symbol-name (asdf::missing-requires c)))))))))
+ (one-iter packages))))
+
+(handler-case
+ (let ((*temporary-files* nil))
+ (unwind-protect
+ (run)
+ (dolist (l *temporary-files*)
+ (when (probe-file l) (delete-file l)))))
+ (error (c)
+ (princ "Install failed due to error:") (terpri)
+ (princ c) (terpri)
+ (quit :unix-status 1)))
+
+;(quit) \ No newline at end of file
diff --git a/Lisp/asdf/asdf.lisp b/Lisp/asdf/asdf.lisp
new file mode 100644
index 0000000..0fd5ca7
--- /dev/null
+++ b/Lisp/asdf/asdf.lisp
@@ -0,0 +1,1104 @@
+;;; This is asdf: Another System Definition Facility. $Revision: 1.1.1.1 $
+;;;
+;;; Feedback, bug reports, and patches are all welcome: please mail to
+;;; <cclan-list@lists.sf.net>. But note first that the canonical
+;;; source for asdf is presently the cCLan CVS repository at
+;;; <URL:http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cclan/asdf/>
+;;;
+;;; If you obtained this copy from anywhere else, and you experience
+;;; trouble using it, or find bugs, you may want to check at the
+;;; location above for a more recent version (and for documentation
+;;; and test files, if your copy came without them) before reporting
+;;; bugs. There are usually two "supported" revisions - the CVS HEAD
+;;; is the latest development version, whereas the revision tagged
+;;; RELEASE may be slightly older but is considered `stable'
+
+;;; Copyright (c) 2001-2003 Daniel Barlow and contributors
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining
+;;; a copy of this software and associated documentation files (the
+;;; "Software"), to deal in the Software without restriction, including
+;;; without limitation the rights to use, copy, modify, merge, publish,
+;;; distribute, sublicense, and/or sell copies of the Software, and to
+;;; permit persons to whom the Software is furnished to do so, subject to
+;;; the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be
+;;; included in all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+;;; LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+;;; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+;;; WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+;;; the problem with writing a defsystem replacement is bootstrapping:
+;;; we can't use defsystem to compile it. Hence, all in one file
+
+(defpackage #:asdf
+ (:export #:defsystem #:oos #:operate #:find-system #:run-shell-command
+ #:system-definition-pathname #:find-component ; miscellaneous
+ #:hyperdocumentation #:hyperdoc
+
+ #:compile-op #:load-op #:load-source-op #:test-system-version
+ #:test-op
+ #:operation ; operations
+ #:feature ; sort-of operation
+ #:version ; metaphorically sort-of an operation
+
+ #:input-files #:output-files #:perform ; operation methods
+ #:operation-done-p #:explain
+
+ #:component #:source-file
+ #:c-source-file #:cl-source-file #:java-source-file
+ #:static-file
+ #:doc-file
+ #:html-file
+ #:text-file
+ #:source-file-type
+ #:module ; components
+ #:system
+ #:unix-dso
+
+ #:module-components ; component accessors
+ #:component-pathname
+ #:component-relative-pathname
+ #:component-name
+ #:component-version
+ #:component-parent
+ #:component-property
+ #:component-system
+
+ #:component-depends-on
+
+ #:system-description
+ #:system-long-description
+ #:system-author
+ #:system-maintainer
+ #:system-license
+
+ #:operation-on-warnings
+ #:operation-on-failure
+
+ ;#:*component-parent-pathname*
+ #:*system-definition-search-functions*
+ #:*central-registry* ; variables
+ #:*compile-file-warnings-behaviour*
+ #:*compile-file-failure-behaviour*
+ #:*asdf-revision*
+
+ #:operation-error #:compile-failed #:compile-warned #:compile-error
+ #:system-definition-error
+ #:missing-component
+ #:missing-dependency
+ #:circular-dependency ; errors
+
+ #:retry
+ #:accept ; restarts
+
+ )
+ (:use :cl))
+
+#+nil
+(error "The author of this file habitually uses #+nil to comment out forms. But don't worry, it was unlikely to work in the New Implementation of Lisp anyway")
+
+
+(in-package #:asdf)
+
+(defvar *asdf-revision* (let* ((v "$Revision: 1.1.1.1 $")
+ (colon (or (position #\: v) -1))
+ (dot (position #\. v)))
+ (and v colon dot
+ (list (parse-integer v :start (1+ colon)
+ :junk-allowed t)
+ (parse-integer v :start (1+ dot)
+ :junk-allowed t)))))
+
+(defvar *compile-file-warnings-behaviour* :warn)
+(defvar *compile-file-failure-behaviour* #+sbcl :error #-sbcl :warn)
+
+(defvar *verbose-out* nil)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; utility stuff
+
+(defmacro aif (test then &optional else)
+ `(let ((it ,test)) (if it ,then ,else)))
+
+(defun pathname-sans-name+type (pathname)
+ "Returns a new pathname with same HOST, DEVICE, DIRECTORY as PATHNAME,
+and NIL NAME and TYPE components"
+ (make-pathname :name nil :type nil :defaults pathname))
+
+(define-modify-macro appendf (&rest args)
+ append "Append onto list")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; classes, condiitons
+
+(define-condition system-definition-error (error) ()
+ ;; [this use of :report should be redundant, but unfortunately it's not.
+ ;; cmucl's lisp::output-instance prefers the kernel:slot-class-print-function
+ ;; over print-object; this is always conditions::%print-condition for
+ ;; condition objects, which in turn does inheritance of :report options at
+ ;; run-time. fortunately, inheritance means we only need this kludge here in
+ ;; order to fix all conditions that build on it. -- rgr, 28-Jul-02.]
+ #+cmu (:report print-object))
+
+(define-condition formatted-system-definition-error (system-definition-error)
+ ((format-control :initarg :format-control :reader format-control)
+ (format-arguments :initarg :format-arguments :reader format-arguments))
+ (:report (lambda (c s)
+ (apply #'format s (format-control c) (format-arguments c)))))
+
+(define-condition circular-dependency (system-definition-error)
+ ((components :initarg :components :reader circular-dependency-components)))
+
+(define-condition missing-component (system-definition-error)
+ ((requires :initform "(unnamed)" :reader missing-requires :initarg :requires)
+ (version :initform nil :reader missing-version :initarg :version)
+ (parent :initform nil :reader missing-parent :initarg :parent)))
+
+(define-condition missing-dependency (missing-component)
+ ((required-by :initarg :required-by :reader missing-required-by)))
+
+(define-condition operation-error (error)
+ ((component :reader error-component :initarg :component)
+ (operation :reader error-operation :initarg :operation))
+ (:report (lambda (c s)
+ (format s (formatter "~@<erred while invoking ~A on ~A~@:>")
+ (error-operation c) (error-component c)))))
+(define-condition compile-error (operation-error) ())
+(define-condition compile-failed (compile-error) ())
+(define-condition compile-warned (compile-error) ())
+
+(defclass component ()
+ ((name :accessor component-name :initarg :name :documentation
+ "Component name: designator for a string composed of portable pathname characters")
+ (version :accessor component-version :initarg :version)
+ (in-order-to :initform nil :initarg :in-order-to)
+ ;;; XXX crap name
+ (do-first :initform nil :initarg :do-first)
+ ;; methods defined using the "inline" style inside a defsystem form:
+ ;; need to store them somewhere so we can delete them when the system
+ ;; is re-evaluated
+ (inline-methods :accessor component-inline-methods :initform nil)
+ (parent :initarg :parent :initform nil :reader component-parent)
+ ;; no direct accessor for pathname, we do this as a method to allow
+ ;; it to default in funky ways if not supplied
+ (relative-pathname :initarg :pathname)
+ (operation-times :initform (make-hash-table )
+ :accessor component-operation-times)
+ ;; XXX we should provide some atomic interface for updating the
+ ;; component properties
+ (properties :accessor component-properties :initarg :properties
+ :initform nil)))
+
+;;;; methods: conditions
+
+(defmethod print-object ((c missing-dependency) s)
+ (format s (formatter "~@<~A, required by ~A~@:>")
+ (call-next-method c nil)
+ (missing-required-by c)))
+
+(defun sysdef-error (format &rest arguments)
+ (error 'formatted-system-definition-error :format-control format :format-arguments arguments))
+
+;;;; methods: components
+
+(defmethod print-object ((c missing-component) s)
+ (format s (formatter "~@<component ~S not found~
+ ~@[ or does not match version ~A~]~
+ ~@[ in ~A~]~@:>")
+ (missing-requires c)
+ (missing-version c)
+ (when (missing-parent c)
+ (component-name (missing-parent c)))))
+
+(defgeneric component-system (component)
+ (:documentation "Find the top-level system containing COMPONENT"))
+
+(defmethod component-system ((component component))
+ (aif (component-parent component)
+ (component-system it)
+ component))
+
+(defmethod print-object ((c component) stream)
+ (print-unreadable-object (c stream :type t :identity t)
+ (ignore-errors
+ (prin1 (component-name c) stream))))
+
+(defclass module (component)
+ ((components :initform nil :accessor module-components :initarg :components)
+ ;; what to do if we can't satisfy a dependency of one of this module's
+ ;; components. This allows a limited form of conditional processing
+ (if-component-dep-fails :initform :fail
+ :accessor module-if-component-dep-fails
+ :initarg :if-component-dep-fails)
+ (default-component-class :accessor module-default-component-class
+ :initform 'cl-source-file :initarg :default-component-class)))
+
+(defgeneric component-pathname (component)
+ (:documentation "Extracts the pathname applicable for a particular component."))
+
+(defun component-parent-pathname (component)
+ (aif (component-parent component)
+ (component-pathname it)
+ *default-pathname-defaults*))
+
+(defgeneric component-relative-pathname (component)
+ (:documentation "Extracts the relative pathname applicable for a particular component."))
+
+(defmethod component-relative-pathname ((component module))
+ (or (slot-value component 'relative-pathname)
+ (make-pathname
+ :directory `(:relative ,(component-name component))
+ :host (pathname-host (component-parent-pathname component)))))
+
+(defmethod component-pathname ((component component))
+ (let ((*default-pathname-defaults* (component-parent-pathname component)))
+ (merge-pathnames (component-relative-pathname component))))
+
+(defgeneric component-property (component property))
+
+(defmethod component-property ((c component) property)
+ (cdr (assoc property (slot-value c 'properties) :test #'equal)))
+
+(defgeneric (setf component-property) (new-value component property))
+
+(defmethod (setf component-property) (new-value (c component) property)
+ (let ((a (assoc property (slot-value c 'properties) :test #'equal)))
+ (if a
+ (setf (cdr a) new-value)
+ (setf (slot-value c 'properties)
+ (acons property new-value (slot-value c 'properties))))))
+
+(defclass system (module)
+ ((description :accessor system-description :initarg :description)
+ (long-description
+ :accessor system-long-description :initarg :long-description)
+ (author :accessor system-author :initarg :author)
+ (maintainer :accessor system-maintainer :initarg :maintainer)
+ (licence :accessor system-licence :initarg :licence)))
+
+;;; version-satisfies
+
+;;; with apologies to christophe rhodes ...
+(defun split (string &optional max (ws '(#\Space #\Tab)))
+ (flet ((is-ws (char) (find char ws)))
+ (nreverse
+ (let ((list nil) (start 0) (words 0) end)
+ (loop
+ (when (and max (>= words (1- max)))
+ (return (cons (subseq string start) list)))
+ (setf end (position-if #'is-ws string :start start))
+ (push (subseq string start end) list)
+ (incf words)
+ (unless end (return list))
+ (setf start (1+ end)))))))
+
+(defgeneric version-satisfies (component version))
+
+(defmethod version-satisfies ((c component) version)
+ (unless (and version (slot-boundp c 'version))
+ (return-from version-satisfies t))
+ (let ((x (mapcar #'parse-integer
+ (split (component-version c) nil '(#\.))))
+ (y (mapcar #'parse-integer
+ (split version nil '(#\.)))))
+ (labels ((bigger (x y)
+ (cond ((not y) t)
+ ((not x) nil)
+ ((> (car x) (car y)) t)
+ ((= (car x) (car y))
+ (bigger (cdr x) (cdr y))))))
+ (and (= (car x) (car y))
+ (or (not (cdr y)) (bigger (cdr x) (cdr y)))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; finding systems
+
+(defvar *defined-systems* (make-hash-table :test 'equal))
+(defun coerce-name (name)
+ (typecase name
+ (component (component-name name))
+ (symbol (string-downcase (symbol-name name)))
+ (string name)
+ (t (sysdef-error (formatter "~@<invalid component designator ~A~@:>")
+ name))))
+
+;;; for the sake of keeping things reasonably neat, we adopt a
+;;; convention that functions in this list are prefixed SYSDEF-
+
+(defvar *system-definition-search-functions*
+ '(sysdef-central-registry-search))
+
+(defun system-definition-pathname (system)
+ (some (lambda (x) (funcall x system))
+ *system-definition-search-functions*))
+
+(defvar *central-registry*
+ '(*default-pathname-defaults*
+ #+nil "/home/dan/src/sourceforge/cclan/asdf/systems/"
+ #+nil "telent:asdf;systems;"))
+
+(defun sysdef-central-registry-search (system)
+ (let ((name (coerce-name system)))
+ (block nil
+ (dolist (dir *central-registry*)
+ (let* ((defaults (eval dir))
+ (file (and defaults
+ (make-pathname
+ :defaults defaults :version :newest
+ :name name :type "asd" :case :local))))
+ (if (and file (probe-file file))
+ (return file)))))))
+
+
+(defun find-system (name &optional (error-p t))
+ (let* ((name (coerce-name name))
+ (in-memory (gethash name *defined-systems*))
+ (on-disk (system-definition-pathname name)))
+ (when (and on-disk
+ (or (not in-memory)
+ (< (car in-memory) (file-write-date on-disk))))
+ (let ((*package* (make-package (gensym (package-name #.*package*))
+ :use '(:cl :asdf))))
+ (format *verbose-out*
+ (formatter "~&~@<; ~@;loading system definition from ~A into ~A~@:>~%")
+ ;; FIXME: This wants to be (ENOUGH-NAMESTRING
+ ;; ON-DISK), but CMUCL barfs on that.
+ on-disk
+ *package*)
+ (load on-disk)))
+ (let ((in-memory (gethash name *defined-systems*)))
+ (if in-memory
+ (progn (if on-disk (setf (car in-memory) (file-write-date on-disk)))
+ (cdr in-memory))
+ (if error-p (error 'missing-component :requires name))))))
+
+(defun register-system (name system)
+ (format *verbose-out*
+ (formatter "~&~@<; ~@;registering ~A as ~A~@:>~%") system name)
+ (setf (gethash (coerce-name name) *defined-systems*)
+ (cons (get-universal-time) system)))
+
+(defun system-registered-p (name)
+ (gethash (coerce-name name) *defined-systems*))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; finding components
+
+(defgeneric find-component (module name &optional version)
+ (:documentation "Finds the component with name NAME present in the
+MODULE module; if MODULE is nil, then the component is assumed to be a
+system."))
+
+(defmethod find-component ((module module) name &optional version)
+ (if (slot-boundp module 'components)
+ (let ((m (find name (module-components module)
+ :test #'equal :key #'component-name)))
+ (if (and m (version-satisfies m version)) m))))
+
+
+;;; a component with no parent is a system
+(defmethod find-component ((module (eql nil)) name &optional version)
+ (let ((m (find-system name nil)))
+ (if (and m (version-satisfies m version)) m)))
+
+;;; component subclasses
+
+(defclass source-file (component) ())
+
+(defclass cl-source-file (source-file) ())
+(defclass c-source-file (source-file) ())
+(defclass java-source-file (source-file) ())
+(defclass static-file (source-file) ())
+(defclass doc-file (static-file) ())
+(defclass html-file (doc-file) ())
+
+(defgeneric source-file-type (component system))
+(defmethod source-file-type ((c cl-source-file) (s module)) "lisp")
+(defmethod source-file-type ((c c-source-file) (s module)) "c")
+(defmethod source-file-type ((c java-source-file) (s module)) "java")
+(defmethod source-file-type ((c html-file) (s module)) "html")
+(defmethod source-file-type ((c static-file) (s module)) nil)
+
+(defmethod component-relative-pathname ((component source-file))
+ (let* ((*default-pathname-defaults* (component-parent-pathname component))
+ (name-type
+ (make-pathname
+ :name (component-name component)
+ :type (source-file-type component
+ (component-system component)))))
+ (if (slot-value component 'relative-pathname)
+ (merge-pathnames
+ (slot-value component 'relative-pathname)
+ name-type)
+ name-type)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; operations
+
+;;; one of these is instantiated whenever (operate ) is called
+
+(defclass operation ()
+ ((forced :initform nil :initarg :force :accessor operation-forced)
+ (original-initargs :initform nil :initarg :original-initargs
+ :accessor operation-original-initargs)
+ (visited-nodes :initform nil :accessor operation-visited-nodes)
+ (visiting-nodes :initform nil :accessor operation-visiting-nodes)
+ (parent :initform nil :initarg :parent :accessor operation-parent)))
+
+(defmethod print-object ((o operation) stream)
+ (print-unreadable-object (o stream :type t :identity t)
+ (ignore-errors
+ (prin1 (operation-original-initargs o) stream))))
+
+(defmethod shared-initialize :after ((operation operation) slot-names
+ &key force
+ &allow-other-keys)
+ (declare (ignore slot-names force))
+ ;; empty method to disable initarg validity checking
+ )
+
+(defgeneric perform (operation component))
+(defgeneric operation-done-p (operation component))
+(defgeneric explain (operation component))
+(defgeneric output-files (operation component))
+(defgeneric input-files (operation component))
+
+(defun node-for (o c)
+ (cons (class-name (class-of o)) c))
+
+(defgeneric operation-ancestor (operation)
+ (:documentation "Recursively chase the operation's parent pointer until we get to the head of the tree"))
+
+(defmethod operation-ancestor ((operation operation))
+ (aif (operation-parent operation)
+ (operation-ancestor it)
+ operation))
+
+
+(defun make-sub-operation (c o dep-c dep-o)
+ (let* ((args (copy-list (operation-original-initargs o)))
+ (force-p (getf args :force)))
+ ;; note explicit comparison with T: any other non-NIL force value
+ ;; (e.g. :recursive) will pass through
+ (cond ((and (null (component-parent c))
+ (null (component-parent dep-c))
+ (not (eql c dep-c)))
+ (when (eql force-p t)
+ (setf (getf args :force) nil))
+ (apply #'make-instance dep-o
+ :parent o
+ :original-initargs args args))
+ ((subtypep (type-of o) dep-o)
+ o)
+ (t
+ (apply #'make-instance dep-o
+ :parent o :original-initargs args args)))))
+
+
+(defgeneric visit-component (operation component data))
+
+(defmethod visit-component ((o operation) (c component) data)
+ (unless (component-visited-p o c)
+ (push (cons (node-for o c) data)
+ (operation-visited-nodes (operation-ancestor o)))))
+
+(defgeneric component-visited-p (operation component))
+
+(defmethod component-visited-p ((o operation) (c component))
+ (assoc (node-for o c)
+ (operation-visited-nodes (operation-ancestor o))
+ :test 'equal))
+
+(defgeneric (setf visiting-component) (new-value operation component))
+
+(defmethod (setf visiting-component) (new-value operation component)
+ ;; MCL complains about unused lexical variables
+ (declare (ignorable new-value operation component)))
+
+(defmethod (setf visiting-component) (new-value (o operation) (c component))
+ (let ((node (node-for o c))
+ (a (operation-ancestor o)))
+ (if new-value
+ (pushnew node (operation-visiting-nodes a) :test 'equal)
+ (setf (operation-visiting-nodes a)
+ (remove node (operation-visiting-nodes a) :test 'equal)))))
+
+(defgeneric component-visiting-p (operation component))
+
+(defmethod component-visiting-p ((o operation) (c component))
+ (let ((node (cons o c)))
+ (member node (operation-visiting-nodes (operation-ancestor o))
+ :test 'equal)))
+
+(defgeneric component-depends-on (operation component))
+
+(defmethod component-depends-on ((o operation) (c component))
+ (cdr (assoc (class-name (class-of o))
+ (slot-value c 'in-order-to))))
+
+(defgeneric component-self-dependencies (operation component))
+
+(defmethod component-self-dependencies ((o operation) (c component))
+ (let ((all-deps (component-depends-on o c)))
+ (remove-if-not (lambda (x)
+ (member (component-name c) (cdr x) :test #'string=))
+ all-deps)))
+
+(defmethod input-files ((operation operation) (c component))
+ (let ((parent (component-parent c))
+ (self-deps (component-self-dependencies operation c)))
+ (if self-deps
+ (mapcan (lambda (dep)
+ (destructuring-bind (op name) dep
+ (output-files (make-instance op)
+ (find-component parent name))))
+ self-deps)
+ ;; no previous operations needed? I guess we work with the
+ ;; original source file, then
+ (list (component-pathname c)))))
+
+(defmethod input-files ((operation operation) (c module)) nil)
+
+(defmethod operation-done-p ((o operation) (c component))
+ (let ((out-files (output-files o c))
+ (in-files (input-files o c)))
+ (cond ((and (not in-files) (not out-files))
+ ;; arbitrary decision: an operation that uses nothing to
+ ;; produce nothing probably isn't doing much
+ t)
+ ((not out-files)
+ (let ((op-done
+ (gethash (type-of o)
+ (component-operation-times c))))
+ (and op-done
+ (>= op-done
+ (or (apply #'max
+ (mapcar #'file-write-date in-files)) 0)))))
+ ((not in-files) nil)
+ (t
+ (and
+ (every #'probe-file out-files)
+ (> (apply #'min (mapcar #'file-write-date out-files))
+ (apply #'max (mapcar #'file-write-date in-files)) ))))))
+
+;;; So you look at this code and think "why isn't it a bunch of
+;;; methods". And the answer is, because standard method combination
+;;; runs :before methods most->least-specific, which is back to front
+;;; for our purposes. And CLISP doesn't have non-standard method
+;;; combinations, so let's keep it simple and aspire to portability
+
+(defgeneric traverse (operation component))
+(defmethod traverse ((operation operation) (c component))
+ (let ((forced nil))
+ (labels ((do-one-dep (required-op required-c required-v)
+ (let* ((dep-c (or (find-component
+ (component-parent c)
+ ;; XXX tacky. really we should build the
+ ;; in-order-to slot with canonicalized
+ ;; names instead of coercing this late
+ (coerce-name required-c) required-v)
+ (error 'missing-dependency :required-by c
+ :version required-v
+ :requires required-c)))
+ (op (make-sub-operation c operation dep-c required-op)))
+ (traverse op dep-c)))
+ (do-dep (op dep)
+ (cond ((eq op 'feature)
+ (or (member (car dep) *features*)
+ (error 'missing-dependency :required-by c
+ :requires (car dep) :version nil)))
+ (t
+ (dolist (d dep)
+ (cond ((consp d)
+ (assert (string-equal
+ (symbol-name (first d))
+ "VERSION"))
+ (appendf forced
+ (do-one-dep op (second d) (third d))))
+ (t
+ (appendf forced (do-one-dep op d nil)))))))))
+ (aif (component-visited-p operation c)
+ (return-from traverse
+ (if (cdr it) (list (cons 'pruned-op c)) nil)))
+ ;; dependencies
+ (if (component-visiting-p operation c)
+ (error 'circular-dependency :components (list c)))
+ (setf (visiting-component operation c) t)
+ (loop for (required-op . deps) in (component-depends-on operation c)
+ do (do-dep required-op deps))
+ ;; constituent bits
+ (let ((module-ops
+ (when (typep c 'module)
+ (let ((at-least-one nil)
+ (forced nil)
+ (error nil))
+ (loop for kid in (module-components c)
+ do (handler-case
+ (appendf forced (traverse operation kid ))
+ (missing-dependency (condition)
+ (if (eq (module-if-component-dep-fails c) :fail)
+ (error condition))
+ (setf error condition))
+ (:no-error (c)
+ (declare (ignore c))
+ (setf at-least-one t))))
+ (when (and (eq (module-if-component-dep-fails c) :try-next)
+ (not at-least-one))
+ (error error))
+ forced))))
+ ;; now the thing itself
+ (when (or forced module-ops
+ (not (operation-done-p operation c))
+ (let ((f (operation-forced (operation-ancestor operation))))
+ (and f (or (not (consp f))
+ (member (component-name
+ (operation-ancestor operation))
+ (mapcar #'coerce-name f)
+ :test #'string=)))))
+ (let ((do-first (cdr (assoc (class-name (class-of operation))
+ (slot-value c 'do-first)))))
+ (loop for (required-op . deps) in do-first
+ do (do-dep required-op deps)))
+ (setf forced (append (delete 'pruned-op forced :key #'car)
+ (delete 'pruned-op module-ops :key #'car)
+ (list (cons operation c))))))
+ (setf (visiting-component operation c) nil)
+ (visit-component operation c (and forced t))
+ forced)))
+
+
+(defmethod perform ((operation operation) (c source-file))
+ (sysdef-error
+ (formatter "~@<required method PERFORM not implemented~
+ for operation ~A, component ~A~@:>")
+ (class-of operation) (class-of c)))
+
+(defmethod perform ((operation operation) (c module))
+ nil)
+
+(defmethod explain ((operation operation) (component component))
+ (format *verbose-out* "~&;;; ~A on ~A~%"
+ operation component))
+
+;;; compile-op
+
+(defclass compile-op (operation)
+ ((proclamations :initarg :proclamations :accessor compile-op-proclamations :initform nil)
+ (on-warnings :initarg :on-warnings :accessor operation-on-warnings
+ :initform *compile-file-warnings-behaviour*)
+ (on-failure :initarg :on-failure :accessor operation-on-failure
+ :initform *compile-file-failure-behaviour*)))
+
+(defmethod perform :before ((operation compile-op) (c source-file))
+ (map nil #'ensure-directories-exist (output-files operation c)))
+
+(defmethod perform :after ((operation operation) (c component))
+ (setf (gethash (type-of operation) (component-operation-times c))
+ (get-universal-time)))
+
+;;; perform is required to check output-files to find out where to put
+;;; its answers, in case it has been overridden for site policy
+(defmethod perform ((operation compile-op) (c cl-source-file))
+ (let ((source-file (component-pathname c))
+ (output-file (car (output-files operation c))))
+ (multiple-value-bind (output warnings-p failure-p)
+ (compile-file source-file
+ :output-file output-file)
+ ;(declare (ignore output))
+ (when warnings-p
+ (case (operation-on-warnings operation)
+ (:warn (warn
+ (formatter "~@<COMPILE-FILE warned while ~
+ performing ~A on ~A.~@:>")
+ operation c))
+ (:error (error 'compile-warned :component c :operation operation))
+ (:ignore nil)))
+ (when failure-p
+ (case (operation-on-failure operation)
+ (:warn (warn
+ (formatter "~@<COMPILE-FILE failed while ~
+ performing ~A on ~A.~@:>")
+ operation c))
+ (:error (error 'compile-failed :component c :operation operation))
+ (:ignore nil)))
+ (unless output
+ (error 'compile-error :component c :operation operation)))))
+
+(defmethod output-files ((operation compile-op) (c cl-source-file))
+ (list (compile-file-pathname (component-pathname c))))
+
+(defmethod perform ((operation compile-op) (c static-file))
+ nil)
+
+(defmethod output-files ((operation compile-op) (c static-file))
+ nil)
+
+;;; load-op
+
+(defclass load-op (operation) ())
+
+(defmethod perform ((o load-op) (c cl-source-file))
+ (mapcar #'load (input-files o c)))
+
+(defmethod perform ((operation load-op) (c static-file))
+ nil)
+(defmethod operation-done-p ((operation load-op) (c static-file))
+ t)
+
+(defmethod output-files ((o operation) (c component))
+ nil)
+
+(defmethod component-depends-on ((operation load-op) (c component))
+ (cons (list 'compile-op (component-name c))
+ (call-next-method)))
+
+;;; load-source-op
+
+(defclass load-source-op (operation) ())
+
+(defmethod perform ((o load-source-op) (c cl-source-file))
+ (let ((source (component-pathname c)))
+ (setf (component-property c 'last-loaded-as-source)
+ (and (load source)
+ (get-universal-time)))))
+
+(defmethod perform ((operation load-source-op) (c static-file))
+ nil)
+
+(defmethod output-files ((operation load-source-op) (c component))
+ nil)
+
+;;; FIXME: we simply copy load-op's dependencies. this is Just Not Right.
+(defmethod component-depends-on ((o load-source-op) (c component))
+ (let ((what-would-load-op-do (cdr (assoc 'load-op
+ (slot-value c 'in-order-to)))))
+ (mapcar (lambda (dep)
+ (if (eq (car dep) 'load-op)
+ (cons 'load-source-op (cdr dep))
+ dep))
+ what-would-load-op-do)))
+
+(defmethod operation-done-p ((o load-source-op) (c source-file))
+ (if (or (not (component-property c 'last-loaded-as-source))
+ (> (file-write-date (component-pathname c))
+ (component-property c 'last-loaded-as-source)))
+ nil t))
+
+(defclass test-op (operation) ())
+
+(defmethod perform ((operation test-op) (c component))
+ nil)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; invoking operations
+
+(defun operate (operation-class system &rest args)
+ (let* ((op (apply #'make-instance operation-class
+ :original-initargs args args))
+ (*verbose-out*
+ (if (getf args :verbose t)
+ *trace-output*
+ (make-broadcast-stream)))
+ (system (if (typep system 'component) system (find-system system)))
+ (steps (traverse op system)))
+ (with-compilation-unit ()
+ (loop for (op . component) in steps do
+ (loop
+ (restart-case
+ (progn (perform op component)
+ (return))
+ (retry ()
+ :report
+ (lambda (s)
+ (format s
+ (formatter "~@<Retry performing ~S on ~S.~@:>")
+ op component)))
+ (accept ()
+ :report
+ (lambda (s)
+ (format s
+ (formatter "~@<Continue, treating ~S on ~S as ~
+ having been successful.~@:>")
+ op component))
+ (setf (gethash (type-of op)
+ (component-operation-times component))
+ (get-universal-time))
+ (return))))))))
+
+(defun oos (&rest args)
+ "Alias of OPERATE function"
+ (apply #'operate args))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; syntax
+
+(defun remove-keyword (key arglist)
+ (labels ((aux (key arglist)
+ (cond ((null arglist) nil)
+ ((eq key (car arglist)) (cddr arglist))
+ (t (cons (car arglist) (cons (cadr arglist)
+ (remove-keyword
+ key (cddr arglist))))))))
+ (aux key arglist)))
+
+(defmacro defsystem (name &body options)
+ (destructuring-bind (&key pathname (class 'system) &allow-other-keys) options
+ (let ((component-options (remove-keyword :class options)))
+ `(progn
+ ;; system must be registered before we parse the body, otherwise
+ ;; we recur when trying to find an existing system of the same name
+ ;; to reuse options (e.g. pathname) from
+ (let ((s (system-registered-p ',name)))
+ (cond ((and s (eq (type-of (cdr s)) ',class))
+ (setf (car s) (get-universal-time)))
+ (s
+ #+clisp
+ (sysdef-error "Cannot redefine the existing system ~A with a different class" s)
+ #-clisp
+ (change-class (cdr s) ',class))
+ (t
+ (register-system (quote ,name)
+ (make-instance ',class :name ',name)))))
+ (parse-component-form nil (apply
+ #'list
+ :module (coerce-name ',name)
+ :pathname
+ (or ,pathname
+ (pathname-sans-name+type
+ (resolve-symlinks *load-truename*))
+ *default-pathname-defaults*)
+ ',component-options))))))
+
+
+(defun class-for-type (parent type)
+ (let ((class (find-class
+ (or (find-symbol (symbol-name type) *package*)
+ (find-symbol (symbol-name type) #.*package*)) nil)))
+ (or class
+ (and (eq type :file)
+ (or (module-default-component-class parent)
+ (find-class 'cl-source-file)))
+ (sysdef-error (formatter "~@<don't recognize component type ~A~@:>")
+ type))))
+
+(defun maybe-add-tree (tree op1 op2 c)
+ "Add the node C at /OP1/OP2 in TREE, unless it's there already.
+Returns the new tree (which probably shares structure with the old one)"
+ (let ((first-op-tree (assoc op1 tree)))
+ (if first-op-tree
+ (progn
+ (aif (assoc op2 (cdr first-op-tree))
+ (if (find c (cdr it))
+ nil
+ (setf (cdr it) (cons c (cdr it))))
+ (setf (cdr first-op-tree)
+ (acons op2 (list c) (cdr first-op-tree))))
+ tree)
+ (acons op1 (list (list op2 c)) tree))))
+
+(defun union-of-dependencies (&rest deps)
+ (let ((new-tree nil))
+ (dolist (dep deps)
+ (dolist (op-tree dep)
+ (dolist (op (cdr op-tree))
+ (dolist (c (cdr op))
+ (setf new-tree
+ (maybe-add-tree new-tree (car op-tree) (car op) c))))))
+ new-tree))
+
+
+(defun remove-keys (key-names args)
+ (loop for ( name val ) on args by #'cddr
+ unless (member (symbol-name name) key-names
+ :key #'symbol-name :test 'equal)
+ append (list name val)))
+
+(defvar *serial-depends-on*)
+
+(defun parse-component-form (parent options)
+ (destructuring-bind
+ (type name &rest rest &key
+ ;; the following list of keywords is reproduced below in the
+ ;; remove-keys form. important to keep them in sync
+ components pathname default-component-class
+ perform explain output-files operation-done-p
+ depends-on serial in-order-to
+ ;; list ends
+ &allow-other-keys) options
+ (check-component-input type name depends-on components in-order-to)
+ (let* ((other-args (remove-keys
+ '(components pathname default-component-class
+ perform explain output-files operation-done-p
+ depends-on serial in-order-to)
+ rest))
+ (ret
+ (or (find-component parent name)
+ (make-instance (class-for-type parent type)))))
+ (when (boundp '*serial-depends-on*)
+ (setf depends-on
+ (concatenate 'list *serial-depends-on* depends-on)))
+ (apply #'reinitialize-instance
+ ret
+ :name (coerce-name name)
+ :pathname pathname
+ :parent parent
+ other-args)
+ (when (typep ret 'module)
+ (setf (module-default-component-class ret)
+ (or default-component-class
+ (and (typep parent 'module)
+ (module-default-component-class parent))))
+ (let ((*serial-depends-on* nil))
+ (setf (module-components ret)
+ (loop for c-form in components
+ for c = (parse-component-form ret c-form)
+ collect c
+ if serial
+ do (push (component-name c) *serial-depends-on*)))))
+
+ (setf (slot-value ret 'in-order-to)
+ (union-of-dependencies
+ in-order-to
+ `((compile-op (compile-op ,@depends-on))
+ (load-op (load-op ,@depends-on))))
+ (slot-value ret 'do-first) `((compile-op (load-op ,@depends-on))))
+
+ (loop for (n v) in `((perform ,perform) (explain ,explain)
+ (output-files ,output-files)
+ (operation-done-p ,operation-done-p))
+ do (map 'nil
+ ;; this is inefficient as most of the stored
+ ;; methods will not be for this particular gf n
+ ;; But this is hardly performance-critical
+ (lambda (m) (remove-method (symbol-function n) m))
+ (component-inline-methods ret))
+ when v
+ do (destructuring-bind (op qual (o c) &body body) v
+ (pushnew
+ (eval `(defmethod ,n ,qual ((,o ,op) (,c (eql ,ret)))
+ ,@body))
+ (component-inline-methods ret))))
+ ret)))
+
+(defun check-component-input (type name depends-on components in-order-to)
+ "A partial test of the values of a component."
+ (unless (listp depends-on)
+ (sysdef-error-component ":depends-on must be a list."
+ type name depends-on))
+ (unless (listp components)
+ (sysdef-error-component ":components must be NIL or a list of components."
+ type name components))
+ (unless (and (listp in-order-to) (listp (car in-order-to)))
+ (sysdef-error-component ":in-order-to must be NIL or a list of components."
+ type name in-order-to)))
+
+(defun sysdef-error-component (msg type name value)
+ (sysdef-error (concatenate 'string msg
+ "~&The value specified for ~(~A~) ~A is ~W")
+ type name value))
+
+(defun resolve-symlinks (path)
+ #-allegro (truename path)
+ #+allegro (excl:pathname-resolve-symbolic-links path)
+ )
+
+;;; optional extras
+
+;;; run-shell-command functions for other lisp implementations will be
+;;; gratefully accepted, if they do the same thing. If the docstring
+;;; is ambiguous, send a bug report
+
+(defun run-shell-command (control-string &rest args)
+ "Interpolate ARGS into CONTROL-STRING as if by FORMAT, and
+synchronously execute the result using a Bourne-compatible shell, with
+output to *verbose-out*. Returns the shell's exit code."
+ (let ((command (apply #'format nil control-string args)))
+ (format *verbose-out* "; $ ~A~%" command)
+ #+sbcl
+ (sb-impl::process-exit-code
+ (sb-ext:run-program
+ "/bin/sh"
+ (list "-c" command)
+ :input nil :output *verbose-out*))
+
+ #+(or cmu scl)
+ (ext:process-exit-code
+ (ext:run-program
+ "/bin/sh"
+ (list "-c" command)
+ :input nil :output *verbose-out*))
+
+ #+allegro
+ (excl:run-shell-command command :input nil :output *verbose-out*)
+
+ #+lispworks
+ (system:call-system-showing-output
+ command
+ :shell-type "/bin/sh"
+ :output-stream *verbose-out*)
+
+ #+clisp ;XXX not exactly *verbose-out*, I know
+ (ext:run-shell-command command :output :terminal :wait t)
+
+ #+openmcl
+ (nth-value 1
+ (ccl:external-process-status
+ (ccl:run-program "/bin/sh" (list "-c" command)
+ :input nil :output *verbose-out*
+ :wait t)))
+
+ #-(or openmcl clisp lispworks allegro scl cmu sbcl)
+ (error "RUN-SHELL-PROGRAM not implemented for this Lisp")
+ ))
+
+
+(defgeneric hyperdocumentation (package name doc-type))
+(defmethod hyperdocumentation ((package symbol) name doc-type)
+ (hyperdocumentation (find-package package) name doc-type))
+
+(defun hyperdoc (name doc-type)
+ (hyperdocumentation (symbol-package name) name doc-type))
+
+
+(pushnew :asdf *features*)
+
+#+sbcl
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (when (sb-ext:posix-getenv "SBCL_BUILDING_CONTRIB")
+ (pushnew :sbcl-hooks-require *features*)))
+
+#+(and sbcl sbcl-hooks-require)
+(progn
+ (defun module-provide-asdf (name)
+ (handler-bind ((style-warning #'muffle-warning))
+ (let* ((*verbose-out* (make-broadcast-stream))
+ (system (asdf:find-system name nil)))
+ (when system
+ (asdf:operate 'asdf:load-op name)
+ t))))
+
+ (pushnew
+ '(merge-pathnames "systems/"
+ (truename (sb-ext:posix-getenv "SBCL_HOME")))
+ *central-registry*)
+
+ (pushnew
+ '(merge-pathnames "site-systems/"
+ (truename (sb-ext:posix-getenv "SBCL_HOME")))
+ *central-registry*)
+
+ (pushnew
+ '(merge-pathnames ".sbcl/systems/"
+ (user-homedir-pathname))
+ *central-registry*)
+
+ (pushnew 'module-provide-asdf sb-ext:*module-provider-functions*))
+
+(provide 'asdf)
diff --git a/Lisp/asdf/asdf.texinfo b/Lisp/asdf/asdf.texinfo
new file mode 100644
index 0000000..e62e2aa
--- /dev/null
+++ b/Lisp/asdf/asdf.texinfo
@@ -0,0 +1,1220 @@
+\input texinfo @c -*- texinfo -*-
+@c %**start of header
+@setfilename asdf.texinfo
+@settitle asdf Manual
+@c %**end of header
+
+@copying
+This manual describes asdf, a system definition facility for Common
+Lisp programs and libraries.
+
+asdf Copyright @copyright{} 2001-2004 Daniel Barlow and contributors
+
+This manual Copyright @copyright{} 2001-2004 Daniel Barlow and
+contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+@end copying
+
+
+
+@titlepage
+@title asdf: another system definition facility
+
+@c The following two commands start the copyright page.
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@c Output the table of contents at the beginning.
+@contents
+
+@c -------------------
+
+@ifnottex
+
+@node Top, Using asdf to load systems, (dir), (dir)
+@top asdf: another system definition facility
+
+@insertcopying
+
+@menu
+* Using asdf to load systems::
+* Defining systems with defsystem::
+* The object model of asdf::
+* Error handling::
+* Compilation error and warning handling::
+* Getting the latest version::
+* TODO list::
+* missing bits in implementation::
+* Inspiration::
+* Concept Index::
+* Function and Class Index::
+* Variable Index::
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Defining systems with defsystem
+
+* The defsystem form::
+* A more involved example::
+* The defsystem grammar::
+
+The object model of asdf
+
+* Operations::
+* Components::
+
+Operations
+
+* Predefined operations of asdf::
+* Creating new operations::
+
+Components
+
+* Common attributes of components::
+* Pre-defined subclasses of component::
+* Creating new component types::
+
+properties
+
+* Pre-defined subclasses of component::
+* Creating new component types::
+
+@end detailmenu
+@end menu
+
+@end ifnottex
+
+@c -------------------
+
+
+@node Using asdf to load systems, Defining systems with defsystem, Top, Top
+@comment node-name, next, previous, up
+@chapter Using asdf to load systems
+@cindex system directory designator
+@vindex *central-registry*
+
+This chapter describes how to use asdf to compile and load ready-made
+Lisp programs and libraries.
+
+@section Downloading asdf
+
+Some Lisp implementations (such as SBCL and OpenMCL) some with asdf
+included already, so there is no need to download it separately.
+Consult your Lisp system's documentation. If you need to download
+asdf and install it by hand, the canonical source is the cCLan CVS
+repository at
+@url{http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cclan/asdf/}.
+
+@section Setting up asdf
+
+The single file @file{asdf.lisp} is all you need to use asdf normally.
+Once you load it in a running Lisp, you're ready to use asdf. For
+maximum convenience you might want to have asdf loaded whenever you
+start your Lisp implementation, for example by loading it from the
+startup script or dumping a custom core -- check your Lisp
+implementation's manual for details.
+
+The variable @code{asdf:*central-registry*} is a list of ``system
+directory designators''@footnote{When we say ``directory'' here, we mean
+``designator for a pathname with a supplied DIRECTORY component''.}.
+A @dfn{system directory designator} is a form which will be evaluated
+whenever a system is to be found, and must evaluate to a directory to
+look in. You might want to set @code{*central-registry*} in your Lisp
+init file, for example:
+
+@lisp
+(setf asdf:*central-registry*
+ '(*default-pathname-defaults*
+ #p"/home/me/cl/systems/"
+ #p"/usr/share/common-lisp/systems/"))
+@end lisp
+
+@section Setting up a system to be loaded
+
+To compile and load a system, you need to ensure that a symbolic link to its
+system definition is in one of the directories in
+@code{*central-registry*}@footnote{It is possible to customize the
+system definition file search. That's considered advanced use, and
+covered later: search forward for
+@code{*system-definition-search-functions*}. @xref{Defining systems
+with defsystem}.}.
+
+For example, if @code{#p"/home/me/cl/systems/"} (note the trailing
+slash) is a member of @code{*central-registry*}, you would set up a
+system @var{foo} that is stored in a directory
+@file{/home/me/src/foo/} for loading with asdf with the following
+commands at the shell (this has to be done only once):
+
+@example
+$ cd /home/me/cl/systems/
+$ ln -s ~/src/foo/foo.asd .
+@end example
+
+@section Loading a system
+
+The system @var{foo} is loaded (and compiled, if necessary) by
+evaluating the following form in your Lisp implementation:
+
+@example
+(asdf:operate 'asdf:load-op '@var{foo})
+@end example
+
+That's all you need to know to use asdf to load systems written by
+others. The rest of this manual deals with writing system
+definitions for Lisp software you write yourself.
+
+@node Defining systems with defsystem, The object model of asdf, Using asdf to load systems, Top
+@comment node-name, next, previous, up
+@chapter Defining systems with defsystem
+
+This chapter describes how to use asdf to define systems and develop
+software.
+
+
+@menu
+* The defsystem form::
+* A more involved example::
+* The defsystem grammar::
+@end menu
+
+@node The defsystem form, A more involved example, Defining systems with defsystem, Defining systems with defsystem
+@comment node-name, next, previous, up
+@section The defsystem form
+
+Systems can be constructed programmatically by instantiating
+components using make-instance. Most of the time, however, it is much
+more practical to use a static @code{defsystem} form. This section
+begins with an example of a system definition, then gives the full
+grammar of @code{defsystem}.
+
+Let's look at a simple system. This is a complete file that would
+usually be saved as @file{hello-lisp.asd}:
+
+@lisp
+(defpackage hello-lisp-system
+ (:use :common-lisp :asdf))
+
+(in-package :hello-lisp-system)
+
+(defsystem "hello-lisp"
+ :description "hello-lisp: a sample Lisp system."
+ :version "0.2"
+ :author "Joe User <joe@@example.com>"
+ :licence "Public Domain"
+ :components ((:file "packages")
+ (:file "macros" :depends-on ("packages"))
+ (:file "hello" :depends-on ("macros"))))
+@end lisp
+
+Some notes about this example:
+
+@itemize
+
+@item
+The file starts with @code{defpackage} and @code{in-package} forms to
+make and use a package expressly for defining this system in. This
+package is named by taking the system name and suffixing
+@code{-system} - note that it is @emph{not} the same package as you
+will use for the application code.
+
+This is not absolutely required by asdf, but helps avoid namespace
+pollution and so is considered good form.
+
+@item
+The defsystem form defines a system named "hello-lisp" that contains
+three source files: @file{packages}, @file{macros} and @file{hello}.
+
+@item
+The file @file{macros} depends on @file{packages} (presumably because
+the package it's in is defined in @file{packages}), and the file
+@file{hello} depends on @file{macros} (and hence, transitively on
+@file{packages}). This means that asdf will compile and load
+@file{packages} and @file{macros} before starting the compilation of
+file @file{hello}.
+
+
+@item
+The files are located in the same directory as the file with the
+system definition. asdf resolves symbolic links before loading the system
+definition file and stores its location in the resulting
+system@footnote{It is possible, though almost never necessary, to
+override this behaviour.}. This is a good thing because the user can
+move the system sources without having to edit the system definition.
+
+@end itemize
+
+@node A more involved example, The defsystem grammar, The defsystem form, Defining systems with defsystem
+@comment node-name, next, previous, up
+@section A more involved example
+
+Let's illustrate some more involved uses of @code{defsystem} via a
+slightly convoluted example:
+
+@lisp
+(defsystem "foo"
+ :version "1.0"
+ :components ((:module "foo" :components ((:file "bar") (:file"baz")
+ (:file "quux"))
+ :perform (compile-op :after (op c)
+ (do-something c))
+ :explain (compile-op :after (op c)
+ (explain-something c)))
+ (:file "blah")))
+@end lisp
+
+The method-form tokens need explaining: essentially, this part:
+
+@lisp
+ :perform (compile-op :after (op c)
+ (do-something c))
+ :explain (compile-op :after (op c)
+ (explain-something c))
+@end lisp
+
+has the effect of
+
+@lisp
+(defmethod perform :after ((op compile-op) (c (eql ...)))
+ (do-something c))
+(defmethod explain :after ((op compile-op) (c (eql ...)))
+ (explain-something c))
+@end lisp
+
+where @code{...} is the component in question; note that although this
+also supports @code{:before} methods, they may not do what you want
+them to -- a @code{:before} method on perform @code{((op compile-op) (c
+(eql ...)))} will run after all the dependencies and sub-components
+have been processed, but before the component in question has been
+compiled.
+
+@node The defsystem grammar, , A more involved example, Defining systems with defsystem
+@comment node-name, next, previous, up
+@section The defsystem grammar
+
+@verbatim
+system-definition := ( defsystem system-designator {option}* )
+
+option := :components component-list
+ | :pathname pathname
+ | :default-component-class
+ | :perform method-form
+ | :explain method-form
+ | :output-files method-form
+ | :operation-done-p method-form
+ | :depends-on ( {simple-component-name}* )
+ | :serial [ t | nil ]
+ | :in-order-to ( {dependency}+ )
+
+component-list := ( {component-def}* )
+
+component-def := simple-component-name
+ | ( component-type name {option}* )
+
+component-type := :module | :file | :system | other-component-type
+
+dependency := (dependent-op {requirement}+)
+requirement := (required-op {required-component}+)
+ | (feature feature-name)
+dependent-op := operation-name
+required-op := operation-name | feature
+@end verbatim
+
+@subsection Serial dependencies
+
+If the @code{:serial t} option is specified for a module, asdf will add
+dependencies for each each child component, on all the children
+textually preceding it. This is done as if by @code{:depends-on}.
+
+@lisp
+:components ((:file "a") (:file "b") (:file "c"))
+:serial t
+@end lisp
+
+is equivalent to
+
+@lisp
+:components ((:file "a")
+ (:file "b" :depends-on ("a"))
+ (:file "c" :depends-on ("a" "b")))
+@end lisp
+
+
+@subsection Source location
+
+The @code{:pathname} option is optional in all cases for systems
+defined via @code{defsystem}, and in the usual case the user is
+recommended not to supply it.
+
+Instead, asdf follows a hairy set of rules that are designed so that
+@enumerate
+@item @code{find-system} will load a system from disk and have its pathname
+default to the right place
+@item this pathname information will not be
+overwritten with @code{*default-pathname-defaults*} (which could be
+somewhere else altogether) if the user loads up the @file{.asd} file
+into his editor and interactively re-evaluates that form.
+@end enumerate
+
+If a system is being loaded for the first time, its top-level pathname
+will be set to:
+
+@itemize
+@item The host/device/directory parts of @code{*load-truename*}, if it is bound
+@item @code{*default-pathname-defaults*}, otherwise
+@end itemize
+
+If a system is being redefined, the top-level pathname will be
+
+@itemize
+@item
+changed, if explicitly supplied or obtained from
+@code{*load-truename*} (so that an updated source location is
+reflected in the system definition)
+@item
+changed if it had previously been set from
+@code{*default-pathname-defaults*}
+@item
+left as before, if it had previously been set from
+@code{*load-truename*} and @code{*load-truename*} is currently
+unbound (so that a developer can evaluate a @code{defsystem} form from
+within an editor without clobbering its source location)
+@end itemize
+
+
+
+@node The object model of asdf, Error handling, Defining systems with defsystem, Top
+@comment node-name, next, previous, up
+@chapter The object model of asdf
+
+asdf is designed in an object-oriented way from the ground up. Both a
+system's structure and the operations that can be performed on systems
+follow a protocol. asdf is extensible to new operations and to new
+component types. This allows the addition of behaviours: for example,
+a new component could be added for Java JAR archives, and methods
+specialised on @code{compile-op} added for it that would accomplish the
+relevant actions.
+
+This chapter deals with @emph{components}, the building blocks of a
+system, and @emph{operations}, the actions that can be performed on a
+system.
+
+
+
+@menu
+* Operations::
+* Components::
+@end menu
+
+@node Operations, Components, The object model of asdf, The object model of asdf
+@comment node-name, next, previous, up
+@section Operations
+@cindex operation
+
+An @dfn{operation} object of the appropriate type is instantiated
+whenever the user wants to do something with a system like
+
+@itemize
+@item compile all its files
+@item load the files into a running lisp environment
+@item copy its source files somewhere else
+@end itemize
+
+Operations can be invoked directly, or examined to see what their
+effects would be without performing them. @emph{FIXME: document how!} There
+are a bunch of methods specialised on operation and component type
+that actually do the grunt work.
+
+The operation object contains whatever state is relevant for this
+purpose (perhaps a list of visited nodes, for example) but primarily
+is a nice thing to specialise operation methods on and easier than
+having them all be EQL methods.
+
+Operations are invoked on systems via @code{operate}.
+
+@deffn {Generic function} operate operation system &rest initargs
+@deffnx {Generic function} oos operation system &rest initargs
+@code{operate} invokes @var{operation} on @var{system}. @code{oos}
+is a synonym for @code{operate}.
+
+@var{operation} is a symbol that is passed, along with the supplied
+@var{initargs}, to @code{make-instance} to create the operation object.
+@var{system} is a system designator.
+
+The initargs are passed to the @code{make-instance} call when creating
+the operation object. Note that dependencies may cause the operation
+to invoke other operations on the system or its components: the new
+operations will be created with the same initargs as the original one.
+
+@end deffn
+
+@menu
+* Predefined operations of asdf::
+* Creating new operations::
+@end menu
+
+@node Predefined operations of asdf, Creating new operations, Operations, Operations
+@comment node-name, next, previous, up
+@subsection Predefined operations of asdf
+
+All the operations described in this section are in the @code{asdf}
+package. They are invoked via the @code{operate} generic function.
+
+@lisp
+(asdf:operate 'asdf:@var{operation-name} '@var{system-name} @{@var{operation-options ...}@})
+@end lisp
+
+@deffn Operation compile-op &key proclamations
+
+This operation compiles the specified component. If proclamations are
+supplied, they will be proclaimed. This is a good place to specify
+optimization settings.
+
+When creating a new component type, you should provide methods for
+@code{compile-op}.
+
+When @code{compile-op} is invoked, component dependencies often cause
+some parts of the system to be loaded as well as compiled. Invoking
+@code{compile-op} does not necessarily load all the parts of the
+system, though; use @code{load-op} to load a system.
+@end deffn
+
+@deffn Operation load-op &key proclamations
+
+This operation loads a system.
+
+The default methods for @code{load-op} compile files before loading them.
+For parity, your own methods on new component types should probably do
+so too.
+@end deffn
+
+@deffn Operation load-source-op
+
+This operation will load the source for the files in a module even if
+the source files have been compiled. Systems sometimes have knotty
+dependencies which require that sources are loaded before they can be
+compiled. This is how you do that.
+
+If you are creating a component type, you need to implement this
+operation - at least, where meaningful.
+@end deffn
+
+@deffn Operation test-system-version &key minimum
+
+Asks the system whether it satisfies a version requirement.
+
+The default method accepts a string, which is expected to contain of a
+number of integers separated by #\. characters. The method is not
+recursive. The component satisfies the version dependency if it has
+the same major number as required and each of its sub-versions is
+greater than or equal to the sub-version number required.
+
+@lisp
+(defun version-satisfies (x y)
+ (labels ((bigger (x y)
+ (cond ((not y) t)
+ ((not x) nil)
+ ((> (car x) (car y)) t)
+ ((= (car x) (car y))
+ (bigger (cdr x) (cdr y))))))
+ (and (= (car x) (car y))
+ (or (not (cdr y)) (bigger (cdr x) (cdr y))))))
+@end lisp
+
+If that doesn't work for your system, you can override it. I hope
+you have as much fun writing the new method as @verb{|#lisp|} did
+reimplementing this one.
+@end deffn
+
+@deffn Operation feature-dependent-op
+
+An instance of @code{feature-dependent-op} will ignore any components
+which have a @code{features} attribute, unless the feature combination
+it designates is satisfied by @code{*features*}. This operation is
+not intended to be instantiated directly, but other operations may
+inherit from it.
+
+@end deffn
+
+@node Creating new operations, , Predefined operations of asdf, Operations
+@comment node-name, next, previous, up
+@subsection Creating new operations
+
+asdf was designed to be extensible in an object-oriented fashion. To
+teach asdf new tricks, a programmer can implement the behaviour he
+wants by creating a subclass of @code{operation}.
+
+
+asdf's pre-defined operations are in no way ``privileged'', but it is
+requested that developers never use the @code{asdf} package for
+operations they develop themselves. The rationale for this rule is
+that we don't want to establish a ``global asdf operation name
+registry'', but also want to avoid name clashes.
+
+An operation must provide methods for the following generic functions
+when invoked with an object of type @code{source-file}: @emph{FIXME describe
+this better}
+
+@itemize
+
+@item @code{output-files}
+@item @code{perform}
+The @code{perform} method must call @code{output-files} to find out
+where to put its files, because the user is allowed to override
+@item @code{output-files} for local policy @code{explain}
+@item @code{operation-done-p}, if you don't like the default one
+
+@end itemize
+
+@node Components, , Operations, The object model of asdf
+@comment node-name, next, previous, up
+@section Components
+@cindex component
+@cindex system
+@cindex system designator
+@vindex *system-definition-search-functions*
+
+A @dfn{component} represents a source file or (recursively) a
+collection of components. A @dfn{system} is (roughly speaking) a
+top-level component that can be found via @code{find-system}.
+
+A @dfn{system designator} is a string or symbol and behaves just like
+any other component name (including with regard to the case conversion
+rules for component names).
+
+
+@defun find-system system-designator &optional (error-p t)
+
+Given a system designator, @code{find-system} finds and returns a
+system. If no system is found, an error of type
+@code{missing-component} is thrown, or @code{nil} is returned if
+@code{error-p} is false.
+
+To find and update systems, @code{find-system} funcalls each element
+in the @code{*system-definition-search-functions*} list, expecting a
+pathname to be returned. The resulting pathname is loaded if either
+of the following conditions is true:
+
+@itemize
+@item there is no system of that name in memory
+@item the file's last-modified time exceeds the last-modified time of the
+ system in memory
+@end itemize
+
+When system definitions are loaded from @file{.asd} files, a new
+scratch package is created for them to load into, so that different
+systems do not overwrite each others operations. The user may also
+wish to (and is recommended to) include @code{defpackage} and
+@code{in-package} forms in his system definition files, however, so
+that they can be loaded manually if need be.
+
+The default value of @code{*system-definition-search-functions*} is a
+function that looks in each of the directories given by evaluating
+members of @code{*central-registry*} for a file whose name is the
+name of the system and whose type is @file{asd}. The first such file
+is returned, whether or not it turns out to actually define the
+appropriate system. Hence, it is strongly advised to define a system
+@var{foo} in the corresponding file @var{foo.asd}.
+@end defun
+
+
+@menu
+* Common attributes of components::
+* Pre-defined subclasses of component::
+* Creating new component types::
+@end menu
+
+@node Common attributes of components, Pre-defined subclasses of component, Components, Components
+@comment node-name, next, previous, up
+@subsection Common attributes of components
+
+All components, regardless of type, have the following attributes.
+All attributes except @code{name} are optional.
+
+@subsubsection Name
+
+A component name is a string or a symbol. If a symbol, its name is
+taken and lowercased. The name must be a suitable value for the
+@code{:name} initarg to @code{make-pathname} in whatever filesystem
+the system is to be found.
+
+The lower-casing-symbols behaviour is unconventional, but was selected
+after some consideration. Observations suggest that the type of
+systems we want to support either have lowercase as customary case
+(Unix, Mac, windows) or silently convert lowercase to uppercase
+(lpns), so this makes more sense than attempting to use @code{:case
+:common} as argument to @code{make-pathname}, which is reported not to
+work on some implementations
+
+@subsubsection Version identifier
+
+This optional attribute is used by the test-system-version
+operation. @xref{Predefined operations of asdf}. For the default method of
+test-system-version, the version should be a string of intergers
+separated by dots, for example @samp{1.0.11}.
+
+@subsubsection Required features
+
+Traditionally defsystem users have used reader conditionals to include
+or exclude specific per-implementation files. This means that any
+single implementation cannot read the entire system, which becomes a
+problem if it doesn't wish to compile it, but instead for example to
+create an archive file containing all the sources, as it will omit to
+process the system-dependent sources for other systems.
+
+Each component in an asdf system may therefore specify features using
+the same syntax as #+ does, and it will (somehow) be ignored for
+certain operations unless the feature conditional is a member of
+@code{*features*}.
+
+
+@subsubsection Dependencies
+
+This attribute specifies dependencies of the component on its
+siblings. It is optional but often necessary.
+
+There is an excitingly complicated relationship between the initarg
+and the method that you use to ask about dependencies
+
+Dependencies are between (operation component) pairs. In your
+initargs for the component, you can say
+
+@lisp
+:in-order-to ((compile-op (load-op "a" "b") (compile-op "c"))
+ (load-op (load-op "foo")))
+@end lisp
+
+This means the following things:
+@itemize
+@item
+before performing compile-op on this component, we must perform
+load-op on @var{a} and @var{b}, and compile-op on @var{c},
+@item
+before performing @code{load-op}, we have to load @var{foo}
+@end itemize
+
+The syntax is approximately
+
+@verbatim
+(this-op {(other-op required-components)}+)
+
+required-components := component-name
+ | (required-components required-components)
+
+component-name := string
+ | (:version string minimum-version-object)
+@end verbatim
+
+Side note:
+
+This is on a par with what ACL defsystem does. mk-defsystem is less
+general: it has an implied dependency
+
+@verbatim
+ for all x, (load x) depends on (compile x)
+@end verbatim
+
+and using a @code{:depends-on} argument to say that @var{b} depends on
+@var{a} @emph{actually} means that
+
+@verbatim
+ (compile b) depends on (load a)
+@end verbatim
+
+This is insufficient for e.g. the McCLIM system, which requires that
+all the files are loaded before any of them can be compiled ]
+
+End side note
+
+In asdf, the dependency information for a given component and
+operation can be queried using @code{(component-depends-on operation
+component)}, which returns a list
+
+@lisp
+((load-op "a") (load-op "b") (compile-op "c") ...)
+@end lisp
+
+@code{component-depends-on} can be subclassed for more specific
+component/operation types: these need to @code{(call-next-method)} and
+append the answer to their dependency, unless they have a good reason
+for completely overriding the default dependencies
+
+(If it weren't for CLISP, we'd be using a @code{LIST} method
+combination to do this transparently. But, we need to support CLISP.
+If you have the time for some CLISP hacking, I'm sure they'd welcome
+your fixes)
+
+@subsubsection pathname
+
+This attribute is optional and if absent will be inferred from the
+component's name, type (the subclass of source-file), and the location
+of its parent.
+
+The rules for this inference are:
+
+(for source-files)
+@itemize
+@item the host is taken from the parent
+@item pathname type is @code{(source-file-type component system)}
+@item the pathname case option is @code{:local}
+@item the pathname is merged against the parent
+@end itemize
+
+(for modules)
+@itemize
+@item the host is taken from the parent
+@item the name and type are @code{NIL}
+@item the directory is @code{(:relative component-name)}
+@item the pathname case option is @code{:local}
+@item the pathname is merged against the parent
+@end itemize
+
+Note that the DEFSYSTEM operator (used to create a ``top-level''
+system) does additional processing to set the filesystem location of
+the top component in that system. This is detailed
+elsewhere, @xref{Defining systems with defsystem}.
+
+The answer to the frequently asked question "how do I create a system
+definition where all the source files have a .cl extension" is thus
+
+@lisp
+(defmethod source-file-type ((c cl-source-file) (s (eql (find-system 'my-sys))))
+ "cl")
+@end lisp
+
+@subsubsection properties
+
+This attribute is optional.
+
+Packaging systems often require information about files or systems in
+addition to that specified by asdf's pre-defined component attributes.
+Programs that create vendor packages out of asdf systems therefore
+have to create ``placeholder'' information to satisfy these systems.
+Sometimes the creator of an asdf system may know the additional
+information and wish to provide it directly.
+
+(component-property component property-name) and associated setf
+method will allow the programmatic update of this information.
+Property names are compared as if by @code{EQL}, so use symbols or
+keywords or something.
+
+@menu
+* Pre-defined subclasses of component::
+* Creating new component types::
+@end menu
+
+@node Pre-defined subclasses of component, Creating new component types, Common attributes of components, Components
+@comment node-name, next, previous, up
+@subsection Pre-defined subclasses of component
+
+@deffn Component source-file
+
+A source file is any file that the system does not know how to
+generate from other components of the system.
+
+Note that this is not necessarily the same thing as ``a file
+containing data that is typically fed to a compiler''. If a file is
+generated by some pre-processor stage (e.g. a @file{.h} file from
+@file{.h.in} by autoconf) then it is not, by this definition, a source
+file. Conversely, we might have a graphic file that cannot be
+automatically regenerated, or a proprietary shared library that we
+received as a binary: these do count as source files for our purposes.
+
+Subclasses of source-file exist for various languages. @emph{FIXME:
+describe these.}
+@end deffn
+
+@deffn Component module
+
+A module is a collection of sub-components.
+
+A module component has the following extra initargs:
+
+@itemize
+@item
+@code{:components} the components contained in this module
+
+@item
+@code{:default-component-class} All child components which don't
+specify their class explicitly are inferred to be of this type.
+
+@item
+@code{:if-component-dep-fails} This attribute takes one of the values
+@code{:fail}, @code{:try-next}, @code{:ignore}, its default value is
+@code{:fail}. The other values can be used for implementing
+conditional compilation based on implementation @code{*features*}, for
+the case where it is not necessary for all files in a module to be
+compiled.
+
+@item
+@code{:serial} When this attribute is set, each subcomponent of this
+component is assumed to depend on all subcomponents before it in the
+list given to @code{:components}, i.e. all of them are loaded before
+a compile or load operation is performed on it.
+
+@end itemize
+
+The default operation knows how to traverse a module, so most
+operations will not need to provide methods specialised on modules.
+
+@code{module} may be subclassed to represent components such as
+foreign-language linked libraries or archive files.
+@end deffn
+
+@deffn Component system
+
+@code{system} is a subclass of @code{module}.
+
+A system is a module with a few extra attributes for documentation
+purposes; these are given elsewhere. @xref{The defsystem grammar}.
+
+Users can create new classes for their systems: the default
+@code{defsystem} macro takes a @code{:classs} keyword
+argument.
+@end deffn
+
+@node Creating new component types, , Pre-defined subclasses of component, Components
+@comment node-name, next, previous, up
+@subsection Creating new component types
+
+New component types are defined by subclassing one of the existing
+component classes and specializing methods on the new component class.
+
+@emph{FIXME: this should perhaps be explained more throughly, not only by
+example ...}
+
+As an example, suppose we have some implementation-dependent
+functionality that we want to isolate in one subdirectory per Lisp
+implementation our system supports. We create a subclass of
+@code{cl-source-file}:
+
+@lisp
+(defclass unportable-cl-source-file (cl-source-file)
+ ())
+@end lisp
+
+A hypothetical function @code{system-dependent-dirname} gives us the
+name of the subdirectory. All that's left is to define how to
+calculate the pathname of an @code{unportable-cl-source-file}.
+
+@lisp
+(defmethod component-pathname ((component unportable-cl-source-file))
+ (let ((pathname (call-next-method))
+ (name (string-downcase (system-dependent-dirname))))
+ (merge-pathnames
+ (make-pathname :directory (list :relative name))
+ pathname)))
+@end lisp
+
+The new component type is used in a @code{defsystem} form in this way:
+
+@lisp
+(defsystem :foo
+ :components
+ ((:file "packages")
+ ...
+ (:unportable-cl-source-file "threads"
+ :depends-on ("packages" ...))
+ ...
+ )
+@end lisp
+
+@node Error handling, Compilation error and warning handling, The object model of asdf, Top
+@comment node-name, next, previous, up
+@chapter Error handling
+@findex SYSTEM-DEFINITION-ERROR
+@findex OPERATION-ERROR
+
+It is an error to define a system incorrectly: an implementation may
+detect this and signal a generalised instance of
+@code{SYSTEM-DEFINITION-ERROR}.
+
+Operations may go wrong (for example when source files contain
+errors). These are signalled using generalised instances of
+@code{OPERATION-ERROR}.
+
+@node Compilation error and warning handling, Getting the latest version, Error handling, Top
+@comment node-name, next, previous, up
+@chapter Compilation error and warning handling
+@vindex *compile-file-warnings-behaviour*
+@vindex *compile-file-errors-behavior*
+
+ASDF checks for warnings and errors when a file is compiled. The
+variables @code{*compile-file-warnings-behaviour*} and
+@code{*compile-file-errors-behavior*} controls the handling of any
+such events. The valid values for these variables are @code{:error},
+@code{:warn}, and @code{:ignore}.
+
+@node Getting the latest version, TODO list, Compilation error and warning handling, Top
+@comment node-name, next, previous, up
+@chapter Getting the latest version
+
+@enumerate
+@item
+Decide which version you want. HEAD is the newest version and
+usually OK, whereas RELEASE is for cautious people (e.g. who already
+have systems using asdf that they don't want broken), a slightly older
+version about which none of the HEAD users have complained.
+
+@item
+Check it out from sourceforge cCLan CVS:
+
+@kbd{cvs -d:pserver:anonymous@@cvs.cclan.sourceforge.net:/cvsroot/cclan login}
+
+(no password: just press @key{Enter})
+
+@kbd{cvs -z3 -d:pserver:anonymous@@cvs.cclan.sourceforge.net:/cvsroot/cclan co -r RELEASE asdf}
+
+or for the bleeding edge, instead
+
+@kbd{cvs -z3 -d:pserver:anonymous@@cvs.cclan.sourceforge.net:/cvsroot/cclan co -A asdf}
+
+@end enumerate
+
+If you are tracking the bleeding edge, you may want to subscribe to
+the cclan-commits mailing list (see
+@url{http://sourceforge.net/mail/?group_id=28536}) to receive commit
+messages and diffs whenever changes are made.
+
+For more CVS information, look at
+@url{http://sourceforge.net/cvs/?group_id=28536}.
+
+
+
+
+@node TODO list, missing bits in implementation, Getting the latest version, Top
+@comment node-name, next, previous, up
+@chapter TODO list
+
+* Outstanding spec questions, things to add
+
+** packaging systems
+
+*** manual page component?
+
+** style guide for .asd files
+
+You should either use keywords or be careful with the package that you
+evaluate defsystem forms in. Otherwise (defsystem partition ...)
+being read in the cl-user package will intern a cl-user:partition
+symbol, which will then collide with the partition:partition symbol.
+
+Actually there's a hairier packages problem to think about too.
+in-order-to is not a keyword: if you read defsystem forms in a package
+that doesn't use ASDF, odd things might happen
+
+** extending defsystem with new options
+
+You might not want to write a whole parser, but just to add options to
+the existing syntax. Reinstate parse-option or something akin
+
+** document all the error classes
+
+** what to do with compile-file failure
+
+Should check the primary return value from compile-file and see if
+that gets us any closer to a sensible error handling strategy
+
+** foreign files
+
+lift unix-dso stuff from db-sockets
+
+** Diagnostics
+
+A ``dry run'' of an operation can be made with the following form:
+
+@lisp
+(traverse (make-instance '<operation-name>)
+ (find-system <system-name>)
+ 'explain)
+@end lisp
+
+This uses unexported symbols. What would be a nice interface for this
+functionality?
+
+@node missing bits in implementation, Inspiration, TODO list, Top
+@comment node-name, next, previous, up
+@chapter missing bits in implementation
+
+** all of the above
+
+** reuse the same scratch package whenever a system is reloaded from disk
+
+** rules for system pathname defaulting are not yet implemented properly
+
+** proclamations probably aren't
+
+** when a system is reloaded with fewer components than it previously
+ had, odd things happen
+
+we should do something inventive when processing a defsystem form,
+like take the list of kids and setf the slot to nil, then transfer
+children from old to new list as they're found
+
+** traverse may become a normal function
+
+If you're defining methods on traverse, speak up.
+
+
+** a lot of load-op methods can be rewritten to use input-files
+
+so should be.
+
+
+** (stuff that might happen later)
+
+*** david lichteblau's patch for symlink resolution?
+
+*** Propagation of the :force option. ``I notice that
+
+ (oos 'compile-op :araneida :force t)
+
+also forces compilation of every other system the :araneida system
+depends on. This is rarely useful to me; usually, when I want to force
+recompilation of something more than a single source file, I want to
+recompile only one system. So it would be more useful to have
+make-sub-operation refuse to propagate @code{:force t} to other systems, and
+propagate only something like @code{:force :recursively}.
+
+Ideally what we actually want is some kind of criterion that says to
+which systems (and which operations) a @code{:force} switch will
+propagate.
+
+The problem is perhaps that `force' is a pretty meaningless concept.
+How obvious is it that @code{load :force t} should force
+@emph{compilation}? But we don't really have the right dependency
+setup for the user to compile @code{:force t} and expect it to work
+(files will not be loaded after compilation, so the compile
+environment for subsequent files will be emptier than it needs to be)
+
+What does the user actually want to do when he forces? Usually, for
+me, update for use with a new version of the lisp compiler. Perhaps
+for recovery when he suspects that something has gone wrong. Or else
+when he's changed compilation options or configuration in some way
+that's not reflected in the dependency graph.
+
+Other possible interface: have a 'revert' function akin to 'make clean'
+
+@lisp
+(asdf:revert 'asdf:compile-op 'araneida)
+@end lisp
+
+would delete any files produced by 'compile-op 'araneida. Of course, it
+wouldn't be able to do much about stuff in the image itself.
+
+How would this work?
+
+traverse
+
+There's a difference between a module's dependencies (peers) and its
+components (children). Perhaps there's a similar difference in
+operations? For example, @code{(load "use") depends-on (load "macros")} is a
+peer, whereas @code{(load "use") depends-on (compile "use")} is more of a
+`subservient' relationship.
+
+@node Inspiration, Concept Index, missing bits in implementation, Top
+@comment node-name, next, previous, up
+@chapter Inspiration
+
+@section mk-defsystem (defsystem-3.x)
+
+We aim to solve basically the same problems as mk-defsystem does.
+However, our architecture for extensibility better exploits CL
+language features (and is documented), and we intend to be portable
+rather than just widely-ported. No slight on the mk-defsystem authors
+and maintainers is intended here; that implementation has the
+unenviable task of supporting pre-ANSI implementations, which is
+no longer necessary.
+
+The surface defsystem syntax of asdf is more-or-less compatible with
+mk-defsystem, except that we do not support the @code{source-foo} and
+@code{binary-foo} prefixes for separating source and binary files, and
+we advise the removal of all options to specify pathnames.
+
+The mk-defsystem code for topologically sorting a module's dependency
+list was very useful.
+
+@section defsystem-4 proposal
+
+Marco and Peter's proposal for defsystem 4 served as the driver for
+many of the features in here. Notable differences are:
+
+@itemize
+@item
+We don't specify output files or output file extensions as part of the
+system.
+
+If you want to find out what files an operation would create, ask the
+operation.
+
+@item
+We don't deal with CL packages
+
+If you want to compile in a particular package, use an in-package form
+in that file (ilisp / SLIME will like you more if you do this anyway)
+
+@item
+There is no proposal here that defsystem does version control.
+
+A system has a given version which can be used to check dependencies,
+but that's all.
+@end itemize
+
+The defsystem 4 proposal tends to look more at the external features,
+whereas this one centres on a protocol for system introspection.
+
+@section kmp's ``The Description of Large Systems'', MIT AI Memu 801
+
+Available in updated-for-CL form on the web at
+@url{http://world.std.com/~pitman/Papers/Large-Systems.html}
+
+In our implementation we borrow kmp's overall PROCESS-OPTIONS and
+concept to deal with creating component trees from defsystem surface
+syntax. [ this is not true right now, though it used to be and
+probably will be again soon ]
+
+
+@c -------------------
+
+
+@node Concept Index, Function and Class Index, Inspiration, Top
+@unnumbered Concept Index
+
+@printindex cp
+
+@node Function and Class Index, Variable Index, Concept Index, Top
+@unnumbered Function and Class Index
+
+@printindex fn
+
+@node Variable Index, , Function and Class Index, Top
+@unnumbered Variable Index
+
+@printindex vr
+
+
+
+
+@bye
+
diff --git a/Lisp/asdf/cclan-package.lisp b/Lisp/asdf/cclan-package.lisp
new file mode 100644
index 0000000..d993e94
--- /dev/null
+++ b/Lisp/asdf/cclan-package.lisp
@@ -0,0 +1,5 @@
+(in-package :cl-user)
+
+(defpackage :cclan (:use #:cl #:asdf)
+ (:export #:all-components #:write-package))
+
diff --git a/Lisp/asdf/cclan.asd b/Lisp/asdf/cclan.asd
new file mode 100644
index 0000000..07dbebb
--- /dev/null
+++ b/Lisp/asdf/cclan.asd
@@ -0,0 +1,8 @@
+;;; -*- Lisp -*-
+(defpackage :cclan-system (:use #:cl #:asdf))
+(in-package :cclan-system)
+
+(defsystem cclan
+ :version "0.1"
+ :components ((:file "cclan-package")
+ (:file "cclan" :depends-on ("cclan-package"))))
diff --git a/Lisp/asdf/cclan.lisp b/Lisp/asdf/cclan.lisp
new file mode 100644
index 0000000..7d08307
--- /dev/null
+++ b/Lisp/asdf/cclan.lisp
@@ -0,0 +1,99 @@
+(in-package :cclan)
+
+;;;; This file contains functions, classes etc that are not part of
+;;;; asdf itself, but extend it in various ways useful for maintainers
+;;;; of new-style cCLan packages
+
+;;;; The public interface consists of the functions whose symbols are
+;;;; exported from the package
+
+;;;; This file does not contain references to asdf internals - or
+;;;; shouldn't, anyway. Send bug reports
+
+
+(defun mapappend (function list)
+ (let ((f (coerce function 'function)))
+ (loop for i in list append (funcall f i))))
+
+(defgeneric all-components (component))
+(defmethod all-components ((source-file source-file))
+ (list source-file))
+
+(defmethod all-components ((module module))
+ (cons module (mapappend #'all-components (module-components module))))
+
+(defmethod all-components ((module symbol))
+ (all-components (find-system module)))
+
+(defun cvs-tag-name (system)
+ (let* ((system (find-system system))
+ (version (component-version system)))
+ (format nil "release_~A" (substitute #\_ #\. version))))
+
+(defun cvs-tag (system)
+ (let* ((system (find-system system))
+ (directory (component-pathname system)))
+ (run-shell-command "cd ~A && cvs tag -F ~A"
+ (namestring directory) (cvs-tag-name system))))
+
+
+(defun write-readme-file (stream suggested-registry system-name)
+ "Write a README.install file detailing a possible sequence of commands to use the newly-untarred system."
+ (format stream "~
+1. Make a symlink in ~W[*] pointing to the .asd file
+2. Start your asdf-enabled lisp
+2a. Ensure that ~W[*] is in asdf:*central-registry*
+3. At the lisp prompt, type '(asdf:operate 'asdf:load-op ~W)'. This
+ will compile and load the system into your running lisp.
+
+[*] This path (~W) is only a suggestion; the important
+thing is that asdf know where to find the .asd file. asdf uses the
+contents of the variable ASDF:*CENTRAL-REGISTRY* to find its system
+definitions.
+
+These instructions were automatically generated by cCLan software. Use
+at your own peril.~%" suggested-registry suggested-registry system-name suggested-registry))
+
+(defun write-package (system)
+ (let* ((parent-dir
+ (parse-namestring
+ (format nil "/tmp/~A.~A/"
+ #+sbcl (sb-unix:unix-getpid)
+ #-sbcl (random 1000000)
+ (get-internal-run-time))))
+ (system (find-system system))
+ (sub-dir-name
+ (format nil "~A_~A"
+ (component-name system) (component-version system)))
+ (cvsroot-file
+ (merge-pathnames "CVS/Root" (component-pathname system)))
+ (old-pwd *default-pathname-defaults*)
+ (*default-pathname-defaults* parent-dir))
+ (ensure-directories-exist parent-dir)
+ (cvs-tag system)
+ (and
+ (zerop (asdf:run-shell-command
+ "cd ~A && cvs -d `cat ~A` checkout -d ~A -r ~A -kv ~A"
+ (namestring parent-dir)
+ (namestring cvsroot-file)
+ sub-dir-name
+ (cvs-tag-name system)
+ (component-name system)))
+ (with-open-file (o (format nil "~A/INSTALL.asdf" sub-dir-name)
+ :direction :output)
+ (write-readme-file o "$HOME/lisp/systems/" (component-name system))
+ t)
+ (zerop (asdf:run-shell-command "cd ~A && tar cf ~A~A.tar ~A"
+ (namestring parent-dir)
+ (namestring old-pwd) sub-dir-name
+ sub-dir-name))
+ (zerop (asdf:run-shell-command
+ "gzip -f9 ~A~A.tar"
+ (namestring old-pwd) sub-dir-name))
+ (format t "Now run~% gpg -b -a ~A~A.tar.gz~%in a shell with a tty"
+ (namestring old-pwd) sub-dir-name))))
+
+(defun class-name-of (x)
+ (class-name (class-of x)))
+
+
diff --git a/Lisp/asdf/debian/README.Debian b/Lisp/asdf/debian/README.Debian
new file mode 100644
index 0000000..b38202d
--- /dev/null
+++ b/Lisp/asdf/debian/README.Debian
@@ -0,0 +1,14 @@
+Debian Package cl-asdf
+----------------------
+
+This package was created for Debian by Kevin M. Rosenberg
+<kmr@debian.org> in Aug 2002. The URL for asdf is
+http://www.telent.net/cliki/asdf. The README file has details
+about the use of asdf.
+
+To load asdf into your Lisp system, give the command
+(load "/usr/share/common-lisp/source/asdf/asdf.lisp")
+
+Additionally, there is an optional module that you can load
+with the command
+(load "/usr/share/common-lisp/source/asdf/wild-modules.lisp")
diff --git a/Lisp/asdf/debian/changelog b/Lisp/asdf/debian/changelog
new file mode 100644
index 0000000..fbac8d8
--- /dev/null
+++ b/Lisp/asdf/debian/changelog
@@ -0,0 +1,304 @@
+cl-asdf (1.81-1) unstable; urgency=low
+
+ * New upstream
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Tue, 30 Dec 2003 12:12:38 -0700
+
+cl-asdf (1.80-1) unstable; urgency=low
+
+ * New upstream
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Fri, 5 Dec 2003 14:55:43 -0700
+
+cl-asdf (1.79-1) unstable; urgency=low
+
+ * New upstream
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Tue, 11 Nov 2003 16:12:07 -0700
+
+cl-asdf (1.78-1) unstable; urgency=low
+
+ * New upstream
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Thu, 9 Oct 2003 16:46:38 -0600
+
+cl-asdf (1.77.2-1) unstable; urgency=low
+
+ * Don't export asdf:wild-module as can cause a full warning when
+ reloading asdf
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Mon, 11 Aug 2003 21:55:16 -0600
+
+cl-asdf (1.77.1-1) unstable; urgency=low
+
+ * cclan.lisp: conditionalize for sbcl (closes: 201822)
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Thu, 17 Jul 2003 23:30:57 -0600
+
+cl-asdf (1.77-1) unstable; urgency=low
+
+ * New upstream
+ * Add automated [cvs2cl] ChangeLog
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Thu, 17 Jul 2003 10:27:27 -0600
+
+cl-asdf (1.76) unstable; urgency=low
+
+ * New upstream
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Thu, 10 Jul 2003 16:42:48 -0600
+
+cl-asdf (1.75) unstable; urgency=low
+
+ * New upstream
+ * Use compat rather than DH_COMPAT
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Thu, 5 Jun 2003 00:15:11 -0600
+
+cl-asdf (1.73b) unstable; urgency=low
+
+ * Update README
+ * export two variables
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Wed, 28 May 2003 11:19:40 -0600
+
+cl-asdf (1.73) unstable; urgency=low
+
+ * Update README to mention asdf::*compile-file-warnings-behaviour*
+ (closes:194957)
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Tue, 27 May 2003 16:00:36 -0600
+
+cl-asdf (1.72) unstable; urgency=low
+
+ * New upstream
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Tue, 20 May 2003 14:07:10 -0600
+
+cl-asdf (1.71) unstable; urgency=low
+
+ * New upstream
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Tue, 13 May 2003 09:33:51 -0600
+
+cl-asdf (1.70) unstable; urgency=low
+
+ * Add another check in check-component-values.
+ * Signal a generalized instance of SYSTEM-DEFINITION-ERROR
+ from check-component-values
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Tue, 6 May 2003 09:32:16 -0600
+
+cl-asdf (1.69) unstable; urgency=low
+
+ * Add check-component-values function with partial checking of components
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Tue, 6 May 2003 08:26:11 -0600
+
+cl-asdf (1.68) unstable; urgency=low
+
+ * New upstream with 'asdf:test-op
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Wed, 19 Mar 2003 10:16:01 -0700
+
+cl-asdf (1.66) unstable; urgency=low
+
+ * New upstream version, added changes to dependent system
+ compilations with :force option.
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Mon, 17 Mar 2003 12:50:00 -0700
+
+cl-asdf (1.62) unstable; urgency=low
+
+ * New upstream, fixes a sbcl-specific directory name
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Fri, 7 Mar 2003 09:23:11 -0700
+
+cl-asdf (1.61-1) unstable; urgency=low
+
+ * New upstream, fixes 'load-source-op
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Tue, 4 Mar 2003 09:48:40 -0700
+
+cl-asdf (1.60-1) unstable; urgency=low
+
+ * New upstream
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Mon, 3 Mar 2003 12:40:27 -0700
+
+cl-asdf (1.59-1) unstable; urgency=low
+
+ * New upstream
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Fri, 14 Feb 2003 09:24:59 -0700
+
+cl-asdf (1.58-1) unstable; urgency=low
+
+ * New upstream
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Sun, 9 Feb 2003 11:55:03 -0700
+
+cl-asdf (1.57-1) unstable; urgency=low
+
+ * New upstream
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Tue, 4 Feb 2003 10:23:03 -0700
+
+cl-asdf (1.55-1) unstable; urgency=low
+
+ * New upstream.version (closes: 172074)
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Mon, 9 Dec 2002 10:23:21 -0700
+
+cl-asdf (1.54-1) unstable; urgency=low
+
+ * New upstream.
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Fri, 8 Nov 2002 07:30:41 -0700
+
+cl-asdf (1.49-1) unstable; urgency=low
+
+ * Remove clc-reregister-all-impl from postinst
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Sat, 5 Oct 2002 09:38:18 -0600
+
+cl-asdf (1.49) unstable; urgency=low
+
+ * New upstream release, fixes run-shell-command for allegro. Code
+ refactoring for run-shell-code.
+ * Support new CLC reregister command
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Wed, 25 Sep 2002 23:57:23 -0600
+
+cl-asdf (1.47) unstable; urgency=low
+
+ * Return numeric exit status for openmcl's run-shell-command
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Fri, 20 Sep 2002 10:22:36 -0600
+
+cl-asdf (1.46) unstable; urgency=low
+
+ * New upstream version, adds run-shell-command for openmcl
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Fri, 20 Sep 2002 10:11:48 -0600
+
+cl-asdf (1.45) unstable; urgency=low
+
+ * Changes to improve clisp support
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Fri, 20 Sep 2002 07:12:21 -0600
+
+cl-asdf (1.44.1-1) unstable; urgency=low
+
+ * Make cclan.asd a symlink, remove :pathname keyword
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Wed, 18 Sep 2002 00:19:26 -0600
+
+cl-asdf (1.44-1) unstable; urgency=low
+
+ * New upstream version
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Tue, 17 Sep 2002 12:24:27 -0600
+
+cl-asdf (1.43-1) unstable; urgency=low
+
+ * New upstream version
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Tue, 17 Sep 2002 10:34:57 -0600
+
+cl-asdf (1.42-2) unstable; urgency=low
+
+ * Add reregister-common-lisp-implementations call when installing cl-asdf.
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Mon, 16 Sep 2002 08:31:13 -0600
+
+cl-asdf (1.42-1) unstable; urgency=low
+
+ * Remove Depends on lisp-compiler for cl-asdf (fixes problem with
+ circular dependencies)
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Sat, 14 Sep 2002 11:59:58 -0600
+
+cl-asdf (1.42) unstable; urgency=low
+
+ * New upstream.
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Fri, 13 Sep 2002 08:40:58 -0600
+
+cl-asdf (1.41) unstable; urgency=low
+
+ * Same release as 1.40, but with proper version number.
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Fri, 13 Sep 2002 08:38:30 -0600
+
+cl-asdf (1.40) unstable; urgency=low
+
+ * New upstream version.
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Fri, 13 Sep 2002 07:31:27 -0600
+
+cl-asdf (1.39) unstable; urgency=low
+
+ * New upstream version.
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Wed, 11 Sep 2002 19:21:32 -0600
+
+cl-asdf (1.38) unstable; urgency=low
+
+ * New upstream version
+ * Re-add register and unregister clc-source for cclan
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Wed, 11 Sep 2002 13:39:51 -0600
+
+cl-asdf (1.35-1) unstable; urgency=low
+
+ * Comment call to register and unregister clc-source until new
+ version of clc is released. (closes: 158697)
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Wed, 28 Aug 2002 18:58:59 -0600
+
+cl-asdf (1.35) unstable; urgency=high
+
+ * New upstream version, fixes important bugs.
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Wed, 28 Aug 2002 09:36:58 -0600
+
+cl-asdf (1.34) unstable; urgency=low
+
+ * New upstream version.
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Wed, 28 Aug 2002 07:18:57 -0600
+
+cl-asdf (0.0+cvs.2002.08.26-1) unstable; urgency=low
+
+ * Add Common Lisp Controller registration functions for cl-cclan
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Mon, 26 Aug 2002 04:21:32 -0600
+
+cl-asdf (0.0+cvs.2002.08.26) unstable; urgency=low
+
+ * New upstream version
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Mon, 26 Aug 2002 01:23:48 -0600
+
+cl-asdf (0.0+cvs.2002.08.22) unstable; urgency=low
+
+ * Add new binary package: cl-cclan
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Thu, 22 Aug 2002 12:43:21 -0600
+
+cl-asdf (0.0+cvs.2002.08.18) unstable; urgency=low
+
+ * New upstream version
+ * Expand description in control file.
+ * Change version numbering scheme since upstream has native debian
+ directory
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Sat, 17 Aug 2002 14:25:33 -0600
+
+cl-asdf (0.0+cvs.2002.08.15-1) unstable; urgency=low
+
+ * Initial Release (closes: 157009)
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Fri, 16 Aug 2002 23:14:49 -0600
+
diff --git a/Lisp/asdf/debian/cl-asdf.postinst b/Lisp/asdf/debian/cl-asdf.postinst
new file mode 100644
index 0000000..6a6e3cf
--- /dev/null
+++ b/Lisp/asdf/debian/cl-asdf.postinst
@@ -0,0 +1,45 @@
+#! /bin/sh
+# postinst script for asdf
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+#
+# quoting from the policy:
+# Any necessary prompting should almost always be confined to the
+# post-installation script, and should be protected with a conditional
+# so that unnecessary prompting doesn't happen if a package's
+# installation fails and the `postinst' is called with `abort-upgrade',
+# `abort-remove' or `abort-deconfigure'.
+
+case "$1" in
+ configure)
+ if [ -x /usr/sbin/clc-reregister-all-impl ]; then
+ /usr/sbin/clc-reregister-all-impl
+ fi
+ ;;
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/Lisp/asdf/debian/cl-cclan.postinst b/Lisp/asdf/debian/cl-cclan.postinst
new file mode 100644
index 0000000..3276e88
--- /dev/null
+++ b/Lisp/asdf/debian/cl-cclan.postinst
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+set -e
+
+pkg=cclan
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+#
+# quoting from the policy:
+# Any necessary prompting should almost always be confined to the
+# post-installation script, and should be protected with a conditional
+# so that unnecessary prompting doesn't happen if a package's
+# installation fails and the `postinst' is called with `abort-upgrade',
+# `abort-remove' or `abort-deconfigure'.
+
+case "$1" in
+ configure)
+ /usr/sbin/register-common-lisp-source $pkg
+ ;;
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/Lisp/asdf/debian/cl-cclan.prerm b/Lisp/asdf/debian/cl-cclan.prerm
new file mode 100644
index 0000000..d8cda90
--- /dev/null
+++ b/Lisp/asdf/debian/cl-cclan.prerm
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+set -e
+
+pkg=cclan
+
+# summary of how this script can be called:
+# * <prerm> `remove'
+# * <old-prerm> `upgrade' <new-version>
+# * <new-prerm> `failed-upgrade' <old-version>
+# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
+# * <deconfigured's-prerm> `deconfigure' `in-favour'
+# <package-being-installed> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ remove|upgrade|deconfigure)
+ /usr/sbin/unregister-common-lisp-source $pkg
+ ;;
+ failed-upgrade)
+ ;;
+ *)
+ echo "prerm called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/Lisp/asdf/debian/compat b/Lisp/asdf/debian/compat
new file mode 100644
index 0000000..7290ba8
--- /dev/null
+++ b/Lisp/asdf/debian/compat
@@ -0,0 +1,2 @@
+4
+4
diff --git a/Lisp/asdf/debian/control b/Lisp/asdf/debian/control
new file mode 100644
index 0000000..850b435
--- /dev/null
+++ b/Lisp/asdf/debian/control
@@ -0,0 +1,26 @@
+Source: cl-asdf
+Section: devel
+Priority: optional
+Maintainer: Kevin M. Rosenberg <kmr@debian.org>
+Build-Depends-Indep: debhelper (>> 4.0.0)
+Standards-Version: 3.6.1.0
+
+Package: cl-asdf
+Architecture: all
+Depends: ${shlibs:Depends}
+Recommends: common-lisp-controller, sbcl | lisp-compiler
+Description: Another System Definition Facility
+ asdf provides a "make" type functions for Common Lisp packages. It
+ provides compilation and loading features for complex Lisp systems
+ with multiple modules and files. It is similar in concept to, but
+ with features different from, "defsystem" which is included in the
+ common-lisp-controller package. Unlike defsystem3 in CLC, asdf is
+ object-oriented and extensible.
+
+Package: cl-cclan
+Architecture: all
+Depends: ${shlibs:Depends}, cl-asdf
+Description: Comprehensive Common Lisp Archive Network
+ cclan is a tool for creating a repository of Common Lisp packages.
+ cclan utilizes asdf to automatically create installable packages for various
+ operating systems.
diff --git a/Lisp/asdf/debian/copyright b/Lisp/asdf/debian/copyright
new file mode 100644
index 0000000..db3d7e5
--- /dev/null
+++ b/Lisp/asdf/debian/copyright
@@ -0,0 +1,37 @@
+This package was debianized by Kevin M. Rosenberg <kmr@debian.org> on
+Fri, 16 Aug 2002 23:14:49 -0600.
+
+It was downloaded from SourceForge CVS server with the below commands:
+ cvs -d:pserver:anonymous@cvs.cclan.sourceforge.net:/cvsroot/cclan login
+ (no password: just press Enter)
+ cvs -z3 -d:pserver:anonymous@cvs.cclan.sourceforge.net:/cvsroot/cclan \
+ co asdf
+
+Upstream Authors: Dan Barlow <dan@telent.net> & Contributors
+
+Copyright:
+
+(This is the MIT / X Consortium license as taken from
+ http://www.opensource.org/licenses/mit-license.html)
+
+Copyright (c) 2001, 2002 Daniel Barlow and contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/Lisp/asdf/debian/docs b/Lisp/asdf/debian/docs
new file mode 100644
index 0000000..e845566
--- /dev/null
+++ b/Lisp/asdf/debian/docs
@@ -0,0 +1 @@
+README
diff --git a/Lisp/asdf/debian/rules b/Lisp/asdf/debian/rules
new file mode 100644
index 0000000..38630bb
--- /dev/null
+++ b/Lisp/asdf/debian/rules
@@ -0,0 +1,84 @@
+#!/usr/bin/make -f
+# GNU copyright 1997 to 1999 by Joey Hess.
+
+pkg=cl-asdf
+pkg-cclan=cl-cclan
+clc-base=usr/share/common-lisp
+clc-src=$(clc-base)/source
+clc-systems=$(clc-base)/systems
+asdf-files=$(clc-src)/asdf
+cclan-files=$(clc-src)/cclan
+doc-dir=usr/share/doc/$(pkg)
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ # Add here commands to configure the package.
+ touch configure-stamp
+
+
+build: build-stamp
+
+build-stamp: configure-stamp
+ dh_testdir
+ # Add here commands to compile the package.
+ touch build-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+ # Add here commands to clean up after the build process.
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/asdf.
+ dh_installdirs -p $(pkg) $(asdf-files) $(doc-dir)/examples
+ dh_install -p $(pkg) asdf.lisp wild-modules.lisp asdf-install.lisp $(asdf-files)
+ chmod +x test/run-tests.sh
+ dh_install -p $(pkg) test/* $(doc-dir)/examples
+ dh_installdirs -p $(pkg-cclan) $(clc-systems) $(cclan-files)
+ dh_install -p $(pkg-cclan) cclan-package.lisp cclan.lisp cclan.asd $(cclan-files)
+ dh_link -p $(pkg-cclan) $(cclan-files)/cclan.asd $(clc-systems)/cclan.asd
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+# dh_installdebconf
+ dh_installdocs
+# dh_installexamples
+ dh_installmenu
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_installinit
+ dh_installcron
+ dh_installman
+ dh_installinfo
+# dh_undocumented
+ dh_installchangelogs ChangeLog
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+# dh_makeshlibs
+ dh_installdeb
+# dh_perl
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/Lisp/asdf/test-mail b/Lisp/asdf/test-mail
new file mode 100644
index 0000000..0aa66d7
--- /dev/null
+++ b/Lisp/asdf/test-mail
@@ -0,0 +1 @@
+Wed Aug 28 21:18:48 BST 2002
diff --git a/Lisp/asdf/test/file1.lisp b/Lisp/asdf/test/file1.lisp
new file mode 100644
index 0000000..3612a2b
--- /dev/null
+++ b/Lisp/asdf/test/file1.lisp
@@ -0,0 +1,4 @@
+(defpackage :test-package (:use :cl))
+(in-package :test-package)
+(defvar *file1* t)
+
diff --git a/Lisp/asdf/test/file2.lisp b/Lisp/asdf/test/file2.lisp
new file mode 100644
index 0000000..a8192bb
--- /dev/null
+++ b/Lisp/asdf/test/file2.lisp
@@ -0,0 +1,2 @@
+(in-package :test-package)
+(assert *file1*)
diff --git a/Lisp/asdf/test/file3.lisp b/Lisp/asdf/test/file3.lisp
new file mode 100644
index 0000000..0ed2df7
--- /dev/null
+++ b/Lisp/asdf/test/file3.lisp
@@ -0,0 +1,4 @@
+(defpackage :test-package (:use :cl))
+(in-package :test-package)
+(defvar *file3* t)
+
diff --git a/Lisp/asdf/test/file4.lisp b/Lisp/asdf/test/file4.lisp
new file mode 100644
index 0000000..45a709a
--- /dev/null
+++ b/Lisp/asdf/test/file4.lisp
@@ -0,0 +1,2 @@
+(in-package :test-package)
+(assert *file3*)
diff --git a/Lisp/asdf/test/run-tests.sh b/Lisp/asdf/test/run-tests.sh
new file mode 100644
index 0000000..0c4f87e
--- /dev/null
+++ b/Lisp/asdf/test/run-tests.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+do_tests() {
+rm *.$2 || true
+( cd .. && echo '(compile-file "asdf")' |$1 )
+for i in *.script;
+do
+ rm *.$2 || true
+ if $1 < $i ;then
+ echo "Using $1, $i passed" >&2
+ else
+ echo "Using $1, $i failed" >&2
+ exit 1
+ fi
+done
+echo "Using $1, all tests apparently successful" >&2
+}
+
+# do_tests {lisp invocation} {fasl extension}
+# - read lisp forms one at a time from standard input
+# - quit with exit status 0 on getting eof
+# - quit with exit status >0 if an unhandled error occurs
+
+set -e
+
+if type sbcl
+then
+ do_tests "sbcl --userinit /dev/null --sysinit /dev/null --noprogrammer" fasl
+fi
+
+if [ -x /usr/bin/lisp ]
+then
+ do_tests "/usr/bin/lisp -batch -noinit" x86f
+fi
+
+if [ -x /usr/bin/clisp ]
+then
+ do_tests "/usr/bin/clisp -norc -ansi -I " fas
+fi
diff --git a/Lisp/asdf/test/test1.asd b/Lisp/asdf/test/test1.asd
new file mode 100644
index 0000000..423d796
--- /dev/null
+++ b/Lisp/asdf/test/test1.asd
@@ -0,0 +1,12 @@
+;;; -*- Lisp -*-
+(asdf:defsystem test1
+ :components ((:file "file2" :in-order-to ((compile-op (load-op "file1"))))
+ (:file "file1")))
+
+#|
+1) from clean, check that all fasl files build and that some function
+ defined in the second file is present
+
+2) delete the second fasl file, and build again. do test 1 again and
+ also check the date on file1.fasl
+|#
diff --git a/Lisp/asdf/test/test1.script b/Lisp/asdf/test/test1.script
new file mode 100644
index 0000000..f39882c
--- /dev/null
+++ b/Lisp/asdf/test/test1.script
@@ -0,0 +1,32 @@
+;;; -*- Lisp -*-
+(load "../asdf")
+(setf asdf:*central-registry* '(*default-pathname-defaults*))
+(asdf:operate 'asdf:load-op 'test1)
+
+;; test that it compiled
+(defvar file1-date (file-write-date (compile-file-pathname "file1")))
+(assert (and file1-date (file-write-date (compile-file-pathname "file2"))))
+
+;; and loaded
+(assert test-package::*file1*)
+
+;; now remove one output file and check that the other is _not_
+;; recompiled
+(sleep 1) ; mtime has 1-second granularity, so pause here for fast machines
+
+(asdf::run-shell-command "rm ~A"
+ (namestring (compile-file-pathname "file2")))
+(asdf:operate 'asdf:load-op 'test1)
+(assert (= file1-date (file-write-date (compile-file-pathname "file1"))))
+(assert (file-write-date (compile-file-pathname "file2")))
+
+;; now touch file1 and check that file2 _is_ also recompiled
+
+;; XXX run-shell-command loses if *default-pathname-defaults* is not the
+;; unix cwd. this is not a problem for run-tests.sh, but can be in general
+
+(let ((before (file-write-date (compile-file-pathname "file2"))))
+ (asdf::run-shell-command "touch file1.lisp")
+ (sleep 1)
+ (asdf:operate 'asdf:load-op 'test1)
+ (assert (> (file-write-date (compile-file-pathname "file2")) before)))
diff --git a/Lisp/asdf/test/test2.asd b/Lisp/asdf/test/test2.asd
new file mode 100644
index 0000000..344d17f
--- /dev/null
+++ b/Lisp/asdf/test/test2.asd
@@ -0,0 +1,8 @@
+;;; -*- Lisp -*-
+(asdf:defsystem test2b
+ :version "1.0"
+ :components ((:file "file2" :in-order-to ((compile-op (load-op "file1"))))
+ (:file "file1"))
+ :depends-on (version 'test2a "1.1"))
+
+
diff --git a/Lisp/asdf/test/test2.script b/Lisp/asdf/test/test2.script
new file mode 100644
index 0000000..bca6012
--- /dev/null
+++ b/Lisp/asdf/test/test2.script
@@ -0,0 +1,19 @@
+;;; -*- Lisp -*-
+(load "../asdf")
+(setf asdf:*central-registry* '(*default-pathname-defaults*))
+;(trace asdf::perform)
+;(trace asdf::find-component)
+;(trace asdf::traverse)
+(asdf:oos 'asdf:load-op 'test2b1)
+(assert (and (probe-file (compile-file-pathname "file3"))
+ (probe-file (compile-file-pathname "file4"))))
+(handler-case
+ (asdf:oos 'asdf:load-op 'test2b2)
+ (asdf:missing-dependency (c)
+ (format t "load failed as expected: - ~%~A~%" c))
+ (:no-error (c) (error "should have failed, oops")))
+(handler-case
+ (asdf:oos 'asdf:load-op 'test2b3)
+ (asdf:missing-dependency (c)
+ (format t "load failed as expected: - ~%~A~%" c))
+ (:no-error (c) (error "should have failed, oops")))
diff --git a/Lisp/asdf/test/test2a.asd b/Lisp/asdf/test/test2a.asd
new file mode 100644
index 0000000..0e031db
--- /dev/null
+++ b/Lisp/asdf/test/test2a.asd
@@ -0,0 +1,12 @@
+;;; -*- Lisp -*-
+(asdf:defsystem test2a
+ :version "1.1"
+ :components ((:file "file4" :in-order-to ((compile-op (load-op "file3"))))
+ (:file "file3")))
+#|
+this system is referenced by test2b[12]
+|#
+
+
+
+
diff --git a/Lisp/asdf/test/test2b1.asd b/Lisp/asdf/test/test2b1.asd
new file mode 100644
index 0000000..985b352
--- /dev/null
+++ b/Lisp/asdf/test/test2b1.asd
@@ -0,0 +1,8 @@
+;;; -*- Lisp -*-
+(asdf:defsystem test2b1
+ :version "1.0"
+ :components ((:file "file2" :in-order-to ((compile-op (load-op "file1"))))
+ (:file "file1"))
+ :in-order-to ((load-op (load-op (version test2a "1.1")))))
+
+
diff --git a/Lisp/asdf/test/test2b2.asd b/Lisp/asdf/test/test2b2.asd
new file mode 100644
index 0000000..3344fcd
--- /dev/null
+++ b/Lisp/asdf/test/test2b2.asd
@@ -0,0 +1,8 @@
+;;; -*- Lisp -*-
+(asdf:defsystem test2b2
+ :version "1.0"
+ :components ((:file "file2" :in-order-to ((compile-op (load-op "file1"))))
+ (:file "file1"))
+ :in-order-to ((load-op (load-op (version test2a "1.2")))))
+
+
diff --git a/Lisp/asdf/test/test2b3.asd b/Lisp/asdf/test/test2b3.asd
new file mode 100644
index 0000000..36771cc
--- /dev/null
+++ b/Lisp/asdf/test/test2b3.asd
@@ -0,0 +1,8 @@
+;;; -*- Lisp -*-
+(asdf:defsystem test2b3
+ :version "1.0"
+ :components ((:file "file2" :in-order-to ((compile-op (load-op "file1"))))
+ (:file "file1"))
+ :depends-on (bet-you-cant-find-this))
+
+
diff --git a/Lisp/asdf/test/test3.asd b/Lisp/asdf/test/test3.asd
new file mode 100644
index 0000000..10f82c9
--- /dev/null
+++ b/Lisp/asdf/test/test3.asd
@@ -0,0 +1,11 @@
+;;; -*- Lisp -*-
+(asdf:defsystem test3
+ :properties ((:prop1 . "value"))
+ :components
+ ((:module "deps"
+ :if-component-dep-fails :try-next
+ :pathname "."
+ :components
+ ((:file "file1" :in-order-to ((compile-op (feature :f1))))
+ (:file "file2" :in-order-to ((compile-op (feature :f2))))))))
+
diff --git a/Lisp/asdf/test/test3.script b/Lisp/asdf/test/test3.script
new file mode 100644
index 0000000..170d4c5
--- /dev/null
+++ b/Lisp/asdf/test/test3.script
@@ -0,0 +1,23 @@
+;;; -*- Lisp -*-
+#+(or f1 f2)
+ (error "This test cannot run if :f1 or :f2 are on *features*")
+(load "../asdf")
+(asdf:run-shell-command "rm ~A ~A"
+ (namestring (compile-file-pathname "file1"))
+ (namestring (compile-file-pathname "file2")))
+(setf asdf:*central-registry* '(*default-pathname-defaults*))
+(in-package :asdf)
+(handler-case
+ (asdf:oos 'asdf:load-op 'test3)
+ (asdf:missing-dependency (c)
+ (format t "first test failed as expected: - ~%~A~%" c))
+ (:no-error (c) (error "should have failed, oops")))
+(pushnew :f1 *features*)
+(asdf:oos 'asdf:load-op 'test3)
+(assert (probe-file (compile-file-pathname "file1")))
+(assert (not (probe-file (compile-file-pathname "file2"))))
+(run-shell-command "rm ~A" (namestring (compile-file-pathname "file1")))
+(setf *features* (cons :f2 (cdr *features*)))
+(asdf:oos 'asdf:load-op 'test3)
+(assert (probe-file (compile-file-pathname "file2")))
+(assert (not (probe-file (compile-file-pathname "file1"))))
diff --git a/Lisp/asdf/test/test4.script b/Lisp/asdf/test/test4.script
new file mode 100644
index 0000000..e0ca859
--- /dev/null
+++ b/Lisp/asdf/test/test4.script
@@ -0,0 +1,8 @@
+;;; -*- Lisp -*-
+(load "../asdf")
+(setf asdf:*central-registry* '(*default-pathname-defaults*))
+(in-package :asdf)
+(assert (not (component-property (find-system 'test3) :foo)))
+(assert (equal (component-property (find-system 'test3) :prop1) "value"))
+(setf (component-property (find-system 'test3) :foo) "bar")
+(assert (equal (component-property (find-system 'test3) :foo) "bar"))
diff --git a/Lisp/asdf/test/wild-module.asd b/Lisp/asdf/test/wild-module.asd
new file mode 100644
index 0000000..8c09008
--- /dev/null
+++ b/Lisp/asdf/test/wild-module.asd
@@ -0,0 +1,6 @@
+;;; -*- Lisp -*-
+
+(asdf:defsystem wild-module
+ :version "0.0"
+ :components ((:wild-module "systems"
+ :pathname "*.asd")))
diff --git a/Lisp/asdf/test/wild-module.script b/Lisp/asdf/test/wild-module.script
new file mode 100644
index 0000000..c514693
--- /dev/null
+++ b/Lisp/asdf/test/wild-module.script
@@ -0,0 +1,7 @@
+;;; -*- Lisp -*-
+
+(load "../asdf")
+(load "../wild-modules")
+
+(setf asdf:*central-registry* '(*default-pathname-defaults*))
+(asdf:operate 'asdf:load-op 'wild-module)
diff --git a/Lisp/asdf/wild-modules.lisp b/Lisp/asdf/wild-modules.lisp
new file mode 100644
index 0000000..2649d7e
--- /dev/null
+++ b/Lisp/asdf/wild-modules.lisp
@@ -0,0 +1,38 @@
+(in-package :asdf)
+
+(defclass wild-module (module)
+ ((component-class :accessor wild-module-component-class
+ :initform 'static-file :initarg :component-class)
+ (component-options :accessor wild-module-component-options
+ :initform nil :initarg :component-options)))
+
+(defmethod (setf module-components) (new-value (module wild-module))
+ (when new-value
+ (sysdef-error "Cannot explicitly set wild-module ~A's components. Please ~
+use a wild pathname instead." module)))
+
+(defmethod reinitialize-instance :after ((self wild-module) &key)
+ (let ((pathname (slot-value self 'relative-pathname)))
+ (and pathname
+ (not (wild-pathname-p pathname))
+ (sysdef-error "Wild-module ~A specified with non-wild pathname ~A."
+ self pathname))
+ (setf (slot-value self 'components)
+ (let* ((*default-pathname-defaults* (component-parent-pathname self))
+ (files (directory (merge-pathnames (component-relative-pathname self))))
+ (class (wild-module-component-class self))
+ (options (wild-module-component-options self)))
+ (mapcar (lambda (file)
+ (apply #'make-instance class
+ :name (file-namestring file)
+ ;; XXX fails when wildcards are in
+ ;; the directory or higher parts.
+ :pathname file
+ :parent self
+ options))
+ files)))))
+
+;; Don't export wild-module or else will get a full warning
+;; when (require 'asdf) if asdf is already loaded
+
+;;(export '(wild-module))
diff --git a/Lisp/build-lisp-image.sh b/Lisp/build-lisp-image.sh
new file mode 100755
index 0000000..f741457
--- /dev/null
+++ b/Lisp/build-lisp-image.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+PATH="$HOME/bin:$PATH"
+export PATH
+
+build_clisp()
+{
+ mkdir $topdir/clisp/base
+ clisp -i save-moxie-image.lisp
+ gzip -c /tmp/lispinit.mem > base/lispinit.mem
+ rm -f /tmp/lispinit.mem
+}
+
+build_openmcl()
+{
+ openmcl -e '(load "save-moxie-image.lisp")'
+ mv /tmp/dppccl.image .
+}
+
+build_sbcl()
+{
+ sbcl --load "save-moxie-image.lisp"
+ mv /tmp/sbcl.core .
+}
+
+topdir=`dirname $0`
+
+#(cd "$topdir/clisp" && build_clisp)
+#(cd "$topdir/openmcl" && build_openmcl)
+(cd "$topdir/sbcl" && build_sbcl)
diff --git a/Lisp/clisp/clisp b/Lisp/clisp/clisp
new file mode 100755
index 0000000..dbf5ae4
--- /dev/null
+++ b/Lisp/clisp/clisp
Binary files differ
diff --git a/Lisp/clisp/save-moxie-image.lisp b/Lisp/clisp/save-moxie-image.lisp
new file mode 100644
index 0000000..7548ffa
--- /dev/null
+++ b/Lisp/clisp/save-moxie-image.lisp
@@ -0,0 +1,5 @@
+(load "../asdf/asdf")
+(pushnew (merge-pathnames ".lisp/systems/" (user-homedir-pathname))
+ asdf:*central-registry*)
+(asdf:operate 'asdf:load-op :moxie)
+(moxie::save-lisp-and-die "/tmp/lispinit.mem")
diff --git a/Lisp/init-template.lisp b/Lisp/init-template.lisp
new file mode 100644
index 0000000..7f348c8
--- /dev/null
+++ b/Lisp/init-template.lisp
@@ -0,0 +1,3 @@
+#-asdf (require 'asdf)
+#-moxie (asdf:operate 'asdf:load-op :moxie)
+(moxie::start-repl) \ No newline at end of file
diff --git a/Lisp/moxie/Map_Sym.txt b/Lisp/moxie/Map_Sym.txt
new file mode 100644
index 0000000..eb1a000
--- /dev/null
+++ b/Lisp/moxie/Map_Sym.txt
@@ -0,0 +1,1956 @@
+&ALLOW-OTHER-KEYS
+../Body/03_da.htm
+&AUX
+../Body/03_da.htm
+&BODY
+../Body/03_dd.htm
+&ENVIRONMENT
+../Body/03_dd.htm
+&KEY
+../Body/03_da.htm
+&OPTIONAL
+../Body/03_da.htm
+&REST
+../Body/03_da.htm
+&WHOLE
+../Body/03_dd.htm
+*
+../Body/a_st.htm
+**
+../Body/v__stst_.htm
+***
+../Body/v__stst_.htm
+*BREAK-ON-SIGNALS*
+../Body/v_break_.htm
+*COMPILE-FILE-PATHNAME*
+../Body/v_cmp_fi.htm
+*COMPILE-FILE-TRUENAME*
+../Body/v_cmp_fi.htm
+*COMPILE-PRINT*
+../Body/v_cmp_pr.htm
+*COMPILE-VERBOSE*
+../Body/v_cmp_pr.htm
+*DEBUG-IO*
+../Body/v_debug_.htm
+*DEBUGGER-HOOK*
+../Body/v_debugg.htm
+*DEFAULT-PATHNAME-DEFAULTS*
+../Body/v_defaul.htm
+*ERROR-OUTPUT*
+../Body/v_debug_.htm
+*FEATURES*
+../Body/v_featur.htm
+*GENSYM-COUNTER*
+../Body/v_gensym.htm
+*LOAD-PATHNAME*
+../Body/v_ld_pns.htm
+*LOAD-PRINT*
+../Body/v_ld_prs.htm
+*LOAD-TRUENAME*
+../Body/v_ld_pns.htm
+*LOAD-VERBOSE*
+../Body/v_ld_prs.htm
+*MACROEXPAND-HOOK*
+../Body/v_mexp_h.htm
+*MODULES*
+../Body/v_module.htm
+*PACKAGE*
+../Body/v_pkg.htm
+*PRINT-ARRAY*
+../Body/v_pr_ar.htm
+*PRINT-BASE*
+../Body/v_pr_bas.htm
+*PRINT-CASE*
+../Body/v_pr_cas.htm
+*PRINT-CIRCLE*
+../Body/v_pr_cir.htm
+*PRINT-ESCAPE*
+../Body/v_pr_esc.htm
+*PRINT-GENSYM*
+../Body/v_pr_gen.htm
+*PRINT-LENGTH*
+../Body/v_pr_lev.htm
+*PRINT-LEVEL*
+../Body/v_pr_lev.htm
+*PRINT-LINES*
+../Body/v_pr_lin.htm
+*PRINT-MISER-WIDTH*
+../Body/v_pr_mis.htm
+*PRINT-PPRINT-DISPATCH*
+../Body/v_pr_ppr.htm
+*PRINT-PRETTY*
+../Body/v_pr_pre.htm
+*PRINT-RADIX*
+../Body/v_pr_bas.htm
+*PRINT-READABLY*
+../Body/v_pr_rda.htm
+*PRINT-RIGHT-MARGIN*
+../Body/v_pr_rig.htm
+*QUERY-IO*
+../Body/v_debug_.htm
+*RANDOM-STATE*
+../Body/v_rnd_st.htm
+*READ-BASE*
+../Body/v_rd_bas.htm
+*READ-DEFAULT-FLOAT-FORMAT*
+../Body/v_rd_def.htm
+*READ-EVAL*
+../Body/v_rd_eva.htm
+*READ-SUPPRESS*
+../Body/v_rd_sup.htm
+*READTABLE*
+../Body/v_rdtabl.htm
+*STANDARD-INPUT*
+../Body/v_debug_.htm
+*STANDARD-OUTPUT*
+../Body/v_debug_.htm
+*TERMINAL-IO*
+../Body/v_termin.htm
+*TRACE-OUTPUT*
+../Body/v_debug_.htm
++
+../Body/a_pl.htm
+++
+../Body/v_pl_plp.htm
++++
+../Body/v_pl_plp.htm
+-
+../Body/a__.htm
+/
+../Body/a_sl.htm
+//
+../Body/v_sl_sls.htm
+///
+../Body/v_sl_sls.htm
+/=
+../Body/f_eq_sle.htm
+1+
+../Body/f_1pl_1_.htm
+1-
+../Body/f_1pl_1_.htm
+<
+../Body/f_eq_sle.htm
+<=
+../Body/f_eq_sle.htm
+=
+../Body/f_eq_sle.htm
+>
+../Body/f_eq_sle.htm
+>=
+../Body/f_eq_sle.htm
+ABORT
+../Body/a_abort.htm
+ABS
+../Body/f_abs.htm
+ACONS
+../Body/f_acons.htm
+ACOS
+../Body/f_asin_.htm
+ACOSH
+../Body/f_sinh_.htm
+ADD-METHOD
+../Body/f_add_me.htm
+ADJOIN
+../Body/f_adjoin.htm
+ADJUST-ARRAY
+../Body/f_adjust.htm
+ADJUSTABLE-ARRAY-P
+../Body/f_adju_1.htm
+ALLOCATE-INSTANCE
+../Body/f_alloca.htm
+ALPHA-CHAR-P
+../Body/f_alpha_.htm
+ALPHANUMERICP
+../Body/f_alphan.htm
+AND
+../Body/a_and.htm
+APPEND
+../Body/f_append.htm
+APPLY
+../Body/f_apply.htm
+APROPOS
+../Body/f_apropo.htm
+APROPOS-LIST
+../Body/f_apropo.htm
+AREF
+../Body/f_aref.htm
+ARITHMETIC-ERROR
+../Body/e_arithm.htm
+ARITHMETIC-ERROR-OPERANDS
+../Body/f_arithm.htm
+ARITHMETIC-ERROR-OPERATION
+../Body/f_arithm.htm
+ARRAY
+../Body/t_array.htm
+ARRAY-DIMENSION
+../Body/f_ar_dim.htm
+ARRAY-DIMENSION-LIMIT
+../Body/v_ar_dim.htm
+ARRAY-DIMENSIONS
+../Body/f_ar_d_1.htm
+ARRAY-DISPLACEMENT
+../Body/f_ar_dis.htm
+ARRAY-ELEMENT-TYPE
+../Body/f_ar_ele.htm
+ARRAY-HAS-FILL-POINTER-P
+../Body/f_ar_has.htm
+ARRAY-IN-BOUNDS-P
+../Body/f_ar_in_.htm
+ARRAY-RANK
+../Body/f_ar_ran.htm
+ARRAY-RANK-LIMIT
+../Body/v_ar_ran.htm
+ARRAY-ROW-MAJOR-INDEX
+../Body/f_ar_row.htm
+ARRAY-TOTAL-SIZE
+../Body/f_ar_tot.htm
+ARRAY-TOTAL-SIZE-LIMIT
+../Body/v_ar_tot.htm
+ARRAYP
+../Body/f_arrayp.htm
+ASH
+../Body/f_ash.htm
+ASIN
+../Body/f_asin_.htm
+ASINH
+../Body/f_sinh_.htm
+ASSERT
+../Body/m_assert.htm
+ASSOC
+../Body/f_assocc.htm
+ASSOC-IF
+../Body/f_assocc.htm
+ASSOC-IF-NOT
+../Body/f_assocc.htm
+ATAN
+../Body/f_asin_.htm
+ATANH
+../Body/f_sinh_.htm
+ATOM
+../Body/a_atom.htm
+BASE-CHAR
+../Body/t_base_c.htm
+BASE-STRING
+../Body/t_base_s.htm
+BIGNUM
+../Body/t_bignum.htm
+BIT
+../Body/a_bit.htm
+BIT-AND
+../Body/f_bt_and.htm
+BIT-ANDC1
+../Body/f_bt_and.htm
+BIT-ANDC2
+../Body/f_bt_and.htm
+BIT-EQV
+../Body/f_bt_and.htm
+BIT-IOR
+../Body/f_bt_and.htm
+BIT-NAND
+../Body/f_bt_and.htm
+BIT-NOR
+../Body/f_bt_and.htm
+BIT-NOT
+../Body/f_bt_and.htm
+BIT-ORC1
+../Body/f_bt_and.htm
+BIT-ORC2
+../Body/f_bt_and.htm
+BIT-VECTOR
+../Body/t_bt_vec.htm
+BIT-VECTOR-P
+../Body/f_bt_vec.htm
+BIT-XOR
+../Body/f_bt_and.htm
+BLOCK
+../Body/s_block.htm
+BOOLE
+../Body/f_boole.htm
+BOOLE-1
+../Body/v_b_1_b.htm
+BOOLE-2
+../Body/v_b_1_b.htm
+BOOLE-AND
+../Body/v_b_1_b.htm
+BOOLE-ANDC1
+../Body/v_b_1_b.htm
+BOOLE-ANDC2
+../Body/v_b_1_b.htm
+BOOLE-C1
+../Body/v_b_1_b.htm
+BOOLE-C2
+../Body/v_b_1_b.htm
+BOOLE-CLR
+../Body/v_b_1_b.htm
+BOOLE-EQV
+../Body/v_b_1_b.htm
+BOOLE-IOR
+../Body/v_b_1_b.htm
+BOOLE-NAND
+../Body/v_b_1_b.htm
+BOOLE-NOR
+../Body/v_b_1_b.htm
+BOOLE-ORC1
+../Body/v_b_1_b.htm
+BOOLE-ORC2
+../Body/v_b_1_b.htm
+BOOLE-SET
+../Body/v_b_1_b.htm
+BOOLE-XOR
+../Body/v_b_1_b.htm
+BOOLEAN
+../Body/t_ban.htm
+BOTH-CASE-P
+../Body/f_upper_.htm
+BOUNDP
+../Body/f_boundp.htm
+BREAK
+../Body/f_break.htm
+BROADCAST-STREAM
+../Body/t_broadc.htm
+BROADCAST-STREAM-STREAMS
+../Body/f_broadc.htm
+BUILT-IN-CLASS
+../Body/t_built_.htm
+BUTLAST
+../Body/f_butlas.htm
+BYTE
+../Body/f_by_by.htm
+BYTE-POSITION
+../Body/f_by_by.htm
+BYTE-SIZE
+../Body/f_by_by.htm
+CAAAAR
+../Body/f_car_c.htm
+CAAADR
+../Body/f_car_c.htm
+CAAAR
+../Body/f_car_c.htm
+CAADAR
+../Body/f_car_c.htm
+CAADDR
+../Body/f_car_c.htm
+CAADR
+../Body/f_car_c.htm
+CAAR
+../Body/f_car_c.htm
+CADAAR
+../Body/f_car_c.htm
+CADADR
+../Body/f_car_c.htm
+CADAR
+../Body/f_car_c.htm
+CADDAR
+../Body/f_car_c.htm
+CADDDR
+../Body/f_car_c.htm
+CADDR
+../Body/f_car_c.htm
+CADR
+../Body/f_car_c.htm
+CALL-ARGUMENTS-LIMIT
+../Body/v_call_a.htm
+CALL-METHOD
+../Body/m_call_m.htm
+CALL-NEXT-METHOD
+../Body/f_call_n.htm
+CAR
+../Body/f_car_c.htm
+CASE
+../Body/m_case_.htm
+CATCH
+../Body/s_catch.htm
+CCASE
+../Body/m_case_.htm
+CDAAAR
+../Body/f_car_c.htm
+CDAADR
+../Body/f_car_c.htm
+CDAAR
+../Body/f_car_c.htm
+CDADAR
+../Body/f_car_c.htm
+CDADDR
+../Body/f_car_c.htm
+CDADR
+../Body/f_car_c.htm
+CDAR
+../Body/f_car_c.htm
+CDDAAR
+../Body/f_car_c.htm
+CDDADR
+../Body/f_car_c.htm
+CDDAR
+../Body/f_car_c.htm
+CDDDAR
+../Body/f_car_c.htm
+CDDDDR
+../Body/f_car_c.htm
+CDDDR
+../Body/f_car_c.htm
+CDDR
+../Body/f_car_c.htm
+CDR
+../Body/f_car_c.htm
+CEILING
+../Body/f_floorc.htm
+CELL-ERROR
+../Body/e_cell_e.htm
+CELL-ERROR-NAME
+../Body/f_cell_e.htm
+CERROR
+../Body/f_cerror.htm
+CHANGE-CLASS
+../Body/f_chg_cl.htm
+CHAR
+../Body/f_char_.htm
+CHAR-CODE
+../Body/f_char_c.htm
+CHAR-CODE-LIMIT
+../Body/v_char_c.htm
+CHAR-DOWNCASE
+../Body/f_char_u.htm
+CHAR-EQUAL
+../Body/f_chareq.htm
+CHAR-GREATERP
+../Body/f_chareq.htm
+CHAR-INT
+../Body/f_char_i.htm
+CHAR-LESSP
+../Body/f_chareq.htm
+CHAR-NAME
+../Body/f_char_n.htm
+CHAR-NOT-EQUAL
+../Body/f_chareq.htm
+CHAR-NOT-GREATERP
+../Body/f_chareq.htm
+CHAR-NOT-LESSP
+../Body/f_chareq.htm
+CHAR-UPCASE
+../Body/f_char_u.htm
+CHAR/=
+../Body/f_chareq.htm
+CHAR<
+../Body/f_chareq.htm
+CHAR<=
+../Body/f_chareq.htm
+CHAR=
+../Body/f_chareq.htm
+CHAR>
+../Body/f_chareq.htm
+CHAR>=
+../Body/f_chareq.htm
+CHARACTER
+../Body/a_ch.htm
+CHARACTERP
+../Body/f_chp.htm
+CHECK-TYPE
+../Body/m_check_.htm
+CIS
+../Body/f_cis.htm
+CLASS
+../Body/t_class.htm
+CLASS-NAME
+../Body/f_class_.htm
+CLASS-OF
+../Body/f_clas_1.htm
+CLEAR-INPUT
+../Body/f_clear_.htm
+CLEAR-OUTPUT
+../Body/f_finish.htm
+CLOSE
+../Body/f_close.htm
+CLRHASH
+../Body/f_clrhas.htm
+CODE-CHAR
+../Body/f_code_c.htm
+COERCE
+../Body/f_coerce.htm
+COMPILATION-SPEED
+../Body/d_optimi.htm
+COMPILE
+../Body/f_cmp.htm
+COMPILE-FILE
+../Body/f_cmp_fi.htm
+COMPILE-FILE-PATHNAME
+../Body/f_cmp__1.htm
+COMPILED-FUNCTION
+../Body/t_cmpd_f.htm
+COMPILED-FUNCTION-P
+../Body/f_cmpd_f.htm
+COMPILER-MACRO
+../Body/f_docume.htm
+COMPILER-MACRO-FUNCTION
+../Body/f_cmp_ma.htm
+COMPLEMENT
+../Body/f_comple.htm
+COMPLEX
+../Body/a_comple.htm
+COMPLEXP
+../Body/f_comp_3.htm
+COMPUTE-APPLICABLE-METHODS
+../Body/f_comput.htm
+COMPUTE-RESTARTS
+../Body/f_comp_1.htm
+CONCATENATE
+../Body/f_concat.htm
+CONCATENATED-STREAM
+../Body/t_concat.htm
+CONCATENATED-STREAM-STREAMS
+../Body/f_conc_1.htm
+COND
+../Body/m_cond.htm
+CONDITION
+../Body/e_cnd.htm
+CONJUGATE
+../Body/f_conjug.htm
+CONS
+../Body/a_cons.htm
+CONSP
+../Body/f_consp.htm
+CONSTANTLY
+../Body/f_cons_1.htm
+CONSTANTP
+../Body/f_consta.htm
+CONTINUE
+../Body/a_contin.htm
+CONTROL-ERROR
+../Body/e_contro.htm
+COPY-ALIST
+../Body/f_cp_ali.htm
+COPY-LIST
+../Body/f_cp_lis.htm
+COPY-PPRINT-DISPATCH
+../Body/f_cp_ppr.htm
+COPY-READTABLE
+../Body/f_cp_rdt.htm
+COPY-SEQ
+../Body/f_cp_seq.htm
+COPY-STRUCTURE
+../Body/f_cp_stu.htm
+COPY-SYMBOL
+../Body/f_cp_sym.htm
+COPY-TREE
+../Body/f_cp_tre.htm
+COS
+../Body/f_sin_c.htm
+COSH
+../Body/f_sinh_.htm
+COUNT
+../Body/f_countc.htm
+COUNT-IF
+../Body/f_countc.htm
+COUNT-IF-NOT
+../Body/f_countc.htm
+CTYPECASE
+../Body/m_tpcase.htm
+DEBUG
+../Body/d_optimi.htm
+DECF
+../Body/m_incf_.htm
+DECLAIM
+../Body/m_declai.htm
+DECLARATION
+../Body/d_declar.htm
+DECLARE
+../Body/s_declar.htm
+DECODE-FLOAT
+../Body/f_dec_fl.htm
+DECODE-UNIVERSAL-TIME
+../Body/f_dec_un.htm
+DEFCLASS
+../Body/m_defcla.htm
+DEFCONSTANT
+../Body/m_defcon.htm
+DEFGENERIC
+../Body/m_defgen.htm
+DEFINE-COMPILER-MACRO
+../Body/m_define.htm
+DEFINE-CONDITION
+../Body/m_defi_5.htm
+DEFINE-METHOD-COMBINATION
+../Body/m_defi_4.htm
+DEFINE-MODIFY-MACRO
+../Body/m_defi_2.htm
+DEFINE-SETF-EXPANDER
+../Body/m_defi_3.htm
+DEFINE-SYMBOL-MACRO
+../Body/m_defi_1.htm
+DEFMACRO
+../Body/m_defmac.htm
+DEFMETHOD
+../Body/m_defmet.htm
+DEFPACKAGE
+../Body/m_defpkg.htm
+DEFPARAMETER
+../Body/m_defpar.htm
+DEFSETF
+../Body/m_defset.htm
+DEFSTRUCT
+../Body/m_defstr.htm
+DEFTYPE
+../Body/m_deftp.htm
+DEFUN
+../Body/m_defun.htm
+DEFVAR
+../Body/m_defpar.htm
+DELETE
+../Body/f_rm_rm.htm
+DELETE-DUPLICATES
+../Body/f_rm_dup.htm
+DELETE-FILE
+../Body/f_del_fi.htm
+DELETE-IF
+../Body/f_rm_rm.htm
+DELETE-IF-NOT
+../Body/f_rm_rm.htm
+DELETE-PACKAGE
+../Body/f_del_pk.htm
+DENOMINATOR
+../Body/f_numera.htm
+DEPOSIT-FIELD
+../Body/f_deposi.htm
+DESCRIBE
+../Body/f_descri.htm
+DESCRIBE-OBJECT
+../Body/f_desc_1.htm
+DESTRUCTURING-BIND
+../Body/m_destru.htm
+DIGIT-CHAR
+../Body/f_digit_.htm
+DIGIT-CHAR-P
+../Body/f_digi_1.htm
+DIRECTORY
+../Body/f_dir.htm
+DIRECTORY-NAMESTRING
+../Body/f_namest.htm
+DISASSEMBLE
+../Body/f_disass.htm
+DIVISION-BY-ZERO
+../Body/e_divisi.htm
+DO
+../Body/m_do_do.htm
+DO*
+../Body/m_do_do.htm
+DO-ALL-SYMBOLS
+../Body/m_do_sym.htm
+DO-EXTERNAL-SYMBOLS
+../Body/m_do_sym.htm
+DO-SYMBOLS
+../Body/m_do_sym.htm
+DOCUMENTATION
+../Body/f_docume.htm
+DOLIST
+../Body/m_dolist.htm
+DOTIMES
+../Body/m_dotime.htm
+DOUBLE-FLOAT
+../Body/t_short_.htm
+DOUBLE-FLOAT-EPSILON
+../Body/v_short_.htm
+DOUBLE-FLOAT-NEGATIVE-EPSILON
+../Body/v_short_.htm
+DPB
+../Body/f_dpb.htm
+DRIBBLE
+../Body/f_dribbl.htm
+DYNAMIC-EXTENT
+../Body/d_dynami.htm
+ECASE
+../Body/m_case_.htm
+ECHO-STREAM
+../Body/t_echo_s.htm
+ECHO-STREAM-INPUT-STREAM
+../Body/f_echo_s.htm
+ECHO-STREAM-OUTPUT-STREAM
+../Body/f_echo_s.htm
+ED
+../Body/f_ed.htm
+EIGHTH
+../Body/f_firstc.htm
+ELT
+../Body/f_elt.htm
+ENCODE-UNIVERSAL-TIME
+../Body/f_encode.htm
+END-OF-FILE
+../Body/e_end_of.htm
+ENDP
+../Body/f_endp.htm
+ENOUGH-NAMESTRING
+../Body/f_namest.htm
+ENSURE-DIRECTORIES-EXIST
+../Body/f_ensu_1.htm
+ENSURE-GENERIC-FUNCTION
+../Body/f_ensure.htm
+EQ
+../Body/f_eq.htm
+EQL
+../Body/a_eql.htm
+EQUAL
+../Body/f_equal.htm
+EQUALP
+../Body/f_equalp.htm
+ERROR
+../Body/a_error.htm
+ETYPECASE
+../Body/m_tpcase.htm
+EVAL
+../Body/f_eval.htm
+EVAL-WHEN
+../Body/s_eval_w.htm
+EVENP
+../Body/f_evenpc.htm
+EVERY
+../Body/f_everyc.htm
+EXP
+../Body/f_exp_e.htm
+EXPORT
+../Body/f_export.htm
+EXPT
+../Body/f_exp_e.htm
+EXTENDED-CHAR
+../Body/t_extend.htm
+FBOUNDP
+../Body/f_fbound.htm
+FCEILING
+../Body/f_floorc.htm
+FDEFINITION
+../Body/f_fdefin.htm
+FFLOOR
+../Body/f_floorc.htm
+FIFTH
+../Body/f_firstc.htm
+FILE-AUTHOR
+../Body/f_file_a.htm
+FILE-ERROR
+../Body/e_file_e.htm
+FILE-ERROR-PATHNAME
+../Body/f_file_e.htm
+FILE-LENGTH
+../Body/f_file_l.htm
+FILE-NAMESTRING
+../Body/f_namest.htm
+FILE-POSITION
+../Body/f_file_p.htm
+FILE-STREAM
+../Body/t_file_s.htm
+FILE-STRING-LENGTH
+../Body/f_file_s.htm
+FILE-WRITE-DATE
+../Body/f_file_w.htm
+FILL
+../Body/f_fill.htm
+FILL-POINTER
+../Body/f_fill_p.htm
+FIND
+../Body/f_find_.htm
+FIND-ALL-SYMBOLS
+../Body/f_find_a.htm
+FIND-CLASS
+../Body/f_find_c.htm
+FIND-IF
+../Body/f_find_.htm
+FIND-IF-NOT
+../Body/f_find_.htm
+FIND-METHOD
+../Body/f_find_m.htm
+FIND-PACKAGE
+../Body/f_find_p.htm
+FIND-RESTART
+../Body/f_find_r.htm
+FIND-SYMBOL
+../Body/f_find_s.htm
+FINISH-OUTPUT
+../Body/f_finish.htm
+FIRST
+../Body/f_firstc.htm
+FIXNUM
+../Body/t_fixnum.htm
+FLET
+../Body/s_flet_.htm
+FLOAT
+../Body/a_float.htm
+FLOAT-DIGITS
+../Body/f_dec_fl.htm
+FLOAT-PRECISION
+../Body/f_dec_fl.htm
+FLOAT-RADIX
+../Body/f_dec_fl.htm
+FLOAT-SIGN
+../Body/f_dec_fl.htm
+FLOATING-POINT-INEXACT
+../Body/e_floa_1.htm
+FLOATING-POINT-INVALID-OPERATION
+../Body/e_floati.htm
+FLOATING-POINT-OVERFLOW
+../Body/e_floa_2.htm
+FLOATING-POINT-UNDERFLOW
+../Body/e_floa_3.htm
+FLOATP
+../Body/f_floatp.htm
+FLOOR
+../Body/f_floorc.htm
+FMAKUNBOUND
+../Body/f_fmakun.htm
+FORCE-OUTPUT
+../Body/f_finish.htm
+FORMAT
+../Body/f_format.htm
+FORMATTER
+../Body/m_format.htm
+FOURTH
+../Body/f_firstc.htm
+FRESH-LINE
+../Body/f_terpri.htm
+FROUND
+../Body/f_floorc.htm
+FTRUNCATE
+../Body/f_floorc.htm
+FTYPE
+../Body/d_ftype.htm
+FUNCALL
+../Body/f_funcal.htm
+FUNCTION
+../Body/a_fn.htm
+FUNCTION-KEYWORDS
+../Body/f_fn_kwd.htm
+FUNCTION-LAMBDA-EXPRESSION
+../Body/f_fn_lam.htm
+FUNCTIONP
+../Body/f_fnp.htm
+GCD
+../Body/f_gcd.htm
+GENERIC-FUNCTION
+../Body/t_generi.htm
+GENSYM
+../Body/f_gensym.htm
+GENTEMP
+../Body/f_gentem.htm
+GET
+../Body/f_get.htm
+GET-DECODED-TIME
+../Body/f_get_un.htm
+GET-DISPATCH-MACRO-CHARACTER
+../Body/f_set__1.htm
+GET-INTERNAL-REAL-TIME
+../Body/f_get_in.htm
+GET-INTERNAL-RUN-TIME
+../Body/f_get__1.htm
+GET-MACRO-CHARACTER
+../Body/f_set_ma.htm
+GET-OUTPUT-STREAM-STRING
+../Body/f_get_ou.htm
+GET-PROPERTIES
+../Body/f_get_pr.htm
+GET-SETF-EXPANSION
+../Body/f_get_se.htm
+GET-UNIVERSAL-TIME
+../Body/f_get_un.htm
+GETF
+../Body/f_getf.htm
+GETHASH
+../Body/f_gethas.htm
+GO
+../Body/s_go.htm
+GRAPHIC-CHAR-P
+../Body/f_graphi.htm
+HANDLER-BIND
+../Body/m_handle.htm
+HANDLER-CASE
+../Body/m_hand_1.htm
+HASH-TABLE
+../Body/t_hash_t.htm
+HASH-TABLE-COUNT
+../Body/f_hash_1.htm
+HASH-TABLE-P
+../Body/f_hash_t.htm
+HASH-TABLE-REHASH-SIZE
+../Body/f_hash_2.htm
+HASH-TABLE-REHASH-THRESHOLD
+../Body/f_hash_3.htm
+HASH-TABLE-SIZE
+../Body/f_hash_4.htm
+HASH-TABLE-TEST
+../Body/f_hash_5.htm
+HOST-NAMESTRING
+../Body/f_namest.htm
+IDENTITY
+../Body/f_identi.htm
+IF
+../Body/s_if.htm
+IGNORABLE
+../Body/d_ignore.htm
+IGNORE
+../Body/d_ignore.htm
+IGNORE-ERRORS
+../Body/m_ignore.htm
+IMAGPART
+../Body/f_realpa.htm
+IMPORT
+../Body/f_import.htm
+IN-PACKAGE
+../Body/m_in_pkg.htm
+INCF
+../Body/m_incf_.htm
+INITIALIZE-INSTANCE
+../Body/f_init_i.htm
+INLINE
+../Body/d_inline.htm
+INPUT-STREAM-P
+../Body/f_in_stm.htm
+INSPECT
+../Body/f_inspec.htm
+INTEGER
+../Body/t_intege.htm
+INTEGER-DECODE-FLOAT
+../Body/f_dec_fl.htm
+INTEGER-LENGTH
+../Body/f_intege.htm
+INTEGERP
+../Body/f_inte_1.htm
+INTERACTIVE-STREAM-P
+../Body/f_intera.htm
+INTERN
+../Body/f_intern.htm
+INTERNAL-TIME-UNITS-PER-SECOND
+../Body/v_intern.htm
+INTERSECTION
+../Body/f_isec_.htm
+INVALID-METHOD-ERROR
+../Body/f_invali.htm
+INVOKE-DEBUGGER
+../Body/f_invoke.htm
+INVOKE-RESTART
+../Body/f_invo_1.htm
+INVOKE-RESTART-INTERACTIVELY
+../Body/f_invo_2.htm
+ISQRT
+../Body/f_sqrt_.htm
+KEYWORD
+../Body/t_kwd.htm
+KEYWORDP
+../Body/f_kwdp.htm
+LABELS
+../Body/s_flet_.htm
+LAMBDA
+../Body/a_lambda.htm
+LAMBDA-LIST-KEYWORDS
+../Body/v_lambda.htm
+LAMBDA-PARAMETERS-LIMIT
+../Body/v_lamb_1.htm
+LAST
+../Body/f_last.htm
+LCM
+../Body/f_lcm.htm
+LDB
+../Body/f_ldb.htm
+LDB-TEST
+../Body/f_ldb_te.htm
+LDIFF
+../Body/f_ldiffc.htm
+LEAST-NEGATIVE-DOUBLE-FLOAT
+../Body/v_most_1.htm
+LEAST-NEGATIVE-LONG-FLOAT
+../Body/v_most_1.htm
+LEAST-NEGATIVE-NORMALIZED-DOUBLE-FLOAT
+../Body/v_most_1.htm
+LEAST-NEGATIVE-NORMALIZED-LONG-FLOAT
+../Body/v_most_1.htm
+LEAST-NEGATIVE-NORMALIZED-SHORT-FLOAT
+../Body/v_most_1.htm
+LEAST-NEGATIVE-NORMALIZED-SINGLE-FLOAT
+../Body/v_most_1.htm
+LEAST-NEGATIVE-SHORT-FLOAT
+../Body/v_most_1.htm
+LEAST-NEGATIVE-SINGLE-FLOAT
+../Body/v_most_1.htm
+LEAST-POSITIVE-DOUBLE-FLOAT
+../Body/v_most_1.htm
+LEAST-POSITIVE-LONG-FLOAT
+../Body/v_most_1.htm
+LEAST-POSITIVE-NORMALIZED-DOUBLE-FLOAT
+../Body/v_most_1.htm
+LEAST-POSITIVE-NORMALIZED-LONG-FLOAT
+../Body/v_most_1.htm
+LEAST-POSITIVE-NORMALIZED-SHORT-FLOAT
+../Body/v_most_1.htm
+LEAST-POSITIVE-NORMALIZED-SINGLE-FLOAT
+../Body/v_most_1.htm
+LEAST-POSITIVE-SHORT-FLOAT
+../Body/v_most_1.htm
+LEAST-POSITIVE-SINGLE-FLOAT
+../Body/v_most_1.htm
+LENGTH
+../Body/f_length.htm
+LET
+../Body/s_let_l.htm
+LET*
+../Body/s_let_l.htm
+LISP-IMPLEMENTATION-TYPE
+../Body/f_lisp_i.htm
+LISP-IMPLEMENTATION-VERSION
+../Body/f_lisp_i.htm
+LIST
+../Body/a_list.htm
+LIST*
+../Body/f_list_.htm
+LIST-ALL-PACKAGES
+../Body/f_list_a.htm
+LIST-LENGTH
+../Body/f_list_l.htm
+LISTEN
+../Body/f_listen.htm
+LISTP
+../Body/f_listp.htm
+LOAD
+../Body/f_load.htm
+LOAD-LOGICAL-PATHNAME-TRANSLATIONS
+../Body/f_ld_log.htm
+LOAD-TIME-VALUE
+../Body/s_ld_tim.htm
+LOCALLY
+../Body/s_locall.htm
+LOG
+../Body/f_log.htm
+LOGAND
+../Body/f_logand.htm
+LOGANDC1
+../Body/f_logand.htm
+LOGANDC2
+../Body/f_logand.htm
+LOGBITP
+../Body/f_logbtp.htm
+LOGCOUNT
+../Body/f_logcou.htm
+LOGEQV
+../Body/f_logand.htm
+LOGICAL-PATHNAME
+../Body/a_logica.htm
+LOGICAL-PATHNAME-TRANSLATIONS
+../Body/f_logica.htm
+LOGIOR
+../Body/f_logand.htm
+LOGNAND
+../Body/f_logand.htm
+LOGNOR
+../Body/f_logand.htm
+LOGNOT
+../Body/f_logand.htm
+LOGORC1
+../Body/f_logand.htm
+LOGORC2
+../Body/f_logand.htm
+LOGTEST
+../Body/f_logtes.htm
+LOGXOR
+../Body/f_logand.htm
+LONG-FLOAT
+../Body/t_short_.htm
+LONG-FLOAT-EPSILON
+../Body/v_short_.htm
+LONG-FLOAT-NEGATIVE-EPSILON
+../Body/v_short_.htm
+LONG-SITE-NAME
+../Body/f_short_.htm
+LOOP
+../Body/m_loop.htm
+LOOP-FINISH
+../Body/m_loop_f.htm
+LOWER-CASE-P
+../Body/f_upper_.htm
+MACHINE-INSTANCE
+../Body/f_mach_i.htm
+MACHINE-TYPE
+../Body/f_mach_t.htm
+MACHINE-VERSION
+../Body/f_mach_v.htm
+MACRO-FUNCTION
+../Body/f_macro_.htm
+MACROEXPAND
+../Body/f_mexp_.htm
+MACROEXPAND-1
+../Body/f_mexp_.htm
+MACROLET
+../Body/s_flet_.htm
+MAKE-ARRAY
+../Body/f_mk_ar.htm
+MAKE-BROADCAST-STREAM
+../Body/f_mk_bro.htm
+MAKE-CONCATENATED-STREAM
+../Body/f_mk_con.htm
+MAKE-CONDITION
+../Body/f_mk_cnd.htm
+MAKE-DISPATCH-MACRO-CHARACTER
+../Body/f_mk_dis.htm
+MAKE-ECHO-STREAM
+../Body/f_mk_ech.htm
+MAKE-HASH-TABLE
+../Body/f_mk_has.htm
+MAKE-INSTANCE
+../Body/f_mk_ins.htm
+MAKE-INSTANCES-OBSOLETE
+../Body/f_mk_i_1.htm
+MAKE-LIST
+../Body/f_mk_lis.htm
+MAKE-LOAD-FORM
+../Body/f_mk_ld_.htm
+MAKE-LOAD-FORM-SAVING-SLOTS
+../Body/f_mk_l_1.htm
+MAKE-METHOD
+../Body/m_call_m.htm
+MAKE-PACKAGE
+../Body/f_mk_pkg.htm
+MAKE-PATHNAME
+../Body/f_mk_pn.htm
+MAKE-RANDOM-STATE
+../Body/f_mk_rnd.htm
+MAKE-SEQUENCE
+../Body/f_mk_seq.htm
+MAKE-STRING
+../Body/f_mk_stg.htm
+MAKE-STRING-INPUT-STREAM
+../Body/f_mk_s_1.htm
+MAKE-STRING-OUTPUT-STREAM
+../Body/f_mk_s_2.htm
+MAKE-SYMBOL
+../Body/f_mk_sym.htm
+MAKE-SYNONYM-STREAM
+../Body/f_mk_syn.htm
+MAKE-TWO-WAY-STREAM
+../Body/f_mk_two.htm
+MAKUNBOUND
+../Body/f_makunb.htm
+MAP
+../Body/f_map.htm
+MAP-INTO
+../Body/f_map_in.htm
+MAPC
+../Body/f_mapc_.htm
+MAPCAN
+../Body/f_mapc_.htm
+MAPCAR
+../Body/f_mapc_.htm
+MAPCON
+../Body/f_mapc_.htm
+MAPHASH
+../Body/f_maphas.htm
+MAPL
+../Body/f_mapc_.htm
+MAPLIST
+../Body/f_mapc_.htm
+MASK-FIELD
+../Body/f_mask_f.htm
+MAX
+../Body/f_max_m.htm
+MEMBER
+../Body/a_member.htm
+MEMBER-IF
+../Body/f_mem_m.htm
+MEMBER-IF-NOT
+../Body/f_mem_m.htm
+MERGE
+../Body/f_merge.htm
+MERGE-PATHNAMES
+../Body/f_merge_.htm
+METHOD
+../Body/t_method.htm
+METHOD-COMBINATION
+../Body/a_method.htm
+METHOD-COMBINATION-ERROR
+../Body/f_meth_1.htm
+METHOD-QUALIFIERS
+../Body/f_method.htm
+MIN
+../Body/f_max_m.htm
+MINUSP
+../Body/f_minusp.htm
+MISMATCH
+../Body/f_mismat.htm
+MOD
+../Body/a_mod.htm
+MOST-NEGATIVE-DOUBLE-FLOAT
+../Body/v_most_1.htm
+MOST-NEGATIVE-FIXNUM
+../Body/v_most_p.htm
+MOST-NEGATIVE-LONG-FLOAT
+../Body/v_most_1.htm
+MOST-NEGATIVE-SHORT-FLOAT
+../Body/v_most_1.htm
+MOST-NEGATIVE-SINGLE-FLOAT
+../Body/v_most_1.htm
+MOST-POSITIVE-DOUBLE-FLOAT
+../Body/v_most_1.htm
+MOST-POSITIVE-FIXNUM
+../Body/v_most_p.htm
+MOST-POSITIVE-LONG-FLOAT
+../Body/v_most_1.htm
+MOST-POSITIVE-SHORT-FLOAT
+../Body/v_most_1.htm
+MOST-POSITIVE-SINGLE-FLOAT
+../Body/v_most_1.htm
+MUFFLE-WARNING
+../Body/a_muffle.htm
+MULTIPLE-VALUE-BIND
+../Body/m_multip.htm
+MULTIPLE-VALUE-CALL
+../Body/s_multip.htm
+MULTIPLE-VALUE-LIST
+../Body/m_mult_1.htm
+MULTIPLE-VALUE-PROG1
+../Body/s_mult_1.htm
+MULTIPLE-VALUE-SETQ
+../Body/m_mult_2.htm
+MULTIPLE-VALUES-LIMIT
+../Body/v_multip.htm
+NAME-CHAR
+../Body/f_name_c.htm
+NAMESTRING
+../Body/f_namest.htm
+NBUTLAST
+../Body/f_butlas.htm
+NCONC
+../Body/f_nconc.htm
+NEXT-METHOD-P
+../Body/f_next_m.htm
+NIL
+../Body/a_nil.htm
+NINTERSECTION
+../Body/f_isec_.htm
+NINTH
+../Body/f_firstc.htm
+NO-APPLICABLE-METHOD
+../Body/f_no_app.htm
+NO-NEXT-METHOD
+../Body/f_no_nex.htm
+NOT
+../Body/a_not.htm
+NOTANY
+../Body/f_everyc.htm
+NOTEVERY
+../Body/f_everyc.htm
+NOTINLINE
+../Body/d_inline.htm
+NRECONC
+../Body/f_revapp.htm
+NREVERSE
+../Body/f_revers.htm
+NSET-DIFFERENCE
+../Body/f_set_di.htm
+NSET-EXCLUSIVE-OR
+../Body/f_set_ex.htm
+NSTRING-CAPITALIZE
+../Body/f_stg_up.htm
+NSTRING-DOWNCASE
+../Body/f_stg_up.htm
+NSTRING-UPCASE
+../Body/f_stg_up.htm
+NSUBLIS
+../Body/f_sublis.htm
+NSUBST
+../Body/f_substc.htm
+NSUBST-IF
+../Body/f_substc.htm
+NSUBST-IF-NOT
+../Body/f_substc.htm
+NSUBSTITUTE
+../Body/f_sbs_s.htm
+NSUBSTITUTE-IF
+../Body/f_sbs_s.htm
+NSUBSTITUTE-IF-NOT
+../Body/f_sbs_s.htm
+NTH
+../Body/f_nth.htm
+NTH-VALUE
+../Body/m_nth_va.htm
+NTHCDR
+../Body/f_nthcdr.htm
+NULL
+../Body/a_null.htm
+NUMBER
+../Body/t_number.htm
+NUMBERP
+../Body/f_nump.htm
+NUMERATOR
+../Body/f_numera.htm
+NUNION
+../Body/f_unionc.htm
+ODDP
+../Body/f_evenpc.htm
+OPEN
+../Body/f_open.htm
+OPEN-STREAM-P
+../Body/f_open_s.htm
+OPTIMIZE
+../Body/d_optimi.htm
+OR
+../Body/a_or.htm
+OTHERWISE
+../Body/m_case_.htm
+OUTPUT-STREAM-P
+../Body/f_in_stm.htm
+PACKAGE
+../Body/t_pkg.htm
+PACKAGE-ERROR
+../Body/e_pkg_er.htm
+PACKAGE-ERROR-PACKAGE
+../Body/f_pkg_er.htm
+PACKAGE-NAME
+../Body/f_pkg_na.htm
+PACKAGE-NICKNAMES
+../Body/f_pkg_ni.htm
+PACKAGE-SHADOWING-SYMBOLS
+../Body/f_pkg_sh.htm
+PACKAGE-USE-LIST
+../Body/f_pkg_us.htm
+PACKAGE-USED-BY-LIST
+../Body/f_pkg__1.htm
+PACKAGEP
+../Body/f_pkgp.htm
+PAIRLIS
+../Body/f_pairli.htm
+PARSE-ERROR
+../Body/e_parse_.htm
+PARSE-INTEGER
+../Body/f_parse_.htm
+PARSE-NAMESTRING
+../Body/f_pars_1.htm
+PATHNAME
+../Body/a_pn.htm
+PATHNAME-DEVICE
+../Body/f_pn_hos.htm
+PATHNAME-DIRECTORY
+../Body/f_pn_hos.htm
+PATHNAME-HOST
+../Body/f_pn_hos.htm
+PATHNAME-MATCH-P
+../Body/f_pn_mat.htm
+PATHNAME-NAME
+../Body/f_pn_hos.htm
+PATHNAME-TYPE
+../Body/f_pn_hos.htm
+PATHNAME-VERSION
+../Body/f_pn_hos.htm
+PATHNAMEP
+../Body/f_pnp.htm
+PEEK-CHAR
+../Body/f_peek_c.htm
+PHASE
+../Body/f_phase.htm
+PI
+../Body/v_pi.htm
+PLUSP
+../Body/f_minusp.htm
+POP
+../Body/m_pop.htm
+POSITION
+../Body/f_pos_p.htm
+POSITION-IF
+../Body/f_pos_p.htm
+POSITION-IF-NOT
+../Body/f_pos_p.htm
+PPRINT
+../Body/f_wr_pr.htm
+PPRINT-DISPATCH
+../Body/f_ppr_di.htm
+PPRINT-EXIT-IF-LIST-EXHAUSTED
+../Body/m_ppr_ex.htm
+PPRINT-FILL
+../Body/f_ppr_fi.htm
+PPRINT-INDENT
+../Body/f_ppr_in.htm
+PPRINT-LINEAR
+../Body/f_ppr_fi.htm
+PPRINT-LOGICAL-BLOCK
+../Body/m_ppr_lo.htm
+PPRINT-NEWLINE
+../Body/f_ppr_nl.htm
+PPRINT-POP
+../Body/m_ppr_po.htm
+PPRINT-TAB
+../Body/f_ppr_ta.htm
+PPRINT-TABULAR
+../Body/f_ppr_fi.htm
+PRIN1
+../Body/f_wr_pr.htm
+PRIN1-TO-STRING
+../Body/f_wr_to_.htm
+PRINC
+../Body/f_wr_pr.htm
+PRINC-TO-STRING
+../Body/f_wr_to_.htm
+PRINT
+../Body/f_wr_pr.htm
+PRINT-NOT-READABLE
+../Body/e_pr_not.htm
+PRINT-NOT-READABLE-OBJECT
+../Body/f_pr_not.htm
+PRINT-OBJECT
+../Body/f_pr_obj.htm
+PRINT-UNREADABLE-OBJECT
+../Body/m_pr_unr.htm
+PROBE-FILE
+../Body/f_probe_.htm
+PROCLAIM
+../Body/f_procla.htm
+PROG
+../Body/m_prog_.htm
+PROG*
+../Body/m_prog_.htm
+PROG1
+../Body/m_prog1c.htm
+PROG2
+../Body/m_prog1c.htm
+PROGN
+../Body/s_progn.htm
+PROGRAM-ERROR
+../Body/e_progra.htm
+PROGV
+../Body/s_progv.htm
+PROVIDE
+../Body/f_provid.htm
+PSETF
+../Body/m_setf_.htm
+PSETQ
+../Body/m_psetq.htm
+PUSH
+../Body/m_push.htm
+PUSHNEW
+../Body/m_pshnew.htm
+QUOTE
+../Body/s_quote.htm
+RANDOM
+../Body/f_random.htm
+RANDOM-STATE
+../Body/t_rnd_st.htm
+RANDOM-STATE-P
+../Body/f_rnd_st.htm
+RASSOC
+../Body/f_rassoc.htm
+RASSOC-IF
+../Body/f_rassoc.htm
+RASSOC-IF-NOT
+../Body/f_rassoc.htm
+RATIO
+../Body/t_ratio.htm
+RATIONAL
+../Body/a_ration.htm
+RATIONALIZE
+../Body/f_ration.htm
+RATIONALP
+../Body/f_rati_1.htm
+READ
+../Body/f_rd_rd.htm
+READ-BYTE
+../Body/f_rd_by.htm
+READ-CHAR
+../Body/f_rd_cha.htm
+READ-CHAR-NO-HANG
+../Body/f_rd_c_1.htm
+READ-DELIMITED-LIST
+../Body/f_rd_del.htm
+READ-FROM-STRING
+../Body/f_rd_fro.htm
+READ-LINE
+../Body/f_rd_lin.htm
+READ-PRESERVING-WHITESPACE
+../Body/f_rd_rd.htm
+READ-SEQUENCE
+../Body/f_rd_seq.htm
+READER-ERROR
+../Body/e_rder_e.htm
+READTABLE
+../Body/t_rdtabl.htm
+READTABLE-CASE
+../Body/f_rdtabl.htm
+READTABLEP
+../Body/f_rdta_1.htm
+REAL
+../Body/t_real.htm
+REALP
+../Body/f_realp.htm
+REALPART
+../Body/f_realpa.htm
+REDUCE
+../Body/f_reduce.htm
+REINITIALIZE-INSTANCE
+../Body/f_reinit.htm
+REM
+../Body/f_mod_r.htm
+REMF
+../Body/m_remf.htm
+REMHASH
+../Body/f_remhas.htm
+REMOVE
+../Body/f_rm_rm.htm
+REMOVE-DUPLICATES
+../Body/f_rm_dup.htm
+REMOVE-IF
+../Body/f_rm_rm.htm
+REMOVE-IF-NOT
+../Body/f_rm_rm.htm
+REMOVE-METHOD
+../Body/f_rm_met.htm
+REMPROP
+../Body/f_rempro.htm
+RENAME-FILE
+../Body/f_rn_fil.htm
+RENAME-PACKAGE
+../Body/f_rn_pkg.htm
+REPLACE
+../Body/f_replac.htm
+REQUIRE
+../Body/f_provid.htm
+REST
+../Body/f_rest.htm
+RESTART
+../Body/t_rst.htm
+RESTART-BIND
+../Body/m_rst_bi.htm
+RESTART-CASE
+../Body/m_rst_ca.htm
+RESTART-NAME
+../Body/f_rst_na.htm
+RETURN
+../Body/m_return.htm
+RETURN-FROM
+../Body/s_ret_fr.htm
+REVAPPEND
+../Body/f_revapp.htm
+REVERSE
+../Body/f_revers.htm
+ROOM
+../Body/f_room.htm
+ROTATEF
+../Body/m_rotate.htm
+ROUND
+../Body/f_floorc.htm
+ROW-MAJOR-AREF
+../Body/f_row_ma.htm
+RPLACA
+../Body/f_rplaca.htm
+RPLACD
+../Body/f_rplaca.htm
+SAFETY
+../Body/d_optimi.htm
+SATISFIES
+../Body/t_satisf.htm
+SBIT
+../Body/f_bt_sb.htm
+SCALE-FLOAT
+../Body/f_dec_fl.htm
+SCHAR
+../Body/f_char_.htm
+SEARCH
+../Body/f_search.htm
+SECOND
+../Body/f_firstc.htm
+SEQUENCE
+../Body/t_seq.htm
+SERIOUS-CONDITION
+../Body/e_seriou.htm
+SET
+../Body/f_set.htm
+SET-DIFFERENCE
+../Body/f_set_di.htm
+SET-DISPATCH-MACRO-CHARACTER
+../Body/f_set__1.htm
+SET-EXCLUSIVE-OR
+../Body/f_set_ex.htm
+SET-MACRO-CHARACTER
+../Body/f_set_ma.htm
+SET-PPRINT-DISPATCH
+../Body/f_set_pp.htm
+SET-SYNTAX-FROM-CHAR
+../Body/f_set_sy.htm
+SETF
+../Body/a_setf.htm
+SETQ
+../Body/s_setq.htm
+SEVENTH
+../Body/f_firstc.htm
+SHADOW
+../Body/f_shadow.htm
+SHADOWING-IMPORT
+../Body/f_shdw_i.htm
+SHARED-INITIALIZE
+../Body/f_shared.htm
+SHIFTF
+../Body/m_shiftf.htm
+SHORT-FLOAT
+../Body/t_short_.htm
+SHORT-FLOAT-EPSILON
+../Body/v_short_.htm
+SHORT-FLOAT-NEGATIVE-EPSILON
+../Body/v_short_.htm
+SHORT-SITE-NAME
+../Body/f_short_.htm
+SIGNAL
+../Body/f_signal.htm
+SIGNED-BYTE
+../Body/t_sgn_by.htm
+SIGNUM
+../Body/f_signum.htm
+SIMPLE-ARRAY
+../Body/t_smp_ar.htm
+SIMPLE-BASE-STRING
+../Body/t_smp_ba.htm
+SIMPLE-BIT-VECTOR
+../Body/t_smp_bt.htm
+SIMPLE-BIT-VECTOR-P
+../Body/f_smp_bt.htm
+SIMPLE-CONDITION
+../Body/e_smp_cn.htm
+SIMPLE-CONDITION-FORMAT-ARGUMENTS
+../Body/f_smp_cn.htm
+SIMPLE-CONDITION-FORMAT-CONTROL
+../Body/f_smp_cn.htm
+SIMPLE-ERROR
+../Body/e_smp_er.htm
+SIMPLE-STRING
+../Body/t_smp_st.htm
+SIMPLE-STRING-P
+../Body/f_smp_st.htm
+SIMPLE-TYPE-ERROR
+../Body/e_smp_tp.htm
+SIMPLE-VECTOR
+../Body/t_smp_ve.htm
+SIMPLE-VECTOR-P
+../Body/f_smp_ve.htm
+SIMPLE-WARNING
+../Body/e_smp_wa.htm
+SIN
+../Body/f_sin_c.htm
+SINGLE-FLOAT
+../Body/t_short_.htm
+SINGLE-FLOAT-EPSILON
+../Body/v_short_.htm
+SINGLE-FLOAT-NEGATIVE-EPSILON
+../Body/v_short_.htm
+SINH
+../Body/f_sinh_.htm
+SIXTH
+../Body/f_firstc.htm
+SLEEP
+../Body/f_sleep.htm
+SLOT-BOUNDP
+../Body/f_slt_bo.htm
+SLOT-EXISTS-P
+../Body/f_slt_ex.htm
+SLOT-MAKUNBOUND
+../Body/f_slt_ma.htm
+SLOT-MISSING
+../Body/f_slt_mi.htm
+SLOT-UNBOUND
+../Body/f_slt_un.htm
+SLOT-VALUE
+../Body/f_slt_va.htm
+SOFTWARE-TYPE
+../Body/f_sw_tpc.htm
+SOFTWARE-VERSION
+../Body/f_sw_tpc.htm
+SOME
+../Body/f_everyc.htm
+SORT
+../Body/f_sort_.htm
+SPACE
+../Body/d_optimi.htm
+SPECIAL
+../Body/d_specia.htm
+SPECIAL-OPERATOR-P
+../Body/f_specia.htm
+SPEED
+../Body/d_optimi.htm
+SQRT
+../Body/f_sqrt_.htm
+STABLE-SORT
+../Body/f_sort_.htm
+STANDARD
+../Body/07_ffb.htm
+STANDARD-CHAR
+../Body/t_std_ch.htm
+STANDARD-CHAR-P
+../Body/f_std_ch.htm
+STANDARD-CLASS
+../Body/t_std_cl.htm
+STANDARD-GENERIC-FUNCTION
+../Body/t_std_ge.htm
+STANDARD-METHOD
+../Body/t_std_me.htm
+STANDARD-OBJECT
+../Body/t_std_ob.htm
+STEP
+../Body/m_step.htm
+STORAGE-CONDITION
+../Body/e_storag.htm
+STORE-VALUE
+../Body/a_store_.htm
+STREAM
+../Body/t_stream.htm
+STREAM-ELEMENT-TYPE
+../Body/f_stm_el.htm
+STREAM-ERROR
+../Body/e_stm_er.htm
+STREAM-ERROR-STREAM
+../Body/f_stm_er.htm
+STREAM-EXTERNAL-FORMAT
+../Body/f_stm_ex.htm
+STREAMP
+../Body/f_stmp.htm
+STRING
+../Body/a_string.htm
+STRING-CAPITALIZE
+../Body/f_stg_up.htm
+STRING-DOWNCASE
+../Body/f_stg_up.htm
+STRING-EQUAL
+../Body/f_stgeq_.htm
+STRING-GREATERP
+../Body/f_stgeq_.htm
+STRING-LEFT-TRIM
+../Body/f_stg_tr.htm
+STRING-LESSP
+../Body/f_stgeq_.htm
+STRING-NOT-EQUAL
+../Body/f_stgeq_.htm
+STRING-NOT-GREATERP
+../Body/f_stgeq_.htm
+STRING-NOT-LESSP
+../Body/f_stgeq_.htm
+STRING-RIGHT-TRIM
+../Body/f_stg_tr.htm
+STRING-STREAM
+../Body/t_stg_st.htm
+STRING-TRIM
+../Body/f_stg_tr.htm
+STRING-UPCASE
+../Body/f_stg_up.htm
+STRING/=
+../Body/f_stgeq_.htm
+STRING<
+../Body/f_stgeq_.htm
+STRING<=
+../Body/f_stgeq_.htm
+STRING=
+../Body/f_stgeq_.htm
+STRING>
+../Body/f_stgeq_.htm
+STRING>=
+../Body/f_stgeq_.htm
+STRINGP
+../Body/f_stgp.htm
+STRUCTURE
+../Body/f_docume.htm
+STRUCTURE-CLASS
+../Body/t_stu_cl.htm
+STRUCTURE-OBJECT
+../Body/t_stu_ob.htm
+STYLE-WARNING
+../Body/e_style_.htm
+SUBLIS
+../Body/f_sublis.htm
+SUBSEQ
+../Body/f_subseq.htm
+SUBSETP
+../Body/f_subset.htm
+SUBST
+../Body/f_substc.htm
+SUBST-IF
+../Body/f_substc.htm
+SUBST-IF-NOT
+../Body/f_substc.htm
+SUBSTITUTE
+../Body/f_sbs_s.htm
+SUBSTITUTE-IF
+../Body/f_sbs_s.htm
+SUBSTITUTE-IF-NOT
+../Body/f_sbs_s.htm
+SUBTYPEP
+../Body/f_subtpp.htm
+SVREF
+../Body/f_svref.htm
+SXHASH
+../Body/f_sxhash.htm
+SYMBOL
+../Body/t_symbol.htm
+SYMBOL-FUNCTION
+../Body/f_symb_1.htm
+SYMBOL-MACROLET
+../Body/s_symbol.htm
+SYMBOL-NAME
+../Body/f_symb_2.htm
+SYMBOL-PACKAGE
+../Body/f_symb_3.htm
+SYMBOL-PLIST
+../Body/f_symb_4.htm
+SYMBOL-VALUE
+../Body/f_symb_5.htm
+SYMBOLP
+../Body/f_symbol.htm
+SYNONYM-STREAM
+../Body/t_syn_st.htm
+SYNONYM-STREAM-SYMBOL
+../Body/f_syn_st.htm
+T
+../Body/a_t.htm
+TAGBODY
+../Body/s_tagbod.htm
+TAILP
+../Body/f_ldiffc.htm
+TAN
+../Body/f_sin_c.htm
+TANH
+../Body/f_sinh_.htm
+TENTH
+../Body/f_firstc.htm
+TERPRI
+../Body/f_terpri.htm
+THE
+../Body/s_the.htm
+THIRD
+../Body/f_firstc.htm
+THROW
+../Body/s_throw.htm
+TIME
+../Body/m_time.htm
+TRACE
+../Body/m_tracec.htm
+TRANSLATE-LOGICAL-PATHNAME
+../Body/f_tr_log.htm
+TRANSLATE-PATHNAME
+../Body/f_tr_pn.htm
+TREE-EQUAL
+../Body/f_tree_e.htm
+TRUENAME
+../Body/f_tn.htm
+TRUNCATE
+../Body/f_floorc.htm
+TWO-WAY-STREAM
+../Body/t_two_wa.htm
+TWO-WAY-STREAM-INPUT-STREAM
+../Body/f_two_wa.htm
+TWO-WAY-STREAM-OUTPUT-STREAM
+../Body/f_two_wa.htm
+TYPE
+../Body/a_type.htm
+TYPE-ERROR
+../Body/e_tp_err.htm
+TYPE-ERROR-DATUM
+../Body/f_tp_err.htm
+TYPE-ERROR-EXPECTED-TYPE
+../Body/f_tp_err.htm
+TYPE-OF
+../Body/f_tp_of.htm
+TYPECASE
+../Body/m_tpcase.htm
+TYPEP
+../Body/f_typep.htm
+UNBOUND-SLOT
+../Body/e_unboun.htm
+UNBOUND-SLOT-INSTANCE
+../Body/f_unboun.htm
+UNBOUND-VARIABLE
+../Body/e_unbo_1.htm
+UNDEFINED-FUNCTION
+../Body/e_undefi.htm
+UNEXPORT
+../Body/f_unexpo.htm
+UNINTERN
+../Body/f_uninte.htm
+UNION
+../Body/f_unionc.htm
+UNLESS
+../Body/m_when_.htm
+UNREAD-CHAR
+../Body/f_unrd_c.htm
+UNSIGNED-BYTE
+../Body/t_unsgn_.htm
+UNTRACE
+../Body/m_tracec.htm
+UNUSE-PACKAGE
+../Body/f_unuse_.htm
+UNWIND-PROTECT
+../Body/s_unwind.htm
+UPDATE-INSTANCE-FOR-DIFFERENT-CLASS
+../Body/f_update.htm
+UPDATE-INSTANCE-FOR-REDEFINED-CLASS
+../Body/f_upda_1.htm
+UPGRADED-ARRAY-ELEMENT-TYPE
+../Body/f_upgr_1.htm
+UPGRADED-COMPLEX-PART-TYPE
+../Body/f_upgrad.htm
+UPPER-CASE-P
+../Body/f_upper_.htm
+USE-PACKAGE
+../Body/f_use_pk.htm
+USE-VALUE
+../Body/a_use_va.htm
+USER-HOMEDIR-PATHNAME
+../Body/f_user_h.htm
+VALUES
+../Body/a_values.htm
+VALUES-LIST
+../Body/f_vals_l.htm
+VARIABLE
+../Body/f_docume.htm
+VECTOR
+../Body/a_vector.htm
+VECTOR-POP
+../Body/f_vec_po.htm
+VECTOR-PUSH
+../Body/f_vec_ps.htm
+VECTOR-PUSH-EXTEND
+../Body/f_vec_ps.htm
+VECTORP
+../Body/f_vecp.htm
+WARN
+../Body/f_warn.htm
+WARNING
+../Body/e_warnin.htm
+WHEN
+../Body/m_when_.htm
+WILD-PATHNAME-P
+../Body/f_wild_p.htm
+WITH-ACCESSORS
+../Body/m_w_acce.htm
+WITH-COMPILATION-UNIT
+../Body/m_w_comp.htm
+WITH-CONDITION-RESTARTS
+../Body/m_w_cnd_.htm
+WITH-HASH-TABLE-ITERATOR
+../Body/m_w_hash.htm
+WITH-INPUT-FROM-STRING
+../Body/m_w_in_f.htm
+WITH-OPEN-FILE
+../Body/m_w_open.htm
+WITH-OPEN-STREAM
+../Body/m_w_op_1.htm
+WITH-OUTPUT-TO-STRING
+../Body/m_w_out_.htm
+WITH-PACKAGE-ITERATOR
+../Body/m_w_pkg_.htm
+WITH-SIMPLE-RESTART
+../Body/m_w_smp_.htm
+WITH-SLOTS
+../Body/m_w_slts.htm
+WITH-STANDARD-IO-SYNTAX
+../Body/m_w_std_.htm
+WRITE
+../Body/f_wr_pr.htm
+WRITE-BYTE
+../Body/f_wr_by.htm
+WRITE-CHAR
+../Body/f_wr_cha.htm
+WRITE-LINE
+../Body/f_wr_stg.htm
+WRITE-SEQUENCE
+../Body/f_wr_seq.htm
+WRITE-STRING
+../Body/f_wr_stg.htm
+WRITE-TO-STRING
+../Body/f_wr_to_.htm
+Y-OR-N-P
+../Body/f_y_or_n.htm
+YES-OR-NO-P
+../Body/f_y_or_n.htm
+ZEROP
+../Body/f_zerop.htm
diff --git a/Lisp/moxie/Mop_Sym.txt b/Lisp/moxie/Mop_Sym.txt
new file mode 100644
index 0000000..1647166
--- /dev/null
+++ b/Lisp/moxie/Mop_Sym.txt
@@ -0,0 +1,128 @@
+SPEC2
+dictionary.html#spec2
+ADD-DEPENDENT
+dictionary.html#add-dependent
+ADD-DIRECT-METHOD
+dictionary.html#add-direct-method
+ADD-DIRECT-SUBCLASS
+dictionary.html#add-direct-subclass
+ADD-METHOD
+dictionary.html#add-method
+ALLOCATE-INSTANCE
+dictionary.html#allocate-instance
+CLASS-
+dictionary.html#class-
+COMPUTE-APPLICABLE-METHODS
+dictionary.html#compute-applicable-methods
+COMPUTE-APPLICABLE-METHODS-USING-CLASSES
+dictionary.html#compute-applicable-methods-using-classes
+COMPUTE-CLASS-PRECEDENCE-LIST
+dictionary.html#compute-class-precedence-list
+COMPUTE-DEFAULT-INITARGS
+dictionary.html#compute-default-initargs
+COMPUTE-DISCRIMINATING-FUNCTION
+dictionary.html#compute-discriminating-function
+COMPUTE-EFFECTIVE-METHOD
+dictionary.html#compute-effective-method
+COMPUTE-EFFECTIVE-SLOT-DEFINITION
+dictionary.html#compute-effective-slot-definition
+COMPUTE-SLOTS
+dictionary.html#compute-slots
+DIRECT-SLOT-DEFINITION-CLASS
+dictionary.html#direct-slot-definition-class
+EFFECTIVE-SLOT-DEFINITION-CLASS
+dictionary.html#effective-slot-definition-class
+ENSURE-CLASS
+dictionary.html#ensure-class
+ENSURE-CLASS-USING-CLASS
+dictionary.html#ensure-class-using-class
+ENSURE-GENERIC-FUNCTION
+dictionary.html#ensure-generic-function
+ENSURE-GENERIC-FUNCTION-USING-CLASS
+dictionary.html#ensure-generic-function-using-class
+EQL-SPECIALIZER-OBJECT
+dictionary.html#eql-specializer-object
+EXTRACT-LAMBDA-LIST
+dictionary.html#extract-lambda-list
+EXTRACT-SPECIALIZER-NAMES
+dictionary.html#extract-specializer-names
+FINALIZE-INHERITANCE
+dictionary.html#finalize-inheritance
+FIND-METHOD-COMBINATION
+dictionary.html#find-method-combination
+FUNCALLABLE-STANDARD-INSTANCE-ACCESS
+dictionary.html#funcallable-standard-instance-access
+GENERIC-FUNCTION-
+dictionary.html#generic-function-
+</A>
+dictionary.html#</a>
+CLASS-MO-INITARGS
+dictionary.html#class-mo-initargs
+</A>
+dictionary.html#</a>
+GF-MO-INITARGS
+dictionary.html#gf-mo-initargs
+INITIALIZATION
+dictionary.html#Initialization
+METHOD-MO-INITARGS
+dictionary.html#method-mo-initargs
+INITIALIZATION
+dictionary.html#Initialization
+SLOTD-MO-INITARGS
+dictionary.html#slotd-mo-initargs
+INTERN-EQL-SPECIALIZER
+dictionary.html#intern-eql-specializer
+MAKE-INSTANCE
+dictionary.html#make-instance
+MAKE-METHOD-LAMBDA
+dictionary.html#make-method-lambda
+MAP-DEPENDENTS
+dictionary.html#map-dependents
+METHOD-
+dictionary.html#method-
+CLASS-MO-READERS
+dictionary.html#class-mo-readers
+GF-MO-READERS
+dictionary.html#gf-mo-readers
+METHOD-MO-READERS
+dictionary.html#method-mo-readers
+SLOTD-MO-READERS
+dictionary.html#slotd-mo-readers
+READER-METHOD-CLASS
+dictionary.html#reader-method-class
+REMOVE-DEPENDENT
+dictionary.html#remove-dependent
+REMOVE-DIRECT-METHOD
+dictionary.html#remove-direct-method
+REMOVE-DIRECT-SUBCLASS
+dictionary.html#remove-direct-subclass
+REMOVE-METHOD
+dictionary.html#remove-method
+SET-FUNCALLABLE-INSTANCE-FUNCTION
+dictionary.html#set-funcallable-instance-function
+(SETF CLASS-NAME)
+dictionary.html#(setf class-name)
+(SETF GENERIC-FUNCTION-NAME)
+dictionary.html#(setf generic-function-name)
+(SETF SLOT-VALUE-USING-CLASS)
+dictionary.html#(setf slot-value-using-class)
+SLOT-BOUNDP-USING-CLASS
+dictionary.html#slot-boundp-using-class
+SLOT-DEFINITION-
+dictionary.html#slot-definition-
+SLOT-MAKUNBOUND-USING-CLASS
+dictionary.html#slot-makunbound-using-class
+SLOT-VALUE-USING-CLASS
+dictionary.html#slot-value-using-class
+SPECIALIZER-DIRECT-GENERIC-FUNCTIONS
+dictionary.html#specializer-direct-generic-functions
+SPECIALIZER-DIRECT-METHODS
+dictionary.html#specializer-direct-methods
+STANDARD-INSTANCE-ACCESS
+dictionary.html#standard-instance-access
+UPDATE-DEPENDENT
+dictionary.html#update-dependent
+VALIDATE-SUPERCLASS
+dictionary.html#validate-superclass
+WRITER-METHOD-CLASS
+dictionary.html#writer-method-class
diff --git a/Lisp/moxie/clhs-lookup.lisp b/Lisp/moxie/clhs-lookup.lisp
new file mode 100644
index 0000000..02a3a32
--- /dev/null
+++ b/Lisp/moxie/clhs-lookup.lisp
@@ -0,0 +1,148 @@
+(defpackage clhs-lookup
+ (:use :common-lisp)
+ (:export :symbol-lookup
+ :populate-table
+ :spec-lookup))
+(in-package :clhs-lookup)
+
+(defparameter *hyperspec-pathname* (translate-logical-pathname "MOXIE:RES;"))
+
+(defparameter *hyperspec-map-file* (merge-pathnames "Map_Sym.txt" *hyperspec-pathname*))
+
+(defparameter *hyperspec-root* "http://www.lispworks.com/reference/HyperSpec/")
+
+;;; AMOP.
+(defparameter *mop-map-file* (merge-pathnames "Mop_Sym.txt" *hyperspec-pathname*))
+
+(defparameter *mop-root* "http://www.alu.org/mop/")
+
+(defvar *symbol-table* (make-hash-table :test 'equal))
+
+(defvar *section-table* (make-hash-table :test 'equal))
+
+(defvar *format-table* (make-hash-table :test 'equal))
+
+(defvar *populated-p* nil)
+
+(defun add-clhs-section-to-table (&rest numbers)
+ (let ((key (format nil "~{~d~^.~}" numbers))
+ (target (concatenate 'string *hyperspec-root* (format nil "Body/~2,'0d_~(~{~36r~}~).htm" (car numbers) (mapcar #'(lambda (x) (+ x 9)) (cdr numbers))))))
+ (setf (gethash key *section-table*) target)))
+
+(defun valid-target (&rest numbers)
+ (probe-file (format nil "Body/~2,'0d_~(~{~36r~}~).htm" (car numbers) (mapcar #'(lambda (x) (+ x 9)) (cdr numbers)))))
+
+(defvar *last-warn-time* 0)
+
+(defun populate-table ()
+ (unless *populated-p*
+ ;; Hyperspec
+ (with-open-file (s *hyperspec-map-file* :if-does-not-exist nil)
+ ;; populate the table with the symbols from the Map file
+ ;; this bit is easy and portable.
+ (unless s
+ (when (> (- (get-universal-time) *last-warn-time*) 10)
+ (format *trace-output* "Warning: could not find hyperspec map file. Adjust the path at the top of clhs-lookup.lisp to get links to the HyperSpec.~%")
+ (setf *last-warn-time* (get-universal-time)))
+ (return-from populate-table nil))
+ (do ((symbol-name (read-line s nil s) (read-line s nil s))
+ (url (read-line s nil s) (read-line s nil s)))
+ ((eq url s) 'done)
+ (setf (gethash symbol-name *symbol-table*) (concatenate 'string *hyperspec-root* (subseq url 3))))
+ ;; add in section references.
+ (let ((*default-pathname-defaults* *hyperspec-pathname*))
+ ;; Yuk. I know. Fixes welcome.
+ (loop for section from 0 to 27
+ do (add-clhs-section-to-table section)
+ do (loop named s for s1 from 1 to 26
+ unless (valid-target section s1)
+ do (return-from s nil)
+ do (add-clhs-section-to-table section s1)
+ do (loop named ss for s2 from 1 to 26
+ unless (valid-target section s1 s2)
+ do (return-from ss nil)
+ do (add-clhs-section-to-table section s1 s2)
+ do (loop named sss for s3 from 1 to 26
+ unless (valid-target section s1 s2 s3)
+ do (return-from sss nil)
+ do (add-clhs-section-to-table section s1 s2 s3)
+ do (loop named ssss for s4 from 1 to 26
+ unless (valid-target section s1 s2 s3 s4)
+ do (return-from ssss nil)
+ do (add-clhs-section-to-table section s1 s2 s3 s4)
+ do (loop named sssss for s5 from 1 to 26
+ unless (valid-target section s1 s2 s3 s4 s5)
+ do (return-from sssss nil)
+ do (add-clhs-section-to-table section s1 s2 s3 s4 s5))))))))
+ ;; format directives
+ (loop for code from 32 to 127
+ do (setf (gethash (format nil "~~~A" (code-char code)) *format-table*)
+ (concatenate 'string
+ *hyperspec-root*
+ (case (code-char code)
+ ((#\c #\C) "Body/22_caa.htm")
+ ((#\%) "Body/22_cab.htm")
+ ((#\&) "Body/22_cac.htm")
+ ((#\|) "Body/22_cad.htm")
+ ((#\~) "Body/22_cae.htm")
+ ((#\r #\R) "Body/22_cba.htm")
+ ((#\d #\D) "Body/22_cbb.htm")
+ ((#\b #\B) "Body/22_cbc.htm")
+ ((#\o #\O) "Body/22_cbd.htm")
+ ((#\x #\X) "Body/22_cbe.htm")
+ ((#\f #\F) "Body/22_cca.htm")
+ ((#\e #\E) "Body/22_ccb.htm")
+ ((#\g #\G) "Body/22_ccc.htm")
+ ((#\$) "Body/22_ccd.htm")
+ ((#\a #\A) "Body/22_cda.htm")
+ ((#\s #\S) "Body/22_cdb.htm")
+ ((#\w #\W) "Body/22_cdc.htm")
+ ((#\_) "Body/22_cea.htm")
+ ;((#\<) "Body/22_ceb.htm")
+ ((#\i #\I) "Body/22_cec.htm")
+ ((#\/) "Body/22_ced.htm")
+ ((#\t #\T) "Body/22_cfa.htm")
+ ;; FIXME
+ ((#\<) "Body/22_cfb.htm")
+ ((#\>) "Body/22_cfc.htm")
+ ((#\*) "Body/22_cga.htm")
+ ((#\[) "Body/22_cgb.htm")
+ ((#\]) "Body/22_cgc.htm")
+ ((#\{) "Body/22_cgd.htm")
+ ((#\}) "Body/22_cge.htm")
+ ((#\?) "Body/22_cgf.htm")
+ ((#\() "Body/22_cha.htm")
+ ((#\)) "Body/22_chb.htm")
+ ((#\p #\P) "Body/22_chc.htm")
+ ((#\;) "Body/22_cia.htm")
+ ((#\^) "Body/22_cib.htm")
+ ((#\Newline) "Body/22_cic.htm")
+ (t "Body/22_c.htm")))))
+ ;; glossary.
+ )
+ ;; MOP
+ (with-open-file (s *mop-map-file* :if-does-not-exist nil)
+ (when s
+ (do ((symbol-name (read-line s nil s) (read-line s nil s))
+ (url (read-line s nil s) (read-line s nil s)))
+ ((eq url s) 'done)
+ (setf (gethash (concatenate 'string "MOP:" symbol-name) *symbol-table*) (concatenate 'string *mop-root* url)))))
+ (setf *populated-p* t)))
+
+(defun spec-lookup (term &key (type :all))
+ (unless *populated-p*
+ (populate-table))
+ (ecase type
+ (:all
+ (or (gethash term *symbol-table*)
+ (gethash term *section-table*)
+ (gethash term *format-table*)))
+ (:symbol
+ (gethash term *symbol-table*))
+ (:section
+ (gethash term *section-table*))
+ (:format
+ (gethash term *format-table*))))
+
+(defun symbol-lookup (term)
+ (spec-lookup term :type :symbol))
diff --git a/Lisp/moxie/compat/compat-clisp.lib b/Lisp/moxie/compat/compat-clisp.lib
new file mode 100644
index 0000000..6d4ac37
--- /dev/null
+++ b/Lisp/moxie/compat/compat-clisp.lib
@@ -0,0 +1,17 @@
+#0Y UTF-8
+(COMMON-LISP::SETQ COMMON-LISP::*PACKAGE* (SYSTEM::%FIND-PACKAGE "MOXIE"))
+(SYSTEM::C-DEFUN 'MOXIE::MAKE-RESULT-STREAM
+ (SYSTEM::LAMBDA-LIST-TO-SIGNATURE 'COMMON-LISP::NIL))
+(SYSTEM::C-DEFUN 'MOXIE::COERCE-INET-ADDRESS-DESIGNATOR
+ (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '(MOXIE::HOST)))
+(SYSTEM::C-DEFUN 'MOXIE::OPEN-CONNECTION
+ (SYSTEM::LAMBDA-LIST-TO-SIGNATURE
+ '(MOXIE::HOST MOXIE::PORT COMMON-LISP::&KEY (MOXIE::BUFFERING :FULL))))
+(SYSTEM::C-DEFUN 'MOXIE::CLOSE-CONNECTION
+ (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '(COMMON-LISP::STREAM)))
+(SYSTEM::C-DEFUN 'MOXIE::ADD-INPUT-HANDLER
+ (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '(COMMON-LISP::STREAM MOXIE::HANDLER)))
+(SYSTEM::C-DEFUN 'MOXIE::REMOVE-INPUT-HANDLER
+ (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '(MOXIE::HANDLER)))
+(SYSTEM::C-DEFUN 'MOXIE::SAVE-LISP-AND-DIE
+ (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '(MOXIE::PATH)))
diff --git a/Lisp/moxie/compat/compat-clisp.lisp b/Lisp/moxie/compat/compat-clisp.lisp
new file mode 100644
index 0000000..160d193
--- /dev/null
+++ b/Lisp/moxie/compat/compat-clisp.lisp
@@ -0,0 +1,24 @@
+;;; -*- Lisp -*-
+;; $Id: compat-clisp.lisp 40 2006-01-02 03:35:07Z bjc $
+(in-package :moxie)
+
+(defun make-result-stream ()
+ (ext:make-stream 3 :direction :output))
+
+(defun coerce-inet-address-designator (host)
+ "Coerce HOST into an addess vector.")
+
+(defun open-connection (host port &key (buffering :full))
+ "Opens a connection to HOST:PORT, returning a STREAM if successful, NIL otherwise.")
+
+(defun close-connection (stream)
+ "Closes STREAM.")
+
+(defun add-input-handler (stream handler)
+ "Adds HANDLER to the input handler list on SOCKET.")
+
+(defun remove-input-handler (handler))
+
+(defun save-lisp-and-die (path)
+ (ext:saveinitmem path)
+ (ext:quit))
diff --git a/Lisp/moxie/compat/compat-openmcl.lisp b/Lisp/moxie/compat/compat-openmcl.lisp
new file mode 100644
index 0000000..6bafbd7
--- /dev/null
+++ b/Lisp/moxie/compat/compat-openmcl.lisp
@@ -0,0 +1,59 @@
+;;; -*- Lisp -*-
+;; $Id: compat-openmcl.lisp 36 2006-01-01 20:47:40Z bjc $
+(in-package :moxie)
+
+(defvar *stream-to-process* (make-hash-table))
+(defvar *stream-to-handler* (make-hash-table))
+
+(defmacro with-thread (thread &body body)
+ `(ccl:process-interrupt ,thread
+ (lambda ()
+ ,@body)))
+
+(defun make-result-stream ()
+ (ccl::make-fd-stream 3 :direction :output))
+
+(defun coerce-inet-address-designator (host)
+ "Coerce HOST into an addess vector."
+ (or (and (integerp host) host)
+ (ccl:dotted-to-ipaddr host :errorp nil)
+ (ignore-errors (ccl:lookup-hostname host))))
+
+(defun open-connection-thread (parent stream)
+ (ccl:socket-connect stream)
+ (loop
+ (ccl:process-input-wait (ccl:stream-device stream :input))
+ (let ((handler (gethash stream *stream-to-handler*)))
+ (with-thread parent
+ (funcall handler stream)))))
+
+(defun open-connection (host port &rest args)
+ "Opens a connection to HOST:PORT, returning a STREAM if successful, NIL otherwise."
+ (declare (ignore args))
+ (let ((s (ccl:make-socket :address-family :internet :type :stream :connect :active
+ :remote-host (coerce-inet-address-designator host)
+ :remote-port port)))
+ (setf (gethash s *stream-to-process*)
+ (ccl:process-run-function (format nil "Connection to ~A:~A" host port)
+ #'open-connection-thread
+ ccl:*current-process* s))
+ s))
+
+(defun close-connection (stream)
+ "Closes STREAM."
+ (ignore-errors
+ (close stream)
+ (ccl:process-kill (gethash stream *stream-to-process*))
+ (remove-input-handler stream)
+ (remhash stream *stream-to-process*)))
+
+(defun add-input-handler (stream handler)
+ "Adds HANDLER to the input handler list on STREAM."
+ (setf (gethash stream *stream-to-handler*) handler))
+
+(defun remove-input-handler (stream)
+ "Removes all handlers from STREAM."
+ (remhash stream *stream-to-handler*))
+
+(defun save-lisp-and-die (path)
+ (ccl:save-application path)) \ No newline at end of file
diff --git a/Lisp/moxie/compat/compat-sbcl.fasl b/Lisp/moxie/compat/compat-sbcl.fasl
new file mode 100644
index 0000000..d1e2b41
--- /dev/null
+++ b/Lisp/moxie/compat/compat-sbcl.fasl
Binary files differ
diff --git a/Lisp/moxie/compat/compat-sbcl.lisp b/Lisp/moxie/compat/compat-sbcl.lisp
new file mode 100644
index 0000000..bb43bc8
--- /dev/null
+++ b/Lisp/moxie/compat/compat-sbcl.lisp
@@ -0,0 +1,49 @@
+;;; -*- Lisp -*-
+;; $Id: compat-sbcl.lisp 36 2006-01-01 20:47:40Z bjc $
+(in-package :moxie)
+
+(defvar *stream-to-handler* (make-hash-table))
+(defvar *stream-to-socket* (make-hash-table))
+
+(defun make-result-stream ()
+ (sb-sys:make-fd-stream 3 :output t))
+
+(defun coerce-inet-address-designator (host)
+ "Coerce HOST into an addess vector."
+ (cond ((typep host '(vector (unsigned-byte 8) 4)) host)
+ ((some #'alpha-char-p host) (sb-bsd-sockets:host-ent-address
+ (sb-bsd-sockets:get-host-by-name host)))
+ (t (sb-bsd-sockets:make-inet-address host))))
+
+(defun open-connection (host port &key (buffering :full))
+ "Opens a connection to HOST:PORT, returning a STREAM if successful, NIL otherwise."
+ (let ((socket (make-instance 'sb-bsd-sockets:inet-socket :type :stream
+ :protocol :tcp)))
+ (sb-bsd-sockets:socket-connect socket (coerce-inet-address-designator host) port)
+ (let ((stream (sb-bsd-sockets:socket-make-stream socket
+ :input t :output t :buffering buffering)))
+ (setf (gethash stream *stream-to-socket*) socket)
+ stream)))
+
+(defun close-connection (stream)
+ "Closes STREAM."
+ (ignore-errors
+ (remove-input-handler stream)
+ (remhash stream *stream-to-socket*)
+ (close stream)))
+
+(defun add-input-handler (stream handler)
+ "Adds HANDLER to the input handler list on SOCKET."
+ (setf (gethash stream *stream-to-handler*)
+ (sb-sys:add-fd-handler (sb-bsd-sockets:socket-file-descriptor (gethash stream *stream-to-socket*))
+ :input
+ (lambda (fd)
+ (declare (ignore fd))
+ (funcall handler stream)))))
+
+(defun remove-input-handler (stream)
+ (awhen (gethash stream *stream-to-handler*)
+ (sb-sys:remove-fd-handler it)))
+
+(defun save-lisp-and-die (path)
+ (sb-ext:save-lisp-and-die path)) \ No newline at end of file
diff --git a/Lisp/moxie/default.fasl b/Lisp/moxie/default.fasl
new file mode 100644
index 0000000..3f88e09
--- /dev/null
+++ b/Lisp/moxie/default.fasl
Binary files differ
diff --git a/Lisp/moxie/default.lisp b/Lisp/moxie/default.lisp
new file mode 100644
index 0000000..a408d68
--- /dev/null
+++ b/Lisp/moxie/default.lisp
@@ -0,0 +1,63 @@
+;;; -*- Lisp -*-
+;; $Id: world.lisp 20 2005-12-27 15:21:23Z bjc $
+;;
+;; Functions that should eventually be moved to the real plug in
+;; support methodology (i.e., with nib files).
+;;
+(in-package :moxie)
+
+(defun notify-front-end-load (&rest args)
+ (declare (ignore args))
+ (send-event-to-world *world* :change-settings (world-vars *world*)))
+
+(defun notify-front-end-close (&rest args)
+ (declare (ignore args))
+ (send-event-to-world *world* :world-closed))
+
+(defun notify-front-end-connect (&rest args)
+ (declare (ignore args))
+ (set-status-buffer "Connected")
+ (send-event-to-world *world* :world-connected))
+
+(defun notify-front-end-disconnect (&rest args)
+ (declare (ignore args))
+ (set-status-buffer "Disconnected")
+ (send-event-to-world *world* :world-disconnected))
+
+(defun notify-front-end-data (line)
+ (print-to-world *world* line))
+
+(defun notify-back-end-data (line)
+ (print-to-world *world* (format nil "-> ~A~%" line)))
+
+(defun notify-back-end-settings (alist)
+ (when (world-save-path *world*)
+ (format t "DEBUG: saving new settings: ~S~%" alist)
+ (save-world-state *world*)))
+
+(add-hook 'notify-front-end-load :world-loaded-hook)
+(add-hook 'notify-front-end-close :world-closed-hook)
+(add-hook 'notify-front-end-connect :world-connected-hook)
+(add-hook 'notify-front-end-disconnect :world-disconnected-hook)
+(add-hook 'notify-front-end-data :output-from-server-hook)
+(add-hook 'notify-back-end-data :input-from-client-hook)
+(add-hook 'notify-back-end-settings :setting-changed-hook)
+
+(defun show-by-filter (key val &optional (test #'eql))
+ (map-by-filter (lambda (world)
+ (format t "Matches ~S = ~S: ~S~%" key val world))
+ key val test))
+
+(defun map-by-filter (fn key val &optional (test #'eql))
+ (map-worlds (lambda (world)
+ (when (funcall test (world-var key world) val)
+ (funcall fn world)))))
+
+(defun do-auto-connect (&rest args)
+ (declare (ignore args))
+ (setf *tmp* *world*)
+ (when (and (not (world-connected *world*)) (world-var :connect-on-open))
+ (format t "DEBUG: auto-connecting to ~A:~A~%" (world-var :hostname) (world-var :port))
+ (world-connect)))
+
+(add-hook 'do-auto-connect :world-loaded-hook) \ No newline at end of file
diff --git a/Lisp/moxie/events.fasl b/Lisp/moxie/events.fasl
new file mode 100644
index 0000000..385f796
--- /dev/null
+++ b/Lisp/moxie/events.fasl
Binary files differ
diff --git a/Lisp/moxie/events.lisp b/Lisp/moxie/events.lisp
new file mode 100644
index 0000000..88afb71
--- /dev/null
+++ b/Lisp/moxie/events.lisp
@@ -0,0 +1,100 @@
+(in-package :moxie)
+
+(defgeneric moxie-event-handler (event &rest args)
+ (:documentation "Handle EVENT (w/ ARGS)."))
+
+(defmethod moxie-event-handler ((event (eql :world-event)) &rest args)
+ (apply #'world-event args))
+
+(defmethod moxie-event-handler ((event (eql :eval)) &rest args)
+ (do* ((f args (cdr f))
+ (form (car f) (car f)))
+ ((null f))
+ (case form
+ (:r (let ((restarts (compute-restarts))
+ (num (cadr f)))
+ (if (and (integerp num)
+ (> num 0) (<= num (length restarts)))
+ (progn
+ (setf f (cdr f))
+ (invoke-restart (elt restarts (1- num))))
+ (print-restarts restarts))))
+ ((:? :h :help) (format t "~A~%" *repl-help*))
+ (t (let (values)
+ (setq - form)
+ (setq values (multiple-value-list (eval -)))
+ (setq /// // // / / values *** ** ** * * (car /))
+ (send-command :repl-result `(:values ,@values))))))
+ (send-command :repl-result `(:prompt ,(repl-prompt))))
+
+(defmethod world-event-handler ((event (eql :close-world)) &rest args)
+ (declare (ignore args))
+ (close-world))
+
+(defmethod world-event-handler ((event (eql :connect-world)) &rest args)
+ (declare (ignore args))
+ (world-connect))
+
+(defmethod world-event-handler ((event (eql :disconnect-world)) &rest args)
+ (declare (ignore args))
+ (world-disconnect))
+
+(defmethod world-event-handler ((event (eql :load-world)) &rest args)
+ (format t "world-event-handler :load-world ~S~%" args)
+ (apply #'load-world-state *world* args))
+
+(defmethod world-event-handler ((event (eql :save-world)) &rest args)
+ (apply #'save-world-state *world* args))
+
+(defmethod world-event-handler ((event (eql :setting-changed)) &rest args)
+ (let* ((form (car args))
+ (key (car form))
+ (val (cadr form))
+ (old-val (world-var key)))
+ (unless (eql old-val val)
+ (format t "DEBUG: changing setting ~S: ~S -> ~S.~%" key old-val val)
+ (setf (world-var key) val)
+ (format t "DEBUG: running hook.~%")
+ (run-hook :setting-changed-hook (list key val old-val))
+ (format t "DEBUG: hook finished.~%"))))
+
+(defmethod world-event-handler ((event (eql :input-from-client-hook)) &rest args)
+ (send-to-mux *world* (or (run-hook event (car args)) (car args))))
+
+(defmethod load-world-state ((world world) &key path &allow-other-keys)
+ (format t "load-world-state ~S ~S~%" world path)
+ (with-open-file (s (or path (world-save-path world)))
+ (awhen (aand (read s) (parse-world-version-1 it))
+ (setf (world-vars world) it)
+ (setf (world-save-path world) path)
+ (let ((*world* world))
+ (run-hook :world-loaded-hook)))))
+
+(defmethod save-world-state ((world world) &key path as-copy &allow-other-keys)
+ (with-open-file (s (or path (world-save-path world))
+ :direction :output :if-exists :supersede
+ :if-does-not-exist :create)
+ (prin1 (write-world-version-1) s))
+ (unless as-copy
+ (setf (world-save-path world) path))
+ (let ((*world* world))
+ (run-hook :world-saved-hook)))
+
+(defun parse-world-version-1 (form)
+ "Parses a world definition in the form '(:KEY value), returning an ALIST."
+ (when (evenp (length form))
+ (labels ((keyvalue-to-alist (form &optional (accumulator nil))
+ (if (null form)
+ accumulator
+ (keyvalue-to-alist (cddr form)
+ (cons (cons (car form) (cadr form)) accumulator)))))
+ (keyvalue-to-alist form))))
+
+(defun write-world-version-1 (&optional (world *world*))
+ "Writes out a FORM of '(:KEY1 value1 :KEY2 value2) from WORLD."
+ (labels ((alist-to-keyvalue (form &optional (accumulator nil))
+ (if (null form)
+ accumulator
+ (alist-to-keyvalue (cdr form)
+ (cons (caar form) (cons (cdar form) accumulator))))))
+ (alist-to-keyvalue (world-vars world)))) \ No newline at end of file
diff --git a/Lisp/moxie/hooks.lisp b/Lisp/moxie/hooks.lisp
new file mode 100644
index 0000000..49714f6
--- /dev/null
+++ b/Lisp/moxie/hooks.lisp
@@ -0,0 +1,21 @@
+;;; -*- Lisp -*-
+;; $Id: moxie.asd,v 1.1.1.1 2005/02/15 06:06:59 shmit Exp $
+#|
+Hooks:
+
+;; Sent from world handlers
+:world-opened-hook *world*
+:world-closed-hook *world*
+:input-from-client-hook line
+:output-from-server-hook line
+
+;; This can probably just be a plugin, off :output-from-server-hook
+:telnet-option-hook telnetCodes
+
+;; Controlled by the front end, ultimately.
+:start-logging-hook
+:stop-logging-hook
+
+;; XXX: IDK
+:timer-hook
+|# \ No newline at end of file
diff --git a/Lisp/moxie/moxie.asd b/Lisp/moxie/moxie.asd
new file mode 100644
index 0000000..bda1706
--- /dev/null
+++ b/Lisp/moxie/moxie.asd
@@ -0,0 +1,34 @@
+;;; -*- Lisp -*-
+;; $Id: moxie.asd 33 2006-01-01 06:41:36Z bjc $
+(defpackage moxie-system
+ (:use :cl :asdf))
+(in-package :moxie-system)
+
+(defsystem :moxie
+ :name "Moxie REPL Components."
+ :version "0.2"
+ :author "Brian Cully <shmit@kublai.com>"
+ :maintainer "Brian Cully <shmit@kublai.com>"
+ :licence "Public Domain"
+ :description "Moxie's Lisp programming interface."
+
+ :depends-on (#+sbcl sb-bsd-sockets)
+ :components ((:file "package")
+ (:module "utils"
+ :components ((:file "bjc-utils"))
+ :depends-on ("package"))
+ (:module "compat"
+ :components ((:file #+sbcl "compat-sbcl"
+ #+clisp "compat-clisp"
+ #+openmcl "compat-openmcl"
+ #-(or sbcl clisp openmcl) (error "Compiler not supported.")))
+ :depends-on ("package"))
+ (:module "main"
+ :pathname ""
+ :components ((:file "moxie")
+ (:file "world" :depends-on ("moxie"))
+ (:file "events" :depends-on ("world"))
+ (:file "repl" :depends-on ("world"))
+ (:file "default" :depends-on ("moxie")))
+ :depends-on ("package" "compat" "utils"))))
+(pushnew :moxie *features*)
diff --git a/Lisp/moxie/moxie.fasl b/Lisp/moxie/moxie.fasl
new file mode 100644
index 0000000..70ee196
--- /dev/null
+++ b/Lisp/moxie/moxie.fasl
Binary files differ
diff --git a/Lisp/moxie/moxie.lisp b/Lisp/moxie/moxie.lisp
new file mode 100644
index 0000000..c18e630
--- /dev/null
+++ b/Lisp/moxie/moxie.lisp
@@ -0,0 +1,218 @@
+;;; The lisp bootstrapping code.
+;; $Id: moxie.lisp 29 2005-12-31 22:59:17Z bjc $
+
+(in-package :moxie)
+
+(defvar *hooks* (make-hash-table)
+ "The hooks.
+See the functions add-hook and remove-hook.")
+
+(defun add-hook (sym mode)
+ "Adds the function SYM to the list MODE."
+ (setf (gethash mode *hooks*)
+ (let ((hooks (reverse (gethash mode *hooks*))))
+ (pushnew sym hooks)
+ (nreverse hooks))))
+
+(defun remove-hook (sym mode)
+ "Removes the function HOOK from the list MODE."
+ (setf (gethash mode *hooks*) (remove sym (gethash mode *hooks*))))
+
+;; We should see how many args there are, and pass that amount in. Not just the return
+;; value. But for now, this means hooks need at least one arg.
+(defun run-hook (mode &optional arg)
+ "Runs all the hooks for MODE, in order of how they were attached."
+ (let ((result nil))
+ (do ((hooks (gethash mode *hooks*) (cdr hooks)))
+ ((or (null hooks) (null (car hooks))) result)
+ (awhen (funcall (car hooks) (or result arg))
+ (setf result it)))))
+
+(defvar *keywords* (make-hash-table :test #'equal))
+
+(defun add-keyword (sym key)
+ "Adds /KEY as a keyword, calling SYM with the rest of the input string."
+ (setf (gethash (string-upcase key) *keywords*) sym))
+
+(defun remove-keyword (key)
+ "Removes /KEY as a keyword."
+ (remhash (string-upcase key) *keywords*))
+
+(defun get-keyword (string)
+ "Finds the keyword in STRING, if any."
+ (when (and (> (length string) 0) (eql #\/ (elt string 0)))
+ (let ((pos (or (position-if (lambda (c)
+ (or (eql #\Space c)
+ (eql #\Newline c)
+ (eql #\Tab c)))
+ string)
+ (length string))))
+ (values
+ (string-upcase (subseq string 1 pos))
+ (aif (and (< pos (length string))
+ (position-if-not (lambda (c)
+ (or (eql #\Space c)
+ (eql #\Newline c)
+ (eql #\Tab c)))
+ string
+ :start pos))
+ (subseq string it (length string))
+ "")))))
+
+(defun run-keyword-hook (string &rest keywords)
+ "Runs through the keyword database for the word at the beginning of STRING."
+ (multiple-value-bind (key rem) (get-keyword string)
+ (when key
+ (or (aand (gethash key *keywords*) (apply it rem keywords)) ""))))
+
+(add-hook 'run-keyword-hook :input-from-client-hook)
+
+;; Keystrokes are keywords that look like this:
+;; keystroke := :[<modifier>-]*<keycode>
+;; modifier := cmd|opt|ctrl|shift|numpad
+;; keycode := <fkey>|character
+;; fkey := f1 .. fn .. f35
+;;
+;; So, CMD-NUMPAD-8 is:
+;; :cmd-numpad-8
+;;
+;; Okay, that won't work for the long term, because :cmd-shift-numpad-8 will be
+;; evaluated differently than :shift-cmd-numpad-8.
+(defvar *keystroke-macros* (make-hash-table)
+ "The keystroke macro to symbol dispatch table.")
+
+(defun add-keystroke-macro (sym keystroke)
+ "Adds KEYSTROKE as a keystroke-macro, calling SYM on dispatch."
+ (setf (gethash keystroke *keystroke-macros*) sym)
+ (register-keystroke-macro keystroke))
+
+(defun remove-keystroke-macro (keystroke)
+ "Removes any hint of KEYSTROKE being invoked as a keystroke-macro."
+ (remhash keystroke *keystroke-macros*)
+ (unregister-keystroke-macro keystroke))
+
+(defun run-keystroke-macro-hook (keystroke)
+ "Dispatches KEYSTROKE to the appropriate hook function."
+ (awhen (gethash keystroke *keystroke-macros*)
+ (funcall it keystroke)))
+
+(add-hook 'run-keystroke-macro-hook :keystroke-macro-hook)
+
+;;
+;; Utility functions
+;;
+(defun map-variables (string vars)
+ "Returns a string made of of substituting $[0-9]+$ in STRING variables with those positions in VARS."
+ (with-output-to-string (result)
+ (let ((strlen (1- (length string))))
+ (loop for i from 0 to strlen
+ as char = (elt string i)
+ do (aif (aand (< (1+ i) strlen) (eql char #\$)
+ (position #\$ string :start (1+ i)))
+ (let ((var (parse-integer (subseq string (1+ i) it))))
+ (when var
+ (princ (elt vars (1- var)) result))
+ (setq i it))
+ (princ char result))))
+ result))
+
+(defun escape-mux-string (string)
+ "Returns a string made from STRING with substitutions for white space."
+ (with-output-to-string (result)
+ (let ((strlen (length string)))
+ (loop for i from 0 to (1- strlen)
+ as char = (elt string i)
+ do (case char
+ ((#\Space)
+ (princ "%b" result))
+ ((#\Tab)
+ (princ "%t" result))
+ ((#\Newline #\Return)
+ (princ "%r" result))
+ (t (princ char result)))))
+ result))
+
+(defun make-attributed-string (string &rest attribute-ranges)
+ (list string attribute-ranges))
+
+(defun make-attributes (&rest attributes)
+ attributes)
+
+(defun make-range (location length)
+ (list :range location length))
+
+(defun make-color (r g b)
+ (list :color r g b))
+
+(defun make-font (name size)
+ (list :font name size))
+
+(defun make-super (n)
+ (cons :super n))
+
+(defun make-underline (n)
+ (cons :underline n))
+
+(defun make-link (url)
+ (cons :link url))
+
+;;
+;; Low level commands which interface directly to Moxie.
+;;
+;; Useful stuff to add:
+;; say, for speaking text
+;; playsound/music, for sound effects
+;;
+
+(defmacro with-response (cmd-and-args &body body)
+ `(progn
+ (apply #'send-command ,@cmd-and-args)
+ (let ((response (read)))
+ ,@body)))
+
+(defun write-array-to-mux (world &rest args)
+ "Send ARGS to the output window associated with WORLD."
+ (format (world-stream world) "~S~%" args)
+ (finish-output (world-stream world)))
+
+(defun send-to-mux (world &rest args)
+ "Send ARGS to the MUX associated with WORLD."
+ (format (world-stream world) "~A~%" (car args))
+ (finish-output (world-stream world)))
+
+(defun print-to-world (world &rest args)
+ "Send ARGS to the output window associated with WORLD."
+ (apply #'send-event-to-world world :output-from-server-hook args))
+
+(defun register-keystroke-macro (keystroke)
+ "Register KEYSTROKE as a macro with Moxie."
+ (send-command :register-keystroke keystroke))
+
+(defun unregister-keystroke-macro (keystroke)
+ "Unregisters KEYSTROKE as a macro with Moxie."
+ (send-command :unregister-keystroke keystroke))
+
+(defun set-status-buffer (string &optional (world *world*))
+ "Set the status buffer of the window associated with WORLD to STRING."
+ (send-event-to-world world :set-status-buffer string))
+
+(defun clear-screen (world)
+ (send-event-to-world world :clear-screen))
+
+(defun enable-logging (world)
+ "Enable logging for WORLD."
+ (send-event-to-world world :enable-logging))
+
+(defun disable-logging (world)
+ "Disable logging for WORLD."
+ (send-event-to-world world :disable-logging))
+
+(defun send-event-to-world (world event &rest args)
+ "Send EVENT and ARGS to WORLD's result handler."
+ (apply #'send-command (world-id world) event args))
+
+(defun send-command (cmd &rest args)
+ "Send CMD and ARGS to Moxie's generic result handler."
+ (let ((*print-pretty* nil))
+ (prin1 `(,cmd ,@args) *moxie-result-stream*))
+ #-clisp (finish-output *moxie-result-stream*)) \ No newline at end of file
diff --git a/Lisp/moxie/package.fasl b/Lisp/moxie/package.fasl
new file mode 100644
index 0000000..0eaf469
--- /dev/null
+++ b/Lisp/moxie/package.fasl
Binary files differ
diff --git a/Lisp/moxie/package.lisp b/Lisp/moxie/package.lisp
new file mode 100644
index 0000000..12514b0
--- /dev/null
+++ b/Lisp/moxie/package.lisp
@@ -0,0 +1,21 @@
+(defpackage moxie
+ (:use :cl :cl-user)
+ (:export *moxie-repl-stream*
+ add-hook remove-hook run-hook
+ add-keyword remove-keyword
+ add-keystroke-macro remove-keystroke-macro
+ map-variables escape-mux-string
+
+ *world* world-var
+
+ make-attributed-string make-attributes make-range make-font
+ make-color make-super make-underline make-link
+ send-to-mux write-array-to-mux print-to-world set-status-buffer clear-screen
+ enable-logging disable-logging))
+(in-package :moxie)
+
+(defvar *moxie-result-stream* nil
+ "Where output from the TPL goes.")
+
+(defvar *world* nil
+ "The world currently calling into a plug in function.") \ No newline at end of file
diff --git a/Lisp/moxie/repl.fasl b/Lisp/moxie/repl.fasl
new file mode 100644
index 0000000..afb126a
--- /dev/null
+++ b/Lisp/moxie/repl.fasl
Binary files differ
diff --git a/Lisp/moxie/repl.lisp b/Lisp/moxie/repl.lisp
new file mode 100644
index 0000000..b5b7bb3
--- /dev/null
+++ b/Lisp/moxie/repl.lisp
@@ -0,0 +1,95 @@
+(in-package :moxie)
+
+(defvar *repl-motd*
+ "Welcome to Moxie!
+
+To get help, enter :HELP at the prompt.")
+
+(defvar *repl-help*
+ "Top level commands:
+ :R [num] Invoke restart NUM, or list restarts.
+ :HELP :H :? Display this message.")
+
+(defvar *repl-level* 0)
+
+(defun start-repl (&optional (use-result-stream t))
+ (let ((*moxie-result-stream* (or (and use-result-stream (make-result-stream))
+ *error-output*)))
+ (format t "~%~A~%" *repl-motd*)
+ (send-command :repl-result `(:prompt ,(repl-prompt)))
+ (repl)))
+
+(defun repl ()
+ "This is Moxie's top level loop. At this point, it's only here
+because we don't want the host lisp to print results or its prompt."
+ (let* ((*debugger-hook* #'repl-dbg)
+ (*repl-level* (1+ *repl-level*))
+ (lex-level *repl-level*))
+ (loop
+ (force-output)
+ (let ((form (read)))
+ (restart-case (eval form)
+ (abort ()
+ :report (lambda (stream)
+ ;; I know this looks weird, but because the
+ ;; formatter is called from the condition
+ ;; handler's environment, and because
+ ;; *repl-level* is special, at the time of
+ ;; evaluation, *repl-level* may be higher than
+ ;; lex-level.
+ (if (eql lex-level *repl-level*)
+ (format stream "Abort handling of current request.")
+ (format stream "Return to REPL level ~A."
+ lex-level)))
+ (send-command :repl-result `(:prompt ,(repl-prompt)))))))))
+
+(defun repl-dbg (condition debugger-hook)
+ "This debugger hook just sends a message to Moxie when the debugger
+has been entered, so Moxie can keep track of the prompt."
+ (declare (ignore debugger-hook))
+ (send-command :repl-dbg `(:condition ,condition)))
+
+(defmacro eval-hook (&rest forms)
+ "Ensure all FORMS are valid for evaluation before calling
+EVAL-HOOK-HELPER."
+ (let ((helped-forms (mapcar (lambda (x) `(quote ,x)) forms)))
+ `(eval-hook-helper ,@helped-forms)))
+
+(defun eval-hook-helper (&rest forms)
+ "Evaluate all FORMS, sending the results to the Moxie output
+stream. When finished processing, send the prompt."
+ (do* ((f forms (cdr f))
+ (form (car f) (car f)))
+ ((null f))
+ (case form
+ (:r (let ((restarts (compute-restarts))
+ (num (cadr f)))
+ (if (and (integerp num)
+ (> num 0) (<= num (length restarts)))
+ (progn
+ (setf f (cdr f))
+ (invoke-restart (elt restarts (1- num))))
+ (print-restarts restarts))))
+ ((:? :h :help) (format t "~A~%" *repl-help*))
+ (t (let (values)
+ (setq - form)
+ (setq values (multiple-value-list (eval -)))
+ (setq /// // // / / values *** ** ** * * (car /))
+ (send-command :repl-result `(:values ,@values))))))
+ (send-command :repl-result `(:prompt ,(repl-prompt))))
+
+(defun print-restarts (restarts)
+ (format t "Available restarts: ~%")
+ (do ((c restarts (cdr c))
+ (i 1 (1+ i)))
+ ((null c))
+ (format t " ~A ~A~%" i (car c)))
+ (format t "Invoke restarts with :R [num]~%"))
+
+(defun repl-prompt ()
+ "Compute the prompt for Moxie's REPL."
+ (format nil "~A~@[[~A]~]> "
+ (if (eql *package* (find-package :cl-user))
+ "CL-USER"
+ (package-name *package*))
+ (when (> *repl-level* 1) *repl-level*))) \ No newline at end of file
diff --git a/Lisp/moxie/repl.lisp.old b/Lisp/moxie/repl.lisp.old
new file mode 100644
index 0000000..8ae7408
--- /dev/null
+++ b/Lisp/moxie/repl.lisp.old
@@ -0,0 +1,87 @@
+(in-package :moxie)
+
+(defvar *repl-motd*
+ "Welcome to Moxie!
+
+To get help, enter :HELP at the prompt.")
+
+(defvar *repl-help*
+ "Top level commands:
+ :R [num] Invoke restart NUM, or list restarts.
+ :HELP :H :? Display this message.")
+
+(defvar *repl-level* 0)
+
+(defun start-repl (&optional (use-result-stream t))
+ (let ((*moxie-result-stream* (or (and use-result-stream (make-result-stream))
+ *error-output*)))
+ (format t "~%~A~%" *repl-motd*)
+ (send-command :repl-result `(:prompt ,(repl-prompt)))))
+
+(defmethod moxie-event-handler ((event (eql :eval)) &rest args)
+ (let* ((*debugger-hook* #'repl-dbg)
+ (*repl-level* (1+ *repl-level*))
+ (lex-level *repl-level*))
+ (dolist (form args)
+ (force-output)
+ (restart-case (eval form)
+ (abort ()
+ :report (lambda (stream)
+ ;; I know this looks weird, but because the formatter is called
+ ;; from the condition handler's environment, and because
+ ;; *repl-level* is special, at the time of evaluation,
+ ;; *repl-level* may be higher than lex-level.
+ (if (eql lex-level *repl-level*)
+ (format stream "Abort handling of current request.")
+ (format stream "Return to REPL level ~A." lex-level)))
+ (send-command :repl-result `(:prompt ,(repl-prompt))))))))
+
+(defun repl-dbg (condition debugger-hook)
+ "This debugger hook just sends a message to Moxie when the debugger has
+been entered, so Moxie can keep track of the prompt."
+ (declare (ignore debugger-hook))
+ (send-command :repl-dbg `(:condition ,condition)))
+
+(defmacro eval-hook (&rest forms)
+ "Ensure all FORMS are valid for evaluation before calling EVAL-HOOK-HELPER."
+ (let ((helped-forms (mapcar (lambda (x) `(quote ,x)) forms)))
+ `(eval-hook-helper ,@helped-forms)))
+
+(defun eval-hook-helper (&rest forms)
+ "Evaluate all FORMS, sending the results to the Moxie output stream. When finished
+processing, send the prompt."
+ (do* ((f forms (cdr f))
+ (form (car f) (car f)))
+ ((null f))
+ (case form
+ (:r (let ((restarts (compute-restarts))
+ (num (cadr f)))
+ (if (and (integerp num)
+ (> num 0) (<= num (length restarts)))
+ (progn
+ (setf f (cdr f))
+ (invoke-restart (elt restarts (1- num))))
+ (print-restarts restarts))))
+ ((:? :h :help) (format t "~A~%" *repl-help*))
+ (t (let (values)
+ (setq - form)
+ (setq values (multiple-value-list (eval -)))
+ (setq /// // // / / values *** ** ** * * (car /))
+ (send-command :repl-result `(:values ,@values))))))
+ (send-command :repl-result `(:prompt ,(repl-prompt))))
+
+(defun print-restarts (restarts)
+ (format t "Available restarts: ~%")
+ (do ((c restarts (cdr c))
+ (i 1 (1+ i)))
+ ((null c))
+ (format t " ~A ~A~%" i (car c)))
+ (format t "Invoke restarts with :R [num]~%"))
+
+(defun repl-prompt ()
+ "Compute the prompt for Moxie's REPL."
+ (format nil "~A~@[[~A]~]> "
+ (if (eql *package* (find-package :cl-user))
+ "CL-USER"
+ (package-name *package*))
+ (when (> *repl-level* 1) *repl-level*))) \ No newline at end of file
diff --git a/Lisp/moxie/utils/bjc-utils.fasl b/Lisp/moxie/utils/bjc-utils.fasl
new file mode 100644
index 0000000..9d6cb67
--- /dev/null
+++ b/Lisp/moxie/utils/bjc-utils.fasl
Binary files differ
diff --git a/Lisp/moxie/utils/bjc-utils.lisp b/Lisp/moxie/utils/bjc-utils.lisp
new file mode 100644
index 0000000..f24774b
--- /dev/null
+++ b/Lisp/moxie/utils/bjc-utils.lisp
@@ -0,0 +1,185 @@
+;;; -*- Lisp -*-
+;; $Id: bjc-utils.lisp 19 2005-12-27 01:40:27Z bjc $
+(in-package :moxie)
+
+(defmacro while (expr &body body)
+ "Evaluate BODY continously until EXPR evaluates to FALSE."
+ `(do ()
+ ((not ,expr))
+ ,@body))
+
+(defmacro acond (&rest clauses)
+ (if (null clauses)
+ nil
+ (let ((cl1 (car clauses))
+ (sym (gensym)))
+ `(let ((,sym ,(car cl1)))
+ (if ,sym
+ (let ((it ,sym))
+ ,@(cdr cl1)
+ (acond ,@(cdr clauses))))))))
+
+(defmacro aif (expr then &optional else)
+ "Anaphoric if: if EXPR is true, set IT to the result of EXPR and evaluate THEN, otherwise evaluate ELSE."
+ `(let ((it ,expr))
+ (if it
+ ,then
+ ,else)))
+
+(defmacro awhen (expr &body body)
+ "Anaphoric when: when EXPR is true, set IT to the result of EXPR and evaluate BODY."
+ `(let ((it ,expr))
+ (when it
+ ,@body)))
+
+(defmacro awhile (expr &body body)
+ "Anaphoric while: while EXPR is true, set IT to the result of EXPR and evaluate BODY."
+ `(do ((it ,expr ,expr))
+ ((not it))
+ ,@body))
+
+(defmacro aand (&rest args)
+ (cond ((null args) t)
+ ((null (cdr args)) (car args))
+ (t `(aif ,(car args) (aand ,@(cdr args))))))
+
+(defmacro aif2 (expr &optional then else)
+ "Two-value version of aif: aif EXPR's second value is TRUE, evaluate THEN, otherwise, evaluate ELSE."
+ (let ((win (gensym)))
+ `(multiple-value-bind (it ,win) ,expr
+ (if (or it ,win) ,then ,else))))
+
+(defmacro awhile2 (expr &body body)
+ "Two-value version of awhile: awhile EXPR's second value is TRUE, evaluate BODY."
+ (let ((flag (gensym)))
+ `(let ((,flag t))
+ (while ,flag
+ (aif2 ,expr
+ (progn ,@body)
+ (setq ,flag nil))))))
+
+(defmacro with-gensyms (syms &body body)
+ `(let ,(mapcar (lambda (s) `(,s (gensym))) syms)
+ ,@body))
+
+(declaim (ftype (function (function) function) memoize))
+(defun memoize (f)
+ "Return memoized version of FN."
+ (let ((cache (make-hash-table :test #'equal)))
+ (lambda (&rest args)
+ (multiple-value-bind (val win) (gethash args cache)
+ (if win
+ val
+ (setf (gethash args cache) (apply f args)))))))
+
+(declaim (ftype (function (function integer) function) memoize-with-timeout))
+(defun memoize-with-timeout (fn len)
+ "Memoize FN for LEN seconds after initial call."
+ (let ((cache (make-hash-table :test #'equal)))
+ (lambda (&rest args)
+ (multiple-value-bind (val win) (gethash args cache)
+ (if (and win (< (get-universal-time) (car val)))
+ (cdr val)
+ (cdr (setf (gethash args cache)
+ (cons (+ len (get-universal-time))
+ (apply fn args)))))))))
+
+(defmacro enumerator (list)
+ "Returns an enumerator for LIST."
+ (let ((index (gensym)))
+ `(let ((,index 0))
+ (lambda ()
+ (progn
+ (incf ,index)
+ (nth (1- ,index) ,list))))))
+
+(defun mkstr (&rest args)
+ "Creates a str from ARGS."
+ (with-output-to-string (s)
+ (dolist (a args)
+ (princ a s))))
+
+;;
+;; This macro can save and load the state of simple variables.
+;;
+;; Use:
+;; > (setq *foo* '(1 2 3)) => (1 2 3)
+;; > (def-i/o foo-w foo-r (*foo*)) => T
+;; > (foo-w #p"/tmp/foo-vars") => NIL
+;; > (makunbound '*foo*) => *FOO*
+;; > (foo-r #p"/tmp/foo-vars") => NIL
+;; > *foo* => (1 2 3)
+(defmacro def-i/o (writer-name reader-name (&rest vars))
+ (let ((file-name (gensym))
+ (var (gensym))
+ (stream (gensym)))
+ `(progn
+ (defun ,writer-name (,file-name)
+ (with-open-file (,stream ,file-name
+ :direction :output :if-exists :supersede)
+ (dolist (,var (list ,@vars))
+ (declare (special ,@vars))
+ (print ,var ,stream))))
+ (defun ,reader-name (,file-name)
+ (with-open-file (,stream ,file-name
+ :direction :input :if-does-not-exist :error)
+ (dolist (,var ',vars)
+ (set ,var (read ,stream)))))
+ t)))
+
+(defun string-has-prefix (string prefix)
+ "Returns T if STRING begins with PREFIX, NIL otherwise."
+ (let ((strlen (length string))
+ (prefixlen (length prefix)))
+ (when (<= prefixlen strlen)
+ (do ((i 0 (1+ i)))
+ ((<= prefixlen i) t)
+ (let ((s (elt string i)) (p (elt prefix i)))
+ (when (not (eql s p))
+ (return-from string-has-prefix nil)))))))
+
+(defmacro llambda (simple-lambda-list &body body)
+ (let ((num-args (gensym))
+ (args (gensym))
+ (accumulated-args (gensym))
+ (call-lambda (gensym)))
+ (labels ((lambda-length (simple-lambda-list &optional (count 0))
+ (if (or (null simple-lambda-list)
+ (member (car simple-lambda-list)
+ '(&allow-other-keys &key &rest &aux &optional)))
+ count
+ (lambda-length (cdr simple-lambda-list) (1+ count)))))
+ `(labels ((,call-lambda (,num-args ,accumulated-args)
+ (lambda (&rest ,args)
+ (if (< (length ,args) ,num-args)
+ (,call-lambda (- ,num-args (length ,args))
+ (append ,accumulated-args ,args))
+ (apply (lambda ,simple-lambda-list ,@body)
+ (append ,accumulated-args ,args))))))
+ (,call-lambda ,(lambda-length simple-lambda-list) nil)))))
+
+(defmacro $c (f &rest args)
+ (let ((a (gensym)))
+ `(lambda ($_)
+ (flet ((my-apply (sym args)
+ (cond ((functionp sym) (apply (the function sym) args))
+ ((macro-function sym)
+ (eval (funcall (macro-function sym)
+ `(,sym ,args)
+ nil)))
+ ((symbol-function sym) (apply (symbol-function sym) args))
+ (t (error "Can't curry ~A" (type-of sym))))))
+ (let ((,a (subs-var '$_ $_
+ (list ,@(if (member '$_ args)
+ args
+ (append args '($_)))))))
+ (my-apply ,f ,a))))))
+
+(defun subs-var (sym val expr &optional accum)
+ (if (null expr)
+ (nreverse accum)
+ (subs-var sym val (cdr expr)
+ (if (and (atom (car expr))
+ (eq (car expr) sym))
+ (cons val accum)
+ (cons (car expr) accum))))) \ No newline at end of file
diff --git a/Lisp/moxie/world.fasl b/Lisp/moxie/world.fasl
new file mode 100644
index 0000000..a903e04
--- /dev/null
+++ b/Lisp/moxie/world.fasl
Binary files differ
diff --git a/Lisp/moxie/world.lisp b/Lisp/moxie/world.lisp
new file mode 100644
index 0000000..af6ee65
--- /dev/null
+++ b/Lisp/moxie/world.lisp
@@ -0,0 +1,120 @@
+;;; -*- Lisp -*-
+;; $Id: world.lisp 48 2006-01-09 00:27:16Z bjc $
+(in-package :moxie)
+
+(defvar *worlds* (make-hash-table)
+ "The world environments, keyed on world id.")
+
+(let ((next-world-id 0))
+ (defclass world ()
+ ((id :initarg :id :initform (incf next-world-id)
+ :accessor world-id
+ :documentation "The world id.")
+ (vars :initarg :vars :initform nil
+ :accessor world-vars
+ :documentation "Savable settings.")
+ (save-path :initarg :save-path :initform nil
+ :accessor world-save-path
+ :documentation "File path.")
+ (stream :initarg :stream :initform nil
+ :accessor world-stream
+ :documentation "Connection to server.")
+ (connected :initarg :connected :initform nil
+ :accessor world-connected
+ :documentation "Are we currently connected?"))
+ (:documentation "All associated world information.")))
+
+(defgeneric load-world-state (world &key path &allow-other-keys)
+ (:documentation "Returns an ALIST from WORLD's disk location, or PATH (if set)."))
+
+(defgeneric save-world-state (world &key path as-copy &allow-other-keys)
+ (:documentation "Saves WORLD's state to its disk location or PATH (if set)."))
+
+(defgeneric world-event-handler (event &rest args)
+ (:documentation "Handle EVENT (w/ ARGS) for *WORLD*."))
+
+(defmethod initialize-instance ((instance world) &rest initargs)
+ (declare (ignore initargs))
+ (format t "initialize-instance world~%")
+ (add-world (call-next-method)))
+
+(defmethod world-event-handler (event &rest args)
+ "Default handler doesn't know about anything, so it logs, instead."
+ (format t "Don't know how to handle event ~S ~S from world ~S.~%"
+ event args (world-id *world*)))
+
+(defun add-world (world)
+ (setf (gethash (world-id world) *worlds*) world))
+
+(defun remove-world (world)
+ (remhash (world-id world) *worlds*))
+
+(defun map-worlds (fn)
+ (let ((result nil))
+ (maphash (lambda (k v)
+ (declare (ignore k))
+ (setf result (cons (funcall fn v) result)))
+ *worlds*)
+ (nreverse result)))
+
+(defun map-world-vars (fn &optional (world *world*))
+ (mapcar (lambda (list)
+ (funcall fn (car list) (cdr list)))
+ (world-vars world)))
+
+(defun world-var (name &optional (world *world*))
+ "Returns the value for NAME in WORLD's environment."
+ (cdr (assoc name (world-vars world))))
+
+(defun set-world-var (name value &optional (world *world*))
+ "Sets the value of NAME to VALUE in WORLD's environment."
+ (setf (world-vars world)
+ (cons (cons name value)
+ (remove-if (lambda (x)
+ (eql (car x) name))
+ (world-vars world)))))
+
+(defsetf world-var (name &optional (world '*world*)) (value)
+ `(set-world-var ,name ,value ,world))
+
+(defun close-world (&optional (world *world*))
+ "Closes WORLD."
+ (world-disconnect world)
+ (remove-world world)
+ (let ((*world* world))
+ (run-hook :world-closed-hook)))
+
+(defun world-connect (&optional (world *world*))
+ "Connects WORLD to the host and port specified."
+ (awhen (aand (world-var :hostname world) (world-var :port world)
+ (open-connection (world-var :hostname world) (world-var :port world)))
+ (add-input-handler it
+ (lambda (stream)
+ (let ((*world* world))
+ (handler-case
+ (while (listen stream)
+ (multiple-value-bind (line missing-newline-p) (read-line stream)
+ (run-hook :output-from-server-hook line)
+ (when missing-newline-p
+ (signal 'end-of-file))))
+ (end-of-file ()
+ (world-disconnect world))))))
+ (setf (world-stream world) it)
+ (setf (world-connected world) t)
+ (let ((*world* world))
+ (run-hook :world-connected-hook))))
+
+(defun world-disconnect (&optional (world *world*))
+ "Closes the connection, if opened, for WORLD."
+ (let ((*world* world))
+ (when (world-connected *world*)
+ (close-connection (world-stream *world*))
+ (setf (world-stream *world*) nil)
+ (setf (world-connected *world*) nil)
+ (run-hook :world-disconnected-hook))))
+
+(defun world-event (world-id &rest args)
+ (format t "DEBUG: world-event ~S ~S~%" world-id args)
+ (let ((*world* (or (gethash world-id *worlds*)
+ (make-instance 'world :id world-id))))
+ (apply #'world-event-handler args))) \ No newline at end of file
diff --git a/Lisp/openmcl/dppccl b/Lisp/openmcl/dppccl
new file mode 100755
index 0000000..49761db
--- /dev/null
+++ b/Lisp/openmcl/dppccl
Binary files differ
diff --git a/Lisp/openmcl/openmcl b/Lisp/openmcl/openmcl
new file mode 100755
index 0000000..1f457fa
--- /dev/null
+++ b/Lisp/openmcl/openmcl
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+# Change the definition of CCL_DEFAULT_DIRECTORY below to refer to
+# your OpenMCL installation directory.
+# Any definition of CCL_DEFAULT_DIRECTORY already present in the environment
+# takes precedence over definitions made below.
+
+if [ -z "$CCL_DEFAULT_DIRECTORY" ]; then
+ CCL_DEFAULT_DIRECTORY="$1"
+fi
+
+# This is shorter (& easier to type), making the invocation below
+# a little easier to read.
+
+DD=${CCL_DEFAULT_DIRECTORY}
+
+# If you don't want to guess the name of the OpenMCL kernel on
+# every invocation (or if you want to use a kernel with a
+# non-default name), you might want to uncomment and change
+# the following line:
+#OPENMCL_KERNEL=some_name
+
+# Set the CCL_DEFAULT_DIRECTORY environment variable;
+# the lisp will use this to setup translations for the CCL: logical host.
+
+if [ -z "$OPENMCL_KERNEL" ]; then
+ case `uname -s` in
+ Darwin)
+ OPENMCL_KERNEL=dppccl
+ ;;
+ Linux)
+ OPENMCL_KERNEL=ppccl
+ ;;
+ *)
+ echo "Can't determine host OS. Fix this."
+ exit 1
+ ;;
+ esac
+fi
+
+CCL_DEFAULT_DIRECTORY=${DD} exec ${DD}/${OPENMCL_KERNEL} "$@"
+
diff --git a/Lisp/openmcl/save-moxie-image.lisp b/Lisp/openmcl/save-moxie-image.lisp
new file mode 100644
index 0000000..1fda5fd
--- /dev/null
+++ b/Lisp/openmcl/save-moxie-image.lisp
@@ -0,0 +1,3 @@
+(require 'asdf)
+(asdf:operate 'asdf:load-op :moxie)
+(moxie::save-lisp-and-die "/tmp/dppccl.image")
diff --git a/Lisp/sbcl/save-moxie-image.lisp b/Lisp/sbcl/save-moxie-image.lisp
new file mode 100644
index 0000000..fed8216
--- /dev/null
+++ b/Lisp/sbcl/save-moxie-image.lisp
@@ -0,0 +1,3 @@
+(require 'asdf)
+(asdf:operate 'asdf:load-op :moxie)
+(moxie::save-lisp-and-die "/tmp/sbcl.core")
diff --git a/Lisp/sbcl/sbcl b/Lisp/sbcl/sbcl
new file mode 100755
index 0000000..76bd663
--- /dev/null
+++ b/Lisp/sbcl/sbcl
Binary files differ
diff --git a/Lisp/startlisp b/Lisp/startlisp
new file mode 100755
index 0000000..a7005cf
--- /dev/null
+++ b/Lisp/startlisp
@@ -0,0 +1,46 @@
+#!/bin/sh
+#
+# Args are Resources, Plugins, and Framework paths.
+#
+
+topdir=`dirname $0`
+cd "$1"
+
+template="init-template.lisp"
+initfile="/tmp/moxie-init.$$.lisp"
+
+start_clisp()
+{
+ if [ ! -f "$1/base" ]; then
+ ln -s . "$1/base"
+ fi
+ "$topdir/clisp" -B "$1" -E UTF-8 -i "$initfile"
+}
+
+start_openmcl()
+{
+ CCL_DEFAULT_DIRECTORY="$1"
+ export CCL_DEFAULT_DIRECTORY
+ "$topdir/openmcl" -l "$initfile"
+}
+
+start_sbcl()
+{
+ "$topdir/sbcl" --core "$1/sbcl.core" --load "$initfile"
+}
+
+#
+# Create the init file by substituting our args for variables in
+# the template.
+#
+sed -e "s,@resources@,$1,g;s,@plugins@,$2,g;s,@framework@,$3,g" < $template > $initfile
+
+#
+# Start up a lisp with the initialization file we just created.
+#
+#start_clisp "$1"
+start_sbcl "$1"
+#start_openmcl "$1"
+
+# Remove the initfile when the lisp quits.
+#rm -f $initfile \ No newline at end of file
diff --git a/LispREPL.h b/LispREPL.h
new file mode 100644
index 0000000..73e53c0
--- /dev/null
+++ b/LispREPL.h
@@ -0,0 +1,47 @@
+//
+// LispREPL.h
+// Moxie
+//
+// Created by Brian Cully on Sat Aug 14 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#define LispFinishedLoadingNotification @"LispFinishedLoadingNotification"
+
+@interface LispREPL : NSObject
+{
+ NSFileHandle *theStdinWriter;
+ NSFileHandle *theStdoutReader;
+ NSFileHandle *theResultReader;
+
+ NSMutableDictionary *theCommandHandlers;
+
+ NSMutableArray *theREPLResults;
+ NSTimer *theDispatcherTimer;
+ NSLock *theDispatcherLock;
+
+ BOOL theLispIsLoaded;
+}
++ (LispREPL *)sharedREPL;
+
+- (BOOL)isLoaded;
+
+- (void)addCommand: (NSString *)command
+ handler: (id)object
+ selector: (SEL)handler;
+- (void)removeCommand: (NSString *)command;
+- (void)runCommand: (NSString *)command withObjects: (id)objects;
+- (BOOL)commandHasHandler: (NSString *)command;
+- (id)handlerForCommand: (NSString *)command;
+- (SEL)selectorForCommand: (NSString *)command;
+
+- (void)eval: (id)aForm;
+@end
+
+@interface LispREPL (Accessors)
+- (NSMutableDictionary *)commandHandlers;
+
+- (NSFileHandle *)stdinWriter;
+- (NSFileHandle *)stdoutReader;
+- (NSFileHandle *)resultReader;
+@end \ No newline at end of file
diff --git a/LispREPL.m b/LispREPL.m
new file mode 100644
index 0000000..0033ad7
--- /dev/null
+++ b/LispREPL.m
@@ -0,0 +1,318 @@
+//
+// LispREPL.m
+// Moxie
+//
+// Created by Brian Cully on Sat Aug 14 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "LispREPL.h"
+#import "LispREPLController.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+enum repl_lock_condition { NO_DATA, HAS_DATA };
+
+@implementation LispREPL
+void
+sig_pipe(int signo)
+{
+ NSLog(@"WARNING: SIGPIPE caught.");
+}
+
+void
+sig_child(int signo)
+{
+ int status;
+
+ if (wait(&status) == -1) {
+ NSLog(@"WARNING: Couldn't clean up child: %s.\n", strerror(errno));
+ return;
+ }
+}
+
++ (LispREPL *)sharedREPL
+{
+ static LispREPL *sharedREPL;
+
+ if (sharedREPL == nil)
+ sharedREPL = [[self alloc] init];
+ return sharedREPL;
+}
+
+- (int)initLispProcess;
+{
+ NSString *helperPath;
+ NSString *resLocation, *pluginLocation, *frameworkLocation;
+ int pin[2], pout[2], res[2];
+ pid_t pid;
+ struct sigaction sa, ocsa, opsa;
+
+ helperPath = [[NSBundle mainBundle] pathForAuxiliaryExecutable: @"startlisp"];
+ if (helperPath == nil) {
+ NSLog(@"Couldn't find helper application in resources!");
+ return -1;
+ }
+
+ resLocation = [[NSBundle mainBundle] resourcePath];
+ pluginLocation = [[NSBundle mainBundle] builtInPlugInsPath];
+ frameworkLocation = [[NSBundle mainBundle] privateFrameworksPath];
+
+ if (pipe(pin) == -1 || pipe(pout) == -1 || pipe(res) == -1) {
+ NSLog(@"Couldn't create pipes for REPL!");
+ return -1;
+ }
+
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = sig_child;
+ sigaction(SIGCHLD, &sa, &ocsa);
+ sa.sa_handler = sig_pipe;
+ sigaction(SIGPIPE, &sa, &opsa);
+
+ setsid();
+ pid = fork();
+ if (pid == -1) {
+ NSLog(@"ERROR: Couldn't fork off lisp process: %s.", strerror(errno));
+ return -1;
+ } else if (pid == 0) {
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &sa, NULL);
+ sigaction(SIGPIPE, &sa, NULL);
+
+ close(pin[1]); close(pout[0]); close(res[0]);
+ if (dup2(pin[0], STDIN_FILENO) == -1 ||
+ dup2(pout[1], STDOUT_FILENO) == -1 ||
+ dup2(pout[1], STDERR_FILENO) == -1 ||
+ dup2(res[1], STDERR_FILENO+1) == -1) {
+ NSLog(@"ERROR: Couldn't setup standard I/O pipes: %s.", strerror(errno));
+ exit(1);
+ }
+ execl([helperPath UTF8String], [[helperPath lastPathComponent] UTF8String],
+ [resLocation UTF8String], [pluginLocation UTF8String], [frameworkLocation UTF8String], NULL);
+ exit(1);
+ }
+
+ close(pin[0]); close(pout[1]); close(res[1]);
+ theStdinWriter = [[NSFileHandle alloc] initWithFileDescriptor: pin[1]
+ closeOnDealloc: YES];
+ theStdoutReader = [[NSFileHandle alloc] initWithFileDescriptor: pout[0]
+ closeOnDealloc: YES];
+ theResultReader = [[NSFileHandle alloc] initWithFileDescriptor: res[0]
+ closeOnDealloc: YES];
+
+ return 0;
+}
+
+- (id)init
+{
+ self = [super init];
+ if (self) {
+ [self initLispProcess];
+
+ // Set up the result reader thread.
+ theREPLResults = [[NSMutableArray alloc] init];
+ theCommandHandlers = [[NSMutableDictionary alloc] init];
+ theDispatcherLock = [[NSConditionLock alloc] initWithCondition: NO_DATA];
+ theLispIsLoaded = NO;
+ [NSThread detachNewThreadSelector: @selector(readREPLResults:)
+ toTarget: self
+ withObject: [self resultReader]];
+ theDispatcherTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1
+ target: self
+ selector: @selector(dispatchREPLResults:)
+ userInfo: nil
+ repeats: YES];
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ // Gotta kill the reader thread here.
+ [theDispatcherLock release];
+ [theDispatcherTimer release];
+
+ // Then close file handles.
+ [[self stdinWriter] release];
+ [[self stdoutReader] release];
+ [[self resultReader] release];
+
+ // Then release our data.
+ [theREPLResults release];
+ [theCommandHandlers release];
+ [super dealloc];
+}
+
+- (BOOL)isLoaded
+{
+ return theLispIsLoaded;
+}
+
+- (NSArray *)handlerInfoForCommand: (id)command
+{
+ NSArray *handlerInfo;
+
+ handlerInfo = [[self commandHandlers] objectForKey: [command isKindOfClass: [NSString class]] ? command : [command stringValue]];
+ if (handlerInfo && [handlerInfo count] == 2)
+ return handlerInfo;
+ return nil;
+}
+
+- (void)setHandlerInfo: (NSArray *)handlerInfo forCommand: (NSString *)command
+{
+ if ([handlerInfo count] == 2)
+ [[self commandHandlers] setObject: handlerInfo forKey: command];
+ else if (handlerInfo == nil)
+ [[self commandHandlers] removeObjectForKey: command];
+}
+
+- (void)addCommand: (NSString *)command
+ handler: (id)object
+ selector: (SEL)handler
+{
+ [self setHandlerInfo: [NSArray arrayWithObjects: object, NSStringFromSelector(handler), nil]
+ forCommand: command];
+}
+
+- (void)removeCommand: (NSString *)command
+{
+ [self setHandlerInfo: nil forCommand: command];
+}
+
+- (void)runCommand: (NSString *)command withObjects: (id)objects
+{
+ id handler;
+ SEL selector;
+
+ handler = [self handlerForCommand: command];
+ if (handler) {
+ selector = [self selectorForCommand: command];
+
+ NS_DURING
+ [handler performSelector: selector withObject: objects];
+ NS_HANDLER
+ NSLog(@"WARNING: Got exception: %@ (%@) while evaluating %@:%@",
+ [localException name], [localException reason], handler, NSStringFromSelector(selector));
+ NS_ENDHANDLER
+ }
+}
+
+- (BOOL)commandHasHandler: (NSString *)command
+{
+ if ([self handlerInfoForCommand: command])
+ return YES;
+ return NO;
+}
+
+- (id)handlerForCommand: (NSString *)command
+{
+ return [[self handlerInfoForCommand: command] objectAtIndex: 0];
+}
+
+- (SEL)selectorForCommand: (NSString *)command
+{
+ return NSSelectorFromString([[self handlerInfoForCommand: command] objectAtIndex: 1]);
+}
+
+- (void)eval: (id)aForm
+{
+ [[self stdinWriter] writeData: [[NSString stringWithFormat: @"%@\n", aForm]
+ dataUsingEncoding: NSUTF8StringEncoding]];
+}
+
+/*
+ * Read and parse result forms from the REPL. Once parsed into arrays, dispatch them via
+ * the main thread by adding them to a worker queue.
+ */
+- (void)readREPLResults: (NSFileHandle *)resultsHandle
+{
+ NS_DURING
+ while (1) {
+ NSAutoreleasePool *rp;
+ id results;
+
+ rp = [[NSAutoreleasePool alloc] init];
+ results = [resultsHandle readLispForm];
+ [theDispatcherLock lock];
+ [theREPLResults addObject: results];
+ [theDispatcherLock unlock];
+ [rp release];
+ }
+ NS_HANDLER
+ [self performSelectorOnMainThread: @selector(replDiedSelector:)
+ withObject: self
+ waitUntilDone: NO];
+ NS_ENDHANDLER
+}
+
+- (void)replDiedSelector: (id)sender
+{
+ [[LispREPLController sharedController] showWindow: self];
+ NSRunCriticalAlertPanel(@"REPL died", @"The REPL sub-process has died, and Moxie cannot continue.",
+ @"OK", @"Retry", @"DEBUG");
+// [NSApp stop: self];
+}
+
+/*
+ * Wait for updates on the queue and dispatch results to the appropriate callback
+ * method on the values, if they're there, and call regular callbacks on the rest of
+ * the elements.
+ */
+- (void)dispatchREPLResults: (NSNotification *)resultsNotification
+{
+ [theDispatcherLock lock];
+ while ([theREPLResults count] > 0) {
+ id result;
+
+ if (theLispIsLoaded == NO) {
+ NSNotificationCenter *defaultCenter;
+ theLispIsLoaded = YES;
+
+ defaultCenter = [NSNotificationCenter defaultCenter];
+ [defaultCenter postNotificationName: LispFinishedLoadingNotification
+ object: self];
+ }
+ result = [theREPLResults objectAtIndex: 0];
+ if ([result isKindOfClass: [NSArray class]]) {
+ NSString *command;
+ NSArray *argArray;
+
+ command = [result objectAtIndex: 0];
+ argArray = [result subarrayWithRange: NSMakeRange(1, [result count] - 1)];
+ [self runCommand: command withObjects: argArray];
+ } else {
+ NSLog(@"ERROR: Couldn't dispatch results: %@", result);
+ }
+ [theREPLResults removeObjectAtIndex: 0];
+ }
+ [theDispatcherLock unlock];
+}
+@end
+
+@implementation LispREPL (Accessors)
+- (NSMutableDictionary *)commandHandlers
+{
+ return theCommandHandlers;
+}
+
+- (NSFileHandle *)stdinWriter
+{
+ return theStdinWriter;
+}
+
+- (NSFileHandle *)stdoutReader
+{
+ return theStdoutReader;
+}
+
+- (NSFileHandle *)resultReader
+{
+ return theResultReader;
+}
+@end \ No newline at end of file
diff --git a/LispREPLController.h b/LispREPLController.h
new file mode 100644
index 0000000..a9abdda
--- /dev/null
+++ b/LispREPLController.h
@@ -0,0 +1,60 @@
+//
+// LispREPLController.h
+// Moxie
+//
+// Created by Brian Cully on Mon Aug 09 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "LispREPL.h"
+
+@interface LispREPLController : NSWindowController
+{
+ IBOutlet NSTextView *theTextView;
+
+ int theMark, theValueMark;
+ BOOL theInputViewIsDirty;
+
+ NSTimer *theREPLUpdateTimer;
+ NSConditionLock *theREPLUpdateLock;
+ NSMutableArray *theUpdates;
+ BOOL waitingForResult;
+
+ NSMutableSet *theKeystrokeMacros;
+
+ NSMutableArray *theInputHistory;
+ unsigned theHistoryLevel;
+}
+
++ (LispREPLController *)sharedController;
+
+- (void)sendEvent: (NSString *)anEvent;
+- (void)sendEvent: (NSString *)anEvent withArg: (id)anArg;
+- (void)sendEventWithArgs: (NSString *)anEvent, ...;
+- (void)sendEvent: (NSString *)anEvent arguments: (va_list)args;
+
+- (BOOL)dispatchKeystrokeMacro: (NSEvent *)anEvent
+ fromID: (NSNumber *)aWorld;
+@end
+
+@interface LispREPLController (TextAttributes)
+- (NSDictionary *)REPLPromptAttributes;
+- (NSDictionary *)REPLInputAttributes;
+- (NSDictionary *)REPLOutputAttributes;
+- (NSDictionary *)REPLReturnValueAttributes;
+@end
+
+@interface LispREPLController (Accessors)
+- (NSTextView *)textView;
+
+- (int)mark;
+- (void)setMark: (int)aPoint;
+- (int)valueMark;
+- (void)setValueMark: (int)aPoint;
+
+- (NSMutableSet *)keystrokeMacros;
+- (void)setKeystrokeMacros: (NSMutableSet *)macros;
+
+- (NSMutableArray *)inputHistory;
+- (void)setInputHistory: (NSMutableArray *)aHistory;
+@end \ No newline at end of file
diff --git a/LispREPLController.m b/LispREPLController.m
new file mode 100644
index 0000000..889b9f1
--- /dev/null
+++ b/LispREPLController.m
@@ -0,0 +1,847 @@
+//
+// LispREPLController.m
+// Moxie
+//
+// Created by Brian Cully on Mon Aug 09 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "LispREPLController.h"
+
+enum repl_lock_condition { NO_DATA, HAS_DATA };
+
+@implementation LispREPLController
++ (LispREPLController *)sharedController
+{
+ static LispREPLController *sharedController = nil;
+
+ if (sharedController == nil) {
+ sharedController = [[LispREPLController alloc] init];
+ }
+ return sharedController;
+}
+
+- (id)init
+{
+ self = [self initWithWindowNibName: @"LispREPL"];
+ if (self) {
+ theHistoryLevel = 0;
+ waitingForResult = YES;
+ [self setWindowFrameAutosaveName: @"lispREPLWindow"];
+ // Make sure the window is there, so we get all the output even if it isn't open.
+ [self window];
+
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ NSNotificationCenter *defaultCenter;
+
+ defaultCenter = [NSNotificationCenter defaultCenter];
+ [defaultCenter removeObserver: self];
+
+ [theUpdates release];
+ [theREPLUpdateLock release];
+
+ [super dealloc];
+}
+
+- (void)scrollToEnd: (NSTextView *)aTextView
+{
+ NSScroller *verticalScroller;
+ NSScrollView *myScrollView;
+
+ myScrollView = (NSScrollView *)[[aTextView superview] superview];
+ verticalScroller = [myScrollView verticalScroller];
+ [aTextView scrollRangeToVisible: NSMakeRange([[aTextView textStorage] length], 0)];
+// if ([verticalScroller isEnabled] == NO || (1.0 - [verticalScroller floatValue]) < 0.000001)
+// [aTextView scrollRangeToVisible: NSMakeRange([[aTextView textStorage] length], 0)];
+}
+
+// Add a newline, print the prompt, and set the mark to the end of the buffer.
+- (void)updateREPLFont
+{
+ NSTextStorage *ts;
+ NSUserDefaults *defaults;
+
+ defaults = [NSUserDefaults standardUserDefaults];
+ ts = [[self textView] textStorage];
+ [ts addAttribute: NSFontAttributeName
+ value: [defaults REPLFont]
+ range: NSMakeRange(0, [ts length])];
+}
+
+// TODO:
+// Optimize redraw by caching previous values and checking for deltas.
+// Unfortunately, the notification posted for changes doesn't include said deltas.
+- (void)redisplay
+{
+ NSRect fontRect;
+ NSTextView *tv;
+ NSUserDefaults *defaults;
+
+ defaults = [NSUserDefaults standardUserDefaults];
+ tv = [self textView];
+ [tv setBackgroundColor: [defaults REPLBackgroundColor]];
+ [tv setInsertionPointColor: [defaults REPLInputTextColor]];
+ [tv setTypingAttributes: [self REPLInputAttributes]];
+ [self updateREPLFont];
+
+ fontRect = [[defaults REPLFont] boundingRectForFont];
+ if (fontRect.size.height > 0) {
+ [[self window] setContentResizeIncrements:
+ NSMakeSize(fontRect.size.width, fontRect.size.height)];
+ }
+}
+
+- (void)windowDidLoad
+{
+ NSNotificationCenter *defaultCenter;
+
+ [super windowDidLoad];
+ [[self window] setOpaque: NO];
+
+ [[LispREPL sharedREPL] addCommand: @":REPL-RESULT"
+ handler: self
+ selector: @selector(setLispResult:)];
+ [[LispREPL sharedREPL] addCommand: @":REPL-DBG"
+ handler: self
+ selector: @selector(lispInDebugger:)];
+ [[LispREPL sharedREPL] addCommand: @":REGISTER-KEYSTROKE"
+ handler: self
+ selector: @selector(registerKeystrokeMacro:)];
+ [[LispREPL sharedREPL] addCommand: @":UNREGISTER-KEYSTROKE"
+ handler: self
+ selector: @selector(unregisterKeystrokeMacro:)];
+
+ theREPLUpdateLock = [[NSConditionLock alloc] initWithCondition: NO_DATA];
+ theUpdates = [[NSMutableArray alloc] init];
+ [NSThread detachNewThreadSelector: @selector(readREPLData:)
+ toTarget: self
+ withObject: [[LispREPL sharedREPL] stdoutReader]];
+
+ [LispREPL sharedREPL];
+
+ theREPLUpdateTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1
+ target: self
+ selector: @selector(scanForREPLData:)
+ userInfo: nil
+ repeats: YES];
+
+ defaultCenter = [NSNotificationCenter defaultCenter];
+ [defaultCenter addObserver: self
+ selector: @selector(preferencesChanged:)
+ name: NSUserDefaultsDidChangeNotification
+ object: [NSUserDefaults standardUserDefaults]];
+
+ [self redisplay];
+}
+
+- (LispSymbol *)keystrokeFromEvent: (NSEvent *)anEvent
+{
+ LispSymbol *rc;
+
+ rc = nil;
+ if ([anEvent type] == NSKeyDown) {
+ NSString *characters;
+ NSString *modifier, *keycode;
+ unsigned int i;
+
+ modifier = @"";
+ if ([anEvent modifierFlags] & NSCommandKeyMask) {
+ modifier = [modifier stringByAppendingString: @"CMD-"];
+ }
+ if ([anEvent modifierFlags] & NSAlternateKeyMask) {
+ modifier = [modifier stringByAppendingString: @"OPT-"];
+ }
+ if ([anEvent modifierFlags] & NSControlKeyMask) {
+ modifier = [modifier stringByAppendingString: @"CTRL-"];
+ }
+ if ([anEvent modifierFlags] & NSShiftKeyMask) {
+ modifier = [modifier stringByAppendingString: @"SHIFT-"];
+ }
+ if ([anEvent modifierFlags] & NSNumericPadKeyMask) {
+ modifier = [modifier stringByAppendingString: @"NUMPAD-"];
+ }
+
+ // This sucks. We should be encoding things in a structure, not a keyword.
+ keycode = @"";
+ characters = [anEvent charactersIgnoringModifiers];
+ for (i = 0; i < [characters length]; i++) {
+ switch ([characters characterAtIndex: i]) {
+ case '(':
+ keycode = @"LPAREN";
+ break;
+ case ')':
+ keycode = @"RPAREN";
+ break;
+ case ':':
+ keycode = @"COLON";
+ break;
+ case '|':
+ keycode = @"PIPE";
+ break;
+ case ';':
+ keycode = @"SEMICOLON";
+ break;
+ case '\\':
+ keycode = @"BACKSLASH";
+ break;
+ case '\'':
+ keycode = @"QUOTE";
+ break;
+ case '`':
+ keycode = @"BACKQUOTE";
+ break;
+ case '\t':
+ keycode = @"TAB";
+ break;
+ case 27:
+ keycode = @"ESC";
+ break;
+ case 127:
+ keycode = @"BACKSPACE";
+ break;
+ case 3:
+ case 13:
+ keycode = @"RETURN";
+ break;
+ case NSUpArrowFunctionKey:
+ keycode = @"UP";
+ break;
+ case NSDownArrowFunctionKey:
+ keycode = @"DOWN";
+ break;
+ case NSLeftArrowFunctionKey:
+ keycode = @"LEFT";
+ break;
+ case NSRightArrowFunctionKey:
+ keycode = @"RIGHT";
+ break;
+ case NSF1FunctionKey:
+ keycode = @"F1";
+ break;
+ case NSF2FunctionKey:
+ keycode = @"F2";
+ break;
+ case NSF3FunctionKey:
+ keycode = @"F3";
+ break;
+ case NSF4FunctionKey:
+ keycode = @"F4";
+ break;
+ case NSF5FunctionKey:
+ keycode = @"F5";
+ break;
+ case NSF6FunctionKey:
+ keycode = @"F6";
+ break;
+ case NSF7FunctionKey:
+ keycode = @"F7";
+ break;
+ case NSF8FunctionKey:
+ keycode = @"F8";
+ break;
+ case NSF9FunctionKey:
+ keycode = @"F9";
+ break;
+ case NSF10FunctionKey:
+ keycode = @"F10";
+ break;
+ case NSF11FunctionKey:
+ keycode = @"F11";
+ break;
+ case NSF12FunctionKey:
+ keycode = @"F12";
+ break;
+ case NSF13FunctionKey:
+ keycode = @"F13";
+ break;
+ case NSF14FunctionKey:
+ keycode = @"F14";
+ break;
+ case NSF15FunctionKey:
+ keycode = @"F15";
+ break;
+ case NSF16FunctionKey:
+ keycode = @"F16";
+ break;
+ case NSF17FunctionKey:
+ keycode = @"F17";
+ break;
+ case NSF18FunctionKey:
+ keycode = @"F18";
+ break;
+ case NSF19FunctionKey:
+ keycode = @"F19";
+ break;
+ case NSF20FunctionKey:
+ keycode = @"F20";
+ break;
+ case NSF21FunctionKey:
+ keycode = @"F21";
+ break;
+ case NSF22FunctionKey:
+ keycode = @"F22";
+ break;
+ case NSF23FunctionKey:
+ keycode = @"F23";
+ break;
+ case NSF24FunctionKey:
+ keycode = @"F24";
+ break;
+ case NSF25FunctionKey:
+ keycode = @"F25";
+ break;
+ case NSF26FunctionKey:
+ keycode = @"F26";
+ break;
+ case NSF27FunctionKey:
+ keycode = @"F27";
+ break;
+ case NSF28FunctionKey:
+ keycode = @"F28";
+ break;
+ case NSF29FunctionKey:
+ keycode = @"F29";
+ break;
+ case NSF30FunctionKey:
+ keycode = @"F30";
+ break;
+ case NSF31FunctionKey:
+ keycode = @"F31";
+ break;
+ case NSF32FunctionKey:
+ keycode = @"F32";
+ break;
+ case NSF33FunctionKey:
+ keycode = @"F33";
+ break;
+ case NSF34FunctionKey:
+ keycode = @"F34";
+ break;
+ case NSF35FunctionKey:
+ keycode = @"F35";
+ break;
+ case NSInsertFunctionKey:
+ keycode = @"INS";
+ break;
+ case NSDeleteFunctionKey:
+ keycode = @"DEL";
+ break;
+ case NSHomeFunctionKey:
+ keycode = @"HOME";
+ break;
+ case NSBeginFunctionKey:
+ keycode = @"BEGIN";
+ break;
+ case NSEndFunctionKey:
+ keycode = @"END";
+ break;
+ case NSPageUpFunctionKey:
+ keycode = @"PAGEUP";
+ break;
+ case NSPageDownFunctionKey:
+ keycode = @"PAGEDOWN";
+ break;
+ case NSClearLineFunctionKey:
+ keycode = @"CLEAR";
+ break;
+ default:
+ keycode = [NSString stringWithFormat: @"%c", [characters characterAtIndex: i]];
+ }
+ }
+ rc = [LispSymbol symbolNamed: [NSString stringWithFormat: @":%@%@", modifier, keycode]];
+ }
+ NSLog(@"DEBUG: sending keycode: %@", rc);
+ return rc;
+}
+
+- (BOOL)dispatchKeystrokeMacro: (NSEvent *)anEvent
+ fromID: (NSNumber *)anID
+{
+ LispSymbol *keystroke;
+ BOOL rc;
+
+ rc = NO;
+ keystroke = [self keystrokeFromEvent: anEvent];
+ if (keystroke) {
+ if ([[self keystrokeMacros] containsObject: keystroke]) {
+ [[LispREPL sharedREPL] eval:
+ [NSString stringWithFormat: @"(moxie::world-event %@ :keystroke-macro-hook %@)",
+ anID, [keystroke lispForm]]];
+ rc = YES;
+ }
+ }
+ return rc;
+}
+
+- (void)registerKeystrokeMacro: (NSArray *)form
+{
+ LispSymbol *keystroke;
+
+ keystroke = [form objectAtIndex: 0];
+ [[self keystrokeMacros] addObject: keystroke];
+}
+
+- (void)unregisterKeystrokeMacro: (NSArray *)form
+{
+ LispSymbol *keystroke;
+
+ keystroke = [form objectAtIndex: 0];
+ [[self keystrokeMacros] removeObject: keystroke];
+}
+
+- (void)goBackwardInHistory
+{
+ if (theHistoryLevel > 0) {
+ NSMutableString *buffer;
+
+ buffer = [[[self textView] textStorage] mutableString];
+ if (NO) {
+ [[self inputHistory] addObject: [buffer substringWithRange: NSMakeRange(0, [buffer length])]];
+ theInputViewIsDirty = NO;
+ theHistoryLevel = [[self inputHistory] count] - 1;
+ }
+ theHistoryLevel--;
+
+ [buffer replaceCharactersInRange: NSMakeRange([self mark],
+ [buffer length] - [self mark])
+ withString: [[self inputHistory] objectAtIndex: theHistoryLevel]];
+ [self scrollToEnd: [self textView]];
+ }
+}
+
+- (void)goForwardInHistory
+{
+ if (theHistoryLevel < [[self inputHistory] count]-1) {
+ NSMutableString *buffer;
+
+ buffer = [[[self textView] textStorage] mutableString];
+ if (theInputViewIsDirty) {
+ [[self inputHistory] addObject: [buffer substringWithRange: NSMakeRange(0, [buffer length])]];
+ theInputViewIsDirty = NO;
+ theHistoryLevel = [[self inputHistory] count];
+ } else
+ theHistoryLevel++;
+
+ [buffer replaceCharactersInRange: NSMakeRange([self mark],
+ [buffer length] - [self mark])
+ withString: [[self inputHistory] objectAtIndex: theHistoryLevel]];
+ [self scrollToEnd: [self textView]];
+ }
+}
+
+- (void)textDidChange: (NSNotification *)aNotification
+{
+ if ([aNotification object] == theTextView) {
+ // Flag the input view as changed.
+ theInputViewIsDirty = YES;
+ }
+}
+
+// XXX - this needs to change badly. We need to do full form
+// parsing here or figure out a way around it entirely.
+//
+// This can probably tie into the indentation system.
+- (BOOL)isValidLispForm: (NSString *)aForm
+{
+ int parenCount;
+ int i, formLen;
+
+ formLen = [aForm length];
+ parenCount = 0;
+ for (i = 0; i < formLen; i++) {
+ switch ([aForm characterAtIndex: i]) {
+ case '(':
+ parenCount++;
+ break;
+ case ')':
+ parenCount--;
+ break;
+ }
+ }
+
+ return parenCount == 0;
+}
+
+- (void)sendInputToLisp: (NSString *)aForm
+{
+ int formLen;
+
+ // Get the new text, which is between the old mark and the end of the buffer.
+ formLen = [aForm length];
+ if (formLen > 0) {
+ NSMutableString *buffer;
+ NSTextStorage *ts;
+
+ // Save line in history.
+ if (theInputViewIsDirty || theHistoryLevel < [[self inputHistory] count]-1) {
+ [[self inputHistory] addObject: [aForm substringWithRange: NSMakeRange(0, formLen)]];
+ theInputViewIsDirty = NO;
+ }
+ theHistoryLevel = [[self inputHistory] count];
+
+ // Update the marks when we send data to lisp.
+ ts = [[self textView] textStorage];
+ buffer = [[[self textView] textStorage] mutableString];
+ [self setMark: [buffer length]];
+ [self setValueMark: [buffer length]];
+
+ if (waitingForResult)
+ [[LispREPL sharedREPL] eval: aForm];
+ else
+ [self sendEvent: @":eval" withArg: [LispSymbol symbolNamed: aForm]]; // XXX: This is a cheap and dirty way to avoid getting
+ // the string quoted. We should just parse out the tree
+ // and send that array.
+ waitingForResult = YES;
+ }
+}
+
+- (void)setLispResult: (NSArray *)alist
+{
+ NSArray *result;
+ NSDictionary *resultDict;
+ NSMutableString *resultStr;
+ NSMutableString *buffer;
+ NSTextStorage *ts;
+ NSString *prompt;
+
+ ts = [[self textView] textStorage];
+ buffer = [[[self textView] textStorage] mutableString];
+
+ resultDict = [NSDictionary dictionaryWithAlist: alist];
+ prompt = [[resultDict objectForKey: @":PROMPT"] objectAtIndex: 0];
+ result = [resultDict objectForKey: @":VALUES"];
+
+ if (result) {
+ resultStr = [NSMutableString stringWithString: @"=>"];
+ if ([result isKindOfClass: [NSArray class]]) {
+ NSEnumerator *resultEnum;
+ id obj;
+
+ resultEnum = [result objectEnumerator];
+ while ((obj = [resultEnum nextObject]) != nil)
+ [resultStr appendFormat: @" %@", [obj lispForm]];
+ } else
+ [resultStr appendFormat: @" %@", [result lispForm]];
+
+ [resultStr appendString: @"\n"];
+
+ [buffer appendString: resultStr];
+ [ts addAttributes: [self REPLReturnValueAttributes]
+ range: NSMakeRange([self valueMark], [resultStr length])];
+ }
+ [self setMark: [buffer length]];
+
+ if (prompt) {
+ waitingForResult = NO;
+
+ [buffer appendString: prompt];
+ [ts addAttributes: [self REPLPromptAttributes]
+ range: NSMakeRange([self mark], [prompt length])];
+ }
+ [self setMark: [buffer length]];
+
+ [ts addAttributes: [self REPLInputAttributes]
+ range: NSMakeRange([self mark] - 1, 1)];
+ [[self textView] setTypingAttributes: [self REPLInputAttributes]];
+
+ [self scrollToEnd: [self textView]];
+}
+
+/*
+ * When we're in the debugger, let it use its own prompt. And in the event that we've already printed our
+ * prompt, delete it.
+ */
+- (void)lispInDebugger: (NSArray *)args
+{
+ NSMutableString *buffer;
+ NSRange range;
+
+ waitingForResult = YES;
+
+ buffer = [[[self textView] textStorage] mutableString];
+ range = NSMakeRange([self valueMark], [self mark] - [self valueMark]);
+ [buffer deleteCharactersInRange: range];
+ [self setMark: [self mark] - range.length];
+}
+
+- (void)scanForREPLData: (NSDictionary *)userInfo
+{
+ [theREPLUpdateLock lock];
+ while ([theUpdates count] > 0) {
+ NSAttributedString *replString;
+ NSData *updateData;
+ NSTextStorage *ts;
+
+ updateData = [theUpdates objectAtIndex: 0];
+ replString = [NSAttributedString attributedStringWithString:
+ [NSString stringWithCString: [updateData bytes]
+ length: [updateData length]]
+ attributes: [self REPLOutputAttributes]];
+
+ // Insert before values, and update marks.
+ ts = [[self textView] textStorage];
+ [ts insertAttributedString: replString atIndex: [self valueMark]];
+ [self setMark: [self mark] + [replString length]];
+ [self setValueMark: [self valueMark] + [replString length]];
+
+ [self scrollToEnd: [self textView]];
+ [theUpdates removeObjectAtIndex: 0];
+ }
+ [theREPLUpdateLock unlock];
+}
+
+- (void)readREPLData: (NSFileHandle *)stdoutInput
+{
+ while (1) {
+ NSAutoreleasePool *rp;
+ NSData *inputData;
+
+ rp = [[NSAutoreleasePool alloc] init];
+ inputData = [stdoutInput availableData];
+ if ([inputData length] == 0)
+ continue;
+ [theREPLUpdateLock lock];
+ [theUpdates addObject: inputData];
+ [theREPLUpdateLock unlock];
+ [rp release];
+ }
+}
+
+- (void)preferencesChanged: (NSNotification *)aNotification
+{
+ [self redisplay];
+}
+
+- (void)changeFont: (id)sender
+{
+ NSDictionary *attrs;
+ NSFont *oldFont, *newFont;
+
+ attrs = [[self textView] typingAttributes];
+ oldFont = [attrs objectForKey: NSFontAttributeName];
+ newFont = [sender convertFont: oldFont];
+
+ [[NSUserDefaults standardUserDefaults] setREPLFontData:
+ [NSArchiver archivedDataWithRootObject: newFont]];
+}
+
+- (BOOL)textView: (NSTextView *)aTextView
+shouldChangeTextInRange: (NSRange)affectedCharRange
+ replacementString: (NSString *)replacementString
+{
+ if (replacementString && affectedCharRange.location < (unsigned)[self mark]) {
+ NSBeep();
+ [[self textView] setSelectedRange: NSMakeRange([self mark], 0)];
+ [self scrollToEnd: [self textView]];
+ return NO;
+ }
+ return YES;
+}
+
+- (NSArray *)textView: (NSTextView *)textView
+ completions: (NSArray *)words
+ forPartialWordRange: (NSRange)charRange
+ indexOfSelectedItem: (int *)i
+{
+ NSLog(@"[LispREPLController textView %@ completions: %@ forPartialWordRange: (%d, %d) indexOfSelectedItem: %d]",
+ textView, words, charRange.location, charRange.length, *i);
+ return words;
+}
+
+- (void)sendEvent: (NSString *)anEvent
+{
+ [self sendEventWithArgs: anEvent, nil];
+}
+
+- (void)sendEvent: (NSString *)anEvent withArg: (id)anArg
+{
+ [self sendEventWithArgs: anEvent, anArg, nil];
+}
+
+-(void)sendEventWithArgs: (NSString *)anEvent, ...
+{
+ va_list ap;
+
+ va_start(ap, anEvent);
+ [self sendEvent: anEvent arguments: ap];
+ va_end(ap);
+}
+
+-(void)sendEvent: (NSString *)anEvent arguments: (va_list)args
+{
+ NSMutableArray *argArray;
+ id arg;
+
+ argArray = [NSMutableArray arrayWithObject: [LispSymbol symbolNamed: anEvent]];
+ while ((arg = va_arg(args, id)) != nil) {
+ [argArray addObject: arg];
+ }
+ [[LispREPL sharedREPL] eval: [NSString stringWithFormat: @"(apply #'moxie::moxie-event-handler '%@)",
+ [argArray lispForm]]];
+}
+
+- (NSNumber *)handleEvent: (NSEvent *)anEvent from: (id)sender
+{
+ BOOL rc;
+
+ rc = NO;
+ if ([anEvent type] == NSKeyDown) {
+ NSMutableString *buffer;
+ NSString *characters;
+ unsigned int i;
+
+ buffer = [[[self textView] textStorage] mutableString];
+ characters = [anEvent charactersIgnoringModifiers];
+ for (i = 0; i < [characters length]; i++) {
+ switch ([characters characterAtIndex: i]) {
+ case '\r':
+ case '\n': {
+ NSString *changedBuffer;
+
+ changedBuffer = [buffer substringFromIndex: [self mark]];
+ if ([self isValidLispForm: changedBuffer]) {
+ [buffer appendString: @"\n"];
+ [self sendInputToLisp: changedBuffer];
+
+ [[self textView] setSelectedRange: NSMakeRange([buffer length], 0)];
+ rc = YES;
+ }
+ break;
+ }
+ case NSUpArrowFunctionKey:
+ if ([anEvent modifierFlags] & NSCommandKeyMask) {
+ [self goBackwardInHistory];
+ rc = YES;
+ }
+ break;
+ case NSDownArrowFunctionKey:
+ if ([anEvent modifierFlags] & NSCommandKeyMask) {
+ [self goForwardInHistory];
+ rc = YES;
+ }
+ break;
+ }
+ }
+ }
+
+ return [NSNumber numberWithBool: rc];
+}
+@end
+
+@implementation LispREPLController (TextAttributes)
+- (NSDictionary *)REPLPromptAttributes
+{
+ NSMutableDictionary *myAttrs;
+ NSUserDefaults *defaults;
+
+ defaults = [NSUserDefaults standardUserDefaults];
+ myAttrs = [NSMutableDictionary dictionary];
+ [myAttrs setObject: [defaults REPLFont] forKey: NSFontAttributeName];
+ [myAttrs setObject: [defaults REPLPromptColor] forKey: NSForegroundColorAttributeName];
+ [myAttrs setObject: @"prompt" forKey: @"REPL.style"];
+
+ return myAttrs;
+}
+
+- (NSDictionary *)REPLInputAttributes
+{
+ NSMutableDictionary *myAttrs;
+ NSUserDefaults *defaults;
+
+ defaults = [NSUserDefaults standardUserDefaults];
+ myAttrs = [NSMutableDictionary dictionary];
+ [myAttrs setObject: [defaults REPLFont] forKey: NSFontAttributeName];
+ [myAttrs setObject: [defaults REPLInputTextColor] forKey: NSForegroundColorAttributeName];
+ [myAttrs setObject: @"input" forKey: @"REPL.style"];
+
+ return myAttrs;
+}
+
+- (NSDictionary *)REPLOutputAttributes
+{
+ NSMutableDictionary *myAttrs;
+ NSUserDefaults *defaults;
+
+ defaults = [NSUserDefaults standardUserDefaults];
+ myAttrs = [NSMutableDictionary dictionary];
+ [myAttrs setObject: [defaults REPLFont] forKey: NSFontAttributeName];
+ [myAttrs setObject: [defaults REPLOutputTextColor] forKey: NSForegroundColorAttributeName];
+ [myAttrs setObject: @"output" forKey: @"REPL.style"];
+
+ return myAttrs;
+}
+
+- (NSDictionary *)REPLReturnValueAttributes
+{
+ NSMutableDictionary *myAttrs;
+ NSUserDefaults *defaults;
+
+ defaults = [NSUserDefaults standardUserDefaults];
+ myAttrs = [NSMutableDictionary dictionary];
+ [myAttrs setObject: [defaults REPLFont] forKey: NSFontAttributeName];
+ [myAttrs setObject: [defaults REPLReturnValueColor] forKey: NSForegroundColorAttributeName];
+ [myAttrs setObject: @"result" forKey: @"REPL.style"];
+
+ return myAttrs;
+}
+@end
+
+@implementation LispREPLController (Accessors)
+- (NSTextView *)textView
+{
+ return theTextView;
+}
+
+- (int)mark
+{
+ return theMark;
+}
+
+- (void)setMark: (int)aPoint
+{
+ theMark = aPoint;
+}
+
+- (NSMutableSet *)keystrokeMacros
+{
+ if (theKeystrokeMacros == nil)
+ [self setKeystrokeMacros: [NSMutableSet set]];
+ return theKeystrokeMacros;
+}
+
+- (void)setKeystrokeMacros: (NSMutableSet *)macros
+{
+ [macros retain];
+ [theKeystrokeMacros release];
+ theKeystrokeMacros = macros;
+}
+
+- (NSMutableArray *)inputHistory
+{
+ if (theInputHistory == nil)
+ [self setInputHistory: [NSMutableArray array]];
+ return theInputHistory;
+}
+
+- (int)valueMark
+{
+ return theValueMark;
+}
+
+- (void)setValueMark: (int)aPoint
+{
+ theValueMark = aPoint;
+}
+
+- (void)setInputHistory: (NSMutableArray *)aHistory
+{
+ [aHistory retain];
+ [theInputHistory release];
+ theInputHistory = aHistory;
+}
+@end \ No newline at end of file
diff --git a/LispSymbol.h b/LispSymbol.h
new file mode 100644
index 0000000..50bdbb6
--- /dev/null
+++ b/LispSymbol.h
@@ -0,0 +1,30 @@
+//
+// LispSymbol.h
+// Moxie
+//
+// Created by Brian Cully on Tue Sep 07 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface LispSymbol : NSObject <NSCopying>
+{
+ NSString *theName;
+}
++ (LispSymbol *)symbolT;
++ (LispSymbol *)symbolNIL;
++ (LispSymbol *)symbolNamed: (NSString *)aName;
+
+- (id)initWithName: (NSString *)aName;
+- (NSString *)lispForm;
+@end
+
+@interface LispSymbol (Accessors)
+- (NSString *)name;
+- (void)setName: (NSString *)aName;
+@end
+
+@interface LispSymbol (Comparators)
+- (BOOL)isEqualToString: (NSString *)aString;
+@end \ No newline at end of file
diff --git a/LispSymbol.m b/LispSymbol.m
new file mode 100644
index 0000000..a73a420
--- /dev/null
+++ b/LispSymbol.m
@@ -0,0 +1,136 @@
+//
+// LispSymbol.m
+// Moxie
+//
+// Created by Brian Cully on Tue Sep 07 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "LispSymbol.h"
+
+@implementation LispSymbol
+LispSymbol *BIG_T = nil;
+LispSymbol *BIG_NIL = nil;
+
++ (LispSymbol *)symbolT
+{
+ if (BIG_T == nil)
+ BIG_T = [[self alloc] initWithName: @"T"];
+ return BIG_T;
+}
+
++ (LispSymbol *)symbolNIL
+{
+ if (BIG_NIL == nil)
+ BIG_NIL = [[self alloc] initWithName: @"NIL"];
+ return BIG_NIL;
+}
+
++ (LispSymbol *)symbolNamed: (NSString *)aName
+{
+ if ([aName caseInsensitiveCompare: @"T"] == NSOrderedSame)
+ return [LispSymbol symbolT];
+ else if ([aName caseInsensitiveCompare: @"NIL"] == NSOrderedSame)
+ return [LispSymbol symbolNIL];
+ else
+ return [[[self alloc] initWithName: aName] autorelease];
+}
+
+- (id)initWithName: (NSString *)aName
+{
+ self = [super init];
+ if (self) {
+ [self setName: aName];
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [self setName: nil];
+ [super dealloc];
+}
+
+- (NSString *)description
+{
+ return [NSString stringWithFormat: @"#<LispSymbol: %@>", [self name]];
+}
+
+- (BOOL)boolValue
+{
+ return [self isEqualToString: @"NIL"] == NO;
+}
+
+- (double)doubleValue
+{
+ return [[self name] doubleValue];
+}
+
+- (float)floatValue
+{
+ return [[self name] floatValue];
+}
+
+- (int)intValue
+{
+ return [[self name] intValue];
+}
+
+- (NSString *)stringValue
+{
+ return [self name];
+}
+
+- (id)copyWithZone: (NSZone *)aZone
+{
+ LispSymbol *result;
+
+ result = [[LispSymbol allocWithZone: aZone] init];
+ [result setName: [self name]];
+ return result;
+}
+
+- (unsigned)hash
+{
+ return [[self name] hash];
+}
+
+- (BOOL)isEqual: (id)anObject
+{
+ BOOL result;
+
+ if ([anObject isKindOfClass: [NSString class]])
+ result = [self isEqualToString: anObject];
+ else if ([anObject isKindOfClass: [self class]]) {
+ result = [self isEqualToString: [anObject name]];
+ } else
+ result = [super isEqual: anObject];
+ return result;
+}
+
+- (NSString *)lispForm
+{
+ return [self name];
+}
+@end
+
+@implementation LispSymbol (Accessors)
+- (NSString *)name
+{
+ return theName;
+}
+
+- (void)setName: (NSString *)aName
+{
+ [aName retain];
+ [theName release];
+ theName = aName;
+}
+@end
+
+@implementation LispSymbol (Comparators)
+- (BOOL)isEqualToString: (NSString *)aString
+{
+ return ([[self name] caseInsensitiveCompare: aString] == NSOrderedSame);
+}
+@end \ No newline at end of file
diff --git a/Moxie.icns b/Moxie.icns
new file mode 100644
index 0000000..a22655d
--- /dev/null
+++ b/Moxie.icns
Binary files differ
diff --git a/Moxie.xcodeproj/bjc.mode1 b/Moxie.xcodeproj/bjc.mode1
new file mode 100644
index 0000000..e2f6d18
--- /dev/null
+++ b/Moxie.xcodeproj/bjc.mode1
@@ -0,0 +1,1393 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActivePerspectiveName</key>
+ <string>Project</string>
+ <key>AllowedModules</key>
+ <array>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Name</key>
+ <string>Groups and Files Outline View</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Name</key>
+ <string>Editor</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCTaskListModule</string>
+ <key>Name</key>
+ <string>Task List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Name</key>
+ <string>File and Smart Group Detail Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Name</key>
+ <string>Detailed Build Results Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Name</key>
+ <string>Project Batch Find Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXRunSessionModule</string>
+ <key>Name</key>
+ <string>Run Log</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Name</key>
+ <string>Bookmarks Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Name</key>
+ <string>Class Browser</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Name</key>
+ <string>Source Code Control Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXDebugBreakpointsModule</string>
+ <key>Name</key>
+ <string>Debug Breakpoints Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDockableInspector</string>
+ <key>Name</key>
+ <string>Inspector</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXOpenQuicklyModule</string>
+ <key>Name</key>
+ <string>Open Quickly Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Name</key>
+ <string>Debugger</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Name</key>
+ <string>Debug Console</string>
+ </dict>
+ </array>
+ <key>Description</key>
+ <string>DefaultDescriptionKey</string>
+ <key>DockingSystemVisible</key>
+ <false/>
+ <key>Extension</key>
+ <string>mode1</string>
+ <key>FavBarConfig</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2898672D095DAA6100B5DC99</string>
+ <key>XCBarModuleItemNames</key>
+ <dict/>
+ <key>XCBarModuleItems</key>
+ <array/>
+ </dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>com.apple.perspectives.project.mode1</string>
+ <key>MajorVersion</key>
+ <integer>31</integer>
+ <key>MinorVersion</key>
+ <integer>1</integer>
+ <key>Name</key>
+ <string>Default</string>
+ <key>Notifications</key>
+ <array/>
+ <key>OpenEditors</key>
+ <array/>
+ <key>PerspectiveWidths</key>
+ <array>
+ <integer>-1</integer>
+ <integer>-1</integer>
+ </array>
+ <key>Perspectives</key>
+ <array>
+ <dict>
+ <key>ChosenToolbarItems</key>
+ <array>
+ <string>active-target-popup</string>
+ <string>action</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>buildOrClean</string>
+ <string>build-and-runOrDebug</string>
+ <string>com.apple.ide.PBXToolbarStopButton</string>
+ <string>get-info</string>
+ <string>toggle-editor</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>com.apple.pbx.toolbar.searchfield</string>
+ </array>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProjectWithEditor</string>
+ <key>Identifier</key>
+ <string>perspective.project</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>231</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>2A37F4AAFDCFA73011CA2CEA</string>
+ <string>1C37FAAC04509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>2</integer>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {231, 730}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <true/>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {248, 748}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>231</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>3 202 982 789 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>248pt</string>
+ </dict>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20306471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>ScrollingTextView.m</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20406471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>ScrollingTextView.m</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>28B4138B0A9B3EC9001560B5</string>
+ <key>history</key>
+ <array>
+ <string>285A43FB096614A700597D37</string>
+ <string>285A46550966239B00597D37</string>
+ <string>285A46AC0966445B00597D37</string>
+ <string>285A46C60966D7DC00597D37</string>
+ <string>285A4743096739E700597D37</string>
+ <string>2861E9EF0967A5FC002A271F</string>
+ <string>2861EAE409687652002A271F</string>
+ <string>2861EAED096877AD002A271F</string>
+ <string>28A2E206096A0C220005CC4E</string>
+ <string>28A2E3620971E2E60005CC4E</string>
+ <string>2826B2720A97638C005CEDA1</string>
+ <string>2826B2730A97638C005CEDA1</string>
+ <string>2826B2740A97638C005CEDA1</string>
+ <string>2826B2750A97638C005CEDA1</string>
+ <string>2826B2760A97638C005CEDA1</string>
+ <string>28B40D6B0A97CBD2001560B5</string>
+ <string>28B412C20A98B52B001560B5</string>
+ <string>28B413010A98B8B7001560B5</string>
+ <string>28B413020A98B8B7001560B5</string>
+ <string>28B413880A9B3EC9001560B5</string>
+ <string>28B413890A9B3EC9001560B5</string>
+ </array>
+ <key>prevStack</key>
+ <array>
+ <string>28986BF0095E4A2200B5DC99</string>
+ <string>28986BF4095E4A2200B5DC99</string>
+ <string>283BCB0B0963158A00791914</string>
+ <string>283BCC4209634B1000791914</string>
+ <string>28889CFB09648F9900527406</string>
+ <string>28889D3A096496D800527406</string>
+ <string>285A45930966165600597D37</string>
+ <string>285A46380966204C00597D37</string>
+ <string>285A46570966239B00597D37</string>
+ <string>2861E99F0967804F002A271F</string>
+ <string>2861E9F10967A5FC002A271F</string>
+ <string>2861EAE609687652002A271F</string>
+ <string>2826B27C0A97638C005CEDA1</string>
+ <string>2826B27D0A97638C005CEDA1</string>
+ <string>2826B27E0A97638C005CEDA1</string>
+ <string>2826B27F0A97638C005CEDA1</string>
+ <string>28B412C40A98B52B001560B5</string>
+ <string>28B413040A98B8B7001560B5</string>
+ <string>28B413050A98B8B7001560B5</string>
+ <string>28B4138A0A9B3EC9001560B5</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {729, 457}}</string>
+ <key>RubberWindowFrame</key>
+ <string>3 202 982 789 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>457pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20506471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 462}, {729, 286}}</string>
+ <key>RubberWindowFrame</key>
+ <string>3 202 982 789 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>286pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>729pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCModuleDock</string>
+ <string>PBXNavigatorGroup</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>28B412B10A98B473001560B5</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>28B412B20A98B473001560B5</string>
+ <string>1CE0B20306471E060097A5F4</string>
+ <string>1CE0B20506471E060097A5F4</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.default</string>
+ </dict>
+ <dict>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProject</string>
+ <key>Identifier</key>
+ <string>perspective.morph</string>
+ <key>IsVertical</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>186</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>29B97314FDCFA39411CA2CEA</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {186, 337}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <integer>1</integer>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {203, 355}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>186</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>373 269 690 397 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Morph</string>
+ <key>PreferredWidth</key>
+ <integer>300</integer>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.default.short</string>
+ </dict>
+ </array>
+ <key>PerspectivesBarVisible</key>
+ <false/>
+ <key>ShelfIsVisible</key>
+ <false/>
+ <key>SourceDescription</key>
+ <string>file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec'</string>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TimeStamp</key>
+ <real>0.0</real>
+ <key>ToolbarDisplayMode</key>
+ <integer>1</integer>
+ <key>ToolbarIsVisible</key>
+ <true/>
+ <key>ToolbarSizeMode</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Perspectives</string>
+ <key>UpdateMessage</key>
+ <string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?</string>
+ <key>WindowJustification</key>
+ <integer>5</integer>
+ <key>WindowOrderList</key>
+ <array>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>28B412CC0A98B52B001560B5</string>
+ </array>
+ <key>WindowString</key>
+ <string>3 202 982 789 0 0 1280 1002 </string>
+ <key>WindowTools</key>
+ <array>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.build</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528F0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string></string>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {1041, 188}}</string>
+ <key>RubberWindowFrame</key>
+ <string>121 135 1041 671 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>188pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBuildLogShowsTranscriptDefaultKey</key>
+ <string>{{0, 5}, {1041, 433}}</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>XCMainBuildResultsModuleGUID</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Build</string>
+ <key>XCBuildResultsTrigger_Collapse</key>
+ <integer>1021</integer>
+ <key>XCBuildResultsTrigger_Open</key>
+ <integer>1011</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 193}, {1041, 438}}</string>
+ <key>RubberWindowFrame</key>
+ <string>121 135 1041 671 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Proportion</key>
+ <string>438pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>630pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Build Results</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBuildResultsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>289868C4095DB27500B5DC99</string>
+ <string>2826B1350A942AAD005CEDA1</string>
+ <string>1CD0528F0623707200166675</string>
+ <string>XCMainBuildResultsModuleGUID</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.build</string>
+ <key>WindowString</key>
+ <string>121 135 1041 671 0 0 1280 1002 </string>
+ <key>WindowToolGUID</key>
+ <string>289868C4095DB27500B5DC99</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.debugger</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>Debugger</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {325, 342}}</string>
+ <string>{{325, 0}, {583, 342}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {908, 342}}</string>
+ <string>{{0, 342}, {908, 429}}</string>
+ </array>
+ </dict>
+ </dict>
+ <key>LauncherConfigVersion</key>
+ <string>8</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C162984064C10D400B95A72</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debug - GLUTExamples (Underwater)</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>DebugConsoleDrawerSize</key>
+ <string>{100, 120}</string>
+ <key>DebugConsoleVisible</key>
+ <string>None</string>
+ <key>DebugConsoleWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>DebugSTDIOWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>Frame</key>
+ <string>{{0, 0}, {908, 771}}</string>
+ <key>RubberWindowFrame</key>
+ <string>242 152 908 812 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Proportion</key>
+ <string>771pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>771pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugSessionModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>28B412C60A98B52B001560B5</string>
+ <string>1C162984064C10D400B95A72</string>
+ <string>28B412C70A98B52B001560B5</string>
+ <string>28B412C80A98B52B001560B5</string>
+ <string>28B412C90A98B52B001560B5</string>
+ <string>28B412CA0A98B52B001560B5</string>
+ <string>28B412CB0A98B52B001560B5</string>
+ <string>28B412CC0A98B52B001560B5</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debug</string>
+ <key>WindowString</key>
+ <string>242 152 908 812 0 0 1280 1002 </string>
+ <key>WindowToolGUID</key>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.find</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CDD528C0622207200134675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>LispREPLController.m</string>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {859, 295}}</string>
+ <key>RubberWindowFrame</key>
+ <string>242 209 859 710 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>859pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>295pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528E0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Project Find</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 300}, {859, 369}}</string>
+ <key>RubberWindowFrame</key>
+ <string>242 209 859 710 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Proportion</key>
+ <string>369pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>669pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project Find</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXProjectFindModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <string>2826B2700A97638A005CEDA1</string>
+ <string>2826B2710A97638A005CEDA1</string>
+ <string>1CDD528C0622207200134675</string>
+ <string>1CD0528E0623707200166675</string>
+ </array>
+ <key>WindowString</key>
+ <string>242 209 859 710 0 0 1280 1002 </string>
+ <key>WindowToolGUID</key>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>MENUSEPARATOR</string>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.debuggerConsole</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAAC065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debugger Console</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {1076, 542}}</string>
+ <key>RubberWindowFrame</key>
+ <string>27 82 1076 583 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Proportion</key>
+ <string>542pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>542pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger Console</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugCLIModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>289868CE095DB3F900B5DC99</string>
+ <string>2826B1450A94A424005CEDA1</string>
+ <string>1C78EAAC065D492600B07095</string>
+ </array>
+ <key>WindowString</key>
+ <string>27 82 1076 583 0 0 1280 1002 </string>
+ <key>WindowToolGUID</key>
+ <string>289868CE095DB3F900B5DC99</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.run</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>LauncherConfigVersion</key>
+ <string>3</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528B0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Run</string>
+ <key>Runner</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {366, 168}}</string>
+ <string>{{0, 173}, {366, 270}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {406, 443}}</string>
+ <string>{{411, 0}, {517, 443}}</string>
+ </array>
+ </dict>
+ </dict>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {633, 242}}</string>
+ <key>RubberWindowFrame</key>
+ <string>31 673 633 283 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXRunSessionModule</string>
+ <key>Proportion</key>
+ <string>242pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>242pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Run Log</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXRunSessionModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C0AD2B3069F1EA900FABCE6</string>
+ <string>2826B1420A94A392005CEDA1</string>
+ <string>1CD0528B0623707200166675</string>
+ <string>2826B1430A94A392005CEDA1</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.run</string>
+ <key>WindowString</key>
+ <string>31 673 633 283 0 0 1280 1002 </string>
+ <key>WindowToolGUID</key>
+ <string>1C0AD2B3069F1EA900FABCE6</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.scm</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB2065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>&lt;No Editor&gt;</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB3065D492600B07095</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {452, 0}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD052920623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>SCM</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ConsoleFrame</key>
+ <string>{{0, 259}, {452, 0}}</string>
+ <key>Frame</key>
+ <string>{{0, 7}, {452, 259}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ <key>TableConfiguration</key>
+ <array>
+ <string>Status</string>
+ <real>30</real>
+ <string>FileName</string>
+ <real>199</real>
+ <string>Path</string>
+ <real>197.09500122070312</real>
+ </array>
+ <key>TableFrame</key>
+ <string>{{0, 0}, {452, 250}}</string>
+ </dict>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Proportion</key>
+ <string>262pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>266pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>SCM</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXCVSModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAB4065D492600B07095</string>
+ <string>1C78EAB5065D492600B07095</string>
+ <string>1C78EAB2065D492600B07095</string>
+ <string>1CD052920623707200166675</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.scm</string>
+ <key>WindowString</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.breakpoints</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>no</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>168</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {168, 350}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <false/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {185, 368}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>168</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>427 700 744 409 0 0 1600 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>185pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA1AED706398EBD00589147</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{190, 0}, {554, 368}}</string>
+ <key>RubberWindowFrame</key>
+ <string>427 700 744 409 0 0 1600 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>554pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>368pt</string>
+ </dict>
+ </array>
+ <key>MajorVersion</key>
+ <integer>2</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Breakpoints</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>2861E8D709675C29002A271F</string>
+ <string>2861E8D809675C29002A271F</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>1CA1AED706398EBD00589147</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.breakpoints</string>
+ <key>WindowString</key>
+ <string>427 700 744 409 0 0 1600 1178 </string>
+ <key>WindowToolGUID</key>
+ <string>2861E8D709675C29002A271F</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debugAnimator</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debug Visualizer</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXNavigatorGroup</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugAnimator</string>
+ <key>WindowString</key>
+ <string>100 100 700 500 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.bookmarks</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Bookmarks</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBookmarksModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>WindowString</key>
+ <string>538 42 401 187 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.classBrowser</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>OptionsSetName</key>
+ <string>Hierarchy, all classes</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA6456E063B45B4001379D8</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Class Browser - NSObject</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ClassesFrame</key>
+ <string>{{0, 0}, {374, 96}}</string>
+ <key>ClassesTreeTableConfiguration</key>
+ <array>
+ <string>PBXClassNameColumnIdentifier</string>
+ <real>208</real>
+ <string>PBXClassBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>Frame</key>
+ <string>{{0, 0}, {630, 331}}</string>
+ <key>MembersFrame</key>
+ <string>{{0, 105}, {374, 395}}</string>
+ <key>MembersTreeTableConfiguration</key>
+ <array>
+ <string>PBXMemberTypeIconColumnIdentifier</string>
+ <real>22</real>
+ <string>PBXMemberNameColumnIdentifier</string>
+ <real>216</real>
+ <string>PBXMemberTypeColumnIdentifier</string>
+ <real>97</real>
+ <string>PBXMemberBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <integer>1</integer>
+ <key>RubberWindowFrame</key>
+ <string>385 179 630 352 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Class Browser</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXClassBrowserModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <string>1C0AD2B0069F1E9B00FABCE6</string>
+ <string>1CA6456E063B45B4001379D8</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.classbrowser</string>
+ <key>WindowString</key>
+ <string>385 179 630 352 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/Moxie.xcodeproj/bjc.pbxuser b/Moxie.xcodeproj/bjc.pbxuser
new file mode 100644
index 0000000..fefde31
--- /dev/null
+++ b/Moxie.xcodeproj/bjc.pbxuser
@@ -0,0 +1,1752 @@
+// !$*UTF8*$!
+{
+ 280FE68F06C8241600AA47DF /* LispREPLController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {688, 840}}";
+ sepNavSelRange = "{816, 0}";
+ sepNavVisRect = "{{0, 415}, {688, 425}}";
+ sepNavWindowFrame = "{{659, 284}, {794, 703}}";
+ };
+ };
+ 280FE69006C8241600AA47DF /* LispREPLController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {836, 11858}}";
+ sepNavSelRange = "{265, 41}";
+ sepNavVisRect = "{{0, 65}, {688, 425}}";
+ sepNavWindowFrame = "{{588, 292}, {794, 703}}";
+ };
+ };
+ 2826B2720A97638C005CEDA1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 27";
+ rLen = 0;
+ rLoc = 519;
+ rType = 0;
+ vrLen = 485;
+ vrLoc = 0;
+ };
+ 2826B2730A97638C005CEDA1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 28396EFA05A444D000CE84B6 /* NSException+LiDebugging.m */;
+ name = "NSException+LiDebugging.m: 20";
+ rLen = 0;
+ rLoc = 306;
+ rType = 0;
+ vrLen = 332;
+ vrLoc = 0;
+ };
+ 2826B2740A97638C005CEDA1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 289962A405B67ADF00ADBE42 /* NSUserDefaults+Moxie.h */;
+ name = "NSUserDefaults+Moxie.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 1005;
+ vrLoc = 3;
+ };
+ 2826B2750A97638C005CEDA1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 289962A505B67ADF00ADBE42 /* NSUserDefaults+Moxie.m */;
+ name = "NSUserDefaults+Moxie.m: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 776;
+ vrLoc = 742;
+ };
+ 2826B2760A97638C005CEDA1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 288A4F1805A13FBD004C4480 /* ScrollingTextView.h */;
+ name = "ScrollingTextView.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 185;
+ vrLoc = 0;
+ };
+ 2826B27C0A97638C005CEDA1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 289962A405B67ADF00ADBE42 /* NSUserDefaults+Moxie.h */;
+ name = "NSUserDefaults+Moxie.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 1005;
+ vrLoc = 3;
+ };
+ 2826B27D0A97638C005CEDA1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 289962A505B67ADF00ADBE42 /* NSUserDefaults+Moxie.m */;
+ name = "NSUserDefaults+Moxie.m: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 776;
+ vrLoc = 742;
+ };
+ 2826B27E0A97638C005CEDA1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 288A4F1805A13FBD004C4480 /* ScrollingTextView.h */;
+ name = "ScrollingTextView.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 185;
+ vrLoc = 0;
+ };
+ 2826B27F0A97638C005CEDA1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 288A4F1905A13FBD004C4480 /* ScrollingTextView.m */;
+ name = "ScrollingTextView.m: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 854;
+ vrLoc = 0;
+ };
+ 282B3E3105A3F8E300A3D04F /* MxWorldSettings.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {812, 868}}";
+ sepNavSelRange = "{1092, 0}";
+ sepNavVisRect = "{{0, 0}, {812, 708}}";
+ sepNavWindowFrame = "{{158, 119}, {857, 837}}";
+ };
+ };
+ 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {812, 7070}}";
+ sepNavSelRange = "{4928, 0}";
+ sepNavVisRect = "{{0, 1354}, {812, 708}}";
+ sepNavWindowFrame = "{{446, 123}, {857, 837}}";
+ };
+ };
+ 28360F9D05A7CEB100841A1E /* WorldStatusController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {812, 3052}}";
+ sepNavSelRange = "{497, 14}";
+ sepNavVisRect = "{{0, 0}, {812, 708}}";
+ sepNavWindowFrame = "{{15, 336}, {857, 837}}";
+ };
+ };
+ 28396EFA05A444D000CE84B6 /* NSException+LiDebugging.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {688, 425}}";
+ sepNavSelRange = "{306, 0}";
+ sepNavVisRect = "{{0, 0}, {688, 425}}";
+ };
+ };
+ 283BCB0B0963158A00791914 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ name = hook;
+ rLen = 4;
+ rLoc = 30223;
+ rType = 0;
+ vrLen = 0;
+ vrLoc = 0;
+ };
+ 283BCC4209634B1000791914 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 28B9CF2F05BA185800A72136 /* WorldController.m */;
+ name = "WorldController.m: 73";
+ rLen = 0;
+ rLoc = 2071;
+ rType = 0;
+ vrLen = 257;
+ vrLoc = 1757;
+ };
+ 284755EF06CF0EF90078110F /* LispREPL.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {756, 713}}";
+ sepNavSelRange = "{849, 0}";
+ sepNavVisRect = "{{0, 0}, {756, 713}}";
+ sepNavWindowFrame = "{{739, 315}, {801, 842}}";
+ };
+ };
+ 284755F006CF0EF90078110F /* LispREPL.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {818, 4452}}";
+ sepNavSelRange = "{6441, 24}";
+ sepNavVisRect = "{{0, 2759}, {756, 713}}";
+ sepNavWindowFrame = "{{458, 130}, {801, 842}}";
+ };
+ };
+ 285A42050965D5BF00597D37 /* World.m:670 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-changeSettings:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 670;
+ modificationTime = 177781258.159431;
+ state = 2;
+ };
+ 285A429A0965F0AC00597D37 /* World.m:804 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-settingsDidChange:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 804;
+ modificationTime = 177781258.159441;
+ state = 2;
+ };
+ 285A42A30965F13800597D37 /* MxWorldSettings.m:104 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */;
+ functionName = "-objectForKey:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 104;
+ modificationTime = 177781258.159451;
+ state = 2;
+ };
+ 285A42BD0965F31400597D37 /* Ansi-Color.lisp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {806, 2044}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {676, 162}}";
+ };
+ };
+ 285A43FB096614A700597D37 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A42BD0965F31400597D37 /* Ansi-Color.lisp */;
+ name = "Ansi-Color.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 368;
+ vrLoc = 0;
+ };
+ 285A4404096614D000597D37 /* startlisp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {745, 644}}";
+ sepNavSelRange = "{839, 0}";
+ sepNavVisRange = "{66, 788}";
+ sepNavVisRect = "{{0, 0}, {756, 713}}";
+ sepNavWindowFrame = "{{401, 105}, {801, 842}}";
+ };
+ };
+ 285A4405096614D100597D37 /* init-template.lisp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {745, 587}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 86}";
+ sepNavVisRect = "{{0, 0}, {469, 91}}";
+ sepNavWindowFrame = "{{107, 247}, {801, 842}}";
+ };
+ };
+ 285A4406096614D100597D37 /* build-lisp-image.sh */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {745, 587}}";
+ sepNavSelRange = "{91, 0}";
+ sepNavVisRange = "{0, 519}";
+ sepNavVisRect = "{{0, 0}, {688, 425}}";
+ sepNavWindowFrame = "{{575, 99}, {801, 746}}";
+ };
+ };
+ 285A448F0966156A00597D37 /* save-moxie-image.lisp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {676, 162}}";
+ sepNavSelRange = "{57, 0}";
+ sepNavVisRect = "{{0, 0}, {676, 162}}";
+ };
+ };
+ 285A44990966157F00597D37 /* openmcl */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {756, 713}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {756, 713}}";
+ sepNavWindowFrame = "{{688, 207}, {801, 842}}";
+ };
+ };
+ 285A449A0966157F00597D37 /* save-moxie-image.lisp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {676, 162}}";
+ sepNavSelRange = "{92, 0}";
+ sepNavVisRect = "{{0, 0}, {676, 162}}";
+ sepNavWindowFrame = "{{38, 186}, {801, 842}}";
+ };
+ };
+ 285A44AB096615B700597D37 /* hooks.lisp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {812, 294}}";
+ sepNavSelRange = "{116, 27}";
+ sepNavVisRect = "{{0, 0}, {812, 263}}";
+ };
+ };
+ 285A44B2096615B700597D37 /* package.lisp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {756, 713}}";
+ sepNavSelRange = "{630, 3}";
+ sepNavVisRect = "{{0, 0}, {756, 713}}";
+ sepNavWindowFrame = "{{15, 331}, {801, 842}}";
+ };
+ };
+ 285A44BB096615B700597D37 /* world.lisp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {676, 1624}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {676, 162}}";
+ };
+ };
+ 285A45930966165600597D37 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4405096614D100597D37 /* init-template.lisp */;
+ name = "init-template.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 86;
+ vrLoc = 0;
+ };
+ 285A46380966204C00597D37 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A448F0966156A00597D37 /* save-moxie-image.lisp */;
+ name = "save-moxie-image.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 66;
+ vrLoc = 0;
+ };
+ 285A46550966239B00597D37 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A449A0966157F00597D37 /* save-moxie-image.lisp */;
+ name = "save-moxie-image.lisp: 3";
+ rLen = 0;
+ rLoc = 90;
+ rType = 0;
+ vrLen = 92;
+ vrLoc = 0;
+ };
+ 285A46570966239B00597D37 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A449A0966157F00597D37 /* save-moxie-image.lisp */;
+ name = "save-moxie-image.lisp: 3";
+ rLen = 0;
+ rLoc = 90;
+ rType = 0;
+ vrLen = 92;
+ vrLoc = 0;
+ };
+ 285A46AC0966445B00597D37 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A448F0966156A00597D37 /* save-moxie-image.lisp */;
+ name = "save-moxie-image.lisp: 2";
+ rLen = 0;
+ rLoc = 57;
+ rType = 0;
+ vrLen = 102;
+ vrLoc = 0;
+ };
+ 285A46C60966D7DC00597D37 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4404096614D000597D37 /* startlisp */;
+ name = "startlisp: 38";
+ rLen = 0;
+ rLoc = 795;
+ rType = 0;
+ vrLen = 164;
+ vrLoc = 0;
+ };
+ 285A46FE0967311E00597D37 /* World.m:300 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-splitView:constrainMaxCoordinate:ofSubviewAt:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 300;
+ modificationTime = 177781258.159461;
+ state = 2;
+ };
+ 285A47110967330100597D37 /* World.m:320 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-splitView:resizeSubviewsWithOldSize:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 320;
+ modificationTime = 177781258.159471;
+ state = 2;
+ };
+ 285A47350967397F00597D37 /* World.m:286 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-splitView:constrainMaxCoordinate:ofSubviewAt:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 286;
+ modificationTime = 177781258.159506;
+ state = 2;
+ };
+ 285A47370967398000597D37 /* World.m:273 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-splitView:constrainMinCoordinate:ofSubviewAt:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 273;
+ modificationTime = 177781258.159519;
+ state = 2;
+ };
+ 285A4743096739E700597D37 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 284755F006CF0EF90078110F /* LispREPL.m */;
+ name = "LispREPL.m: 256";
+ rLen = 0;
+ rLoc = 7475;
+ rType = 0;
+ vrLen = 407;
+ vrLoc = 7266;
+ };
+ 2861E8A50967593A002A271F /* World.m:270 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-splitViewDidResizeSubviews:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 270;
+ modificationTime = 177781258.159556;
+ state = 2;
+ };
+ 2861E97409677C9E002A271F /* LispREPLController.m:661 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 280FE69006C8241600AA47DF /* LispREPLController.m */;
+ functionName = "-sendEvent:withArg:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 661;
+ modificationTime = 177781258.159568;
+ state = 2;
+ };
+ 2861E99F0967804F002A271F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 18";
+ rLen = 0;
+ rLoc = 324;
+ rType = 0;
+ vrLen = 199;
+ vrLoc = 149;
+ };
+ 2861E9E00967A48A002A271F /* save-moxie-image.lisp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {745, 587}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 96}";
+ sepNavVisRect = "{{0, 0}, {469, 91}}";
+ };
+ };
+ 2861E9EF0967A5FC002A271F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A44BB096615B700597D37 /* world.lisp */;
+ name = "world.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 339;
+ vrLoc = 0;
+ };
+ 2861E9F10967A5FC002A271F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A44BB096615B700597D37 /* world.lisp */;
+ name = "world.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 339;
+ vrLoc = 0;
+ };
+ 2861EA200968469A002A271F /* LispREPL.m:223 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 284755F006CF0EF90078110F /* LispREPL.m */;
+ functionName = "-eval:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 223;
+ modificationTime = 177781258.159579;
+ state = 2;
+ };
+ 2861EA7309685E21002A271F /* World.m:116 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-worldClosed";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 116;
+ modificationTime = 177782870.275219;
+ state = 1;
+ };
+ 2861EA9709686370002A271F /* World.m:643 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-changeSettings:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 643;
+ modificationTime = 177781258.159624;
+ state = 2;
+ };
+ 2861EAE409687652002A271F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2861E9E00967A48A002A271F /* save-moxie-image.lisp */;
+ name = "save-moxie-image.lisp: 4";
+ rLen = 0;
+ rLoc = 96;
+ rType = 0;
+ vrLen = 96;
+ vrLoc = 0;
+ };
+ 2861EAE609687652002A271F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2861E9E00967A48A002A271F /* save-moxie-image.lisp */;
+ name = "save-moxie-image.lisp: 4";
+ rLen = 0;
+ rLoc = 96;
+ rType = 0;
+ vrLen = 96;
+ vrLoc = 0;
+ };
+ 2861EAED096877AD002A271F /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4405096614D100597D37 /* init-template.lisp */;
+ name = "init-template.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 86;
+ vrLoc = 0;
+ };
+ 2861EB2C09687E12002A271F /* MxWorldSettings.m:380 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */;
+ functionName = "-backgroundColorData";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 380;
+ modificationTime = 177781258.159636;
+ state = 2;
+ };
+ 2861EB2E09687E14002A271F /* MxWorldSettings.m:370 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */;
+ functionName = "-textColorData";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 370;
+ modificationTime = 177781258.159749;
+ state = 2;
+ };
+ 2861EB7E09688ACA002A271F /* MxWorldSettings.m:199 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */;
+ functionName = "-stringForKey:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 199;
+ modificationTime = 177781258.159806;
+ state = 2;
+ };
+ 2861EBB709688DEE002A271F /* MxWorldSettings.m:190 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */;
+ functionName = "-setBool:forKey:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 190;
+ modificationTime = 177781258.159819;
+ state = 2;
+ };
+ 2861EBC609688E96002A271F /* MxWorldSettings.m:161 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */;
+ functionName = "-boolForKey:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 161;
+ modificationTime = 177781258.159857;
+ state = 2;
+ };
+ 286D8C1505A4099100D7C2A2 /* WorldSettingsController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {812, 1582}}";
+ sepNavSelRange = "{1653, 59}";
+ sepNavVisRect = "{{0, 644}, {812, 263}}";
+ sepNavWindowFrame = "{{61, 289}, {801, 842}}";
+ };
+ };
+ 286FE9F205BE3B9E005A01FF /* English */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {756, 713}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {756, 713}}";
+ sepNavWindowFrame = "{{84, 268}, {801, 842}}";
+ };
+ };
+ 28889CF809648F9500527406 /* NSException+LiDebugging.m:20 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 28396EFA05A444D000CE84B6 /* NSException+LiDebugging.m */;
+ functionName = "-raise";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 20;
+ modificationTime = 177781258.159405;
+ state = 2;
+ };
+ 28889CFB09648F9900527406 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */;
+ name = "rgbColor = [aColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace];";
+ rLen = 81;
+ rLoc = 10579;
+ rType = 0;
+ vrLen = 360;
+ vrLoc = 10035;
+ };
+ 28889D3A096496D800527406 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 28396EFA05A444D000CE84B6 /* NSException+LiDebugging.m */;
+ name = "NSException+LiDebugging.m: 20";
+ rLen = 0;
+ rLoc = 306;
+ rType = 0;
+ vrLen = 0;
+ vrLoc = 0;
+ };
+ 288A4F1805A13FBD004C4480 /* ScrollingTextView.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {688, 425}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {688, 425}}";
+ };
+ };
+ 288A4F1905A13FBD004C4480 /* ScrollingTextView.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {688, 896}}";
+ sepNavSelRange = "{1654, 0}";
+ sepNavVisRect = "{{0, 373}, {688, 425}}";
+ };
+ };
+ 289866A0095DAA5400B5DC99 /* Moxie */ = {
+ isa = PBXExecutable;
+ activeArgIndices = (
+ );
+ argumentStrings = (
+ );
+ autoAttachOnCrash = 1;
+ breakpointsEnabled = 0;
+ configStateDict = {
+ };
+ customDataFormattersEnabled = 1;
+ debuggerPlugin = GDBDebugging;
+ disassemblyDisplayState = 0;
+ dylibVariantSuffix = "";
+ enableDebugStr = 1;
+ environmentEntries = (
+ );
+ executableSystemSymbolLevel = 0;
+ executableUserSymbolLevel = 0;
+ libgmallocEnabled = 0;
+ name = Moxie;
+ savedGlobals = {
+ };
+ sourceDirectories = (
+ );
+ };
+ 2898672E095DAA6100B5DC99 /* Source Control */ = {
+ isa = PBXSourceControlManager;
+ fallbackIsa = XCSourceControlManager;
+ isSCMEnabled = 1;
+ scmConfiguration = {
+ SubversionToolPath = /usr/local/bin/svn;
+ };
+ scmType = scm.subversion;
+ };
+ 2898672F095DAA6100B5DC99 /* Code sense */ = {
+ isa = PBXCodeSenseManager;
+ indexTemplatePath = "";
+ };
+ 289868D4095DB43400B5DC99 /* LispREPLController.m:589 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 280FE69006C8241600AA47DF /* LispREPLController.m */;
+ functionName = "-scanForREPLData:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 589;
+ modificationTime = 177781258.158947;
+ state = 2;
+ };
+ 28986B7C095DD2A600B5DC99 /* LispREPLController.m:605 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 280FE69006C8241600AA47DF /* LispREPLController.m */;
+ functionName = "-readREPLData:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 605;
+ modificationTime = 177781258.159237;
+ state = 2;
+ };
+ 28986B87095DD30D00B5DC99 /* LispREPLController.m:608 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 280FE69006C8241600AA47DF /* LispREPLController.m */;
+ functionName = "-readREPLData:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 608;
+ modificationTime = 177781258.15933;
+ state = 2;
+ };
+ 28986BF0095E4A2200B5DC99 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 284755F006CF0EF90078110F /* LispREPL.m */;
+ name = "LispREPL.m: 223";
+ rLen = 0;
+ rLoc = 7501;
+ rType = 0;
+ vrLen = 215;
+ vrLoc = 6811;
+ };
+ 28986BF4095E4A2200B5DC99 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 280FE69006C8241600AA47DF /* LispREPLController.m */;
+ name = "- (void)readREPLData: (NSFileHandle *)stdoutInput";
+ rLen = 50;
+ rLoc = 20140;
+ rType = 0;
+ vrLen = 134;
+ vrLoc = 19829;
+ };
+ 289962A405B67ADF00ADBE42 /* NSUserDefaults+Moxie.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {688, 728}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 15}, {688, 425}}";
+ };
+ };
+ 289962A505B67ADF00ADBE42 /* NSUserDefaults+Moxie.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {688, 3766}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 466}, {688, 425}}";
+ };
+ };
+ 28A2E1F6096A0B4E0005CC4E /* MxWorldSettings.m:168 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */;
+ functionName = "-boolForKey:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 168;
+ modificationTime = 177781258.159869;
+ state = 2;
+ };
+ 28A2E205096A0C210005CC4E /* WorldSettingsController.m:69 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 286D8C1505A4099100D7C2A2 /* WorldSettingsController.m */;
+ functionName = "-mainWindowChanged:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 69;
+ modificationTime = 177781258.159939;
+ state = 2;
+ };
+ 28A2E206096A0C220005CC4E /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */;
+ name = "MxWorldSettings.m: 486";
+ rLen = 0;
+ rLoc = 14310;
+ rType = 0;
+ vrLen = 0;
+ vrLoc = 0;
+ };
+ 28A2E20E096A0C440005CC4E /* WorldSettingsController.m:50 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 286D8C1505A4099100D7C2A2 /* WorldSettingsController.m */;
+ functionName = "-windowDidLoad";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 50;
+ modificationTime = 177781258.159953;
+ state = 2;
+ };
+ 28A2E27A097015DF0005CC4E /* World.m:65 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-windowControllerDidLoadNib:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 65;
+ modificationTime = 177781258.160014;
+ state = 2;
+ };
+ 28A2E2B40971B3630005CC4E /* MxWorldSettings.m:132 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */;
+ functionName = "-setObject:forKey:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 132;
+ modificationTime = 177781258.16006;
+ state = 2;
+ };
+ 28A2E2B60971B3650005CC4E /* MxWorldSettings.m:100 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */;
+ functionName = "-objectForKey:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 100;
+ modificationTime = 177781258.160104;
+ state = 2;
+ };
+ 28A2E2BE0971B3E10005CC4E /* World.m:800 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-settingsDidChange:";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 800;
+ modificationTime = 177781258.160117;
+ state = 2;
+ };
+ 28A2E3620971E2E60005CC4E /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 28B9CF2F05BA185800A72136 /* WorldController.m */;
+ name = "WorldController.m: cycleDocumentWindows:";
+ rLen = 0;
+ rLoc = 1538;
+ rType = 0;
+ vrLen = 161;
+ vrLoc = 2496;
+ };
+ 28A2E37E0971E4860005CC4E /* World.m:41 */ = {
+ isa = PBXFileBreakpoint;
+ actions = (
+ );
+ breakpointStyle = 0;
+ continueAfterActions = 0;
+ countType = 0;
+ delayBeforeContinue = 0;
+ fileReference = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ functionName = "-dealloc";
+ hitCount = 1;
+ ignoreCount = 0;
+ lineNumber = 41;
+ modificationTime = 177781258.160126;
+ state = 2;
+ };
+ 28B40D6B0A97CBD2001560B5 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2A37F4ACFDCFA73011CA2CEA /* World.m */;
+ name = "- (NSNumber *)handleEvent: (NSEvent *)anEvent from: (id)sender";
+ rLen = 63;
+ rLoc = 12877;
+ rType = 0;
+ vrLen = 1283;
+ vrLoc = 12874;
+ };
+ 28B412C20A98B52B001560B5 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 280FE69006C8241600AA47DF /* LispREPLController.m */;
+ name = "+ (LispREPLController *)sharedController";
+ rLen = 41;
+ rLoc = 265;
+ rType = 0;
+ vrLen = 805;
+ vrLoc = 41;
+ };
+ 28B412C40A98B52B001560B5 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 280FE69006C8241600AA47DF /* LispREPLController.m */;
+ name = "+ (LispREPLController *)sharedController";
+ rLen = 41;
+ rLoc = 265;
+ rType = 0;
+ vrLen = 805;
+ vrLoc = 41;
+ };
+ 28B413010A98B8B7001560B5 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 28F903A306EE490C00D5ADA9 /* LispSymbol.m */;
+ name = "- (BOOL)boolValue";
+ rLen = 18;
+ rLoc = 1141;
+ rType = 0;
+ vrLen = 497;
+ vrLoc = 1945;
+ };
+ 28B413020A98B8B7001560B5 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 28F903A206EE490C00D5ADA9 /* LispSymbol.h */;
+ name = "LispSymbol.h: symbolNIL";
+ rLen = 0;
+ rLoc = 290;
+ rType = 0;
+ vrLen = 600;
+ vrLoc = 0;
+ };
+ 28B413040A98B8B7001560B5 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 28F903A306EE490C00D5ADA9 /* LispSymbol.m */;
+ name = "- (BOOL)boolValue";
+ rLen = 18;
+ rLoc = 1141;
+ rType = 0;
+ vrLen = 497;
+ vrLoc = 1945;
+ };
+ 28B413050A98B8B7001560B5 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 28F903A206EE490C00D5ADA9 /* LispSymbol.h */;
+ name = "LispSymbol.h: symbolNIL";
+ rLen = 0;
+ rLoc = 290;
+ rType = 0;
+ vrLen = 600;
+ vrLoc = 0;
+ };
+ 28B413880A9B3EC9001560B5 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 280FE68F06C8241600AA47DF /* LispREPLController.h */;
+ name = "LispREPLController.h: sendEvent:arguments:";
+ rLen = 0;
+ rLoc = 816;
+ rType = 0;
+ vrLen = 890;
+ vrLoc = 625;
+ };
+ 28B413890A9B3EC9001560B5 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 288A4F1905A13FBD004C4480 /* ScrollingTextView.m */;
+ name = "ScrollingTextView.m: 52";
+ rLen = 0;
+ rLoc = 1654;
+ rType = 0;
+ vrLen = 963;
+ vrLoc = 758;
+ };
+ 28B4138A0A9B3EC9001560B5 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 280FE68F06C8241600AA47DF /* LispREPLController.h */;
+ name = "LispREPLController.h: sendEvent:arguments:";
+ rLen = 0;
+ rLoc = 816;
+ rType = 0;
+ vrLen = 890;
+ vrLoc = 625;
+ };
+ 28B4138B0A9B3EC9001560B5 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 288A4F1905A13FBD004C4480 /* ScrollingTextView.m */;
+ name = "ScrollingTextView.m: layoutManager:didCompleteLayoutForTextContainer:atEnd:";
+ rLen = 483;
+ rLoc = 758;
+ rType = 0;
+ vrLen = 1180;
+ vrLoc = 427;
+ };
+ 28B9CF2E05BA185800A72136 /* WorldController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {749, 574}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRect = "{{0, 0}, {749, 574}}";
+ };
+ };
+ 28B9CF2F05BA185800A72136 /* WorldController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {768, 1974}}";
+ sepNavSelRange = "{4498, 0}";
+ sepNavVisRange = "{2831, 1813}";
+ sepNavVisRect = "{{0, 0}, {0, 0}}";
+ sepNavWindowFrame = "{{93, 43}, {794, 703}}";
+ };
+ };
+ 28C6947A06F55DC000341CDE /* NSDictionary+LispExtensions.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {812, 708}}";
+ sepNavSelRange = "{246, 0}";
+ sepNavVisRect = "{{0, 0}, {812, 708}}";
+ sepNavWindowFrame = "{{38, 315}, {857, 837}}";
+ };
+ };
+ 28C6947B06F55DC000341CDE /* NSDictionary+LispExtensions.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {812, 756}}";
+ sepNavSelRange = "{1349, 0}";
+ sepNavVisRect = "{{0, 48}, {812, 708}}";
+ sepNavWindowFrame = "{{38, 315}, {857, 837}}";
+ };
+ };
+ 28E9BB9E0DA428F900CDD80A /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ };
+ 28E9BBAD0DA4290200CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 25";
+ rLen = 0;
+ rLoc = 485;
+ rType = 0;
+ vrLen = 485;
+ vrLoc = 0;
+ };
+ 28E9BBB40DA429E000CDD80A /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ };
+ 28E9BBB50DA429FB00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 13";
+ rLen = 0;
+ rLoc = 274;
+ rType = 0;
+ vrLen = 120;
+ vrLoc = 152;
+ };
+ 28E9BBB60DA429FB00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 13";
+ rLen = 0;
+ rLoc = 274;
+ rType = 0;
+ vrLen = 0;
+ vrLoc = 0;
+ };
+ 28E9BBB90DA429FB00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 27";
+ rLen = 0;
+ rLoc = 519;
+ rType = 0;
+ vrLen = 485;
+ vrLoc = 0;
+ };
+ 28E9BBBC0DA42A4200CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 16";
+ rLen = 0;
+ rLoc = 274;
+ rType = 0;
+ vrLen = 0;
+ vrLoc = 0;
+ };
+ 28E9BBBD0DA42A4200CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 8";
+ rLen = 0;
+ rLoc = 97;
+ rType = 0;
+ vrLen = 491;
+ vrLoc = 0;
+ };
+ 28E9BBC70DA447EA00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4404096614D000597D37 /* startlisp */;
+ name = "startlisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 787;
+ vrLoc = 66;
+ };
+ 28E9BBC80DA447EA00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4405096614D100597D37 /* init-template.lisp */;
+ name = "init-template.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 86;
+ vrLoc = 0;
+ };
+ 28E9BBC90DA447EA00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 16";
+ rLen = 0;
+ rLoc = 274;
+ rType = 0;
+ vrLen = 491;
+ vrLoc = 0;
+ };
+ 28E9BBCA0DA447EA00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 16";
+ rLen = 0;
+ rLoc = 274;
+ rType = 0;
+ vrLen = 112;
+ vrLoc = 178;
+ };
+ 28E9BBCB0DA447EA00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4404096614D000597D37 /* startlisp */;
+ name = "startlisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 787;
+ vrLoc = 66;
+ };
+ 28E9BBCC0DA447EA00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4405096614D100597D37 /* init-template.lisp */;
+ name = "init-template.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 86;
+ vrLoc = 0;
+ };
+ 28E9BBCD0DA447EA00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 22";
+ rLen = 0;
+ rLoc = 359;
+ rType = 0;
+ vrLen = 490;
+ vrLoc = 0;
+ };
+ 28E9BBCF0DA448CF00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 22";
+ rLen = 0;
+ rLoc = 359;
+ rType = 0;
+ vrLen = 490;
+ vrLoc = 0;
+ };
+ 28E9BBD00DA448CF00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4404096614D000597D37 /* startlisp */;
+ name = "startlisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 772;
+ vrLoc = 66;
+ };
+ 28E9BBD10DA448CF00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 22";
+ rLen = 0;
+ rLoc = 359;
+ rType = 0;
+ vrLen = 490;
+ vrLoc = 0;
+ };
+ 28E9BBD20DA448CF00CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4404096614D000597D37 /* startlisp */;
+ name = "startlisp: 46";
+ rLen = 0;
+ rLoc = 839;
+ rType = 0;
+ vrLen = 787;
+ vrLoc = 67;
+ };
+ 28E9BBD40DA44B9600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4404096614D000597D37 /* startlisp */;
+ name = "startlisp: 46";
+ rLen = 0;
+ rLoc = 839;
+ rType = 0;
+ vrLen = 788;
+ vrLoc = 66;
+ };
+ 28E9BBD50DA44B9600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4405096614D100597D37 /* init-template.lisp */;
+ name = "init-template.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 86;
+ vrLoc = 0;
+ };
+ 28E9BBD60DA44B9600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2861E9E00967A48A002A271F /* save-moxie-image.lisp */;
+ name = "save-moxie-image.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 96;
+ vrLoc = 0;
+ };
+ 28E9BBD70DA44B9600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 22";
+ rLen = 0;
+ rLoc = 359;
+ rType = 0;
+ vrLen = 490;
+ vrLoc = 0;
+ };
+ 28E9BBD80DA44B9600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4404096614D000597D37 /* startlisp */;
+ name = "startlisp: 46";
+ rLen = 0;
+ rLoc = 839;
+ rType = 0;
+ vrLen = 788;
+ vrLoc = 66;
+ };
+ 28E9BBD90DA44B9600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4405096614D100597D37 /* init-template.lisp */;
+ name = "init-template.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 86;
+ vrLoc = 0;
+ };
+ 28E9BBDA0DA44B9600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4404096614D000597D37 /* startlisp */;
+ name = "startlisp: 46";
+ rLen = 0;
+ rLoc = 839;
+ rType = 0;
+ vrLen = 788;
+ vrLoc = 66;
+ };
+ 28E9BBDB0DA44B9600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4405096614D100597D37 /* init-template.lisp */;
+ name = "init-template.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 86;
+ vrLoc = 0;
+ };
+ 28E9BBDC0DA44B9600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 22";
+ rLen = 0;
+ rLoc = 359;
+ rType = 0;
+ vrLen = 490;
+ vrLoc = 0;
+ };
+ 28E9BBDD0DA44B9600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 2861E9E00967A48A002A271F /* save-moxie-image.lisp */;
+ name = "save-moxie-image.lisp: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 96;
+ vrLoc = 0;
+ };
+ 28E9BBDE0DA44B9600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 8";
+ rLen = 0;
+ rLoc = 91;
+ rType = 0;
+ vrLen = 519;
+ vrLoc = 0;
+ };
+ 28E9BBE00DA44BB600CDD80A /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 285A4406096614D100597D37 /* build-lisp-image.sh */;
+ name = "build-lisp-image.sh: 8";
+ rLen = 0;
+ rLoc = 91;
+ rType = 0;
+ vrLen = 519;
+ vrLoc = 0;
+ };
+ 28F903A206EE490C00D5ADA9 /* LispSymbol.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {688, 425}}";
+ sepNavSelRange = "{290, 0}";
+ sepNavVisRect = "{{0, 0}, {688, 425}}";
+ sepNavWindowFrame = "{{61, 428}, {794, 703}}";
+ };
+ };
+ 28F903A306EE490C00D5ADA9 /* LispSymbol.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {688, 1904}}";
+ sepNavSelRange = "{1141, 18}";
+ sepNavVisRect = "{{0, 1479}, {688, 425}}";
+ sepNavWindowFrame = "{{61, 325}, {794, 703}}";
+ };
+ };
+ 28F9046D06F2305300D5ADA9 /* NSFileHandle+LispExtensions.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1073, 1946}}";
+ sepNavSelRange = "{2839, 0}";
+ sepNavVisRect = "{{0, 183}, {1073, 460}}";
+ sepNavWindowFrame = "{{38, 449}, {794, 703}}";
+ };
+ };
+ 2A37F4A9FDCFA73011CA2CEA /* Project object */ = {
+ activeArchitecture = i386;
+ activeBuildConfigurationName = Development;
+ activeExecutable = 289866A0095DAA5400B5DC99 /* Moxie */;
+ activeTarget = 8D15AC270486D014006FF6A4 /* Moxie */;
+ addToTargets = (
+ 8D15AC270486D014006FF6A4 /* Moxie */,
+ );
+ breakpoints = (
+ 289868D4095DB43400B5DC99 /* LispREPLController.m:589 */,
+ 28986B7C095DD2A600B5DC99 /* LispREPLController.m:605 */,
+ 28986B87095DD30D00B5DC99 /* LispREPLController.m:608 */,
+ 28889CF809648F9500527406 /* NSException+LiDebugging.m:20 */,
+ 285A42050965D5BF00597D37 /* World.m:670 */,
+ 285A429A0965F0AC00597D37 /* World.m:804 */,
+ 285A42A30965F13800597D37 /* MxWorldSettings.m:104 */,
+ 285A46FE0967311E00597D37 /* World.m:300 */,
+ 285A47110967330100597D37 /* World.m:320 */,
+ 285A47350967397F00597D37 /* World.m:286 */,
+ 285A47370967398000597D37 /* World.m:273 */,
+ 2861E8A50967593A002A271F /* World.m:270 */,
+ 2861E97409677C9E002A271F /* LispREPLController.m:661 */,
+ 2861EA200968469A002A271F /* LispREPL.m:223 */,
+ 2861EA7309685E21002A271F /* World.m:116 */,
+ 2861EA9709686370002A271F /* World.m:643 */,
+ 2861EB2C09687E12002A271F /* MxWorldSettings.m:380 */,
+ 2861EB2E09687E14002A271F /* MxWorldSettings.m:370 */,
+ 2861EB7E09688ACA002A271F /* MxWorldSettings.m:199 */,
+ 2861EBB709688DEE002A271F /* MxWorldSettings.m:190 */,
+ 2861EBC609688E96002A271F /* MxWorldSettings.m:161 */,
+ 28A2E1F6096A0B4E0005CC4E /* MxWorldSettings.m:168 */,
+ 28A2E205096A0C210005CC4E /* WorldSettingsController.m:69 */,
+ 28A2E20E096A0C440005CC4E /* WorldSettingsController.m:50 */,
+ 28A2E27A097015DF0005CC4E /* World.m:65 */,
+ 28A2E2B40971B3630005CC4E /* MxWorldSettings.m:132 */,
+ 28A2E2B60971B3650005CC4E /* MxWorldSettings.m:100 */,
+ 28A2E2BE0971B3E10005CC4E /* World.m:800 */,
+ 28A2E37E0971E4860005CC4E /* World.m:41 */,
+ );
+ codeSenseManager = 2898672F095DAA6100B5DC99 /* Code sense */;
+ executables = (
+ 289866A0095DAA5400B5DC99 /* Moxie */,
+ );
+ perUserDictionary = {
+ "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 20,
+ 210,
+ 20,
+ 110,
+ 109,
+ 20,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXBreakpointsDataSource_ActionID,
+ PBXBreakpointsDataSource_TypeID,
+ PBXBreakpointsDataSource_BreakpointID,
+ PBXBreakpointsDataSource_UseID,
+ PBXBreakpointsDataSource_LocationID,
+ PBXBreakpointsDataSource_ConditionID,
+ PBXBreakpointsDataSource_ContinueID,
+ );
+ };
+ PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 300,
+ 200,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXErrorsWarningsDataSource_TypeID,
+ PBXErrorsWarningsDataSource_MessageID,
+ PBXErrorsWarningsDataSource_LocationID,
+ );
+ };
+ PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 22,
+ 300,
+ 377.5835,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXExecutablesDataSource_ActiveFlagID,
+ PBXExecutablesDataSource_NameID,
+ PBXExecutablesDataSource_CommentsID,
+ );
+ };
+ PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 567,
+ 20,
+ 48,
+ 43,
+ 43,
+ 20,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ PBXFileDataSource_Target_ColumnID,
+ );
+ };
+ PBXConfiguration.PBXFileTableDataSource3.PBXFindDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFindDataSource_LocationID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 200,
+ 120,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFindDataSource_MessageID,
+ PBXFindDataSource_LocationID,
+ );
+ };
+ PBXConfiguration.PBXFileTableDataSource3.XCSCMDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 20,
+ 253,
+ 20,
+ 48,
+ 43,
+ 43,
+ 20,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_SCM_ColumnID,
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ PBXFileDataSource_Target_ColumnID,
+ );
+ };
+ PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 200,
+ 97,
+ 20,
+ 48,
+ 43,
+ 43,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXTargetDataSource_PrimaryAttribute,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ );
+ };
+ PBXPerProjectTemplateStateSaveDate = 228861856;
+ PBXWorkspaceStateSaveDate = 228861856;
+ };
+ perUserProjectItems = {
+ 2826B2720A97638C005CEDA1 = 2826B2720A97638C005CEDA1 /* PBXTextBookmark */;
+ 2826B2730A97638C005CEDA1 = 2826B2730A97638C005CEDA1 /* PBXTextBookmark */;
+ 2826B2740A97638C005CEDA1 = 2826B2740A97638C005CEDA1 /* PBXTextBookmark */;
+ 2826B2750A97638C005CEDA1 = 2826B2750A97638C005CEDA1 /* PBXTextBookmark */;
+ 2826B2760A97638C005CEDA1 = 2826B2760A97638C005CEDA1 /* PBXTextBookmark */;
+ 2826B27C0A97638C005CEDA1 = 2826B27C0A97638C005CEDA1 /* PBXTextBookmark */;
+ 2826B27D0A97638C005CEDA1 = 2826B27D0A97638C005CEDA1 /* PBXTextBookmark */;
+ 2826B27E0A97638C005CEDA1 = 2826B27E0A97638C005CEDA1 /* PBXTextBookmark */;
+ 2826B27F0A97638C005CEDA1 = 2826B27F0A97638C005CEDA1 /* PBXTextBookmark */;
+ 283BCB0B0963158A00791914 = 283BCB0B0963158A00791914 /* PBXTextBookmark */;
+ 283BCC4209634B1000791914 = 283BCC4209634B1000791914 /* PBXTextBookmark */;
+ 285A43FB096614A700597D37 = 285A43FB096614A700597D37 /* PBXTextBookmark */;
+ 285A45930966165600597D37 = 285A45930966165600597D37 /* PBXTextBookmark */;
+ 285A46380966204C00597D37 = 285A46380966204C00597D37 /* PBXTextBookmark */;
+ 285A46550966239B00597D37 = 285A46550966239B00597D37 /* PBXTextBookmark */;
+ 285A46570966239B00597D37 = 285A46570966239B00597D37 /* PBXTextBookmark */;
+ 285A46AC0966445B00597D37 = 285A46AC0966445B00597D37 /* PBXTextBookmark */;
+ 285A46C60966D7DC00597D37 = 285A46C60966D7DC00597D37 /* PBXTextBookmark */;
+ 285A4743096739E700597D37 = 285A4743096739E700597D37 /* PBXTextBookmark */;
+ 2861E99F0967804F002A271F = 2861E99F0967804F002A271F /* PBXTextBookmark */;
+ 2861E9EF0967A5FC002A271F = 2861E9EF0967A5FC002A271F /* PBXTextBookmark */;
+ 2861E9F10967A5FC002A271F = 2861E9F10967A5FC002A271F /* PBXTextBookmark */;
+ 2861EAE409687652002A271F = 2861EAE409687652002A271F /* PBXTextBookmark */;
+ 2861EAE609687652002A271F = 2861EAE609687652002A271F /* PBXTextBookmark */;
+ 2861EAED096877AD002A271F = 2861EAED096877AD002A271F /* PBXTextBookmark */;
+ 28889CFB09648F9900527406 = 28889CFB09648F9900527406 /* PBXTextBookmark */;
+ 28889D3A096496D800527406 = 28889D3A096496D800527406 /* PBXTextBookmark */;
+ 28986BF0095E4A2200B5DC99 = 28986BF0095E4A2200B5DC99 /* PBXTextBookmark */;
+ 28986BF4095E4A2200B5DC99 = 28986BF4095E4A2200B5DC99 /* PBXTextBookmark */;
+ 28A2E206096A0C220005CC4E = 28A2E206096A0C220005CC4E /* PBXTextBookmark */;
+ 28A2E3620971E2E60005CC4E = 28A2E3620971E2E60005CC4E /* PBXTextBookmark */;
+ 28B40D6B0A97CBD2001560B5 = 28B40D6B0A97CBD2001560B5 /* PBXTextBookmark */;
+ 28B412C20A98B52B001560B5 = 28B412C20A98B52B001560B5 /* PBXTextBookmark */;
+ 28B412C40A98B52B001560B5 = 28B412C40A98B52B001560B5 /* PBXTextBookmark */;
+ 28B413010A98B8B7001560B5 = 28B413010A98B8B7001560B5 /* PBXTextBookmark */;
+ 28B413020A98B8B7001560B5 = 28B413020A98B8B7001560B5 /* PBXTextBookmark */;
+ 28B413040A98B8B7001560B5 = 28B413040A98B8B7001560B5 /* PBXTextBookmark */;
+ 28B413050A98B8B7001560B5 = 28B413050A98B8B7001560B5 /* PBXTextBookmark */;
+ 28B413880A9B3EC9001560B5 = 28B413880A9B3EC9001560B5 /* PBXTextBookmark */;
+ 28B413890A9B3EC9001560B5 = 28B413890A9B3EC9001560B5 /* PBXTextBookmark */;
+ 28B4138A0A9B3EC9001560B5 = 28B4138A0A9B3EC9001560B5 /* PBXTextBookmark */;
+ 28B4138B0A9B3EC9001560B5 = 28B4138B0A9B3EC9001560B5 /* PBXTextBookmark */;
+ 28E9BB9E0DA428F900CDD80A /* PBXBookmark */ = 28E9BB9E0DA428F900CDD80A /* PBXBookmark */;
+ 28E9BBAD0DA4290200CDD80A /* PBXTextBookmark */ = 28E9BBAD0DA4290200CDD80A /* PBXTextBookmark */;
+ 28E9BBB40DA429E000CDD80A /* PBXBookmark */ = 28E9BBB40DA429E000CDD80A /* PBXBookmark */;
+ 28E9BBB50DA429FB00CDD80A /* PBXTextBookmark */ = 28E9BBB50DA429FB00CDD80A /* PBXTextBookmark */;
+ 28E9BBB60DA429FB00CDD80A /* PBXTextBookmark */ = 28E9BBB60DA429FB00CDD80A /* PBXTextBookmark */;
+ 28E9BBB90DA429FB00CDD80A /* PBXTextBookmark */ = 28E9BBB90DA429FB00CDD80A /* PBXTextBookmark */;
+ 28E9BBBC0DA42A4200CDD80A /* PBXTextBookmark */ = 28E9BBBC0DA42A4200CDD80A /* PBXTextBookmark */;
+ 28E9BBBD0DA42A4200CDD80A /* PBXTextBookmark */ = 28E9BBBD0DA42A4200CDD80A /* PBXTextBookmark */;
+ 28E9BBC70DA447EA00CDD80A /* PBXTextBookmark */ = 28E9BBC70DA447EA00CDD80A /* PBXTextBookmark */;
+ 28E9BBC80DA447EA00CDD80A /* PBXTextBookmark */ = 28E9BBC80DA447EA00CDD80A /* PBXTextBookmark */;
+ 28E9BBC90DA447EA00CDD80A /* PBXTextBookmark */ = 28E9BBC90DA447EA00CDD80A /* PBXTextBookmark */;
+ 28E9BBCA0DA447EA00CDD80A /* PBXTextBookmark */ = 28E9BBCA0DA447EA00CDD80A /* PBXTextBookmark */;
+ 28E9BBCB0DA447EA00CDD80A /* PBXTextBookmark */ = 28E9BBCB0DA447EA00CDD80A /* PBXTextBookmark */;
+ 28E9BBCC0DA447EA00CDD80A /* PBXTextBookmark */ = 28E9BBCC0DA447EA00CDD80A /* PBXTextBookmark */;
+ 28E9BBCD0DA447EA00CDD80A /* PBXTextBookmark */ = 28E9BBCD0DA447EA00CDD80A /* PBXTextBookmark */;
+ 28E9BBCF0DA448CF00CDD80A /* PBXTextBookmark */ = 28E9BBCF0DA448CF00CDD80A /* PBXTextBookmark */;
+ 28E9BBD00DA448CF00CDD80A /* PBXTextBookmark */ = 28E9BBD00DA448CF00CDD80A /* PBXTextBookmark */;
+ 28E9BBD10DA448CF00CDD80A /* PBXTextBookmark */ = 28E9BBD10DA448CF00CDD80A /* PBXTextBookmark */;
+ 28E9BBD20DA448CF00CDD80A /* PBXTextBookmark */ = 28E9BBD20DA448CF00CDD80A /* PBXTextBookmark */;
+ 28E9BBD40DA44B9600CDD80A /* PBXTextBookmark */ = 28E9BBD40DA44B9600CDD80A /* PBXTextBookmark */;
+ 28E9BBD50DA44B9600CDD80A /* PBXTextBookmark */ = 28E9BBD50DA44B9600CDD80A /* PBXTextBookmark */;
+ 28E9BBD60DA44B9600CDD80A /* PBXTextBookmark */ = 28E9BBD60DA44B9600CDD80A /* PBXTextBookmark */;
+ 28E9BBD70DA44B9600CDD80A /* PBXTextBookmark */ = 28E9BBD70DA44B9600CDD80A /* PBXTextBookmark */;
+ 28E9BBD80DA44B9600CDD80A /* PBXTextBookmark */ = 28E9BBD80DA44B9600CDD80A /* PBXTextBookmark */;
+ 28E9BBD90DA44B9600CDD80A /* PBXTextBookmark */ = 28E9BBD90DA44B9600CDD80A /* PBXTextBookmark */;
+ 28E9BBDA0DA44B9600CDD80A /* PBXTextBookmark */ = 28E9BBDA0DA44B9600CDD80A /* PBXTextBookmark */;
+ 28E9BBDB0DA44B9600CDD80A /* PBXTextBookmark */ = 28E9BBDB0DA44B9600CDD80A /* PBXTextBookmark */;
+ 28E9BBDC0DA44B9600CDD80A /* PBXTextBookmark */ = 28E9BBDC0DA44B9600CDD80A /* PBXTextBookmark */;
+ 28E9BBDD0DA44B9600CDD80A /* PBXTextBookmark */ = 28E9BBDD0DA44B9600CDD80A /* PBXTextBookmark */;
+ 28E9BBDE0DA44B9600CDD80A /* PBXTextBookmark */ = 28E9BBDE0DA44B9600CDD80A /* PBXTextBookmark */;
+ 28E9BBE00DA44BB600CDD80A /* PBXTextBookmark */ = 28E9BBE00DA44BB600CDD80A /* PBXTextBookmark */;
+ };
+ sourceControlManager = 2898672E095DAA6100B5DC99 /* Source Control */;
+ userBuildSettings = {
+ };
+ };
+ 2A37F4ACFDCFA73011CA2CEA /* World.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {746, 13104}}";
+ sepNavSelRange = "{12877, 63}";
+ sepNavVisRect = "{{0, 5922}, {688, 425}}";
+ sepNavWindowFrame = "{{402, 152}, {857, 837}}";
+ };
+ };
+ 2A37F4AEFDCFA73011CA2CEA /* World.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {812, 1106}}";
+ sepNavSelRange = "{1482, 0}";
+ sepNavVisRect = "{{0, 758}, {812, 263}}";
+ sepNavWindowFrame = "{{84, 407}, {794, 703}}";
+ };
+ };
+ 8D15AC270486D014006FF6A4 /* Moxie */ = {
+ activeExec = 0;
+ executables = (
+ 289866A0095DAA5400B5DC99 /* Moxie */,
+ );
+ };
+}
diff --git a/Moxie.xcodeproj/bjc.perspectivev3 b/Moxie.xcodeproj/bjc.perspectivev3
new file mode 100644
index 0000000..d0cbbec
--- /dev/null
+++ b/Moxie.xcodeproj/bjc.perspectivev3
@@ -0,0 +1,1493 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActivePerspectiveName</key>
+ <string>Project</string>
+ <key>AllowedModules</key>
+ <array>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Name</key>
+ <string>Groups and Files Outline View</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Name</key>
+ <string>Editor</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCTaskListModule</string>
+ <key>Name</key>
+ <string>Task List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Name</key>
+ <string>File and Smart Group Detail Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Name</key>
+ <string>Detailed Build Results Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Name</key>
+ <string>Project Batch Find Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCProjectFormatConflictsModule</string>
+ <key>Name</key>
+ <string>Project Format Conflicts List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Name</key>
+ <string>Bookmarks Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Name</key>
+ <string>Class Browser</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Name</key>
+ <string>Source Code Control Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXDebugBreakpointsModule</string>
+ <key>Name</key>
+ <string>Debug Breakpoints Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDockableInspector</string>
+ <key>Name</key>
+ <string>Inspector</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXOpenQuicklyModule</string>
+ <key>Name</key>
+ <string>Open Quickly Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Name</key>
+ <string>Debugger</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Name</key>
+ <string>Debug Console</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCSnapshotModule</string>
+ <key>Name</key>
+ <string>Snapshots Tool</string>
+ </dict>
+ </array>
+ <key>BundlePath</key>
+ <string>/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources</string>
+ <key>Description</key>
+ <string>AIODescriptionKey</string>
+ <key>DockingSystemVisible</key>
+ <false/>
+ <key>Extension</key>
+ <string>perspectivev3</string>
+ <key>FavBarConfig</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>28E9BBAA0DA4290200CDD80A</string>
+ <key>XCBarModuleItemNames</key>
+ <dict/>
+ <key>XCBarModuleItems</key>
+ <array/>
+ </dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>com.apple.perspectives.project.defaultV3</string>
+ <key>MajorVersion</key>
+ <integer>34</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>All-In-One</string>
+ <key>Notifications</key>
+ <array/>
+ <key>OpenEditors</key>
+ <array/>
+ <key>PerspectiveWidths</key>
+ <array>
+ <integer>-1</integer>
+ <integer>-1</integer>
+ </array>
+ <key>Perspectives</key>
+ <array>
+ <dict>
+ <key>ChosenToolbarItems</key>
+ <array>
+ <string>XCToolbarPerspectiveControl</string>
+ <string>NSToolbarSeparatorItem</string>
+ <string>active-combo-popup</string>
+ <string>action</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>buildOrClean</string>
+ <string>build-and-goOrGo</string>
+ <string>debugger-enable-breakpoints</string>
+ <string>com.apple.ide.PBXToolbarStopButton</string>
+ <string>get-info</string>
+ <string>toggle-editor</string>
+ <string>Quick Model</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>com.apple.pbx.toolbar.searchfield</string>
+ </array>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProject</string>
+ <key>Identifier</key>
+ <string>perspective.project</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA23ED40692098700951B8B</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>185</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>2A37F4AAFDCFA73011CA2CEA</string>
+ <string>285A43F80966147F00597D37</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>11</integer>
+ <integer>3</integer>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {185, 787}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <false/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {202, 805}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>185</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>15 155 1013 846 0 0 1680 1028 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>202pt</string>
+ </dict>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>28E9BB9F0DA4290200CDD80A</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>build-lisp-image.sh</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>28E9BBA00DA4290200CDD80A</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>build-lisp-image.sh</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>28E9BBE00DA44BB600CDD80A</string>
+ <key>history</key>
+ <array>
+ <string>28E9BBD40DA44B9600CDD80A</string>
+ <string>28E9BBD50DA44B9600CDD80A</string>
+ <string>28E9BBD60DA44B9600CDD80A</string>
+ <string>28E9BBD70DA44B9600CDD80A</string>
+ </array>
+ <key>prevStack</key>
+ <array>
+ <string>28E9BBCA0DA447EA00CDD80A</string>
+ <string>28E9BBCB0DA447EA00CDD80A</string>
+ <string>28E9BBCC0DA447EA00CDD80A</string>
+ <string>28E9BBD10DA448CF00CDD80A</string>
+ <string>28E9BBD80DA44B9600CDD80A</string>
+ <string>28E9BBD90DA44B9600CDD80A</string>
+ <string>28E9BBDA0DA44B9600CDD80A</string>
+ <string>28E9BBDB0DA44B9600CDD80A</string>
+ <string>28E9BBDC0DA44B9600CDD80A</string>
+ <string>28E9BBDD0DA44B9600CDD80A</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.CommonNavigatorGroupSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {806, 619}}</string>
+ <key>RubberWindowFrame</key>
+ <string>15 155 1013 846 0 0 1680 1028 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>619pt</string>
+ </dict>
+ <dict>
+ <key>Proportion</key>
+ <string>181pt</string>
+ <key>Tabs</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA23EDF0692099D00951B8B</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{10, 27}, {806, 154}}</string>
+ <key>RubberWindowFrame</key>
+ <string>15 155 1013 846 0 0 1680 1028 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA23EE00692099D00951B8B</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Project Find</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{10, 31}, {603, 297}}</string>
+ </dict>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXCVSModuleFilterTypeKey</key>
+ <integer>1032</integer>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA23EE10692099D00951B8B</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>SCM Results</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{10, 31}, {603, 297}}</string>
+ </dict>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBuildLogShowsTranscriptDefaultKey</key>
+ <string>{{0, 83}, {806, 71}}</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>XCMainBuildResultsModuleGUID</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Build</string>
+ <key>XCBuildResultsTrigger_Collapse</key>
+ <integer>1021</integer>
+ <key>XCBuildResultsTrigger_Open</key>
+ <integer>1011</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{10, 27}, {806, 154}}</string>
+ </dict>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ </dict>
+ </array>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>806pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCModuleDock</string>
+ <string>PBXNavigatorGroup</string>
+ <string>XCDockableTabModule</string>
+ <string>XCDetailModule</string>
+ <string>PBXProjectFindModule</string>
+ <string>PBXCVSModule</string>
+ <string>PBXBuildResultsModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>28E9BBA10DA4290200CDD80A</string>
+ <string>1CA23ED40692098700951B8B</string>
+ <string>28E9BBA20DA4290200CDD80A</string>
+ <string>28E9BB9F0DA4290200CDD80A</string>
+ <string>28E9BBA30DA4290200CDD80A</string>
+ <string>1CA23EDF0692099D00951B8B</string>
+ <string>1CA23EE00692099D00951B8B</string>
+ <string>1CA23EE10692099D00951B8B</string>
+ <string>XCMainBuildResultsModuleGUID</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.defaultV3</string>
+ </dict>
+ <dict>
+ <key>ChosenToolbarItems</key>
+ <array>
+ <string>XCToolbarPerspectiveControl</string>
+ <string>NSToolbarSeparatorItem</string>
+ <string>build-and-go</string>
+ <string>go</string>
+ <string>debugger-enable-breakpoints</string>
+ <string>debugger-fix-and-continue</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>debugger-restart-executable</string>
+ <string>debugger-pause</string>
+ <string>debugger-step-over</string>
+ <string>debugger-step-into</string>
+ <string>debugger-step-out</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>com.apple.ide.XCBreakpointsToolbarItem</string>
+ <string>servicesModulebreakpoints</string>
+ <string>debugger-show-console-window</string>
+ </array>
+ <key>ControllerClassBaseName</key>
+ <string>PBXDebugSessionModule</string>
+ <key>IconName</key>
+ <string>DebugTabIcon</string>
+ <key>Identifier</key>
+ <string>perspective.debug</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CCC7628064C1048000F2A68</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debugger Console</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {810, 0}}</string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>Debugger</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {395, 213}}</string>
+ <string>{{395, 0}, {415, 213}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {810, 213}}</string>
+ <string>{{0, 213}, {810, 225}}</string>
+ </array>
+ </dict>
+ </dict>
+ <key>LauncherConfigVersion</key>
+ <string>8</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CCC7629064C1048000F2A68</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debug</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>DebugConsoleVisible</key>
+ <string>None</string>
+ <key>DebugConsoleWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>DebugSTDIOWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>Frame</key>
+ <string>{{0, 7}, {810, 438}}</string>
+ <key>PBXDebugSessionStackFrameViewKey</key>
+ <dict>
+ <key>DebugVariablesTableConfiguration</key>
+ <array>
+ <string>Name</string>
+ <real>120</real>
+ <string>Value</string>
+ <real>85</real>
+ <string>Summary</string>
+ <real>185</real>
+ </array>
+ <key>Frame</key>
+ <string>{{395, 0}, {415, 213}}</string>
+ </dict>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Proportion</key>
+ <string>438pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debug</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXDebugCLIModule</string>
+ <string>PBXDebugSessionModule</string>
+ <string>PBXDebugProcessAndThreadModule</string>
+ <string>PBXDebugProcessViewModule</string>
+ <string>PBXDebugThreadViewModule</string>
+ <string>PBXDebugStackFrameViewModule</string>
+ <string>PBXNavigatorGroup</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>28E9BBA40DA4290200CDD80A</string>
+ <string>1CCC7628064C1048000F2A68</string>
+ <string>1CCC7629064C1048000F2A68</string>
+ <string>28E9BBA50DA4290200CDD80A</string>
+ <string>28E9BBA60DA4290200CDD80A</string>
+ <string>28E9BBA70DA4290200CDD80A</string>
+ <string>28E9BBA80DA4290200CDD80A</string>
+ <string>28E9BBA90DA4290200CDD80A</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugV3</string>
+ </dict>
+ </array>
+ <key>PerspectivesBarVisible</key>
+ <true/>
+ <key>ShelfIsVisible</key>
+ <false/>
+ <key>SourceDescription</key>
+ <string>file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecification.xcperspec'</string>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TimeStamp</key>
+ <real>0.0</real>
+ <key>ToolbarDisplayMode</key>
+ <integer>2</integer>
+ <key>ToolbarIsVisible</key>
+ <true/>
+ <key>ToolbarSizeMode</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Perspectives</string>
+ <key>UpdateMessage</key>
+ <string></string>
+ <key>WindowJustification</key>
+ <integer>5</integer>
+ <key>WindowOrderList</key>
+ <array>
+ <string>/Users/bjc/src/MyStuff/Moxie/Moxie.xcodeproj</string>
+ </array>
+ <key>WindowString</key>
+ <string>15 155 1013 846 0 0 1680 1028 </string>
+ <key>WindowToolsV3</key>
+ <array>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debugger</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>Debugger</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {317, 164}}</string>
+ <string>{{317, 0}, {377, 164}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {694, 164}}</string>
+ <string>{{0, 164}, {694, 216}}</string>
+ </array>
+ </dict>
+ </dict>
+ <key>LauncherConfigVersion</key>
+ <string>8</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C162984064C10D400B95A72</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debug - GLUTExamples (Underwater)</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>DebugConsoleDrawerSize</key>
+ <string>{100, 120}</string>
+ <key>DebugConsoleVisible</key>
+ <string>None</string>
+ <key>DebugConsoleWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>DebugSTDIOWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>Frame</key>
+ <string>{{0, 0}, {694, 380}}</string>
+ <key>RubberWindowFrame</key>
+ <string>321 238 694 422 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugSessionModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>1C0AD2AB069F1E9B00FABCE6</string>
+ <string>1C162984064C10D400B95A72</string>
+ <string>1C0AD2AC069F1E9B00FABCE6</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugV3</string>
+ <key>WindowString</key>
+ <string>321 238 694 422 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.build</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528F0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>&lt;No Editor&gt;</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD052900623707200166675</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {500, 215}}</string>
+ <key>RubberWindowFrame</key>
+ <string>192 257 500 500 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>218pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>XCMainBuildResultsModuleGUID</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Build</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 222}, {500, 236}}</string>
+ <key>RubberWindowFrame</key>
+ <string>192 257 500 500 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Proportion</key>
+ <string>236pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>458pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Build Results</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBuildResultsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAA5065D492600B07095</string>
+ <string>1C78EAA6065D492600B07095</string>
+ <string>1CD0528F0623707200166675</string>
+ <string>XCMainBuildResultsModuleGUID</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.buildV3</string>
+ <key>WindowString</key>
+ <string>192 257 500 500 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.find</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CDD528C0622207200134675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>&lt;No Editor&gt;</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528D0623707200166675</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {781, 167}}</string>
+ <key>RubberWindowFrame</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>781pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>50%</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528E0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Project Find</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{8, 0}, {773, 254}}</string>
+ <key>RubberWindowFrame</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Proportion</key>
+ <string>50%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>428pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project Find</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXProjectFindModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <string>1C530D58069F1CE1000CFCEE</string>
+ <string>1C530D59069F1CE1000CFCEE</string>
+ <string>1CDD528C0622207200134675</string>
+ <string>1C530D5A069F1CE1000CFCEE</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>1CD0528E0623707200166675</string>
+ </array>
+ <key>WindowString</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.snapshots</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>XCSnapshotModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Snapshots</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCSnapshotModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <string>Yes</string>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.snapshots</string>
+ <key>WindowString</key>
+ <string>315 824 300 550 0 0 1440 878 </string>
+ <key>WindowToolIsVisible</key>
+ <string>Yes</string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debuggerConsole</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAAC065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debugger Console</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {700, 358}}</string>
+ <key>RubberWindowFrame</key>
+ <string>149 87 700 400 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Proportion</key>
+ <string>358pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>358pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger Console</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugCLIModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C530D5B069F1CE1000CFCEE</string>
+ <string>1C530D5C069F1CE1000CFCEE</string>
+ <string>1C78EAAC065D492600B07095</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.consoleV3</string>
+ <key>WindowString</key>
+ <string>149 87 440 400 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C530D5B069F1CE1000CFCEE</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.scm</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB2065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>&lt;No Editor&gt;</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB3065D492600B07095</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {452, 0}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD052920623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>SCM</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ConsoleFrame</key>
+ <string>{{0, 259}, {452, 0}}</string>
+ <key>Frame</key>
+ <string>{{0, 7}, {452, 259}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ <key>TableConfiguration</key>
+ <array>
+ <string>Status</string>
+ <real>30</real>
+ <string>FileName</string>
+ <real>199</real>
+ <string>Path</string>
+ <real>197.09500122070312</real>
+ </array>
+ <key>TableFrame</key>
+ <string>{{0, 0}, {452, 250}}</string>
+ </dict>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Proportion</key>
+ <string>262pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>266pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>SCM</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXCVSModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAB4065D492600B07095</string>
+ <string>1C78EAB5065D492600B07095</string>
+ <string>1C78EAB2065D492600B07095</string>
+ <string>1CD052920623707200166675</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.scmV3</string>
+ <key>WindowString</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.breakpoints</string>
+ <key>IsVertical</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>no</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>168</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {168, 350}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <integer>0</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {185, 368}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>168</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>185pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA1AED706398EBD00589147</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{190, 0}, {554, 368}}</string>
+ <key>RubberWindowFrame</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>554pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>368pt</string>
+ </dict>
+ </array>
+ <key>MajorVersion</key>
+ <integer>3</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Breakpoints</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CDDB66807F98D9800BB5817</string>
+ <string>1CDDB66907F98D9800BB5817</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>1CA1AED706398EBD00589147</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.breakpointsV3</string>
+ <key>WindowString</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1CDDB66807F98D9800BB5817</string>
+ <key>WindowToolIsVisible</key>
+ <integer>1</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debugAnimator</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debug Visualizer</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXNavigatorGroup</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugAnimatorV3</string>
+ <key>WindowString</key>
+ <string>100 100 700 500 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.bookmarks</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Proportion</key>
+ <string>166pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>166pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Bookmarks</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBookmarksModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>WindowString</key>
+ <string>538 42 401 187 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.projectFormatConflicts</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>XCProjectFormatConflictsModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project Format Conflicts</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCProjectFormatConflictsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>WindowContentMinSize</key>
+ <string>450 300</string>
+ <key>WindowString</key>
+ <string>50 850 472 307 0 0 1440 877</string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.classBrowser</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>OptionsSetName</key>
+ <string>Hierarchy, all classes</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA6456E063B45B4001379D8</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Class Browser - NSObject</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ClassesFrame</key>
+ <string>{{0, 0}, {369, 96}}</string>
+ <key>ClassesTreeTableConfiguration</key>
+ <array>
+ <string>PBXClassNameColumnIdentifier</string>
+ <real>208</real>
+ <string>PBXClassBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>Frame</key>
+ <string>{{0, 0}, {616, 353}}</string>
+ <key>MembersFrame</key>
+ <string>{{0, 105}, {369, 395}}</string>
+ <key>MembersTreeTableConfiguration</key>
+ <array>
+ <string>PBXMemberTypeIconColumnIdentifier</string>
+ <real>22</real>
+ <string>PBXMemberNameColumnIdentifier</string>
+ <real>216</real>
+ <string>PBXMemberTypeColumnIdentifier</string>
+ <real>94</real>
+ <string>PBXMemberBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <integer>1</integer>
+ <key>RubberWindowFrame</key>
+ <string>597 125 616 374 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Proportion</key>
+ <string>354pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>354pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Class Browser</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXClassBrowserModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EABA065D492600B07095</string>
+ <string>1C78EABB065D492600B07095</string>
+ <string>1CA6456E063B45B4001379D8</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.classbrowser</string>
+ <key>WindowString</key>
+ <string>597 125 616 374 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.refactoring</string>
+ <key>IncludeInToolsMenu</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{0, 0}, {500, 335}</string>
+ <key>RubberWindowFrame</key>
+ <string>{0, 0}, {500, 335}</string>
+ </dict>
+ <key>Module</key>
+ <string>XCRefactoringModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Refactoring</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCRefactoringModule</string>
+ </array>
+ <key>WindowString</key>
+ <string>200 200 500 356 0 0 1920 1200 </string>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/Moxie.xcodeproj/project.pbxproj b/Moxie.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..a7fa4f2
--- /dev/null
+++ b/Moxie.xcodeproj/project.pbxproj
@@ -0,0 +1,876 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 280FE68806C7533F00AA47DF /* LispREPL.nib in Resources */ = {isa = PBXBuildFile; fileRef = 280FE68706C7533F00AA47DF /* LispREPL.nib */; };
+ 280FE69106C8241600AA47DF /* LispREPLController.h in Headers */ = {isa = PBXBuildFile; fileRef = 280FE68F06C8241600AA47DF /* LispREPLController.h */; };
+ 280FE69206C8241600AA47DF /* LispREPLController.m in Sources */ = {isa = PBXBuildFile; fileRef = 280FE69006C8241600AA47DF /* LispREPLController.m */; };
+ 28212A6005A6CEF600BEF07C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28212A5F05A6CEF600BEF07C /* Security.framework */; };
+ 2825D1AF05BE3ED300A9958B /* SettingNames.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2825D1AE05BE3ED300A9958B /* SettingNames.strings */; };
+ 2827172606DAFDE200D3A4C2 /* NSAttributedString+Moxie.h in Headers */ = {isa = PBXBuildFile; fileRef = 2827172406DAFDE200D3A4C2 /* NSAttributedString+Moxie.h */; };
+ 2827172706DAFDE200D3A4C2 /* NSAttributedString+Moxie.m in Sources */ = {isa = PBXBuildFile; fileRef = 2827172506DAFDE200D3A4C2 /* NSAttributedString+Moxie.m */; };
+ 282B3E3305A3F8E300A3D04F /* MxWorldSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 282B3E3105A3F8E300A3D04F /* MxWorldSettings.h */; };
+ 282B3E3405A3F8E300A3D04F /* MxWorldSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */; };
+ 28360F9B05A7CE3300841A1E /* WorldSelector.nib in Resources */ = {isa = PBXBuildFile; fileRef = 28360F9905A7CE3300841A1E /* WorldSelector.nib */; };
+ 28360F9E05A7CEB100841A1E /* WorldStatusController.h in Headers */ = {isa = PBXBuildFile; fileRef = 28360F9C05A7CEB100841A1E /* WorldStatusController.h */; };
+ 28360F9F05A7CEB100841A1E /* WorldStatusController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28360F9D05A7CEB100841A1E /* WorldStatusController.m */; };
+ 28396EFB05A444D000CE84B6 /* NSException+LiDebugging.m in Sources */ = {isa = PBXBuildFile; fileRef = 28396EFA05A444D000CE84B6 /* NSException+LiDebugging.m */; };
+ 28406A1605D0DDB4008DEAD7 /* MoxieWorld.icns in Resources */ = {isa = PBXBuildFile; fileRef = 28406A1505D0DDB4008DEAD7 /* MoxieWorld.icns */; };
+ 284755F106CF0EF90078110F /* LispREPL.h in Headers */ = {isa = PBXBuildFile; fileRef = 284755EF06CF0EF90078110F /* LispREPL.h */; };
+ 284755F206CF0EF90078110F /* LispREPL.m in Sources */ = {isa = PBXBuildFile; fileRef = 284755F006CF0EF90078110F /* LispREPL.m */; };
+ 2857BB5E05BAA0F00053FE42 /* World.nib in Resources */ = {isa = PBXBuildFile; fileRef = 2857BB5D05BAA0F00053FE42 /* World.nib */; };
+ 2857BB6005BAA0FB0053FE42 /* Preferences.nib in Resources */ = {isa = PBXBuildFile; fileRef = 2857BB5F05BAA0FB0053FE42 /* Preferences.nib */; };
+ 285A42D70965F35400597D37 /* Ansi-Color.lisp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 285A42BD0965F31400597D37 /* Ansi-Color.lisp */; };
+ 285A42D80965F35400597D37 /* Idle-Monster.lisp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 285A42BE0965F31400597D37 /* Idle-Monster.lisp */; };
+ 285A42D90965F35400597D37 /* Logger.lisp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 285A42BF0965F31400597D37 /* Logger.lisp */; };
+ 285A42DA0965F35400597D37 /* MXP.lisp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 285A42C00965F31400597D37 /* MXP.lisp */; };
+ 285A42DB0965F35400597D37 /* Numpad-Movement.lisp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 285A42C10965F31400597D37 /* Numpad-Movement.lisp */; };
+ 285A42DC0965F35400597D37 /* Sample-Plugin.lisp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 285A42C20965F31400597D37 /* Sample-Plugin.lisp */; };
+ 285A42DD0965F35400597D37 /* Telnet.lisp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 285A42C30965F31400597D37 /* Telnet.lisp */; };
+ 285A4408096614D100597D37 /* init-template.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 285A4405096614D100597D37 /* init-template.lisp */; };
+ 285A44900966156A00597D37 /* lisp.run in Resources */ = {isa = PBXBuildFile; fileRef = 285A448C0966156A00597D37 /* lisp.run */; };
+ 285A44BC096615B700597D37 /* clhs-lookup.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 285A44A2096615B700597D37 /* clhs-lookup.lisp */; };
+ 285A44BD096615B700597D37 /* compat-clisp.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 285A44A4096615B700597D37 /* compat-clisp.lisp */; };
+ 285A44BE096615B700597D37 /* compat-openmcl.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 285A44A5096615B700597D37 /* compat-openmcl.lisp */; };
+ 285A44C0096615B700597D37 /* compat-sbcl.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 285A44A7096615B700597D37 /* compat-sbcl.lisp */; };
+ 285A44C3096615B700597D37 /* default.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 285A44AA096615B700597D37 /* default.lisp */; };
+ 285A44C4096615B700597D37 /* hooks.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 285A44AB096615B700597D37 /* hooks.lisp */; };
+ 285A44C5096615B700597D37 /* Map_Sym.txt in Resources */ = {isa = PBXBuildFile; fileRef = 285A44AC096615B700597D37 /* Map_Sym.txt */; };
+ 285A44C6096615B700597D37 /* Mop_Sym.txt in Resources */ = {isa = PBXBuildFile; fileRef = 285A44AD096615B700597D37 /* Mop_Sym.txt */; };
+ 285A44C7096615B700597D37 /* moxie.asd in Resources */ = {isa = PBXBuildFile; fileRef = 285A44AE096615B700597D37 /* moxie.asd */; };
+ 285A44C9096615B700597D37 /* moxie.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 285A44B0096615B700597D37 /* moxie.lisp */; };
+ 285A44CB096615B700597D37 /* package.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 285A44B2096615B700597D37 /* package.lisp */; };
+ 285A44D0096615B700597D37 /* bjc-utils.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 285A44B8096615B700597D37 /* bjc-utils.lisp */; };
+ 285A44D3096615B700597D37 /* world.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 285A44BB096615B700597D37 /* world.lisp */; };
+ 285A45970966171D00597D37 /* startlisp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 285A4404096614D000597D37 /* startlisp */; };
+ 285A45980966172600597D37 /* openmcl in CopyFiles */ = {isa = PBXBuildFile; fileRef = 285A44990966157F00597D37 /* openmcl */; };
+ 285A45990966173400597D37 /* clisp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 285A448E0966156A00597D37 /* clisp */; };
+ 2861E88A09674C62002A271F /* repl.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 2861E88909674C62002A271F /* repl.lisp */; };
+ 2861E9E20967A48A002A271F /* save-moxie-image.lisp in Resources */ = {isa = PBXBuildFile; fileRef = 2861E9E00967A48A002A271F /* save-moxie-image.lisp */; };
+ 2861E9E30967A48A002A271F /* sbcl.core in Resources */ = {isa = PBXBuildFile; fileRef = 2861E9E10967A48A002A271F /* sbcl.core */; };
+ 2861E9EB0967A5E4002A271F /* sbcl in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2861E9E80967A4F4002A271F /* sbcl */; };
+ 286C3B5E070A4B8900B6E2B1 /* NSNumber+LispExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 286C3B5C070A4B8900B6E2B1 /* NSNumber+LispExtensions.h */; };
+ 286C3B5F070A4B8900B6E2B1 /* NSNumber+LispExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 286C3B5D070A4B8900B6E2B1 /* NSNumber+LispExtensions.m */; };
+ 286D8C1605A4099100D7C2A2 /* WorldSettingsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 286D8C1405A4099100D7C2A2 /* WorldSettingsController.h */; };
+ 286D8C1705A4099100D7C2A2 /* WorldSettingsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 286D8C1505A4099100D7C2A2 /* WorldSettingsController.m */; };
+ 288A4F1A05A13FBD004C4480 /* ScrollingTextView.h in Headers */ = {isa = PBXBuildFile; fileRef = 288A4F1805A13FBD004C4480 /* ScrollingTextView.h */; };
+ 288A4F1B05A13FBD004C4480 /* ScrollingTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 288A4F1905A13FBD004C4480 /* ScrollingTextView.m */; };
+ 288D8A7105AD21A10058CC79 /* WorldSettings.nib in Resources */ = {isa = PBXBuildFile; fileRef = 288D8A7005AD21A10058CC79 /* WorldSettings.nib */; };
+ 289962A605B67ADF00ADBE42 /* NSUserDefaults+Moxie.h in Headers */ = {isa = PBXBuildFile; fileRef = 289962A405B67ADF00ADBE42 /* NSUserDefaults+Moxie.h */; };
+ 289962A705B67ADF00ADBE42 /* NSUserDefaults+Moxie.m in Sources */ = {isa = PBXBuildFile; fileRef = 289962A505B67ADF00ADBE42 /* NSUserDefaults+Moxie.m */; };
+ 28A2E1DD096985710005CC4E /* dppccl in Resources */ = {isa = PBXBuildFile; fileRef = 28A2E1DB096985710005CC4E /* dppccl */; };
+ 28A2E1DE096985710005CC4E /* dppccl.image in Resources */ = {isa = PBXBuildFile; fileRef = 28A2E1DC096985710005CC4E /* dppccl.image */; };
+ 28B9CF3005BA185800A72136 /* WorldController.h in Headers */ = {isa = PBXBuildFile; fileRef = 28B9CF2E05BA185800A72136 /* WorldController.h */; };
+ 28B9CF3105BA185800A72136 /* WorldController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28B9CF2F05BA185800A72136 /* WorldController.m */; };
+ 28C36FBD05BFCB3000BAA9B7 /* Moxie.icns in Resources */ = {isa = PBXBuildFile; fileRef = 28C36FBC05BFCB3000BAA9B7 /* Moxie.icns */; };
+ 28C6947C06F55DC000341CDE /* NSDictionary+LispExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 28C6947A06F55DC000341CDE /* NSDictionary+LispExtensions.h */; };
+ 28C6947D06F55DC000341CDE /* NSDictionary+LispExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C6947B06F55DC000341CDE /* NSDictionary+LispExtensions.m */; };
+ 28CDC68E06D0E4BB00D3A886 /* Moxie Help in Resources */ = {isa = PBXBuildFile; fileRef = 28CDC68D06D0E4BB00D3A886 /* Moxie Help */; };
+ 28D8059F06E9B04C002B3FAF /* NSString+LispExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 28D8059D06E9B04C002B3FAF /* NSString+LispExtensions.h */; };
+ 28D805A006E9B04C002B3FAF /* NSString+LispExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D8059E06E9B04C002B3FAF /* NSString+LispExtensions.m */; };
+ 28D925D505B7B09100CC250A /* PreferencesController.h in Headers */ = {isa = PBXBuildFile; fileRef = 28D925D305B7B09100CC250A /* PreferencesController.h */; };
+ 28D925D605B7B09100CC250A /* PreferencesController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D925D405B7B09100CC250A /* PreferencesController.m */; };
+ 28F9039C06EE45AF00D5ADA9 /* NSArray+LispExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 28F9039A06EE45AF00D5ADA9 /* NSArray+LispExtensions.h */; };
+ 28F9039D06EE45AF00D5ADA9 /* NSArray+LispExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 28F9039B06EE45AF00D5ADA9 /* NSArray+LispExtensions.m */; };
+ 28F903A406EE490C00D5ADA9 /* LispSymbol.h in Headers */ = {isa = PBXBuildFile; fileRef = 28F903A206EE490C00D5ADA9 /* LispSymbol.h */; };
+ 28F903A506EE490C00D5ADA9 /* LispSymbol.m in Sources */ = {isa = PBXBuildFile; fileRef = 28F903A306EE490C00D5ADA9 /* LispSymbol.m */; };
+ 28F9046E06F2305300D5ADA9 /* NSFileHandle+LispExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 28F9046C06F2305300D5ADA9 /* NSFileHandle+LispExtensions.h */; };
+ 28F9046F06F2305300D5ADA9 /* NSFileHandle+LispExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 28F9046D06F2305300D5ADA9 /* NSFileHandle+LispExtensions.m */; };
+ 8D15AC290486D014006FF6A4 /* Moxie_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32DBCF750370BD2300C91783 /* Moxie_Prefix.pch */; };
+ 8D15AC2A0486D014006FF6A4 /* World.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A37F4AEFDCFA73011CA2CEA /* World.h */; };
+ 8D15AC2C0486D014006FF6A4 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */; };
+ 8D15AC2D0486D014006FF6A4 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 2A37F4B6FDCFA73011CA2CEA /* MainMenu.nib */; };
+ 8D15AC2F0486D014006FF6A4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165FFE840EACC02AAC07 /* InfoPlist.strings */; };
+ 8D15AC310486D014006FF6A4 /* World.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4ACFDCFA73011CA2CEA /* World.m */; settings = {ATTRIBUTES = (); }; };
+ 8D15AC320486D014006FF6A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4B0FDCFA73011CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
+ 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 285A45950966170B00597D37 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 6;
+ files = (
+ 2861E9EB0967A5E4002A271F /* sbcl in CopyFiles */,
+ 285A45970966171D00597D37 /* startlisp in CopyFiles */,
+ 285A45980966172600597D37 /* openmcl in CopyFiles */,
+ 285A45990966173400597D37 /* clisp in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 28986CC9095E4CB700B5DC99 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 13;
+ files = (
+ 285A42D70965F35400597D37 /* Ansi-Color.lisp in CopyFiles */,
+ 285A42D80965F35400597D37 /* Idle-Monster.lisp in CopyFiles */,
+ 285A42D90965F35400597D37 /* Logger.lisp in CopyFiles */,
+ 285A42DA0965F35400597D37 /* MXP.lisp in CopyFiles */,
+ 285A42DB0965F35400597D37 /* Numpad-Movement.lisp in CopyFiles */,
+ 285A42DC0965F35400597D37 /* Sample-Plugin.lisp in CopyFiles */,
+ 285A42DD0965F35400597D37 /* Telnet.lisp in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 089C1660FE840EACC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 280FE67F06C7533400AA47DF /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/LispREPL.nib; sourceTree = "<group>"; };
+ 280FE68F06C8241600AA47DF /* LispREPLController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LispREPLController.h; sourceTree = "<group>"; };
+ 280FE69006C8241600AA47DF /* LispREPLController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LispREPLController.m; sourceTree = "<group>"; };
+ 28212A5F05A6CEF600BEF07C /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
+ 2827172406DAFDE200D3A4C2 /* NSAttributedString+Moxie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+Moxie.h"; sourceTree = "<group>"; };
+ 2827172506DAFDE200D3A4C2 /* NSAttributedString+Moxie.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+Moxie.m"; sourceTree = "<group>"; };
+ 282B3E3105A3F8E300A3D04F /* MxWorldSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MxWorldSettings.h; sourceTree = "<group>"; };
+ 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MxWorldSettings.m; sourceTree = "<group>"; };
+ 28360F9A05A7CE3300841A1E /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/WorldSelector.nib; sourceTree = "<group>"; };
+ 28360F9C05A7CEB100841A1E /* WorldStatusController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WorldStatusController.h; sourceTree = "<group>"; };
+ 28360F9D05A7CEB100841A1E /* WorldStatusController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WorldStatusController.m; sourceTree = "<group>"; };
+ 28396EFA05A444D000CE84B6 /* NSException+LiDebugging.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = "NSException+LiDebugging.m"; sourceTree = "<group>"; };
+ 28406A1505D0DDB4008DEAD7 /* MoxieWorld.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = MoxieWorld.icns; sourceTree = "<group>"; };
+ 284755EF06CF0EF90078110F /* LispREPL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LispREPL.h; sourceTree = "<group>"; };
+ 284755F006CF0EF90078110F /* LispREPL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LispREPL.m; sourceTree = "<group>"; };
+ 285A42BD0965F31400597D37 /* Ansi-Color.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "Ansi-Color.lisp"; sourceTree = "<group>"; };
+ 285A42BE0965F31400597D37 /* Idle-Monster.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "Idle-Monster.lisp"; sourceTree = "<group>"; };
+ 285A42BF0965F31400597D37 /* Logger.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Logger.lisp; sourceTree = "<group>"; };
+ 285A42C00965F31400597D37 /* MXP.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = MXP.lisp; sourceTree = "<group>"; };
+ 285A42C10965F31400597D37 /* Numpad-Movement.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "Numpad-Movement.lisp"; sourceTree = "<group>"; };
+ 285A42C20965F31400597D37 /* Sample-Plugin.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "Sample-Plugin.lisp"; sourceTree = "<group>"; };
+ 285A42C30965F31400597D37 /* Telnet.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Telnet.lisp; sourceTree = "<group>"; };
+ 285A4404096614D000597D37 /* startlisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = startlisp; sourceTree = "<group>"; };
+ 285A4405096614D100597D37 /* init-template.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "init-template.lisp"; sourceTree = "<group>"; };
+ 285A4406096614D100597D37 /* build-lisp-image.sh */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = "build-lisp-image.sh"; sourceTree = "<group>"; };
+ 285A445B0966152600597D37 /* asdf */ = {isa = PBXFileReference; lastKnownFileType = folder; path = asdf; sourceTree = "<group>"; };
+ 285A448C0966156A00597D37 /* lisp.run */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = lisp.run; sourceTree = "<group>"; };
+ 285A448D0966156A00597D37 /* lispinit.mem */ = {isa = PBXFileReference; lastKnownFileType = file; path = lispinit.mem; sourceTree = "<group>"; };
+ 285A448E0966156A00597D37 /* clisp */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = clisp; sourceTree = "<group>"; };
+ 285A448F0966156A00597D37 /* save-moxie-image.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "save-moxie-image.lisp"; sourceTree = "<group>"; };
+ 285A44990966157F00597D37 /* openmcl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = openmcl; sourceTree = "<group>"; };
+ 285A449A0966157F00597D37 /* save-moxie-image.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "save-moxie-image.lisp"; sourceTree = "<group>"; };
+ 285A44A2096615B700597D37 /* clhs-lookup.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "clhs-lookup.lisp"; sourceTree = "<group>"; };
+ 285A44A4096615B700597D37 /* compat-clisp.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "compat-clisp.lisp"; sourceTree = "<group>"; };
+ 285A44A5096615B700597D37 /* compat-openmcl.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "compat-openmcl.lisp"; sourceTree = "<group>"; };
+ 285A44A6096615B700597D37 /* compat-sbcl.fasl */ = {isa = PBXFileReference; lastKnownFileType = file; path = "compat-sbcl.fasl"; sourceTree = "<group>"; };
+ 285A44A7096615B700597D37 /* compat-sbcl.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "compat-sbcl.lisp"; sourceTree = "<group>"; };
+ 285A44A8096615B700597D37 /* semantic.cache */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = semantic.cache; sourceTree = "<group>"; };
+ 285A44AA096615B700597D37 /* default.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = default.lisp; sourceTree = "<group>"; };
+ 285A44AB096615B700597D37 /* hooks.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = hooks.lisp; sourceTree = "<group>"; };
+ 285A44AC096615B700597D37 /* Map_Sym.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Map_Sym.txt; sourceTree = "<group>"; };
+ 285A44AD096615B700597D37 /* Mop_Sym.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Mop_Sym.txt; sourceTree = "<group>"; };
+ 285A44AE096615B700597D37 /* moxie.asd */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = moxie.asd; sourceTree = "<group>"; };
+ 285A44B0096615B700597D37 /* moxie.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = moxie.lisp; sourceTree = "<group>"; };
+ 285A44B2096615B700597D37 /* package.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = package.lisp; sourceTree = "<group>"; };
+ 285A44B7096615B700597D37 /* bjc-utils.fasl */ = {isa = PBXFileReference; lastKnownFileType = file; path = "bjc-utils.fasl"; sourceTree = "<group>"; };
+ 285A44B8096615B700597D37 /* bjc-utils.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "bjc-utils.lisp"; sourceTree = "<group>"; };
+ 285A44B9096615B700597D37 /* semantic.cache */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = semantic.cache; sourceTree = "<group>"; };
+ 285A44BB096615B700597D37 /* world.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = world.lisp; sourceTree = "<group>"; };
+ 2861E88909674C62002A271F /* repl.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = repl.lisp; sourceTree = "<group>"; };
+ 2861E9E00967A48A002A271F /* save-moxie-image.lisp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "save-moxie-image.lisp"; sourceTree = "<group>"; };
+ 2861E9E10967A48A002A271F /* sbcl.core */ = {isa = PBXFileReference; lastKnownFileType = file; path = sbcl.core; sourceTree = "<group>"; };
+ 2861E9E80967A4F4002A271F /* sbcl */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = sbcl; sourceTree = "<group>"; };
+ 286C3B5C070A4B8900B6E2B1 /* NSNumber+LispExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNumber+LispExtensions.h"; sourceTree = "<group>"; };
+ 286C3B5D070A4B8900B6E2B1 /* NSNumber+LispExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNumber+LispExtensions.m"; sourceTree = "<group>"; };
+ 286D8C1405A4099100D7C2A2 /* WorldSettingsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorldSettingsController.h; sourceTree = "<group>"; };
+ 286D8C1505A4099100D7C2A2 /* WorldSettingsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WorldSettingsController.m; sourceTree = "<group>"; };
+ 286FE9F205BE3B9E005A01FF /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/SettingNames.strings; sourceTree = "<group>"; };
+ 288A4EFA05A12FDE004C4480 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/WorldSettings.nib; sourceTree = "<group>"; };
+ 288A4F1805A13FBD004C4480 /* ScrollingTextView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ScrollingTextView.h; sourceTree = "<group>"; };
+ 288A4F1905A13FBD004C4480 /* ScrollingTextView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = ScrollingTextView.m; sourceTree = "<group>"; };
+ 289962A405B67ADF00ADBE42 /* NSUserDefaults+Moxie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSUserDefaults+Moxie.h"; sourceTree = "<group>"; };
+ 289962A505B67ADF00ADBE42 /* NSUserDefaults+Moxie.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSUserDefaults+Moxie.m"; sourceTree = "<group>"; };
+ 28A0F61C05B17A4700035E74 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/World.nib; sourceTree = "<group>"; };
+ 28A2E1DB096985710005CC4E /* dppccl */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = dppccl; sourceTree = "<group>"; };
+ 28A2E1DC096985710005CC4E /* dppccl.image */ = {isa = PBXFileReference; lastKnownFileType = file; path = dppccl.image; sourceTree = "<group>"; };
+ 28B9CF2E05BA185800A72136 /* WorldController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WorldController.h; sourceTree = "<group>"; };
+ 28B9CF2F05BA185800A72136 /* WorldController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WorldController.m; sourceTree = "<group>"; };
+ 28C36FBC05BFCB3000BAA9B7 /* Moxie.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Moxie.icns; sourceTree = "<group>"; };
+ 28C6947A06F55DC000341CDE /* NSDictionary+LispExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+LispExtensions.h"; sourceTree = "<group>"; };
+ 28C6947B06F55DC000341CDE /* NSDictionary+LispExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+LispExtensions.m"; sourceTree = "<group>"; };
+ 28CDC67006D0E46A00D3A886 /* English */ = {isa = PBXFileReference; lastKnownFileType = folder; name = English; path = "English.lproj/Moxie Help"; sourceTree = "<group>"; };
+ 28D8059D06E9B04C002B3FAF /* NSString+LispExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+LispExtensions.h"; sourceTree = "<group>"; };
+ 28D8059E06E9B04C002B3FAF /* NSString+LispExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+LispExtensions.m"; sourceTree = "<group>"; };
+ 28D925D105B7AF5E00CC250A /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/Preferences.nib; sourceTree = "<group>"; };
+ 28D925D305B7B09100CC250A /* PreferencesController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PreferencesController.h; sourceTree = "<group>"; };
+ 28D925D405B7B09100CC250A /* PreferencesController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PreferencesController.m; sourceTree = "<group>"; };
+ 28F9039A06EE45AF00D5ADA9 /* NSArray+LispExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+LispExtensions.h"; sourceTree = "<group>"; };
+ 28F9039B06EE45AF00D5ADA9 /* NSArray+LispExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+LispExtensions.m"; sourceTree = "<group>"; };
+ 28F903A206EE490C00D5ADA9 /* LispSymbol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LispSymbol.h; sourceTree = "<group>"; };
+ 28F903A306EE490C00D5ADA9 /* LispSymbol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LispSymbol.m; sourceTree = "<group>"; };
+ 28F9046C06F2305300D5ADA9 /* NSFileHandle+LispExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSFileHandle+LispExtensions.h"; sourceTree = "<group>"; };
+ 28F9046D06F2305300D5ADA9 /* NSFileHandle+LispExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSFileHandle+LispExtensions.m"; sourceTree = "<group>"; };
+ 2A37F4ACFDCFA73011CA2CEA /* World.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = World.m; sourceTree = "<group>"; };
+ 2A37F4AEFDCFA73011CA2CEA /* World.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = World.h; sourceTree = "<group>"; };
+ 2A37F4B0FDCFA73011CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 2A37F4B7FDCFA73011CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; };
+ 2A37F4BAFDCFA73011CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = English; path = English.lproj/Credits.rtf; sourceTree = "<group>"; };
+ 2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+ 2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+ 32DBCF750370BD2300C91783 /* Moxie_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Moxie_Prefix.pch; sourceTree = "<group>"; };
+ 8D15AC360486D014006FF6A4 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+ 8D15AC370486D014006FF6A4 /* Moxie.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Moxie.app; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D15AC330486D014006FF6A4 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */,
+ 28212A6005A6CEF600BEF07C /* Security.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */,
+ 28212A5F05A6CEF600BEF07C /* Security.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 1058C7A8FEA54F5311CA2CBB /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */,
+ 2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ 19C28FB0FE9D524F11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D15AC370486D014006FF6A4 /* Moxie.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 285A42B80965F2D700597D37 /* PlugIns */ = {
+ isa = PBXGroup;
+ children = (
+ 285A42BD0965F31400597D37 /* Ansi-Color.lisp */,
+ 285A42BE0965F31400597D37 /* Idle-Monster.lisp */,
+ 285A42BF0965F31400597D37 /* Logger.lisp */,
+ 285A42C00965F31400597D37 /* MXP.lisp */,
+ 285A42C10965F31400597D37 /* Numpad-Movement.lisp */,
+ 285A42C20965F31400597D37 /* Sample-Plugin.lisp */,
+ 285A42C30965F31400597D37 /* Telnet.lisp */,
+ );
+ path = PlugIns;
+ sourceTree = "<group>";
+ };
+ 285A43F80966147F00597D37 /* Lisp */ = {
+ isa = PBXGroup;
+ children = (
+ 285A44A1096615B700597D37 /* moxie */,
+ 285A44960966157F00597D37 /* openmcl */,
+ 2861E9DF0967A48A002A271F /* sbcl */,
+ 285A448A0966156A00597D37 /* clisp */,
+ 285A445B0966152600597D37 /* asdf */,
+ 285A4404096614D000597D37 /* startlisp */,
+ 285A4405096614D100597D37 /* init-template.lisp */,
+ 285A4406096614D100597D37 /* build-lisp-image.sh */,
+ );
+ path = Lisp;
+ sourceTree = "<group>";
+ };
+ 285A448A0966156A00597D37 /* clisp */ = {
+ isa = PBXGroup;
+ children = (
+ 285A448B0966156A00597D37 /* base */,
+ 285A448E0966156A00597D37 /* clisp */,
+ 285A448F0966156A00597D37 /* save-moxie-image.lisp */,
+ );
+ path = clisp;
+ sourceTree = "<group>";
+ };
+ 285A448B0966156A00597D37 /* base */ = {
+ isa = PBXGroup;
+ children = (
+ 285A448C0966156A00597D37 /* lisp.run */,
+ 285A448D0966156A00597D37 /* lispinit.mem */,
+ );
+ path = base;
+ sourceTree = "<group>";
+ };
+ 285A44960966157F00597D37 /* openmcl */ = {
+ isa = PBXGroup;
+ children = (
+ 28A2E1DB096985710005CC4E /* dppccl */,
+ 28A2E1DC096985710005CC4E /* dppccl.image */,
+ 285A44990966157F00597D37 /* openmcl */,
+ 285A449A0966157F00597D37 /* save-moxie-image.lisp */,
+ );
+ path = openmcl;
+ sourceTree = "<group>";
+ };
+ 285A44A1096615B700597D37 /* moxie */ = {
+ isa = PBXGroup;
+ children = (
+ 285A44A3096615B700597D37 /* compat */,
+ 285A44B6096615B700597D37 /* utils */,
+ 285A44A2096615B700597D37 /* clhs-lookup.lisp */,
+ 285A44AA096615B700597D37 /* default.lisp */,
+ 285A44AB096615B700597D37 /* hooks.lisp */,
+ 2861E88909674C62002A271F /* repl.lisp */,
+ 285A44AC096615B700597D37 /* Map_Sym.txt */,
+ 285A44AD096615B700597D37 /* Mop_Sym.txt */,
+ 285A44AE096615B700597D37 /* moxie.asd */,
+ 285A44B0096615B700597D37 /* moxie.lisp */,
+ 285A44B2096615B700597D37 /* package.lisp */,
+ 285A44BB096615B700597D37 /* world.lisp */,
+ );
+ path = moxie;
+ sourceTree = "<group>";
+ };
+ 285A44A3096615B700597D37 /* compat */ = {
+ isa = PBXGroup;
+ children = (
+ 285A44A4096615B700597D37 /* compat-clisp.lisp */,
+ 285A44A5096615B700597D37 /* compat-openmcl.lisp */,
+ 285A44A6096615B700597D37 /* compat-sbcl.fasl */,
+ 285A44A7096615B700597D37 /* compat-sbcl.lisp */,
+ 285A44A8096615B700597D37 /* semantic.cache */,
+ );
+ path = compat;
+ sourceTree = "<group>";
+ };
+ 285A44B6096615B700597D37 /* utils */ = {
+ isa = PBXGroup;
+ children = (
+ 285A44B7096615B700597D37 /* bjc-utils.fasl */,
+ 285A44B8096615B700597D37 /* bjc-utils.lisp */,
+ 285A44B9096615B700597D37 /* semantic.cache */,
+ );
+ path = utils;
+ sourceTree = "<group>";
+ };
+ 2861E9DF0967A48A002A271F /* sbcl */ = {
+ isa = PBXGroup;
+ children = (
+ 2861E9E80967A4F4002A271F /* sbcl */,
+ 2861E9E10967A48A002A271F /* sbcl.core */,
+ 2861E9E00967A48A002A271F /* save-moxie-image.lisp */,
+ );
+ path = sbcl;
+ sourceTree = "<group>";
+ };
+ 28FA94F806D5945700E4CC31 /* Cocoa Extensions */ = {
+ isa = PBXGroup;
+ children = (
+ 28396EFA05A444D000CE84B6 /* NSException+LiDebugging.m */,
+ 289962A405B67ADF00ADBE42 /* NSUserDefaults+Moxie.h */,
+ 289962A505B67ADF00ADBE42 /* NSUserDefaults+Moxie.m */,
+ 288A4F1805A13FBD004C4480 /* ScrollingTextView.h */,
+ 288A4F1905A13FBD004C4480 /* ScrollingTextView.m */,
+ 2827172406DAFDE200D3A4C2 /* NSAttributedString+Moxie.h */,
+ 2827172506DAFDE200D3A4C2 /* NSAttributedString+Moxie.m */,
+ 28D8059D06E9B04C002B3FAF /* NSString+LispExtensions.h */,
+ 28D8059E06E9B04C002B3FAF /* NSString+LispExtensions.m */,
+ 28F9039A06EE45AF00D5ADA9 /* NSArray+LispExtensions.h */,
+ 28F9039B06EE45AF00D5ADA9 /* NSArray+LispExtensions.m */,
+ 28F9046C06F2305300D5ADA9 /* NSFileHandle+LispExtensions.h */,
+ 28F9046D06F2305300D5ADA9 /* NSFileHandle+LispExtensions.m */,
+ 28C6947A06F55DC000341CDE /* NSDictionary+LispExtensions.h */,
+ 28C6947B06F55DC000341CDE /* NSDictionary+LispExtensions.m */,
+ 286C3B5C070A4B8900B6E2B1 /* NSNumber+LispExtensions.h */,
+ 286C3B5D070A4B8900B6E2B1 /* NSNumber+LispExtensions.m */,
+ );
+ name = "Cocoa Extensions";
+ sourceTree = "<group>";
+ };
+ 2A37F4AAFDCFA73011CA2CEA /* Moxie */ = {
+ isa = PBXGroup;
+ children = (
+ 2A37F4ABFDCFA73011CA2CEA /* Classes */,
+ 28FA94F806D5945700E4CC31 /* Cocoa Extensions */,
+ 285A43F80966147F00597D37 /* Lisp */,
+ 285A42B80965F2D700597D37 /* PlugIns */,
+ 28CDC68D06D0E4BB00D3A886 /* Moxie Help */,
+ 2A37F4AFFDCFA73011CA2CEA /* Other Sources */,
+ 2A37F4B8FDCFA73011CA2CEA /* Resources */,
+ 2A37F4C3FDCFA73011CA2CEA /* Frameworks */,
+ 19C28FB0FE9D524F11CA2CBB /* Products */,
+ );
+ name = Moxie;
+ sourceTree = "<group>";
+ };
+ 2A37F4ABFDCFA73011CA2CEA /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ 282B3E3105A3F8E300A3D04F /* MxWorldSettings.h */,
+ 282B3E3205A3F8E300A3D04F /* MxWorldSettings.m */,
+ 28B9CF2E05BA185800A72136 /* WorldController.h */,
+ 28B9CF2F05BA185800A72136 /* WorldController.m */,
+ 280FE68F06C8241600AA47DF /* LispREPLController.h */,
+ 280FE69006C8241600AA47DF /* LispREPLController.m */,
+ 284755EF06CF0EF90078110F /* LispREPL.h */,
+ 284755F006CF0EF90078110F /* LispREPL.m */,
+ 28D925D305B7B09100CC250A /* PreferencesController.h */,
+ 28D925D405B7B09100CC250A /* PreferencesController.m */,
+ 286D8C1405A4099100D7C2A2 /* WorldSettingsController.h */,
+ 286D8C1505A4099100D7C2A2 /* WorldSettingsController.m */,
+ 28360F9C05A7CEB100841A1E /* WorldStatusController.h */,
+ 28360F9D05A7CEB100841A1E /* WorldStatusController.m */,
+ 2A37F4AEFDCFA73011CA2CEA /* World.h */,
+ 2A37F4ACFDCFA73011CA2CEA /* World.m */,
+ 28F903A206EE490C00D5ADA9 /* LispSymbol.h */,
+ 28F903A306EE490C00D5ADA9 /* LispSymbol.m */,
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 2A37F4AFFDCFA73011CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 32DBCF750370BD2300C91783 /* Moxie_Prefix.pch */,
+ 2A37F4B0FDCFA73011CA2CEA /* main.m */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ 2A37F4B8FDCFA73011CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 28C36FBC05BFCB3000BAA9B7 /* Moxie.icns */,
+ 28406A1505D0DDB4008DEAD7 /* MoxieWorld.icns */,
+ 8D15AC360486D014006FF6A4 /* Info.plist */,
+ 089C165FFE840EACC02AAC07 /* InfoPlist.strings */,
+ 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */,
+ 2A37F4B6FDCFA73011CA2CEA /* MainMenu.nib */,
+ 280FE68706C7533F00AA47DF /* LispREPL.nib */,
+ 2857BB5D05BAA0F00053FE42 /* World.nib */,
+ 288D8A7005AD21A10058CC79 /* WorldSettings.nib */,
+ 28360F9905A7CE3300841A1E /* WorldSelector.nib */,
+ 2857BB5F05BAA0FB0053FE42 /* Preferences.nib */,
+ 2825D1AE05BE3ED300A9958B /* SettingNames.strings */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 2A37F4C3FDCFA73011CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */,
+ 1058C7A8FEA54F5311CA2CBB /* Other Frameworks */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 8D15AC280486D014006FF6A4 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D15AC290486D014006FF6A4 /* Moxie_Prefix.pch in Headers */,
+ 8D15AC2A0486D014006FF6A4 /* World.h in Headers */,
+ 288A4F1A05A13FBD004C4480 /* ScrollingTextView.h in Headers */,
+ 282B3E3305A3F8E300A3D04F /* MxWorldSettings.h in Headers */,
+ 286D8C1605A4099100D7C2A2 /* WorldSettingsController.h in Headers */,
+ 28360F9E05A7CEB100841A1E /* WorldStatusController.h in Headers */,
+ 289962A605B67ADF00ADBE42 /* NSUserDefaults+Moxie.h in Headers */,
+ 28D925D505B7B09100CC250A /* PreferencesController.h in Headers */,
+ 28B9CF3005BA185800A72136 /* WorldController.h in Headers */,
+ 280FE69106C8241600AA47DF /* LispREPLController.h in Headers */,
+ 284755F106CF0EF90078110F /* LispREPL.h in Headers */,
+ 2827172606DAFDE200D3A4C2 /* NSAttributedString+Moxie.h in Headers */,
+ 28D8059F06E9B04C002B3FAF /* NSString+LispExtensions.h in Headers */,
+ 28F9039C06EE45AF00D5ADA9 /* NSArray+LispExtensions.h in Headers */,
+ 28F903A406EE490C00D5ADA9 /* LispSymbol.h in Headers */,
+ 28F9046E06F2305300D5ADA9 /* NSFileHandle+LispExtensions.h in Headers */,
+ 28C6947C06F55DC000341CDE /* NSDictionary+LispExtensions.h in Headers */,
+ 286C3B5E070A4B8900B6E2B1 /* NSNumber+LispExtensions.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 8D15AC270486D014006FF6A4 /* Moxie */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 284BD82A08554DD700BAB8A9 /* Build configuration list for PBXNativeTarget "Moxie" */;
+ buildPhases = (
+ 8D15AC280486D014006FF6A4 /* Headers */,
+ 8D15AC300486D014006FF6A4 /* Sources */,
+ 8D15AC330486D014006FF6A4 /* Frameworks */,
+ 283A0309071246CD00ED28E5 /* ShellScript */,
+ 285A45950966170B00597D37 /* CopyFiles */,
+ 8D15AC2B0486D014006FF6A4 /* Resources */,
+ 28986CC9095E4CB700B5DC99 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Moxie;
+ productInstallPath = "$(HOME)/Applications";
+ productName = Moxie;
+ productReference = 8D15AC370486D014006FF6A4 /* Moxie.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 2A37F4A9FDCFA73011CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 284BD82E08554DD700BAB8A9 /* Build configuration list for PBXProject "Moxie" */;
+ compatibilityVersion = "Xcode 2.4";
+ hasScannedForEncodings = 1;
+ mainGroup = 2A37F4AAFDCFA73011CA2CEA /* Moxie */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 8D15AC270486D014006FF6A4 /* Moxie */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D15AC2B0486D014006FF6A4 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D15AC2C0486D014006FF6A4 /* Credits.rtf in Resources */,
+ 8D15AC2D0486D014006FF6A4 /* MainMenu.nib in Resources */,
+ 8D15AC2F0486D014006FF6A4 /* InfoPlist.strings in Resources */,
+ 288D8A7105AD21A10058CC79 /* WorldSettings.nib in Resources */,
+ 28360F9B05A7CE3300841A1E /* WorldSelector.nib in Resources */,
+ 2857BB5E05BAA0F00053FE42 /* World.nib in Resources */,
+ 2857BB6005BAA0FB0053FE42 /* Preferences.nib in Resources */,
+ 2825D1AF05BE3ED300A9958B /* SettingNames.strings in Resources */,
+ 28C36FBD05BFCB3000BAA9B7 /* Moxie.icns in Resources */,
+ 28406A1605D0DDB4008DEAD7 /* MoxieWorld.icns in Resources */,
+ 280FE68806C7533F00AA47DF /* LispREPL.nib in Resources */,
+ 28CDC68E06D0E4BB00D3A886 /* Moxie Help in Resources */,
+ 285A4408096614D100597D37 /* init-template.lisp in Resources */,
+ 285A44900966156A00597D37 /* lisp.run in Resources */,
+ 285A44BC096615B700597D37 /* clhs-lookup.lisp in Resources */,
+ 285A44BD096615B700597D37 /* compat-clisp.lisp in Resources */,
+ 285A44BE096615B700597D37 /* compat-openmcl.lisp in Resources */,
+ 285A44C0096615B700597D37 /* compat-sbcl.lisp in Resources */,
+ 285A44C3096615B700597D37 /* default.lisp in Resources */,
+ 285A44C4096615B700597D37 /* hooks.lisp in Resources */,
+ 285A44C5096615B700597D37 /* Map_Sym.txt in Resources */,
+ 285A44C6096615B700597D37 /* Mop_Sym.txt in Resources */,
+ 285A44C7096615B700597D37 /* moxie.asd in Resources */,
+ 285A44C9096615B700597D37 /* moxie.lisp in Resources */,
+ 285A44CB096615B700597D37 /* package.lisp in Resources */,
+ 285A44D0096615B700597D37 /* bjc-utils.lisp in Resources */,
+ 285A44D3096615B700597D37 /* world.lisp in Resources */,
+ 2861E88A09674C62002A271F /* repl.lisp in Resources */,
+ 2861E9E20967A48A002A271F /* save-moxie-image.lisp in Resources */,
+ 2861E9E30967A48A002A271F /* sbcl.core in Resources */,
+ 28A2E1DD096985710005CC4E /* dppccl in Resources */,
+ 28A2E1DE096985710005CC4E /* dppccl.image in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 283A0309071246CD00ED28E5 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 12;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "cd Lisp\n./build-lisp-image.sh\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D15AC300486D014006FF6A4 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D15AC310486D014006FF6A4 /* World.m in Sources */,
+ 8D15AC320486D014006FF6A4 /* main.m in Sources */,
+ 288A4F1B05A13FBD004C4480 /* ScrollingTextView.m in Sources */,
+ 282B3E3405A3F8E300A3D04F /* MxWorldSettings.m in Sources */,
+ 286D8C1705A4099100D7C2A2 /* WorldSettingsController.m in Sources */,
+ 28396EFB05A444D000CE84B6 /* NSException+LiDebugging.m in Sources */,
+ 28360F9F05A7CEB100841A1E /* WorldStatusController.m in Sources */,
+ 289962A705B67ADF00ADBE42 /* NSUserDefaults+Moxie.m in Sources */,
+ 28D925D605B7B09100CC250A /* PreferencesController.m in Sources */,
+ 28B9CF3105BA185800A72136 /* WorldController.m in Sources */,
+ 280FE69206C8241600AA47DF /* LispREPLController.m in Sources */,
+ 284755F206CF0EF90078110F /* LispREPL.m in Sources */,
+ 2827172706DAFDE200D3A4C2 /* NSAttributedString+Moxie.m in Sources */,
+ 28D805A006E9B04C002B3FAF /* NSString+LispExtensions.m in Sources */,
+ 28F9039D06EE45AF00D5ADA9 /* NSArray+LispExtensions.m in Sources */,
+ 28F903A506EE490C00D5ADA9 /* LispSymbol.m in Sources */,
+ 28F9046F06F2305300D5ADA9 /* NSFileHandle+LispExtensions.m in Sources */,
+ 28C6947D06F55DC000341CDE /* NSDictionary+LispExtensions.m in Sources */,
+ 286C3B5F070A4B8900B6E2B1 /* NSNumber+LispExtensions.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 089C165FFE840EACC02AAC07 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 089C1660FE840EACC02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+ 280FE68706C7533F00AA47DF /* LispREPL.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 280FE67F06C7533400AA47DF /* English */,
+ );
+ name = LispREPL.nib;
+ sourceTree = "<group>";
+ };
+ 2825D1AE05BE3ED300A9958B /* SettingNames.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 286FE9F205BE3B9E005A01FF /* English */,
+ );
+ name = SettingNames.strings;
+ sourceTree = "<group>";
+ };
+ 28360F9905A7CE3300841A1E /* WorldSelector.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 28360F9A05A7CE3300841A1E /* English */,
+ );
+ name = WorldSelector.nib;
+ sourceTree = "<group>";
+ };
+ 2857BB5D05BAA0F00053FE42 /* World.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 28A0F61C05B17A4700035E74 /* English */,
+ );
+ name = World.nib;
+ sourceTree = "<group>";
+ };
+ 2857BB5F05BAA0FB0053FE42 /* Preferences.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 28D925D105B7AF5E00CC250A /* English */,
+ );
+ name = Preferences.nib;
+ sourceTree = "<group>";
+ };
+ 288D8A7005AD21A10058CC79 /* WorldSettings.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 288A4EFA05A12FDE004C4480 /* English */,
+ );
+ name = WorldSettings.nib;
+ sourceTree = "<group>";
+ };
+ 28CDC68D06D0E4BB00D3A886 /* Moxie Help */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 28CDC67006D0E46A00D3A886 /* English */,
+ );
+ name = "Moxie Help";
+ sourceTree = "<group>";
+ };
+ 2A37F4B6FDCFA73011CA2CEA /* MainMenu.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 2A37F4B7FDCFA73011CA2CEA /* English */,
+ );
+ name = MainMenu.nib;
+ sourceTree = "<group>";
+ };
+ 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 2A37F4BAFDCFA73011CA2CEA /* English */,
+ );
+ name = Credits.rtf;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 284BD82B08554DD700BAB8A9 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ DEBUGGING_SYMBOLS = YES;
+ DYLIB_CURRENT_VERSION = "";
+ GCC_ALTIVEC_EXTENSIONS = YES;
+ GCC_DYNAMIC_NO_PIC = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_TRIGRAPHS = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_MODEL_CPU = "";
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Moxie_prefix.pch;
+ GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+ GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+ GCC_WARN_MISSING_PARENTHESES = YES;
+ GCC_WARN_PEDANTIC = NO;
+ GCC_WARN_SHADOW = YES;
+ GCC_WARN_SIGN_COMPARE = YES;
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = NO;
+ GCC_WARN_UNKNOWN_PRAGMAS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_PARAMETER = NO;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = "";
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ PRODUCT_NAME = Moxie;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ 284BD82C08554DD700BAB8A9 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEAD_CODE_STRIPPING = YES;
+ GCC_ALTIVEC_EXTENSIONS = YES;
+ GCC_DYNAMIC_NO_PIC = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_ENABLE_TRIGRAPHS = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Moxie_Prefix.pch;
+ GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ GCC_WARN_UNKNOWN_PRAGMAS = NO;
+ HEADER_SEARCH_PATHS = "";
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES;
+ PRODUCT_NAME = Moxie;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ 284BD82D08554DD700BAB8A9 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_ENABLE_TRIGRAPHS = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Moxie_Prefix.pch;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+ GCC_WARN_UNKNOWN_PRAGMAS = NO;
+ HEADER_SEARCH_PATHS = "";
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ PRODUCT_NAME = Moxie;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = app;
+ };
+ name = Default;
+ };
+ 284BD82F08554DD700BAB8A9 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_ALTIVEC_EXTENSIONS = YES;
+ GCC_AUTO_VECTORIZATION = YES;
+ };
+ name = Development;
+ };
+ 284BD83008554DD700BAB8A9 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_ALTIVEC_EXTENSIONS = YES;
+ GCC_AUTO_VECTORIZATION = YES;
+ };
+ name = Deployment;
+ };
+ 284BD83108554DD700BAB8A9 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_ALTIVEC_EXTENSIONS = YES;
+ GCC_AUTO_VECTORIZATION = YES;
+ };
+ name = Default;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 284BD82A08554DD700BAB8A9 /* Build configuration list for PBXNativeTarget "Moxie" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 284BD82B08554DD700BAB8A9 /* Development */,
+ 284BD82C08554DD700BAB8A9 /* Deployment */,
+ 284BD82D08554DD700BAB8A9 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ 284BD82E08554DD700BAB8A9 /* Build configuration list for PBXProject "Moxie" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 284BD82F08554DD700BAB8A9 /* Development */,
+ 284BD83008554DD700BAB8A9 /* Deployment */,
+ 284BD83108554DD700BAB8A9 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 2A37F4A9FDCFA73011CA2CEA /* Project object */;
+}
diff --git a/MoxieWorld.icns b/MoxieWorld.icns
new file mode 100644
index 0000000..738c515
--- /dev/null
+++ b/MoxieWorld.icns
Binary files differ
diff --git a/Moxie_Prefix.pch b/Moxie_Prefix.pch
new file mode 100644
index 0000000..338122d
--- /dev/null
+++ b/Moxie_Prefix.pch
@@ -0,0 +1,16 @@
+//
+// Prefix header for all source files of the 'Moxie' target in the 'Moxie' project
+//
+
+#ifdef __OBJC__
+ #import <Cocoa/Cocoa.h>
+ #import "NSAttributedString+Moxie.h"
+ #import "NSArray+LispExtensions.h"
+ #import "NSDictionary+LispExtensions.h"
+ #import "NSFileHandle+LispExtensions.h"
+ #import "NSNumber+LispExtensions.h"
+ #import "NSString+LispExtensions.h"
+ #import "NSUserDefaults+Moxie.h"
+ #import "LispSymbol.h"
+ #import "ScrollingTextView.h"
+#endif
diff --git a/MxWorldSettings.h b/MxWorldSettings.h
new file mode 100644
index 0000000..fb29ec5
--- /dev/null
+++ b/MxWorldSettings.h
@@ -0,0 +1,62 @@
+//
+// MxWorldSettings.h
+// Moxie
+//
+// Created by Brian Cully on Thu Jan 01 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#define MxWorldSettingsDidChangeNotification @"MxWorldSettingsDidChangeNotification"
+#define MxSettingName @"MxSettingName"
+#define MxSettingOldValue @"MxSettingOldValue"
+
+@interface MxWorldSettings : NSObject
+{
+ NSMutableDictionary *theSettings;
+}
++ (MxWorldSettings *)settingsWithDictionary: (NSDictionary *)aDictionary;
++ (MxWorldSettings *)settingsFromDefaults;
+- (NSString *)description;
+
+- (id)objectForKey: (NSString *)aKey;
+- (void)setObject: (id)anObject forKey: (NSString *)aKey;
+- (void)removeObjectForKey: (NSString *)aKey;
+
+- (BOOL)boolForKey: (NSString *)aKey;
+- (void)setBool: (BOOL)aValue forKey: (NSString *)aKey;
+- (NSString *)stringForKey: (NSString *)aKey;
+@end
+
+@interface MxWorldSettings (MoxieSettings)
+- (NSString *)hostname;
+- (void)setHostname: (NSString *)aHostname;
+- (NSNumber *)port;
+- (void)setPort: (NSNumber *)aPort;
+- (BOOL)connectOnOpen;
+- (void)setConnectOnOpen: (BOOL)shouldConnect;
+- (NSString *)character;
+- (void)setCharacter: (NSString *)aName;
+- (NSString *)password;
+- (void)setPassword: (NSString *)aPassword;
+- (NSColor *)textColor;
+- (void)setTextColor: (NSColor *)aColor;
+- (NSColor *)backgroundColor;
+- (void)setBackgroundColor: (NSColor *)aColor;
+- (NSFont *)font;
+- (void)setFont: (NSFont *)aFont;
+- (BOOL)loggingEnabled;
+- (void)setLoggingEnabled: (BOOL)isEnabled;
+- (BOOL)logTimeStamp;
+- (void)setLogTimeStamp: (BOOL)isEnabled;
+- (BOOL)logInput;
+- (void)setLogInput: (BOOL)isEnabled;
+
+- (NSRect)windowFrame;
+- (void)setWindowFrame: (NSRect)aFrame;
+- (unsigned int)inputViewSize;
+- (void)setInputViewSize: (unsigned int)aSize;
+@end
+
+@interface NSUserDefaults (MxWorldSettingsAdditions)
+- (void)setDefaultsFromWorldSettings: (MxWorldSettings *)someSettings;
+@end \ No newline at end of file
diff --git a/MxWorldSettings.m b/MxWorldSettings.m
new file mode 100644
index 0000000..47b3817
--- /dev/null
+++ b/MxWorldSettings.m
@@ -0,0 +1,505 @@
+//
+// MxWorldSettings.m
+// Moxie
+//
+// Created by Brian Cully on Thu Jan 01 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "MxWorldSettings.h"
+
+#include <Security/SecKeychain.h>
+#include <Security/SecKeychainItem.h>
+#include <Security/SecAccess.h>
+#include <Security/SecTrustedApplication.h>
+#include <Security/SecACL.h>
+
+#define MxHostnameSettingName ":HOSTNAME"
+#define MxPortSettingName ":PORT"
+
+@implementation MxWorldSettings
+- (NSMutableDictionary *)settings
+{
+ return theSettings;
+}
+
+- (void)setSettings: (NSMutableDictionary *)someSettings
+{
+ [someSettings retain];
+ [theSettings release];
+ theSettings = someSettings;
+}
+
++ (MxWorldSettings *)settingsWithDictionary: (NSDictionary *)aDictionary
+{
+ MxWorldSettings *result;
+
+ result = [[[MxWorldSettings alloc] init] autorelease];
+ [result setSettings: [NSMutableDictionary dictionaryWithDictionary: aDictionary]];
+ return result;
+}
+
++ (MxWorldSettings *)settingsFromDefaults
+{
+ MxWorldSettings *tmpSettings;
+ NSUserDefaults *defaults;
+
+ tmpSettings = [[[MxWorldSettings alloc] init] autorelease];
+ defaults = [NSUserDefaults standardUserDefaults];
+ if ([defaults objectForKey: @":CONNECT-ON-OPEN"])
+ [tmpSettings setConnectOnOpen: [[defaults objectForKey: @":CONNECT-ON-OPEN"] boolValue]];
+ else
+ [tmpSettings setConnectOnOpen: NO];
+
+ if ([defaults objectForKey: @":TEXT-COLOR"])
+ [tmpSettings setTextColor:
+ [NSUnarchiver unarchiveObjectWithData: [defaults objectForKey: @":TEXT-COLOR"]]];
+ else
+ [tmpSettings setTextColor: [NSColor blackColor]];
+
+ if ([defaults objectForKey: @":BACKGROUND-COLOR"])
+ [tmpSettings setBackgroundColor:
+ [NSUnarchiver unarchiveObjectWithData: [defaults objectForKey: @":BACKGROUND-COLOR"]]];
+ else
+ [tmpSettings setBackgroundColor: [NSColor whiteColor]];
+
+ if ([defaults objectForKey: @":FONT"])
+ [tmpSettings setFont:
+ [NSUnarchiver unarchiveObjectWithData: [defaults objectForKey: @":FONT"]]];
+ else
+ [tmpSettings setFont: [NSFont fontWithName: @"Monaco" size: 10.0]];
+
+ [tmpSettings setLoggingEnabled: [defaults boolForKey: @":LOGGING-ENABLED"]];
+ [tmpSettings setLogTimeStamp: [defaults boolForKey: @":LOG-TIME-STAMPS"]];
+ [tmpSettings setLogInput: [defaults boolForKey: @":LOG-INPUT"]];
+
+ return tmpSettings;
+}
+
+- (id)init
+{
+ self = [super init];
+ if (self) {
+ [self setSettings: [NSMutableDictionary dictionary]];
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [self setSettings: nil];
+
+ [super dealloc];
+}
+
+- (NSString *)description
+{
+ return [[self settings] description];
+}
+
+- (id)objectForKey: (NSString *)aKey
+{
+ id value;
+
+ value = [[self settings] objectForKey: [LispSymbol symbolNamed: aKey]];
+ if ([value isKindOfClass: [NSArray class]] && [value count] == 1)
+ return [value objectAtIndex: 0];
+ return value;
+}
+
+- (void)removeObjectForKey: (NSString *)aKey
+{
+ id oldObject;
+
+ oldObject = [[self settings] objectForKey: [LispSymbol symbolNamed: aKey]];
+ if (oldObject) {
+ NSDictionary *userInfo;
+ NSNotificationCenter *defaultCenter;
+
+ userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ aKey, MxSettingName, oldObject, MxSettingOldValue, nil];
+
+ [[self settings] removeObjectForKey: aKey];
+
+ defaultCenter = [NSNotificationCenter defaultCenter];
+ [defaultCenter postNotificationName: MxWorldSettingsDidChangeNotification
+ object: self
+ userInfo: userInfo];
+
+ }
+}
+
+- (void)setObject: (id)anObject forKey: (NSString *)aKey
+{
+ if (anObject) {
+ NSDictionary *userInfo;
+ NSNotificationCenter *defaultCenter;
+ id oldObject;
+
+ userInfo = nil;
+ oldObject = [[self settings] objectForKey: [LispSymbol symbolNamed: aKey]];
+ if (!(oldObject == anObject || [oldObject isEqual: anObject])) {
+ if (oldObject)
+ userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ aKey, MxSettingName, oldObject, MxSettingOldValue, nil];
+
+ [[self settings] setObject: anObject forKey: [LispSymbol symbolNamed: aKey]];
+
+ defaultCenter = [NSNotificationCenter defaultCenter];
+ [defaultCenter postNotificationName: MxWorldSettingsDidChangeNotification
+ object: self
+ userInfo: userInfo];
+ }
+ } else
+ [self removeObjectForKey: aKey];
+}
+
+- (BOOL)boolForKey: (NSString *)aKey
+{
+ id value;
+
+ value = [self objectForKey: aKey];
+ if ([value isKindOfClass: [NSArray class]]) {
+ if ([value count] == 0)
+ return NO;
+ value = [value objectAtIndex: 0];
+ }
+
+ if ([value respondsToSelector: @selector(boolValue)]) {
+ NSInvocation *invocation;
+ NSMethodSignature *sig;
+
+ sig = [value methodSignatureForSelector: @selector(boolValue)];
+ if ([sig methodReturnLength] == sizeof(BOOL)) {
+ BOOL rc;
+
+ invocation = [NSInvocation invocationWithMethodSignature: sig];
+ [invocation setTarget: value];
+ [invocation setSelector: @selector(boolValue)];
+ [invocation invoke];
+ [invocation getReturnValue: &rc];
+
+ return rc;
+ }
+ }
+ return NO;
+}
+
+- (void)setBool: (BOOL)aValue forKey: (NSString *)aKey
+{
+ [self setObject: aValue ? [LispSymbol symbolT] : [LispSymbol symbolNIL]
+ forKey: aKey];
+}
+
+- (NSString *)stringForKey: (NSString *)aKey
+{
+ NSString *value;
+
+ value = [[[self settings] objectForKey: aKey] objectAtIndex: 0];
+ if ([value respondsToSelector: @selector(stringValue)])
+ return [value performSelector: @selector(stringValue)];
+ else
+ return value;
+}
+@end
+
+@implementation MxWorldSettings (MoxieSettings)
+- (NSString *)hostname
+{
+ return [self stringForKey: @":HOSTNAME"];
+}
+
+- (void)setHostname: (NSString *)aHostname
+{
+ [self setObject: aHostname forKey: @":HOSTNAME"];
+}
+
+- (NSNumber *)port
+{
+ return [NSNumber numberWithInt: [[self objectForKey: @":PORT"] intValue]];
+}
+
+- (void)setPort: (NSNumber *)aPort
+{
+ [self setObject: aPort forKey: @":PORT"];
+}
+
+- (BOOL)connectOnOpen
+{
+ return [self boolForKey: @":CONNECT-ON-OPEN"];
+}
+
+- (void)setConnectOnOpen: (BOOL)shouldConnect
+{
+ [self setBool: shouldConnect forKey: @":CONNECT-ON-OPEN"];
+}
+
+- (NSString *)character
+{
+ return [self stringForKey: @":CHARACTER"];
+}
+
+- (void)setCharacter: (NSString *)aName
+{
+ [self setObject: aName forKey: @":CHARACTER"];
+}
+
+- (NSString *)password
+{
+ return [self stringForKey: @":PASSWORD"];
+}
+
+- (void)setPassword: (NSString *)aPassword
+{
+ [self setObject: aPassword forKey: @":PASSWORD"];
+}
+
+/*
+- (NSString *)password
+{
+ if ([[self characterName] length] > 0 &&
+ [[self hostname] length] > 0 &&
+ [self port]) {
+ const char *serverName, *accountName;
+ void *pwData;
+ UInt32 pwLen;
+
+ serverName = [[self hostname] UTF8String];
+ accountName = [[self characterName] UTF8String];
+ if (SecKeychainFindInternetPassword(NULL, strlen(serverName), serverName, 0, NULL,
+ strlen(accountName), accountName, 0, NULL,
+ [[self port] unsignedLongValue],
+ kSecProtocolTypeTelnet, kSecAuthenticationTypeDefault,
+ &pwLen, &pwData, NULL) == noErr) {
+ NSString *password;
+
+ // We found a password in the keychain.
+ password = [NSString stringWithUTF8String: pwData];
+ return password;
+ }
+ }
+
+ return nil;
+}
+
+- (void)setPassword: (NSString *)aPassword
+{
+ if ([[self characterName] length] > 0 &&
+ [[self hostname] length] > 0 &&
+ [self port]) {
+ const char *serverName, *accountName, *pwData;
+ UInt32 pwLen;
+
+ serverName = [[self hostname] UTF8String];
+ accountName = [[self characterName] UTF8String];
+ pwData = [aPassword UTF8String];
+ pwLen = strlen(pwData);
+ SecKeychainAddInternetPassword(NULL, strlen(serverName), serverName, 0, NULL,
+ strlen(accountName), accountName, 0, NULL,
+ [[self port] unsignedLongValue],
+ kSecProtocolTypeTelnet, kSecAuthenticationTypeDefault,
+ pwLen, pwData, NULL);
+ }
+}
+*/
+
+- (NSColor *)textColor
+{
+ NSArray *rgbaVals;
+
+ rgbaVals = [self objectForKey: @":TEXT-COLOR"];
+ if (rgbaVals) {
+ return [NSColor colorWithCalibratedRed: [[rgbaVals objectAtIndex: 0] floatValue]
+ green: [[rgbaVals objectAtIndex: 1] floatValue]
+ blue: [[rgbaVals objectAtIndex: 2] floatValue]
+ alpha: [[rgbaVals objectAtIndex: 3] floatValue]];
+ }
+ return nil;
+}
+
+- (void)setTextColor: (NSColor *)aColor
+{
+ if (aColor == nil)
+ [self removeObjectForKey: @":TEXT-COLOR"];
+ else {
+ NSColor *rgbColor;
+ float r, g, b, a;
+
+ rgbColor = [aColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
+ [rgbColor getRed: &r green: &g blue: &b alpha: &a];
+ [self setObject: [NSArray arrayWithObjects:
+ [NSNumber numberWithFloat: r], [NSNumber numberWithFloat: g], [NSNumber numberWithFloat: b],
+ [NSNumber numberWithFloat: a], nil]
+ forKey: @":TEXT-COLOR"];
+ }
+}
+
+- (NSColor *)backgroundColor
+{
+ NSArray *rgbaVals;
+
+ rgbaVals = [self objectForKey: @":BACKGROUND-COLOR"];
+ if (rgbaVals) {
+ return [NSColor colorWithCalibratedRed: [[rgbaVals objectAtIndex: 0] floatValue]
+ green: [[rgbaVals objectAtIndex: 1] floatValue]
+ blue: [[rgbaVals objectAtIndex: 2] floatValue]
+ alpha: [[rgbaVals objectAtIndex: 3] floatValue]];
+ }
+ return nil;
+}
+
+- (void)setBackgroundColor: (NSColor *)aColor
+{
+ if (aColor == nil)
+ [self removeObjectForKey: @":BACKGROUND-COLOR"];
+ else {
+ NSColor *rgbColor;
+ float r, g, b, a;
+
+ rgbColor = [aColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
+ [rgbColor getRed: &r green: &g blue: &b alpha: &a];
+ [self setObject: [NSArray arrayWithObjects:
+ [NSNumber numberWithFloat: r], [NSNumber numberWithFloat: g], [NSNumber numberWithFloat: b],
+ [NSNumber numberWithFloat: a], nil]
+ forKey: @":BACKGROUND-COLOR"];
+ }
+}
+
+- (NSData *)textColorData
+{
+ return [NSArchiver archivedDataWithRootObject: [self textColor]];
+}
+
+- (void)setTextColorData: (NSData *)colorData
+{
+ return [self setTextColor: [NSUnarchiver unarchiveObjectWithData: colorData]];
+}
+
+- (NSData *)backgroundColorData
+{
+ return [NSArchiver archivedDataWithRootObject: [self backgroundColor]];
+}
+
+- (void)setBackgroundColorData: (NSData *)colorData
+{
+ return [self setBackgroundColor: [NSUnarchiver unarchiveObjectWithData: colorData]];
+}
+
+- (NSString *)fontDisplayName
+{
+ return [[self font] displayName];
+}
+
+// XXX: defaults probably shouldn't be here.
+- (NSFont *)font
+{
+ NSArray *fontInfo;
+
+ fontInfo = [self objectForKey: @":FONT"];
+ if (fontInfo && [fontInfo count] == 2) {
+ NSFont *result;
+
+ result = [NSFont fontWithName: [fontInfo objectAtIndex: 0]
+ size: [[fontInfo objectAtIndex: 1] floatValue]];
+ if (!result)
+ result = [NSFont fontWithName: @"Monaco" size: 10.0];
+ return result;
+ }
+ return nil;
+}
+
+- (void)setFont: (NSFont *)aFont
+{
+ if (aFont == nil)
+ [self removeObjectForKey: @":FONT"];
+ else {
+ NSArray *value = [NSArray arrayWithObjects:
+ [aFont fontName], [NSNumber numberWithFloat: [aFont pointSize]], nil];
+
+ [self setObject: value forKey: @":FONT"];
+ }
+}
+
+- (BOOL)loggingEnabled
+{
+ return [self boolForKey: @":LOGGING-ENABLED"];
+}
+
+- (void)setLoggingEnabled: (BOOL)isEnabled
+{
+ [self setBool: isEnabled forKey: @":LOGGING-ENABLED"];
+}
+
+- (BOOL)logTimeStamp
+{
+ return [self boolForKey: @":LOG-TIME-STAMP"];
+}
+
+- (void)setLogTimeStamp: (BOOL)isEnabled
+{
+ [self setBool: isEnabled forKey: @":LOG-TIME-STAMP"];
+}
+
+- (BOOL)logInput
+{
+ return [self boolForKey: @":LOG-INPUT"];
+}
+
+- (void)setLogInput: (BOOL)isEnabled
+{
+ [self setBool: isEnabled forKey: @":LOG-INPUT"];
+}
+
+- (NSRect)windowFrame
+{
+ NSArray *windowSize, *windowOrigin;
+
+ windowSize = [self objectForKey: @":WINDOW-SIZE"];
+ windowOrigin = [self objectForKey: @":WINDOW-ORIGIN"];
+ if (!windowSize || ! windowOrigin ||
+ [windowSize count] != 2 || [windowOrigin count] != 2)
+ return NSMakeRect(-1, -1, -1, -1);
+
+ return NSMakeRect([[windowOrigin objectAtIndex: 0] floatValue],
+ [[windowOrigin objectAtIndex: 1] floatValue],
+ [[windowSize objectAtIndex: 0] floatValue],
+ [[windowSize objectAtIndex: 1] floatValue]);
+}
+
+- (void)setWindowFrame: (NSRect)aFrame
+{
+ NSArray *origin = [NSArray arrayWithObjects:
+ [LispSymbol symbolNamed: [NSString stringWithFormat: @"%f", aFrame.origin.x]],
+ [LispSymbol symbolNamed: [NSString stringWithFormat: @"%f", aFrame.origin.y]], nil];
+ NSArray *size = [NSArray arrayWithObjects:
+ [LispSymbol symbolNamed: [NSString stringWithFormat: @"%f", aFrame.size.width]],
+ [LispSymbol symbolNamed: [NSString stringWithFormat: @"%f", aFrame.size.height]], nil];
+
+ [self setObject: origin forKey: @":WINDOW-ORIGIN"];
+ [self setObject: size forKey: @":WINDOW-SIZE"];
+}
+
+- (unsigned int)inputViewSize
+{
+ return [[self objectForKey: @":INPUT-VIEW-SIZE"] intValue];
+}
+
+- (void)setInputViewSize: (unsigned int)aSize
+{
+ [self setObject: [LispSymbol symbolNamed: [NSString stringWithFormat: @"%u", aSize]]
+ forKey: @":INPUT-VIEW-SIZE"];
+}
+@end
+
+@implementation NSUserDefaults (MxWorldSettingsAdditions)
+- (void)setDefaultsFromWorldSettings: (MxWorldSettings *)someSettings
+{
+ [self setObject: [someSettings objectForKey: @":CONNECT-ON-OPEN"] forKey: @":CONNECT-ON-OPEN"];
+ [self setObject: [someSettings objectForKey: @":TEXT-COLOR"] forKey: @":TEXT-COLOR"];
+ [self setObject: [someSettings objectForKey: @":BACKGROUND-COLOR"] forKey: @":BACKGROUND-COLOR"];
+ [self setObject: [someSettings objectForKey: @":FONT"] forKey: @":FONT"];
+ [self setObject: [someSettings objectForKey: @":LOGGING-ENABLED"] forKey: @":LOGGING-ENABLED"];
+ [self setObject: [someSettings objectForKey: @":LOG-TIME-STAMP"] forKey: @":LOG-TIME-STAMP"];
+ [self setObject: [someSettings objectForKey: @":LOG-INPUT"] forKey: @":LOG-INPUT"];
+}
+@end \ No newline at end of file
diff --git a/NSArray+LispExtensions.h b/NSArray+LispExtensions.h
new file mode 100644
index 0000000..d03fe7d
--- /dev/null
+++ b/NSArray+LispExtensions.h
@@ -0,0 +1,13 @@
+//
+// NSArray+LispExtensions.h
+// Moxie
+//
+// Created by Brian Cully on Tue Sep 07 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSArray (LispExtensions)
+- (NSString *)lispForm;
+@end \ No newline at end of file
diff --git a/NSArray+LispExtensions.m b/NSArray+LispExtensions.m
new file mode 100644
index 0000000..308516e
--- /dev/null
+++ b/NSArray+LispExtensions.m
@@ -0,0 +1,36 @@
+//
+// NSArray+LispExtensions.m
+// Moxie
+//
+// Created by Brian Cully on Tue Sep 07 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "NSArray+LispExtensions.h"
+
+@implementation NSArray (LispExtensions)
+- (NSString *)lispForm
+{
+ NSEnumerator *objectEnum;
+ NSMutableString *result;
+ id obj;
+
+ if ([self count] == 0)
+ return @"NIL";
+
+ objectEnum = [self objectEnumerator];
+ result = [NSMutableString stringWithString: @"("];
+ obj = [objectEnum nextObject];
+ while (obj != nil) {
+ NSString *form;
+
+ form = [obj lispForm];
+ [result appendString: form];
+ obj = [objectEnum nextObject];
+ if (obj)
+ [result appendString: @" "];
+ }
+ [result appendString: @")"];
+ return result;
+}
+@end \ No newline at end of file
diff --git a/NSAttributedString+Moxie.h b/NSAttributedString+Moxie.h
new file mode 100644
index 0000000..f3b0823
--- /dev/null
+++ b/NSAttributedString+Moxie.h
@@ -0,0 +1,14 @@
+//
+// NSAttributedString+Moxie.h
+// Moxie
+//
+// Created by Brian Cully on Tue Aug 24 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+@interface NSAttributedString (Moxie)
++ (id)attributedStringWithString: (NSString *)aString;
++ (id)attributedStringWithString: (NSString *)aString
+ attributes: (NSDictionary *)attributes;
++ (NSAttributedString *)attributedStringWithForm: (NSArray *)aForm
+ defaultAttributes: (NSDictionary *)defaultAttributes;
+@end \ No newline at end of file
diff --git a/NSAttributedString+Moxie.m b/NSAttributedString+Moxie.m
new file mode 100644
index 0000000..4837c0b
--- /dev/null
+++ b/NSAttributedString+Moxie.m
@@ -0,0 +1,192 @@
+//
+// NSAttributedString+Moxie.m
+// Moxie
+//
+// Created by Brian Cully on Tue Aug 24 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "NSAttributedString+Moxie.h"
+
+@implementation NSAttributedString (Moxie)
++ (id)attributedStringWithString: (NSString *)aString
+{
+ NSAttributedString *retval;
+
+ retval = [[self alloc] initWithString: aString];
+ return [retval autorelease];
+}
+
++ (id)attributedStringWithString: (NSString *)aString
+ attributes: (NSDictionary *)attributes
+{
+ NSAttributedString *retval;
+
+ retval = [[self alloc] initWithString: aString
+ attributes: attributes];
+ return [retval autorelease];
+}
+
++ (NSAttributedString *)attributedStringWithForm: (NSArray *)aForm
+ defaultAttributes: (NSDictionary *)defaultAttributes
+{
+ NSArray *rangeForms, *attrRange;
+ NSEnumerator *rangeEnum;
+ NSMutableAttributedString *result;
+ NSString *string;
+
+ if ([aForm count] < 2)
+ return nil;
+
+ string = [aForm objectAtIndex: 0];
+ rangeForms = [aForm objectAtIndex: 1];
+
+ result = [NSMutableAttributedString attributedStringWithString: string attributes: defaultAttributes];
+ rangeEnum = [rangeForms objectEnumerator];
+ while ((attrRange = [rangeEnum nextObject]) != nil) {
+ NSArray *tmpForm;
+ NSDictionary *attrDict;
+ NSMutableDictionary *myAttributes;
+ NSRange range;
+
+ attrDict = [NSDictionary dictionaryWithAlist: attrRange];
+ myAttributes = [NSMutableDictionary dictionary];
+
+ // Should handle :BOLD as well.
+ tmpForm = [attrDict objectForKey: @":RANGE"];
+ if (tmpForm)
+ range = NSMakeRange([[tmpForm objectAtIndex: 0] intValue], [[tmpForm objectAtIndex: 1] intValue]);
+ else
+ range = NSMakeRange(0, [string length]);
+
+ tmpForm = [attrDict objectForKey: @":FONT"];
+ if (tmpForm) {
+ NSFont *font;
+
+ font = [NSFont fontWithName: [tmpForm objectAtIndex: 0]
+ size: [[tmpForm objectAtIndex: 1] doubleValue]];
+ if (font)
+ [myAttributes setObject: font forKey: NSFontAttributeName];
+ else
+ NSLog(@"WARNING: Couldn't find font named: %@.", [tmpForm objectAtIndex: 0]);
+ }
+
+ tmpForm = [attrDict objectForKey: @":LINK"];
+ if (tmpForm) {
+ [myAttributes setObject: [NSURL URLWithString: [tmpForm objectAtIndex: 0]]
+ forKey: NSLinkAttributeName];
+ [myAttributes setObject: [NSCursor pointingHandCursor]
+ forKey: NSCursorAttributeName];
+ }
+
+ tmpForm = [attrDict objectForKey: @":ITALIC"];
+ if (tmpForm) {
+ [myAttributes setObject: [NSNumber numberWithFloat: [[tmpForm objectAtIndex: 0] doubleValue]]
+ forKey: NSObliquenessAttributeName];
+ }
+
+ tmpForm = [attrDict objectForKey: @":SUPER"];
+ if (tmpForm) {
+ [myAttributes setObject: [NSNumber numberWithInt: [[tmpForm objectAtIndex: 0] intValue]]
+ forKey: NSSuperscriptAttributeName];
+ }
+
+ tmpForm = [attrDict objectForKey: @":UNDERLINE"];
+ if (tmpForm) {
+ [myAttributes setObject: [NSNumber numberWithInt: [[tmpForm objectAtIndex: 0] intValue]]
+ forKey: NSUnderlineStyleAttributeName];
+ }
+
+ tmpForm = [attrDict objectForKey: @":STRIKETHROUGH"];
+ if (tmpForm) {
+ [myAttributes setObject: [NSNumber numberWithInt: [[tmpForm objectAtIndex: 0] intValue]]
+ forKey: NSStrikethroughStyleAttributeName];
+ }
+
+ tmpForm = [attrDict objectForKey: @":COLOR"];
+ if (tmpForm) {
+ int r, g, b;
+
+ r = [[tmpForm objectAtIndex: 0] intValue];
+ g = [[tmpForm objectAtIndex: 1] intValue];
+ b = [[tmpForm objectAtIndex: 2] intValue];
+ [myAttributes setObject: [NSColor colorWithCalibratedRed: (r * 1.0) / 255
+ green: (g * 1.0) / 255
+ blue: (b * 1.0) / 255
+ alpha: 1.0]
+ forKey: NSForegroundColorAttributeName];
+ }
+
+ tmpForm = [attrDict objectForKey: @":BACKGROUND-COLOR"];
+ if (tmpForm) {
+ NSColor *bgColor;
+ int r, g, b;
+ float a;
+
+ r = [[tmpForm objectAtIndex: 0] intValue];
+ g = [[tmpForm objectAtIndex: 1] intValue];
+ b = [[tmpForm objectAtIndex: 2] intValue];
+ a = 1.0;
+ bgColor = [defaultAttributes objectForKey: NSBackgroundColorAttributeName];
+ if (bgColor) {
+ a = [bgColor alphaComponent];
+ NSLog(@"DEBUG:\t alpha: %f", a);
+ }
+ [myAttributes setObject: [NSColor colorWithCalibratedRed: (r * 1.0) / 255
+ green: (g * 1.0) / 255
+ blue: (b * 1.0) / 255
+ alpha: a]
+ forKey: NSBackgroundColorAttributeName];
+ }
+
+
+ // These two attributes are broken, because they rely on information we might
+ // not have. To whit, the FG and BG colors of the open world.
+ tmpForm = [attrDict objectForKey: @":BOLD"];
+ if (tmpForm) {
+ NSColor *preColor;
+ float r, g, b, a;
+
+ preColor = [myAttributes objectForKey: NSForegroundColorAttributeName];
+ if (preColor == nil)
+ preColor = [defaultAttributes objectForKey: NSForegroundColorAttributeName];
+ if (preColor) {
+ [preColor getRed: &r green: &g blue: &b alpha: &a];
+ r += 0.3; g += 0.3; b += 0.3;
+ r = MIN(r, 1.0);
+ g = MIN(g, 1.0);
+ b = MIN(b, 1.0);
+ [myAttributes setObject: [NSColor colorWithCalibratedRed: r green: g blue: b alpha: a]
+ forKey: NSForegroundColorAttributeName];
+ }
+ }
+
+ tmpForm = [attrDict objectForKey: @":INVERSE"];
+ if (tmpForm) {
+ NSColor *fgColor, *bgColor;
+
+ fgColor = [myAttributes objectForKey: NSForegroundColorAttributeName];
+ if (fgColor == nil)
+ fgColor = [defaultAttributes objectForKey: NSForegroundColorAttributeName];
+ bgColor = [myAttributes objectForKey: NSBackgroundColorAttributeName];
+ if (bgColor == nil)
+ bgColor = [defaultAttributes objectForKey: NSBackgroundColorAttributeName];
+
+ [fgColor retain];
+ [bgColor retain];
+ if (fgColor && bgColor) {
+ [myAttributes setObject: bgColor
+ forKey: NSForegroundColorAttributeName];
+ [myAttributes setObject: fgColor
+ forKey: NSBackgroundColorAttributeName];
+ }
+ [fgColor release];
+ [bgColor release];
+ }
+
+ [result addAttributes: myAttributes range: range];
+ }
+
+ return result;
+}
+@end \ No newline at end of file
diff --git a/NSDictionary+LispExtensions.h b/NSDictionary+LispExtensions.h
new file mode 100644
index 0000000..c5948eb
--- /dev/null
+++ b/NSDictionary+LispExtensions.h
@@ -0,0 +1,15 @@
+//
+// NSDictionary+LispExtensions.h
+// Moxie
+//
+// Created by Brian Cully on Mon Sep 13 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSDictionary (LispExtensions)
++ (NSMutableDictionary *)dictionaryWithAlist: (NSArray *)attrList;
+
+- (NSString *)lispForm;
+@end \ No newline at end of file
diff --git a/NSDictionary+LispExtensions.m b/NSDictionary+LispExtensions.m
new file mode 100644
index 0000000..ee0c01f
--- /dev/null
+++ b/NSDictionary+LispExtensions.m
@@ -0,0 +1,54 @@
+//
+// NSDictionary+LispExtensions.m
+// Moxie
+//
+// Created by Brian Cully on Mon Sep 13 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "NSDictionary+LispExtensions.h"
+
+@implementation NSDictionary (LispExtensions)
+/*
+ * Assoc Lists are arrays of the form ((KEY0 VALUES0) (KEY1 VALUES1) ... (KEYN VALUESN)).
+ * Useful for lisp, not for Cocoa where we can use NSDictionary.
+ */
++ (NSMutableDictionary *)dictionaryWithAlist: (NSArray *)attrList
+{
+ NSEnumerator *objEnum;
+ NSMutableDictionary *result;
+ NSArray *row;
+
+ result = [NSMutableDictionary dictionary];
+ objEnum = [attrList objectEnumerator];
+ while ((row = [objEnum nextObject]) != nil) {
+ NSArray *subarray;
+ NSRange valueRange;
+ id key;
+
+ key = [row objectAtIndex: 0];
+ valueRange = NSMakeRange(1, [row count] - 1);
+ subarray = [row subarrayWithRange: valueRange];
+ [result setObject: subarray forKey: key];
+ }
+ return result;
+}
+
+- (NSString *)lispForm
+{
+ NSEnumerator *keyEnum;
+ NSMutableString *result;
+ id key;
+
+ result = [NSMutableString stringWithString: @"("];
+ keyEnum = [self keyEnumerator];
+ while ((key = [keyEnum nextObject]) != nil) {
+ id value;
+
+ value = [self objectForKey: key];
+ [result appendFormat: @"(%@ . %@)", [key lispForm], [value lispForm]];
+ }
+ [result appendString: @")"];
+ return result;
+}
+@end \ No newline at end of file
diff --git a/NSException+LiDebugging.m b/NSException+LiDebugging.m
new file mode 100644
index 0000000..a4addd4
--- /dev/null
+++ b/NSException+LiDebugging.m
@@ -0,0 +1,22 @@
+//
+// NSException+LiDebugging.m
+// Liaison
+//
+// Created by Brian Cully on Sun Sep 14 2003.
+// Copyright (c) 2003 Brian Cully. All rights reserved.
+//
+
+@interface LiException : NSException
+@end
+
+@implementation LiException
++ (void)load
+{
+ [self poseAsClass: [NSException class]];
+}
+
+- (void)raise
+{
+ [super raise];
+}
+@end
diff --git a/NSFileHandle+LispExtensions.h b/NSFileHandle+LispExtensions.h
new file mode 100644
index 0000000..f4cfa46
--- /dev/null
+++ b/NSFileHandle+LispExtensions.h
@@ -0,0 +1,13 @@
+//
+// NSFileHandle+LispExtensions.h
+// Moxie
+//
+// Created by Brian Cully on Fri Sep 10 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSFileHandle (LispExtensions)
+- (id)readLispForm;
+@end \ No newline at end of file
diff --git a/NSFileHandle+LispExtensions.m b/NSFileHandle+LispExtensions.m
new file mode 100644
index 0000000..87e4059
--- /dev/null
+++ b/NSFileHandle+LispExtensions.m
@@ -0,0 +1,139 @@
+//
+// NSFileHandle+LispExtensions.m
+// Moxie
+//
+// Created by Brian Cully on Fri Sep 10 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "NSFileHandle+LispExtensions.h"
+
+@implementation NSFileHandle (LispExtensions)
+- (void)alertDidEndSelector: (NSAlert *)alert
+ returnCode: (int)returnCode
+ contextInfo: (void *)contextInfo
+{
+ [NSApp terminate: self];
+}
+
+- (unichar)readNextCharFromBufferAndMove: (BOOL)moveFilePointer
+{
+ // XXX: SO not thread safe.
+ static NSString *buffer = nil;
+ static unsigned int bindex = 0;
+ unichar c;
+
+ if (buffer == nil || bindex >= [buffer length]) {
+ NSData *formData;
+
+ formData = [self availableData];
+ if ([formData length] == 0) {
+ [[NSException exceptionWithName: @"REPLDeath" reason: @"The plug in subsystem died." userInfo: nil] raise];
+ } else {
+ if (buffer)
+ [buffer release];
+ buffer = [[NSString alloc] initWithCString: [formData bytes]
+ length: [formData length]];
+ bindex = 0;
+ }
+ }
+ c = [buffer characterAtIndex: bindex];
+ if (moveFilePointer)
+ bindex++;
+ return c;
+}
+
+- (NSString *)readLispString
+{
+ NSMutableString *result;
+ unichar c;
+
+ result = [NSMutableString string];
+ c = [self readNextCharFromBufferAndMove: YES];
+ while ((c = [self readNextCharFromBufferAndMove: YES]) != '"') {
+ if (c == '\\')
+ c = [self readNextCharFromBufferAndMove: YES];
+ [result appendFormat: @"%c", c];
+ }
+ return result;
+}
+
+- (LispSymbol *)readLispSymbol
+{
+ NSMutableString *formString;
+ unichar c;
+
+ formString = [NSMutableString string];
+ c = [self readNextCharFromBufferAndMove: NO];
+ while (c != '(' && c != ')' &&
+ [[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember: c] == NO) {
+ // Handle string lengths.
+ if (c == '"') {
+ [formString appendFormat: @"\"%@\"", [self readLispString]];
+ } else {
+ c = [self readNextCharFromBufferAndMove: YES];
+ [formString appendFormat: @"%c", c];
+ }
+
+ // Get the next char without swallowing, so we can see if
+ // we use it before we swallow.
+ c = [self readNextCharFromBufferAndMove: NO];
+ }
+ return [LispSymbol symbolNamed: formString];
+}
+
+- (id)readLispAtom
+{
+ id result;
+ unichar c;
+
+ c = [self readNextCharFromBufferAndMove: NO];
+ if (c == '"') {
+ // Parse as a string.
+ result = [self readLispString];
+ } else {
+ result = [self readLispSymbol];
+ }
+ return result;
+}
+
+- (id)readLispForm
+{
+ id result;
+ unichar c;
+
+ result = nil;
+
+ // Advance past white space and unmatched parens.
+ c = [self readNextCharFromBufferAndMove: NO];
+ while ([[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember: c] ||
+ c == ')') {
+ [self readNextCharFromBufferAndMove: YES];
+ c = [self readNextCharFromBufferAndMove: NO];
+ }
+
+ // Begin form parsing.
+ if (c == '(') {
+ NSMutableArray *form;
+
+ // Recursively parse form until closing paren.
+ [self readNextCharFromBufferAndMove: YES];
+ form = [NSMutableArray array];
+ while ([self readNextCharFromBufferAndMove: NO] != ')') {
+ id obj;
+
+ obj = [self readLispForm];
+ if ([obj isEqual: @"."] == NO) {
+ if ([obj isEqual: @"NIL"])
+ [form addObject: [NSArray array]];
+ else
+ [form addObject: obj];
+ }
+ }
+ [self readNextCharFromBufferAndMove: YES];
+ result = form;
+ } else
+ result = [self readLispAtom];
+ return result;
+}
+@end \ No newline at end of file
diff --git a/NSNumber+LispExtensions.h b/NSNumber+LispExtensions.h
new file mode 100644
index 0000000..fbe79a0
--- /dev/null
+++ b/NSNumber+LispExtensions.h
@@ -0,0 +1,13 @@
+//
+// NSNumber+LispExtensions.h
+// Moxie
+//
+// Created by Brian Cully on Tue Sep 28 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSNumber (LispExtensions)
+- (NSString *)lispForm;
+@end \ No newline at end of file
diff --git a/NSNumber+LispExtensions.m b/NSNumber+LispExtensions.m
new file mode 100644
index 0000000..af59018
--- /dev/null
+++ b/NSNumber+LispExtensions.m
@@ -0,0 +1,16 @@
+//
+// NSNumber+LispExtensions.m
+// Moxie
+//
+// Created by Brian Cully on Tue Sep 28 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "NSNumber+LispExtensions.h"
+
+@implementation NSNumber (LispExtensions)
+- (NSString *)lispForm
+{
+ return [self description];
+}
+@end \ No newline at end of file
diff --git a/NSString+LispExtensions.h b/NSString+LispExtensions.h
new file mode 100644
index 0000000..9187e43
--- /dev/null
+++ b/NSString+LispExtensions.h
@@ -0,0 +1,13 @@
+//
+// NSString+LispExtensions.h
+// Moxie
+//
+// Created by Brian Cully on Sat Sep 04 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSString (LispExtensions)
+- (NSString *)lispForm;
+@end \ No newline at end of file
diff --git a/NSString+LispExtensions.m b/NSString+LispExtensions.m
new file mode 100644
index 0000000..4d36e52
--- /dev/null
+++ b/NSString+LispExtensions.m
@@ -0,0 +1,40 @@
+//
+// NSString+LispExtensions.m
+// Moxie
+//
+// Created by Brian Cully on Sat Sep 04 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "NSString+LispExtensions.h"
+
+@implementation NSString (LispExtensions)
+- (NSString *)lispForm
+{
+ NSMutableString *result;
+ NSRange subrange;
+ unsigned int len, i;
+
+ result = [NSMutableString stringWithString: @"\""];
+ len = [self length];
+ subrange.location = 0;
+ for (i = 0; i < len; i++) {
+ switch ([self characterAtIndex: i]) {
+ case '\\':
+ case '\"':
+ subrange.length = i - subrange.location;
+ [result appendString: [self substringWithRange: subrange]];
+ [result appendString: @"\\"];
+ subrange.location = i;
+ break;
+ }
+ }
+ if (subrange.location < len) {
+ subrange.length = len - subrange.location;
+ [result appendString: [self substringWithRange: subrange]];
+ }
+ [result appendString: @"\""];
+
+ return result;
+}
+@end \ No newline at end of file
diff --git a/NSUserDefaults+Moxie.h b/NSUserDefaults+Moxie.h
new file mode 100644
index 0000000..2d68b3f
--- /dev/null
+++ b/NSUserDefaults+Moxie.h
@@ -0,0 +1,52 @@
+//
+// NSUserDefaults+Moxie.h
+// Moxie
+//
+// Created by Brian Cully on Thu Jan 15 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSUserDefaults (MoxieDefaults)
+- (BOOL)startupShowWorldSelector;
+- (BOOL)selectorIsFloating;
+- (BOOL)selectorIsAlwaysVisible;
+- (NSArray *)startupWorlds;
+- (void)setStartupWorlds: (NSArray *)someWorlds;
+- (NSString *)logDirectory;
+
+- (NSData *)connectedColorData;
+- (void)setConnectedColorData: (NSData *)colorData;
+- (NSData *)disconnectedColorData;
+- (void)setDisconnectedColorData: (NSData *)colorData;
+- (NSData *)recentActivityColorData;
+- (void)setRecentActivityColorData: (NSData *)colorData;
+
+- (NSData *)REPLInputTextColorData;
+- (void)setREPLInputTextColorData: (NSData *)colorData;
+- (NSData *)REPLOutputTextColorData;
+- (void)setREPLOutputTextColorData: (NSData *)colorData;
+- (NSData *)REPLPromptColorData;
+- (void)setREPLPromptColorData: (NSData *)colorData;
+- (NSData *)REPLReturnValueColorData;
+- (void)setREPLReturnValueColorData: (NSData *)colorData;
+- (NSData *)REPLBackgroundColorData;
+- (void)setREPLBackgroundColorData: (NSData *)colorData;
+- (NSData *)REPLFontData;
+- (void)setREPLFontData: (NSData *)fontData;
+@end
+
+
+@interface NSUserDefaults (MoxieTranslators)
+- (NSColor *)connectedColor;
+- (NSColor *)disconnectedColor;
+- (NSColor *)recentActivityColor;
+- (NSColor *)REPLInputTextColor;
+- (NSColor *)REPLOutputTextColor;
+- (NSColor *)REPLPromptColor;
+- (NSColor *)REPLReturnValueColor;
+- (NSColor *)REPLBackgroundColor;
+- (NSFont *)REPLFont;
+- (NSString *)REPLFontName;
+@end \ No newline at end of file
diff --git a/NSUserDefaults+Moxie.m b/NSUserDefaults+Moxie.m
new file mode 100644
index 0000000..1d3f609
--- /dev/null
+++ b/NSUserDefaults+Moxie.m
@@ -0,0 +1,269 @@
+//
+// NSUserDefaults+Moxie.m
+// Moxie
+//
+// Created by Brian Cully on Thu Jan 15 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+@implementation NSUserDefaults (MoxieDefaults)
+- (BOOL)startupShowWorldSelector
+{
+ if ([self objectForKey: @"startup.showWorldSelector"])
+ return [self boolForKey: @"startup.showWorldSelector"];
+ else
+ return NO;
+}
+
+- (BOOL)selectorIsFloating
+{
+ if ([self objectForKey: @"selector.alwaysOnTop"])
+ return [self boolForKey: @"selector.alwaysOnTop"];
+ else
+ return NO;
+}
+
+- (BOOL)selectorIsAlwaysVisible
+{
+ if ([self objectForKey: @"selector.alwaysVisible"])
+ return [self boolForKey: @"selector.alwaysVisible"];
+ else
+ return NO;
+}
+
+- (NSArray *)startupWorlds
+{
+ return [self arrayForKey: @"startup.worlds"];
+}
+
+- (void)setStartupWorlds: (NSArray *)someWorlds
+{
+ [self setObject: someWorlds forKey: @"startup.worlds"];
+}
+
+- (NSString *)logDirectory
+{
+ return [@"~/Documents/Moxie Transcripts/" stringByExpandingTildeInPath];
+}
+
+- (NSData *)connectedColorData
+{
+ NSData *tmpData;
+
+ tmpData = [self dataForKey: @"selector.colorConnected"];
+ if (tmpData == nil)
+ tmpData = [NSArchiver archivedDataWithRootObject: [NSColor blackColor]];
+ return tmpData;
+}
+
+- (void)setConnectedColorData: (NSData *)colorData
+{
+ if (colorData == nil)
+ [self removeObjectForKey: @"selector.colorConnected"];
+ else
+ [self setObject: colorData forKey: @"selector.colorConnected"];
+}
+
+- (NSData *)disconnectedColorData
+{
+ NSData *tmpData;
+
+ tmpData = [self dataForKey: @"selector.colorDisconnected"];
+ if (tmpData == nil)
+ tmpData = [NSArchiver archivedDataWithRootObject: [NSColor blackColor]];
+ return tmpData;
+}
+
+- (void)setDisconnectedColorData: (NSData *)colorData
+{
+ if (colorData == nil)
+ [self removeObjectForKey: @"selector.colorDisconnected"];
+ else
+ [self setObject: colorData forKey: @"selector.colorDisconnected"];
+}
+
+- (NSData *)recentActivityColorData
+{
+ NSData *tmpData;
+
+ tmpData = [self dataForKey: @"selector.colorNewActivity"];
+ if (tmpData == nil)
+ tmpData = [NSArchiver archivedDataWithRootObject: [NSColor blackColor]];
+ return tmpData;
+}
+
+- (void)setRecentActivityColorData: (NSData *)colorData
+{
+ if (colorData == nil)
+ [self removeObjectForKey: @"selector.colorNewActivity"];
+ else
+ [self setObject: colorData forKey: @"selector.colorNewActivity"];
+}
+
+- (NSData *)REPLInputTextColorData
+{
+ NSData *tmpData;
+
+ tmpData = [self dataForKey: @"REPL.inputTextColor"];
+ if (tmpData == nil)
+ tmpData = [NSArchiver archivedDataWithRootObject:
+ [NSColor blackColor]];
+ return tmpData;
+}
+
+- (void)setREPLInputTextColorData: (NSData *)colorData
+{
+ if (colorData == nil)
+ [self removeObjectForKey: @"REPL.inputTextColor"];
+ else
+ [self setObject: colorData forKey: @"REPL.inputTextColor"];
+}
+
+- (NSData *)REPLOutputTextColorData
+{
+ NSData *tmpData;
+
+ tmpData = [self dataForKey: @"REPL.outputTextColor"];
+ if (tmpData == nil)
+ tmpData = [NSArchiver archivedDataWithRootObject:
+ [NSColor blackColor]];
+ return tmpData;
+}
+
+- (void)setREPLOutputTextColorData: (NSData *)colorData
+{
+ if (colorData == nil)
+ [self removeObjectForKey: @"REPL.outputTextColor"];
+ else
+ [self setObject: colorData forKey: @"REPL.outputTextColor"];
+}
+
+- (NSData *)REPLPromptColorData
+{
+ NSData *tmpData;
+
+ tmpData = [self dataForKey: @"REPL.promptColor"];
+ if (tmpData == nil)
+ tmpData = [NSArchiver archivedDataWithRootObject:
+ [NSColor blackColor]];
+ return tmpData;
+}
+
+- (void)setREPLPromptColorData: (NSData *)colorData
+{
+ if (colorData == nil)
+ [self removeObjectForKey: @"REPL.promptColor"];
+ else
+ [self setObject: colorData forKey: @"REPL.promptColor"];
+}
+
+- (NSData *)REPLReturnValueColorData
+{
+ NSData *tmpData;
+
+ tmpData = [self dataForKey: @"REPL.resultColor"];
+ if (tmpData == nil)
+ tmpData = [NSArchiver archivedDataWithRootObject:
+ [NSColor whiteColor]];
+ return tmpData;
+}
+
+- (void)setREPLReturnValueColorData: (NSData *)colorData
+{
+ if (colorData == nil)
+ [self removeObjectForKey: @"REPL.resultColor"];
+ else
+ [self setObject: colorData forKey: @"REPL.resultColor"];
+}
+
+- (NSData *)REPLBackgroundColorData
+{
+ NSData *tmpData;
+
+ tmpData = [self dataForKey: @"REPL.backgroundColor"];
+ if (tmpData == nil)
+ tmpData = [NSArchiver archivedDataWithRootObject:
+ [NSColor whiteColor]];
+ return tmpData;
+}
+
+- (void)setREPLBackgroundColorData: (NSData *)colorData
+{
+ if (colorData == nil)
+ [self removeObjectForKey: @"REPL.backgroundColor"];
+ else
+ [self setObject: colorData forKey: @"REPL.backgroundColor"];
+}
+
+- (NSData *)REPLFontData
+{
+ NSData *tmpData;
+
+ tmpData = [self dataForKey: @"REPL.font"];
+ if (tmpData == nil)
+ tmpData = [NSArchiver archivedDataWithRootObject:
+ [NSFont userFixedPitchFontOfSize: 0]];
+ return tmpData;
+}
+
+- (void)setREPLFontData: (NSData *)fontData;
+{
+ if (fontData == nil)
+ [self removeObjectForKey: @"REPL.font"];
+ else
+ [self setObject: fontData forKey: @"REPL.font"];
+}
+@end
+
+@implementation NSUserDefaults (MoxieTranslators)
+- (NSColor *)recentActivityColor
+{
+ return [NSUnarchiver unarchiveObjectWithData: [self recentActivityColorData]];
+}
+
+- (NSColor *)connectedColor
+{
+ return [NSUnarchiver unarchiveObjectWithData: [self connectedColorData]];
+}
+
+- (NSColor *)disconnectedColor
+{
+ return [NSUnarchiver unarchiveObjectWithData: [self disconnectedColorData]];
+}
+
+- (NSColor *)REPLInputTextColor
+{
+ return [NSUnarchiver unarchiveObjectWithData: [self REPLInputTextColorData]];
+}
+
+- (NSColor *)REPLOutputTextColor
+{
+ return [NSUnarchiver unarchiveObjectWithData: [self REPLOutputTextColorData]];
+}
+
+- (NSColor *)REPLPromptColor
+{
+ return [NSUnarchiver unarchiveObjectWithData: [self REPLPromptColorData]];
+}
+
+- (NSColor *)REPLReturnValueColor
+{
+ return [NSUnarchiver unarchiveObjectWithData: [self REPLReturnValueColorData]];
+}
+
+- (NSColor *)REPLBackgroundColor
+{
+ return [NSUnarchiver unarchiveObjectWithData: [self REPLBackgroundColorData]];
+}
+
+- (NSFont *)REPLFont
+{
+ return [NSUnarchiver unarchiveObjectWithData: [self REPLFontData]];
+}
+
+- (NSString *)REPLFontName
+{
+ return [NSString stringWithFormat: @"%@ %0.1f", [[self REPLFont] fontName],
+ [[self REPLFont] pointSize]];
+}
+@end \ No newline at end of file
diff --git a/PlugIns/Ansi-Color.lisp b/PlugIns/Ansi-Color.lisp
new file mode 100644
index 0000000..d6f64af
--- /dev/null
+++ b/PlugIns/Ansi-Color.lisp
@@ -0,0 +1,145 @@
+(defpackage ansi-color
+ (:use :cl :cl-user :moxie :bjc-utils))
+(in-package :ansi-color)
+
+(defvar *black-color* '(0 0 0))
+(defvar *red-color* '(200 0 0))
+(defvar *green-color* '(0 200 0))
+(defvar *yellow-color* '(200 200 0))
+(defvar *blue-color* '(0 0 200))
+(defvar *purple-color* '(200 0 200))
+(defvar *cyan-color* '(0 200 200))
+(defvar *white-color* '(200 200 200))
+
+(defun active-attributes (&optional (world *world*))
+ (world-var 'active-attrs world))
+
+(defsetf active-attributes (&optional (world '*world*)) (values)
+ `(setf (world-var 'active-attrs ,world) ,values))
+
+(defun add-attribute (attribute)
+ (remove-attribute (car attribute))
+ (setf (active-attributes)
+ (cons attribute (active-attributes))))
+
+(defun attribute-value (attribute)
+ (cdr (assoc attribute (active-attributes))))
+
+(defun remove-attribute (attribute)
+ (setf (active-attributes)
+ (remove attribute (active-attributes) :key #'car)))
+
+(defun set-attribute-for-code (code)
+ (case code
+ (0 (when (active-attributes)
+ (setf (active-attributes) nil)))
+ (1 (add-attribute '(:bold 1)))
+ (3 (add-attribute '(:italic 0.25)))
+ (4 (add-attribute '(:underline 1)))
+ (7 (add-attribute '(:inverse 1)))
+ (9 (add-attribute '(:strikethrough 1)))
+ (22 (remove-attribute :bold))
+ (23 (remove-attribute :italic))
+ (24 (remove-attribute :underline))
+ (27 (remove-attribute :inverse))
+ (29 (remove-attribute :strikethrough))
+ (30 (add-attribute (cons :color *black-color*)))
+ (31 (add-attribute (cons :color *red-color*)))
+ (32 (add-attribute (cons :color *green-color*)))
+ (33 (add-attribute (cons :color *yellow-color*)))
+ (34 (add-attribute (cons :color *blue-color*)))
+ (35 (add-attribute (cons :color *purple-color*)))
+ (36 (add-attribute (cons :color *cyan-color*)))
+ (37 (add-attribute (cons :color *white-color*)))
+ (39 (remove-attribute :color))
+ (40 (add-attribute (cons :background-color *black-color*)))
+ (41 (add-attribute (cons :background-color *red-color*)))
+ (42 (add-attribute (cons :background-color *green-color*)))
+ (43 (add-attribute (cons :background-color *yellow-color*)))
+ (44 (add-attribute (cons :background-color *blue-color*)))
+ (45 (add-attribute (cons :background-color *purple-color*)))
+ (46 (add-attribute (cons :background-color *cyan-color*)))
+ (47 (add-attribute (cons :background-color *white-color*)))
+ (49 (remove-attribute :background-color))))
+
+(defun end-of-ansi-position (string start)
+ "Returns the position in STRING after START where an ANSI escape sequence ends."
+ (position-if (lambda (c)
+ (or (and (char< c #\z) (char> c #\a))
+ (and (char< c #\Z) (char> c #\A))))
+ string :start start))
+
+(defun colorize-ansi-string (string)
+ (declare (ignore keywords))
+ (let* (*print-pretty*
+ (string (concatenate 'string
+ (aif (world-var 'cached-escape)
+ (progn
+ (setf (world-var 'cached-escape) nil)
+ it)
+ "")
+ (if (stringp string) string (car string))))
+ (scanlen (length string))
+ (attr-index 0)
+ (attributes nil)
+ (skipped-chars 0)
+ (result (with-output-to-string (stripped-string)
+ (let ((final-scan (do* ((i 0 (1+ i)))
+ ((>= i scanlen) i)
+ (when (eql (elt string i) #\Escape)
+ (aif (end-of-ansi-position string i)
+ (progn
+ ;; When we have a code, we should dump the last
+ ;; set of attributes.
+ (princ (subseq string attr-index i) stripped-string)
+ (awhen (active-attributes)
+ (push (cons (make-range (- attr-index skipped-chars)
+ (- i attr-index))
+ (active-attributes)) attributes))
+
+ ;; Grab the code sequence, break it up, and set the
+ ;; attributes for it.
+ (let ((code-str (subseq string (+ i 2) it)))
+ (flet ((code-in-bounds (start end)
+ (let ((start (or start 0))
+ (end (or end (length code-str))))
+ (set-attribute-for-code (or (and (= start end) 0)
+ (parse-integer (subseq code-str start end)
+ :junk-allowed t))))))
+ ;; Coalesce attributes split up by semicolons.
+ (do* ((last-pos 0 (1+ semi-pos))
+ (semi-pos (position #\; code-str)
+ (position #\; code-str :start last-pos))
+ (code (code-in-bounds last-pos semi-pos)
+ (code-in-bounds last-pos semi-pos)))
+ ((null semi-pos)))))
+ (setf skipped-chars (+ skipped-chars (- (1+ it) i)))
+ (setf i it)
+ (setf attr-index (1+ i)))
+ ;; We have an escape, but can't parse it.
+ ;; save it in a buffer for later use.
+ (progn
+ (setf (world-var 'cached-escape) (subseq string i scanlen))
+ (setf scanlen i)))))))
+ ;; Append final attributes and string.
+ (when (<= attr-index scanlen)
+ (princ (subseq string attr-index scanlen) stripped-string)
+ (push (cons (make-range (- attr-index skipped-chars) (- scanlen attr-index))
+ (active-attributes)) attributes))))))
+ (if attributes
+ (apply #'make-attributed-string result attributes)
+ result)))
+
+(defun test-output (&rest vars)
+ (with-output-to-string (s)
+ (dolist (v vars)
+ (format t "first char: ~S, var ~S~%" (elt v 0) v)
+ (princ v s))))
+
+(defun printer-test ()
+ (test-output "string-1" (format nil "string-2~%")))
+
+(defun make-ansi-sequence ()
+ (format nil "~C[~A;~Am~A ~C[~A;~A;~AmAnd another" #\Escape 0 31 "A sequence" #\Escape 1 22 37))
+
+(add-hook 'colorize-ansi-string :output-from-server-hook)
diff --git a/PlugIns/Idle-Monster.lisp b/PlugIns/Idle-Monster.lisp
new file mode 100644
index 0000000..827813a
--- /dev/null
+++ b/PlugIns/Idle-Monster.lisp
@@ -0,0 +1,10 @@
+(defpackage idle-monster
+ (:use :cl :cl-user :moxie :bjc-utils))
+(in-package :idle-monster)
+
+(defun send-idle-cmd (&rest args)
+ (declare (ignore args))
+ "Sends a command to the current world when idle."
+ (print-to-world *world* (format nil "Idle!~%")))
+
+;(add-hook 'send-idle-cmd :timer-hook) \ No newline at end of file
diff --git a/PlugIns/Logger.lisp b/PlugIns/Logger.lisp
new file mode 100644
index 0000000..f456fc3
--- /dev/null
+++ b/PlugIns/Logger.lisp
@@ -0,0 +1,73 @@
+;;; -*- Lisp -*-
+;;; $Id: Logger.lisp 20 2005-12-27 15:21:23Z bjc $
+
+(defpackage default-logger
+ (:use :cl :cl-user :moxie :bjc-utils))
+(in-package :default-logger)
+
+(defvar *default-log-directory* (merge-pathnames "Documents/Moxie Transcripts/"
+ (user-homedir-pathname)))
+
+(defun start-logging-hook (&optional arg)
+ (let ((log-filen (car (world-var :log-file-path))))
+ (setf (world-var :log-stream)
+ (open log-filen :direction :output
+ :if-exists :append :if-does-not-exist :create))
+ (awhen (world-var :log-stream)
+ (format it "[Logging started on: ~A]~%" (format-timestamp (get-universal-time)))
+ (finish-output it)
+ (print-to-world *world* (format nil "Now logging to: ~A~%" log-filen)))))
+
+(defun stop-logging-hook (&optional arg)
+ (awhen (world-var :log-stream)
+ (format it "[Logging ended on: ~A]~%" (format-timestamp (get-universal-time)))
+ (finish-output it)
+ (close it)
+ (setf (world-var :log-stream) nil)
+ (print-to-world *world* (format nil "Logging is now disabled.~%"))))
+
+(defun log-output (string)
+ "Log STRING to DEFAULT-FILE-NAME."
+ (awhen (world-var :log-stream)
+ (let* (*print-pretty*
+ (string (if (stringp string) string (car string))))
+ (format it "~A ~A" (format-timestamp (get-universal-time)) string)
+ (finish-output it))))
+
+(defun log-input (string)
+ "Log STRING to DEFAULT-FILE-NAME."
+ (awhen (world-var :log-stream)
+ (let* (*print-pretty*
+ (string (if (stringp string) string (car string))))
+ (format it "~A -> ~A~%" (format-timestamp (get-universal-time)) string)
+ (finish-output it))))
+
+(defun format-timestamp (universal-time)
+ (multiple-value-bind (sec min hour date mon year day daylight-p zone)
+ (decode-universal-time universal-time)
+ (format nil "[~D-~2,'0D-~2,'0D ~2,'0D:~2,'0D:~2,'0D]" year mon date hour min sec)))
+
+;;
+;; Convienence aliases
+;;
+(defun logger-alias (arg)
+ (if (> (length arg) 0)
+ (start-logging-to arg)
+ (if (world-var :log-stream)
+ (disable-logging *world*)
+ (enable-logging *world*)))
+ nil)
+
+(defun start-logging-to (filename)
+ (awhen (world-var :log-stream)
+ (disable-logging *world*))
+ (setf (world-var :log-file-path)
+ (list (merge-pathnames filename *default-log-directory*)))
+ (enable-logging *world*))
+
+(add-hook 'start-logging-hook :start-logging-hook)
+(add-hook 'stop-logging-hook :stop-logging-hook)
+(add-hook 'log-output :output-from-server-hook)
+(add-hook 'log-input :input-from-client-hook)
+
+(add-keyword 'logger-alias "log") \ No newline at end of file
diff --git a/PlugIns/MXP.lisp b/PlugIns/MXP.lisp
new file mode 100644
index 0000000..8694608
--- /dev/null
+++ b/PlugIns/MXP.lisp
@@ -0,0 +1,54 @@
+;; -*- Lisp -*-
+;; $Id: MXP.lisp 20 2005-12-27 15:21:23Z bjc $
+
+(defpackage mxp
+ (:use :cl :cl-user :moxie :bjc-utils))
+(in-package :mxp)
+
+(defun parse-mxp-args (string)
+ (let ((last-space 0))
+ (loop as next-space = (position-if (lambda (c)
+ (or (eql c #\Space) (eql c #\Tab) (eql c #\Newline)))
+ string
+ :start last-space)
+ collect (if next-space
+ (prog1
+ (subseq string last-space next-space)
+ (setf last-space (1+ next-space)))
+ (subseq string last-space (length string)))
+ while next-space)))
+
+;; We have to get the world name here, which isn't being set
+;; for some reason in the world-opened-hook.
+;;
+;; Update: the reason is that world-opened-hook doesn't have
+;; anything on it. We need to create a function to make the
+;; alist in args the environment for the world, and figure out
+;; where to put it.
+;;
+;; Built in plugin via runhook?
+;; Do we want runhook at all, since this is so low-level we may
+;; not want people messing with it.
+(defun play-sound (args)
+ (format t "msp dir: ~S~%" (merge-pathnames (car args)
+ (merge-pathnames "Library/Moxie/MSP/"
+ (user-homedir-pathname)))))
+
+(defun dispatch-mxp-command (string)
+ (let* ((strlen (length string))
+ (lp-pos (position #\( string))
+ (rp-pos (and lp-pos (position #\) string)))
+ (cmd (subseq string 0 (or lp-pos strlen)))
+ (args (and rp-pos (parse-mxp-args (subseq string (1+ lp-pos) rp-pos)))))
+ (cond ((or (string= cmd "MUSIC") (string= cmd "SOUND"))
+ (play-sound args))
+ (t (format t "Found MXP cmd: ~S, args: ~S~%" cmd args)))
+ (subseq string (1+ rp-pos))))
+
+(defun scan-mxp-data (string)
+ (let ((string (if (stringp string) string (car string))))
+ (when (and (> (length string) 2)
+ (string= (subseq string 0 2) "!!"))
+ (dispatch-mxp-command (subseq string 2)))))
+
+(add-hook 'scan-mxp-data :output-from-server-hook)
diff --git a/PlugIns/Numpad-Movement.lisp b/PlugIns/Numpad-Movement.lisp
new file mode 100644
index 0000000..5924b68
--- /dev/null
+++ b/PlugIns/Numpad-Movement.lisp
@@ -0,0 +1,45 @@
+;;; Keystroke macros to use the keypad for directional movement.
+;; $Id: Numpad-Movement.lisp 20 2005-12-27 15:21:23Z bjc $
+(defpackage :numpad-movement
+ (:use :cl :cl-user :moxie :bjc-utils))
+(in-package :numpad-movement)
+
+(defun keystroke-north (&rest keywords)
+ (send-to-mux *world* (format nil "north~%")))
+(defun keystroke-south (&rest keywords)
+ (send-to-mux *world* (format nil "south~%")))
+(defun keystroke-east (&rest keywords)
+ (send-to-mux *world* (format nil "east~%")))
+(defun keystroke-west (&rest keywords)
+ (send-to-mux *world* (format nil "west~%")))
+(defun keystroke-northeast (&rest keywords)
+ (send-to-mux *world* (format nil "northeast~%")))
+(defun keystroke-northwest (&rest keywords)
+ (send-to-mux *world* (format nil "northwest~%")))
+(defun keystroke-southeast (&rest keywords)
+ (send-to-mux *world* (format nil "southeast~%")))
+(defun keystroke-southwest (&rest keywords)
+ (send-to-mux *world* (format nil "southwest~%")))
+(defun keystroke-up (&rest keywords)
+ (send-to-mux *world* (format nil "up~%")))
+(defun keystroke-down (&rest keywords)
+ (send-to-mux *world* (format nil "down~%")))
+
+(defun clear-screen-fun (&optional args)
+ (declare (ignore arg))
+ (format t "clear-screen ~S~%" *world*)
+ (clear-screen *world*)
+ nil)
+
+(add-keystroke-macro 'keystroke-north :numpad-8)
+(add-keystroke-macro 'keystroke-south :numpad-2)
+(add-keystroke-macro 'keystroke-east :numpad-6)
+(add-keystroke-macro 'keystroke-west :numpad-4)
+(add-keystroke-macro 'keystroke-northeast :numpad-9)
+(add-keystroke-macro 'keystroke-northwest :numpad-7)
+(add-keystroke-macro 'keystroke-southeast :numpad-3)
+(add-keystroke-macro 'keystroke-southwest :numpad-1)
+(add-keystroke-macro 'keystroke-up :numpad-+)
+(add-keystroke-macro 'keystroke-down :numpad--)
+(add-keystroke-macro 'clear-screen-fun :clear)
+(add-keyword 'clear-screen-fun "clear") \ No newline at end of file
diff --git a/PlugIns/Sample-Plugin.lisp b/PlugIns/Sample-Plugin.lisp
new file mode 100644
index 0000000..434cc8d
--- /dev/null
+++ b/PlugIns/Sample-Plugin.lisp
@@ -0,0 +1,60 @@
+#-cl-ppcre (asdf:operate 'asdf:load-op :cl-ppcre)
+(defpackage sample-plugin
+ (:use :cl :cl-user :moxie :bjc-utils :cl-ppcre))
+(in-package :sample-plugin)
+
+(defvar *page-highlight-attrs* (list (make-color 240 10 240)))
+
+(defun print-mandel (&optional (stream *standard-output*))
+ "Prints a mandelbrot set to STREAM."
+ (loop for y from -1 to 1.1 by 0.1 do
+ (format stream "~%")
+ (loop for x from -2 to 1 by 0.04 do
+ (let* ((c 126)
+ (z (complex x y))
+ (a z))
+ (loop while (< (abs
+ (setq z (+ (* z z) a)))
+ 2)
+ while (> (decf c) 32))
+ (princ (code-char c) stream)))))
+
+(defun mandel-in-string ()
+ (escape-mux-string (with-output-to-string (s)
+ (print-mandel s)
+ s)))
+
+(defun mandel-page (string)
+ "Sends a mandelbrot set to the first arg in STRING."
+ (map-variables "p $1$=$2$"
+ (list (car (split "\\s+" string))
+ (mandel-in-string))))
+
+(defun highlight-pages (string)
+ "Highlights a page if it comes in."
+ (let ((string (if (stringp string) string (car string))))
+ (multiple-value-bind (match names)
+ (scan-to-strings "^((.*)\\s+pages:|From afar, (\\w+))" string)
+ (when match
+ (format t "You were paged by: ~A.~%" (elt names 1))
+ (make-attributed-string string *page-highlight-attrs*)))))
+
+(defun complex-attribute (keystroke)
+ (let ((attr-string (make-attributed-string "Foobarbaz"
+ `(,(make-color 255 255 255) (:italic 0.25))
+ `(,(make-range 3 3)
+ ,(make-super 1)
+ ,(make-color 127 127 127))
+ `(,(make-range 6 3)
+ ,(make-super 2)
+ ,(make-color 63 63 63)))))
+ (format t "complex attribute: ~S~%" attr-string)
+ (print-to-world *world* attr-string)))
+
+;; Now that we have the functions defined, hook 'em into Moxie.
+(add-hook 'highlight-pages :output-from-server-hook)
+
+; Register MANDEL-PAGE for the command "/MANDEl"
+(add-keyword 'mandel-page "mandel")
+
+(add-keystroke-macro 'complex-attribute :f1)
diff --git a/PlugIns/Telnet.lisp b/PlugIns/Telnet.lisp
new file mode 100644
index 0000000..2410af4
--- /dev/null
+++ b/PlugIns/Telnet.lisp
@@ -0,0 +1,149 @@
+;; -*- Lisp -*-
+;; $Id: Telnet.lisp 20 2005-12-27 15:21:23Z bjc $
+
+(defpackage telnet-options
+ (:use :cl :cl-user :moxie :bjc-utils))
+(in-package :telnet-options)
+
+(defconstant +iac+ 255
+ "Interpret as Command")
+
+(defconstant +se+ 240
+ "End of subnegotiation parameters.")
+
+(defconstant +nop+ 241
+ "No operation.")
+
+(defconstant +data-mark+ 242
+ "The data stream portion of a Synch.
+This should always be accompanied
+by a TCP Urgent notification.")
+
+(defconstant +break+ 243
+ "NVT character BRK.")
+
+(defconstant +interrupt-process+ 244
+ "The function IP.")
+
+(defconstant +abort-output+ 245
+ "The function AO.")
+
+(defconstant +are-you-there+ 246
+ "The function AYT.")
+
+(defconstant +erase-character+ 247
+ "The function EC.")
+
+(defconstant +erase-line+ 248
+ "The function EL.")
+
+(defconstant +go-ahead+ 249
+ "The GA signal.")
+
+(defconstant +sb+ 250
+ "Indicates that what follows is
+subnegotiation of the indicated option.")
+
+(defconstant +will+ 251
+ "Indicates the desire to begin
+performing, or confirmation that
+you are now performing, the
+indicated option.")
+
+(defconstant +wont+ 252
+ "Indicates the refusal to perform,
+or continue performing, the
+indicated option.")
+
+(defconstant +do+ 253
+ "Indicates the request that the
+other party perform, or
+confirmation that you are expecting
+the other party to perform, the
+indicated option.")
+
+(defconstant +dont+ 254
+ "Indicates the demand tha the
+other party stop performing,
+or confirmation that you are no
+longer expecting the other party
+to perform, the indicated option.")
+
+(defconstant +option-binary+ 0
+ "Enable binary (8 bit) data transmission, instead of the stripped 7 bit ASCII default.")
+(defconstant +option-echo+ 1
+ "Enable remote echo, suppressing local echo.")
+(defconstant +option-supress-go-ahead+ 3
+ "Enable go-ahead suppression.")
+(defconstant +option-status+ 5
+ "Enable option spamming for easier negotiations.")
+(defconstant +option-timing-mark+ 6
+ "Return a timing mark when this is recieved.")
+(defconstant +option-terminal+ 24
+ "Return terminal type.")
+(defconstant +option-window-size+ 31
+ "Negotiate about window size.")
+(defconstant +option-authentication+ 37
+ "Negotiate authentication.")
+(defconstant +option-environment+ 39
+ "Negotiate environment variables.")
+(defconstant +option-extended-options-list+ 255
+ "Read the next byte for further options.")
+
+(defconstant +option-mccp1+ 85
+ "Mud Client Compression Protocol version 1.")
+(defconstant +option-mccp2+ 86
+ "Mud Client Compression Protocol version 2.")
+(defconstant +option-msp+ 90
+ "Mud Sound Protocol.")
+(defconstant +option-mxp+ 91
+ "Mud eXtension Protocol.")
+
+(defun ack-cmd (cmd)
+ "Computes the ACK code for CMD."
+ (cond ((eql cmd +do+) +will+)
+ ((eql cmd +will+) +do+)
+ ((eql cmd +dont+) +wont+)
+ ((eql cmd +wont+) +dont+)))
+
+(defun nack-cmd (cmd)
+ "Computes the NACK code for CMD."
+ (cond ((eql cmd +do+) +wont+)
+ ((eql cmd +will+) +dont+)
+ ((eql cmd +dont+) +will+)
+ ((eql cmd +wont+) +do+)))
+
+(defun send-option (cmd option)
+ (let ((options (world-var 'options)))
+ (unless options
+ (setf (world-var 'options) (make-hash-table))
+ (setf options (world-var 'options)))
+ (unless (eql cmd (gethash option options))
+ (setf (gethash option options) cmd)
+ (send-bytes (list +iac+ cmd option)))))
+
+(defun send-bytes (bytes)
+ (write-array-to-mux *world* bytes))
+
+(defun handle-command-array (array)
+ "Array is a byte-vector of the complete IAC code, including any IAC characters."
+ (format t "(handle-command-array ~S)~%" array)
+ (when (and (> (length array) 1) (eql (elt array 0) +iac+))
+ (let ((cmd (elt array 1)))
+ (cond ((or (eql cmd +do+) (eql cmd +will+))
+ (awhen (aand (> (length array) 2) (elt array 2))
+ (cond ((eql it +option-timing-mark+)
+ (send-bytes (list +iac+ ack-cmd cmd) it))
+ ((or (eql it +option-binary+)
+ (eql it +option-supress-go-ahead+)
+ (eql it +option-status+)
+ (eql it +option-msp+)
+ (eql it +option-mxp+))
+ (send-option (ack-cmd cmd) it))
+ (t (send-option (nack-cmd cmd) it)))))
+ ((or (eql cmd +dont+) (eql cmd +wont+))
+ (awhen (aand (> (length array) 2) (elt array 2))
+ (send-option (ack-cmd cmd) it)))
+ (t (format t "Can't handle command ~S.~%" cmd))))))
+
+(add-hook 'handle-command-array :telnet-option-hook)
diff --git a/PreferencesController.h b/PreferencesController.h
new file mode 100644
index 0000000..0020eb6
--- /dev/null
+++ b/PreferencesController.h
@@ -0,0 +1,15 @@
+/* PreferencesController */
+
+@interface PreferencesController : NSWindowController
+{
+ IBOutlet NSArrayController *theStartupItemsController;
+ IBOutlet NSTableView *theStartupItemsTableView;
+}
+
++ (PreferencesController *)sharedController;
+
+- (IBAction)addStartupWorld: (id)sender;
+- (IBAction)removeStartupWorld: (id)sender;
+
+- (void)refreshStartupTableView;
+@end \ No newline at end of file
diff --git a/PreferencesController.m b/PreferencesController.m
new file mode 100644
index 0000000..1852adb
--- /dev/null
+++ b/PreferencesController.m
@@ -0,0 +1,156 @@
+#import "PreferencesController.h"
+
+@implementation PreferencesController
++ (PreferencesController *)sharedController
+{
+ static PreferencesController *sharedController = nil;
+
+ if (sharedController == nil) {
+ sharedController = [[PreferencesController alloc] init];
+ }
+ return sharedController;
+}
+
+- (id)init
+{
+ self = [self initWithWindowNibName: @"Preferences"];
+ [self setWindowFrameAutosaveName: @"preferencesWindow"];
+ return self;
+}
+
+- (IBAction)addStartupWorld: (id)sender
+{
+ NSOpenPanel *openPanel;
+
+ openPanel = [NSOpenPanel openPanel];
+ [openPanel setAllowsMultipleSelection: YES];
+ [openPanel beginSheetForDirectory: nil
+ file: nil
+ types: [NSArray arrayWithObject: @"moxie"]
+ modalForWindow: [self window]
+ modalDelegate: self
+ didEndSelector: @selector(openPanelDidEnd:returnCode:contextInfo:)
+ contextInfo: NULL];
+}
+
+- (void)openPanelDidEnd: (NSOpenPanel *)sheet
+ returnCode: (int)returnCode
+ contextInfo: (void *)contextInfo
+{
+ if (returnCode == NSOKButton) {
+ NSEnumerator *pathEnum;
+ NSMutableArray *newContents;
+ NSString *path;
+
+ newContents = [NSMutableArray arrayWithArray: [[NSUserDefaults standardUserDefaults] startupWorlds]];
+ pathEnum = [[sheet filenames] objectEnumerator];
+ while ((path = [pathEnum nextObject]) != nil) {
+ [newContents addObject: path];
+ }
+
+ [[NSUserDefaults standardUserDefaults] setStartupWorlds: newContents];
+ [self refreshStartupTableView];
+ }
+}
+
+- (IBAction)removeStartupWorld: (id)sender
+{
+ NSEnumerator *rowEnum;
+ NSMutableArray *newStartupItems;
+ NSNumber *row;
+ int removedRows;
+
+ newStartupItems = [[[NSUserDefaults standardUserDefaults] startupWorlds] mutableCopy];
+ removedRows = 0;
+ rowEnum = [theStartupItemsTableView selectedRowEnumerator];
+ while ((row = [rowEnum nextObject]) != nil) {
+ [newStartupItems removeObjectAtIndex: [row intValue]-removedRows];
+ removedRows++;
+ }
+ [[NSUserDefaults standardUserDefaults] setStartupWorlds: newStartupItems];
+ [self refreshStartupTableView];
+}
+
+- (void)refreshStartupTableView
+{
+ NSEnumerator *startupEnum;
+ NSMutableArray *newContent;
+ NSString *path;
+
+ newContent = [NSMutableArray array];
+ startupEnum = [[[NSUserDefaults standardUserDefaults] startupWorlds] objectEnumerator];
+ while ((path = [startupEnum nextObject]) != nil) {
+ NSDictionary *tmpDict;
+
+ tmpDict = [NSDictionary dictionaryWithObject: [[path lastPathComponent] stringByDeletingPathExtension]
+ forKey: @"name"];
+ [newContent addObject: tmpDict];
+ }
+ [theStartupItemsController setContent: newContent];
+}
+
+- (void)windowDidLoad
+{
+ NSUserDefaults *prefs;
+ [super windowDidLoad];
+
+ // Set the colors in the status panel. NSPreferencesController doesn't use accessor methods, so
+ // we have to do this by hand.
+ prefs = [NSUserDefaults standardUserDefaults];
+ [prefs setRecentActivityColorData: [prefs recentActivityColorData]];
+ [prefs setConnectedColorData: [prefs connectedColorData]];
+ [prefs setDisconnectedColorData: [prefs disconnectedColorData]];
+ [self refreshStartupTableView];
+
+ [theStartupItemsTableView registerForDraggedTypes:
+ [NSArray arrayWithObjects: NSFilenamesPboardType, NSURLPboardType, nil]];
+}
+
+- (NSString *)REPLFontName
+{
+ return [[NSUserDefaults standardUserDefaults] REPLFontName];
+}
+@end
+
+@implementation PreferencesController (StartupItemTableViewDataSource)
+- (NSDragOperation)tableView: (NSTableView *)aTableView
+ validateDrop: (id <NSDraggingInfo>)sender
+ proposedRow: (int)i
+ proposedDropOperation: (NSDragOperation)operation;
+{
+ NSArray *paths;
+ NSPasteboard *pb;
+
+ pb = [sender draggingPasteboard];
+ paths = [pb propertyListForType: NSFilenamesPboardType];
+ if ([[paths objectAtIndex: 0] hasSuffix: @".moxie"]) {
+ [aTableView setDropRow: -1 dropOperation: NSTableViewDropOn];
+ return NSDragOperationLink;
+ }
+ return NSDragOperationNone;
+}
+
+- (BOOL)tableView: (NSTableView *)aTableView
+ acceptDrop: (id <NSDraggingInfo>)sender
+ row: (int)anIndex
+ dropOperation: (NSTableViewDropOperation)anOperation
+{
+ NSEnumerator *pathEnum;
+ NSMutableArray *newContents;
+ NSPasteboard *pb;
+ NSString *path;
+
+ newContents = [NSMutableArray arrayWithArray: [[NSUserDefaults standardUserDefaults] startupWorlds]];
+ pb = [sender draggingPasteboard];
+ pathEnum = [[pb propertyListForType: NSFilenamesPboardType] objectEnumerator];
+ while ((path = [pathEnum nextObject]) != nil) {
+ if ([path hasSuffix: @".moxie"]) {
+ [newContents addObject: path];
+ }
+ }
+
+ [[NSUserDefaults standardUserDefaults] setStartupWorlds: newContents];
+ [self refreshStartupTableView];
+ return [newContents count] > 0;
+}
+@end \ No newline at end of file
diff --git a/ScrollingTextView.h b/ScrollingTextView.h
new file mode 100644
index 0000000..b917bff
--- /dev/null
+++ b/ScrollingTextView.h
@@ -0,0 +1,11 @@
+/* ScrollingTextView */
+
+#import <Cocoa/Cocoa.h>
+
+@interface ScrollingTextView : NSTextView
+{
+ IBOutlet NSResponder *theResponder;
+}
+
+- (void)keyDownToSuper: (NSEvent *)anEvent;
+@end \ No newline at end of file
diff --git a/ScrollingTextView.m b/ScrollingTextView.m
new file mode 100644
index 0000000..196cf28
--- /dev/null
+++ b/ScrollingTextView.m
@@ -0,0 +1,63 @@
+#import "ScrollingTextView.h"
+
+@implementation ScrollingTextView
+- (id)initWithFrame: (NSRect)aFrame
+{
+ self = [super initWithFrame: aFrame];
+ [[self layoutManager] setDelegate: self];
+ return self;
+}
+
+- (void)layoutManager: (NSLayoutManager *)aLayoutManager
+didCompleteLayoutForTextContainer: (NSTextContainer *)aTextContainer
+ atEnd:(BOOL)flag
+{
+ if (flag) {
+ NSClipView *clipView;
+
+ clipView = (NSClipView *)[self superview];
+ if ([clipView isKindOfClass: [NSClipView class]]) {
+ [clipView scrollToPoint:
+ [clipView constrainScrollPoint: NSMakePoint(0.0, [self frame].size.height)]];
+ [[clipView superview] reflectScrolledClipView: clipView];
+ }
+ }
+}
+
+- (BOOL)performKeyEquivalent: (NSEvent *)anEvent
+{
+ NSDocument *targetDoc;
+ BOOL rc;
+
+ rc = NO;
+ targetDoc = [[[self window] windowController] document];
+ if ([targetDoc respondsToSelector: @selector(handleEvent:from:)])
+ rc = [[targetDoc performSelector: @selector(handleEvent:from:)
+ withObject: anEvent
+ withObject: self] boolValue] ? YES : [super performKeyEquivalent: anEvent];
+ return rc;
+}
+
+- (void)keyDown: (NSEvent *)anEvent
+{
+ if ([[self delegate] respondsToSelector: @selector(handleEvent:from:)]) {
+ if ([[[self delegate] performSelector: @selector(handleEvent:from:) withObject: anEvent
+ withObject:self] boolValue] == NO)
+ [super keyDown: anEvent];
+ } else
+ [super keyDown: anEvent];
+}
+
+- (void)keyDownToSuper: (NSEvent *)anEvent
+{
+ [super keyDown: anEvent];
+}
+
+- (void)changeFont: (id)sender
+{
+ if ([[self delegate] respondsToSelector: @selector(changeFont:)]) {
+ [[self delegate] performSelector: @selector(changeFont:)
+ withObject: sender];
+ }
+}
+@end
diff --git a/World.h b/World.h
new file mode 100644
index 0000000..93a290a
--- /dev/null
+++ b/World.h
@@ -0,0 +1,79 @@
+//
+// World.h
+// Moxie
+//
+// Created by Brian Cully on Wed Dec 24 2003.
+// Copyright (c) 2003 Brian Cully. All rights reserved.
+//
+
+
+#import "LispREPLController.h"
+#import "MxWorldSettings.h"
+
+enum parsemode_t {
+ DESC, LOOK, NEW, CONTENTS, EXITS, EXAMINE, EXITLIST
+};
+
+enum _statusmode_t {
+ MxRecentActivity, MxConnected, MxDisconnected
+};
+typedef enum _statusmode_t MxWorldStatus;
+
+@interface World : NSDocument
+{
+ IBOutlet ScrollingTextView *theOutputView;
+ IBOutlet ScrollingTextView *theInputView;
+ IBOutlet NSSplitView *theSplitView;
+ IBOutlet NSProgressIndicator *theProgressIndicator;
+ IBOutlet NSTextField *theRoomField;
+
+ IBOutlet NSButton *theConnectButton;
+
+ id theID;
+ MxWorldStatus theStatus;
+ NSString *theQueuedRoomString;
+
+ NSMutableArray *theInputHistory;
+ unsigned theHistoryLevel;
+ BOOL theInputViewIsDirty;
+ id closeDelegate;
+ SEL didCloseSelector;
+ void *closeContext;
+
+ MxWorldSettings *theSettings;
+ NSTimer *theTimer;
+}
+- (IBAction)open: (id)sender;
+- (IBAction)close: (id)sender;
+
+- (void)startProgressBar;
+- (void)stopProgressBar;
+- (NSString *)statusBuffer;
+- (void)setStatusBuffer: (NSString *)aString;
+
+- (id)identifier;
+- (void)setIdentifier: (id)anID;
+
+- (NSDictionary *)defaultTextAttributes;
+- (void)redisplay;
+
+- (void)sendWindowEvent: (NSString *)anEvent;
+- (void)sendWindowEvent: (NSString *)anEvent withArg: (id)anArg;
+-(void)sendWindowEventWithArgs: (NSString *)anEvent, ...;
+@end
+
+@interface World (Accessors)
+- (NSWindow *)window;
+- (NSString *)queuedRoomString;
+- (void)setQueuedRoomString: (NSString *)aString;
+- (MxWorldStatus)status;
+- (void)setStatus: (MxWorldStatus)aStatus;
+- (NSMutableString *)outputBuffer;
+- (NSMutableString *)inputBuffer;
+- (NSMutableArray *)inputHistory;
+- (void)setInputHistory: (NSMutableArray *)aHistory;
+- (MxWorldSettings *)settings;
+- (void)setSettings: (MxWorldSettings *)someSettings;
+- (NSTimer *)timer;
+- (void)setTimer: (NSTimer *)aTimer;
+@end \ No newline at end of file
diff --git a/World.m b/World.m
new file mode 100644
index 0000000..80ee4dc
--- /dev/null
+++ b/World.m
@@ -0,0 +1,936 @@
+//
+// World.m
+// Moxie
+//
+// Created by Brian Cully on Wed Dec 24 2003.
+// Copyright (c) 2003 Brian Cully. All rights reserved.
+//
+
+#import "World.h"
+
+#import "WorldSettingsController.h"
+#import "WorldStatusController.h"
+
+#import <objc/objc-runtime.h>
+
+#include <unistd.h>
+
+NSString *
+localizedSettingName(NSString *settingName)
+{
+ NSString *localeString;
+
+ localeString = NSLocalizedStringFromTable(settingName, @"SettingNames", nil);
+ if (localeString)
+ return localeString;
+ return settingName;
+}
+
+@implementation World
+- (id)init
+{
+ self = [super init];
+ if (self) {
+ [self setIdentifier: [LispSymbol symbolNamed: [NSString stringWithFormat: @":COCOA-ID-%u", (unsigned int)self]]];
+ theHistoryLevel = 0;
+ [self setStatus: MxDisconnected];
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [self setInputHistory: nil];
+ [self setSettings: nil];
+ [self setTimer: nil];
+
+ [super dealloc];
+}
+
+- (NSString *)windowNibName
+{
+ return @"World";
+}
+
+- (void)windowControllerDidLoadNib: (NSWindowController *)aController
+{
+ [super windowControllerDidLoadNib: aController];
+
+ [self setHasUndoManager: YES];
+ [[self undoManager] removeAllActions];
+ [theProgressIndicator setUsesThreadedAnimation: YES];
+
+ [[self window] setOpaque: NO];
+ [[self window] useOptimizedDrawing: NO]; // Text views overlap split views.
+}
+
+- (NSString *)displayName
+{
+ return [[super displayName] stringByDeletingPathExtension];
+}
+
+- (BOOL)readFromURL: (NSURL *)absoluteURL ofType: (NSString *)aType error: (NSError **)errorPtr
+{
+ NSLog(@"DEBUG: [World readFromURL: %@ ofType: %@ error: (ptr)]", absoluteURL, aType);
+
+ *errorPtr = nil;
+ [self sendWindowEventWithArgs: @":LOAD-WORLD", [LispSymbol symbolNamed: @":PATH"], [absoluteURL path], nil];
+ return YES;
+}
+
+- (BOOL)writeToURL: (NSURL *)absoluteURL ofType: (NSString *)aType error: (NSError **)errorPtr
+{
+ NSLog(@"DEBUG: [World writeToURL: %@ ofType: %@ error: (ptr)]", absoluteURL, aType);
+
+ *errorPtr = nil;
+ [self sendWindowEventWithArgs: @":SAVE-WORLD", [LispSymbol symbolNamed: @":PATH"], [absoluteURL path], nil];
+ usleep(2000000); // XXX - should just wait until the file shows up or something.
+ return YES;
+}
+
+- (BOOL)isDocumentEdited
+{
+ BOOL edited;
+
+ edited = [self status] != MxDisconnected;
+ [[self window] setDocumentEdited: edited]; // We need to do this because "save:" clears it.
+ return edited;
+}
+
+- (void)worldConnected
+{
+ [self setStatus: MxConnected];
+ [theConnectButton setTitle: @"Disconnect"];
+ [theConnectButton setAction: @selector(close:)];
+}
+
+- (void)worldDisconnected
+{
+ [self setStatus: MxDisconnected];
+ [theConnectButton setTitle: @"Connect"];
+ [theConnectButton setAction: @selector(open:)];
+}
+
+- (void)worldClosed
+{
+ NSLog(@"DEBUG: %@ should close world.", [[self identifier] stringValue]);
+}
+
+- (void)textDidChange: (NSNotification *)aNotification
+{
+ if ([aNotification object] == theInputView) {
+ // Flag the input view as changed.
+ theInputViewIsDirty = YES;
+ }
+}
+
+- (BOOL)validateMenuItem: (NSMenuItem *)anItem
+{
+ if ([anItem action] == @selector(pasteWithFormatting:)) {
+ NSPasteboard *pb;
+
+ pb = [NSPasteboard generalPasteboard];
+ if ([[pb types] containsObject: NSStringPboardType])
+ return YES;
+ else
+ return NO;
+ }
+ return [super validateMenuItem: anItem];
+}
+
+- (IBAction)open: (id)sender
+{
+ [self sendWindowEvent: @":connect-world"];
+}
+
+- (IBAction)close: (id)sender
+{
+ [self sendWindowEvent: @":disconnect-world"];
+}
+
+- (void)startProgressBar
+{
+ [theProgressIndicator startAnimation: self];
+}
+
+- (void)stopProgressBar
+{
+ if ([[LispREPL sharedREPL] isLoaded])
+ [theProgressIndicator stopAnimation: self];
+}
+
+- (NSString *)statusBuffer
+{
+ return [theRoomField stringValue];
+}
+
+// XXX - there appears to be a race condition here with
+// theRoomField not being available.
+- (void)setStatusBuffer: (NSString *)aString
+{
+ if ([self queuedRoomString])
+ [self setQueuedRoomString: aString];
+ else if (aString)
+ [theRoomField setStringValue: aString];
+}
+
+- (id)identifier
+{
+ return theID;
+}
+
+- (void)setIdentifier: (id)anID
+{
+ [[LispREPL sharedREPL] removeCommand: [anID stringValue]];
+ [[LispREPL sharedREPL] addCommand: [anID stringValue]
+ handler: self
+ selector: @selector(windowEventFinished:)];
+ [anID retain];
+ [theID release];
+ theID = anID;
+}
+
+- (NSDictionary *)defaultTextAttributes
+{
+ NSMutableDictionary *myAttrs;
+
+ myAttrs = [NSMutableDictionary dictionary];
+ if ([[self settings] font])
+ [myAttrs setObject: [[self settings] font] forKey: NSFontAttributeName];
+ if ([[self settings] textColor])
+ [myAttrs setObject: [[self settings] textColor] forKey: NSForegroundColorAttributeName];
+ if ([[self settings] backgroundColor])
+ [myAttrs setObject: [[self settings] backgroundColor] forKey: NSBackgroundColorAttributeName];
+
+ return myAttrs;
+}
+
+- (void)redisplay
+{
+ NSMutableDictionary *myAttrs;
+
+ myAttrs = [[NSMutableDictionary alloc] init];
+ if ([[self settings] font])
+ [myAttrs setObject: [[self settings] font] forKey: NSFontAttributeName];
+ if ([[self settings] textColor])
+ [myAttrs setObject: [[self settings] textColor] forKey: NSForegroundColorAttributeName];
+
+ [[theOutputView textStorage] setAttributes: myAttrs
+ range: NSMakeRange(0, [[self outputBuffer] length])];
+ [myAttrs release];
+}
+
+- (void)windowWillClose: (id) sender
+{
+ [self setTimer: nil];
+ [[NSNotificationCenter defaultCenter] removeObserver: self];
+ [self sendWindowEvent: @":CLOSE-WORLD"];
+ [[LispREPL sharedREPL] removeCommand: [[self identifier] stringValue]];
+}
+
+- (void)windowDidBecomeKey: (NSNotification *)aNotification
+{
+ [[aNotification object] makeFirstResponder: theInputView];
+}
+
+- (void)windowDidResize: (NSNotification *)aNotification
+{
+ NSWindow *window;
+ NSRect scaledWindowFrame, fontRect;
+
+ fontRect = [[[self settings] font] boundingRectForFont];
+
+ window = [aNotification object];
+ scaledWindowFrame = [window frame];
+ scaledWindowFrame.size.width = round(scaledWindowFrame.size.width / fontRect.size.width);
+ scaledWindowFrame.size.height = round(scaledWindowFrame.size.height / fontRect.size.height);
+
+ [[self settings] setWindowFrame: scaledWindowFrame];
+}
+
+- (void)scrollToEnd: (NSTextView *)aTextView
+{
+ NSScroller *verticalScroller;
+ NSScrollView *myScrollView;
+
+ myScrollView = (NSScrollView *)[[aTextView superview] superview];
+ verticalScroller = [myScrollView verticalScroller];
+ if ([verticalScroller isEnabled] == NO || (1.0 - [verticalScroller floatValue]) < 0.000001)
+ [aTextView scrollRangeToVisible: NSMakeRange([[aTextView textStorage] length], 0)];
+}
+
+- (void)splitViewDidResizeSubviews: (NSNotification *)aNotification
+{
+ NSSize fontSize, inputSize;
+ float scaledHeight;
+
+ fontSize = [[[self settings] font] boundingRectForFont].size;
+ inputSize = [theInputView frame].size;
+ scaledHeight = round(inputSize.height / fontSize.height);
+ [[self settings] setInputViewSize: scaledHeight];
+}
+
+- (float)splitView: (NSSplitView *)sender constrainMinCoordinate: (float)proposedMin ofSubviewAt: (int)offset
+{
+ NSRect fontRect;
+ float fontHeight;
+
+ NSLog(@"DEBUG: splitView: sender constrainMinCoordinate: %f ofSubviewAt: %d", proposedMin, offset);
+ fontRect = [[[self settings] font] boundingRectForFont];
+ fontHeight = fontRect.size.height - fontRect.origin.y;
+ NSLog(@"DEBUG: returning %f.", fontHeight);
+
+ return fontHeight;
+}
+
+- (float)splitView: (NSSplitView *)sender constrainMaxCoordinate: (float)proposedMax ofSubviewAt: (int)offset
+{
+ NSRect fontRect;
+ float fontHeight;
+
+ NSLog(@"DEBUG: splitView: sender constrainMaxCoordinate: %f ofSubviewAt: %d", proposedMax, offset);
+ fontRect = [[[self settings] font] boundingRectForFont];
+ fontHeight = fontRect.size.height - fontRect.origin.y;
+ fontHeight *= round(proposedMax / fontHeight);
+ NSLog(@"DEBUG: returning %f.", fontHeight);
+
+ return fontHeight;
+}
+
+- (float)splitView: (NSSplitView *)sender
+constrainSplitPosition: (float)proposedPosition
+ ofSubviewAt: (int)offset
+{
+ NSRect fontRect;
+
+ fontRect = [[[self settings] font] boundingRectForFont];
+ if (fontRect.size.height > 0) {
+ float myPos, fontHeight;
+ int numLines;
+
+ fontHeight = fontRect.size.height;
+
+ numLines = ceil(proposedPosition / fontHeight);
+ myPos = numLines * fontHeight - fontHeight / 2;
+ return floor(myPos + 0.5);
+ }
+ return proposedPosition;
+}
+
+- (void)splitView: (NSSplitView *)sender resizeSubviewsWithOldSize: (NSSize)oldSize
+{
+ NSView *topView, *bottomView;
+ NSRect newFrame, outputFrame, inputFrame, fontRect;
+ float dividerThickness;
+
+ // Split view is flipped.
+ topView = [[theSplitView subviews] objectAtIndex: 0];
+ bottomView = [[theSplitView subviews] objectAtIndex: 1];
+ dividerThickness = [sender dividerThickness];
+ newFrame = [sender frame];
+
+ inputFrame = [bottomView frame];
+ outputFrame = [topView frame];
+
+/*
+ inputFrame.origin.y = newFrame.size.height;
+ inputFrame.size.width = newFrame.size.width;
+ */
+ inputFrame.size.height = [[self settings] inputViewSize];
+ fontRect = [[[self settings] font] boundingRectForFont];
+ if (fontRect.size.height > 0)
+ inputFrame.size.height *= fontRect.size.height;
+ inputFrame.origin.y = newFrame.size.height - inputFrame.size.height;
+ inputFrame.size.width = newFrame.size.width;
+
+ outputFrame.size.width = newFrame.size.width;
+ outputFrame.size.height = inputFrame.origin.y - dividerThickness - outputFrame.origin.y;
+
+ [topView setFrame: outputFrame];
+ [bottomView setFrame: inputFrame];
+
+ [theOutputView scrollRangeToVisible: NSMakeRange([[theOutputView textStorage] length], 0)];
+}
+
+- (void)goBackwardInHistory
+{
+ if (theHistoryLevel > 0) {
+ NSMutableString *buffer;
+
+ buffer = [self inputBuffer];
+ if (theInputViewIsDirty) {
+ [[self inputHistory] addObject: [buffer substringWithRange: NSMakeRange(0, [buffer length])]];
+ theInputViewIsDirty = NO;
+ theHistoryLevel = [[self inputHistory] count] - 1;
+ }
+ theHistoryLevel--;
+ [buffer setString: [[self inputHistory] objectAtIndex: theHistoryLevel]];
+ [[theInputView textStorage] setAttributes: [self defaultTextAttributes]
+ range: NSMakeRange(0, [buffer length])];
+ }
+}
+
+- (void)goForwardInHistory
+{
+ if (theHistoryLevel < [[self inputHistory] count]-1) {
+ NSMutableString *buffer;
+
+ buffer = [self inputBuffer];
+ if (theInputViewIsDirty) {
+ [[self inputHistory] addObject: [buffer substringWithRange: NSMakeRange(0, [buffer length])]];
+ theInputViewIsDirty = NO;
+ theHistoryLevel = [[self inputHistory] count];
+ } else
+ theHistoryLevel++;
+
+ [buffer setString: [[self inputHistory] objectAtIndex: theHistoryLevel]];
+ [[theInputView textStorage] setAttributes: [self defaultTextAttributes]
+ range: NSMakeRange(0, [buffer length])];
+ }
+}
+
+- (void)sendInputBuffer
+{
+ NSMutableString *buffer;
+
+ buffer = [self inputBuffer];
+ if ([buffer length] > 0) {
+ // Save line in history.
+ if (theInputViewIsDirty || theHistoryLevel < [[self inputHistory] count]-1) {
+ [[self inputHistory] addObject: [buffer substringWithRange: NSMakeRange(0, [buffer length])]];
+ theInputViewIsDirty = NO;
+ }
+ theHistoryLevel = [[self inputHistory] count];
+ }
+
+ [self sendWindowEvent: @":input-from-client-hook" withArg: buffer];
+ [buffer setString: @""];
+}
+
+- (void)printLispResult: (id)result;
+{
+ NSAttributedString *attributedResults;
+
+ [self setStatus: MxRecentActivity];
+ if ([result isKindOfClass: [NSArray class]]) {
+ attributedResults = [NSAttributedString attributedStringWithForm: result
+ defaultAttributes: [self defaultTextAttributes]];
+ } else
+ attributedResults = [NSAttributedString attributedStringWithString: result
+ attributes: [self defaultTextAttributes]];
+ [[theOutputView textStorage] insertAttributedString: attributedResults
+ atIndex: [[self outputBuffer] length]];
+ [self scrollToEnd: theOutputView];
+}
+
+- (NSNumber *)handleEvent: (NSEvent *)anEvent from: (id)sender
+{
+ BOOL rc;
+
+ rc = NO;
+ if ([anEvent type] == NSKeyDown) {
+ if (sender == theInputView) {
+ // Do this here, because it gets randomly reset sometimes.
+ [theInputView setTypingAttributes: [self defaultTextAttributes]];
+ if ([[LispREPLController sharedController] dispatchKeystrokeMacro: anEvent
+ fromID: [self identifier]])
+ rc = YES;
+ else {
+ NSString *characters;
+ unsigned int i;
+
+ characters = [anEvent charactersIgnoringModifiers];
+ for (i = 0; i < [characters length]; i++) {
+ switch ([characters characterAtIndex: i]) {
+ case '\r':
+ case '\n':
+ [self sendInputBuffer];
+ rc = YES;
+ break;
+ case NSUpArrowFunctionKey:
+ if ([anEvent modifierFlags] & NSCommandKeyMask) {
+ [self goBackwardInHistory];
+ }
+ rc = YES;
+ break;
+ case NSDownArrowFunctionKey:
+ if ([anEvent modifierFlags] & NSCommandKeyMask) {
+ [self goForwardInHistory];
+ }
+ rc = YES;
+ break;
+ case NSPageUpFunctionKey:
+ [theOutputView pageUp: self];
+ rc = YES;
+ break;
+ case NSPageDownFunctionKey:
+ [theOutputView pageDown: self];
+ rc = YES;
+ break;
+ }
+ }
+ }
+ } else {
+ [[self window] makeFirstResponder: theInputView];
+ [theInputView keyDown: anEvent];
+ rc = YES;
+ }
+ }
+
+ return [NSNumber numberWithBool: rc];
+}
+
+/*
+ * Ideally, lisp would be able to query these things whenever it wanted, however,
+ * that's fairly difficult to get right, so we do something a little more limited,
+ * but easier.
+ */
+- (NSString *)lispEnvironment
+{
+ NSMutableDictionary *environment;
+ NSString *logPath;
+
+ logPath = [[[NSUserDefaults standardUserDefaults] logDirectory] stringByAppendingPathComponent: [self displayName]];
+ logPath = [logPath stringByAppendingPathExtension: @"txt"];
+
+ environment = [NSMutableDictionary dictionary];
+ [environment setObject: [self displayName]
+ forKey: [LispSymbol symbolNamed: @":DOCUMENT-NAME"]];
+ [environment setObject: logPath
+ forKey: [LispSymbol symbolNamed: @":LOG-FILE-PATH"]];
+ return [environment lispForm];
+}
+
+- (void)canCloseDocumentWithDelegate: (id)delegate
+ shouldCloseSelector: (SEL)shouldCloseSelector
+ contextInfo: (void *)contextInfo
+{
+ if ([self isDocumentEdited]) {
+ NSString *alertString, *infoString;
+
+ [[self windowForSheet] makeKeyAndOrderFront: nil];
+ alertString = [NSString stringWithFormat: @"Close connection to %@?", [self displayName]];
+ infoString = [NSString stringWithFormat: @"Closing this window will terminate your connection to %@.",
+ [self displayName]];
+ closeDelegate = delegate;
+ didCloseSelector = shouldCloseSelector;
+ closeContext = contextInfo;
+ NSBeginAlertSheet(alertString,
+ @"Close", @"Cancel", nil,
+ [self windowForSheet], self,
+ @selector(didEndCloseSheet:returnCode:contextInfo:),
+ nil, NULL, infoString);
+ } else
+ objc_msgSend(delegate, shouldCloseSelector, self, YES, contextInfo);
+}
+
+- (void)didEndCloseSheet: (NSWindow *)sheet
+ returnCode: (int)rc
+ contextInfo: (void *)context
+{
+ if (rc == NSAlertDefaultReturn) {
+ // Close
+ [self close: self];
+ } else
+ (void)objc_msgSend(closeDelegate, didCloseSelector, self, NO, closeContext);
+}
+
+- (IBAction)pasteWithFormatting: (id)sender
+{
+ NSMutableString *newString;
+ NSPasteboard *pb;
+ NSString *pbString;
+ NSRange substringRange;
+ unsigned int i;
+
+ NSLog(@"DEBUG: paste with formatting");
+ pb = [NSPasteboard generalPasteboard];
+ pbString = [pb stringForType: NSStringPboardType];
+
+ newString = [NSMutableString stringWithString: pbString];
+ substringRange.location = 0;
+ for (i = 0; i < [newString length]; i++) {
+ switch ([newString characterAtIndex: i]) {
+ case '\r':
+ [newString deleteCharactersInRange: NSMakeRange(i, 1)];
+ i--;
+ break;
+ case '\n':
+ [newString replaceCharactersInRange: NSMakeRange(i, 1)
+ withString: @"%r"];
+ i++;
+ break;
+ case '\t':
+ [newString replaceCharactersInRange: NSMakeRange(i, 1)
+ withString: @"%t"];
+ i++;
+ break;
+ case ' ':
+ if ([newString characterAtIndex: i-1] == ' ') {
+ [newString replaceCharactersInRange: NSMakeRange(i, 1)
+ withString: @"%b"];
+ i++;
+ }
+ break;
+ case '\\':
+ [newString replaceCharactersInRange: NSMakeRange(i, 1)
+ withString: @"\\\\"];
+ i++;
+ break;
+ case '[':
+ [newString replaceCharactersInRange: NSMakeRange(i, 1)
+ withString: @"%["];
+ i++;
+ break;
+ case ']':
+ [newString replaceCharactersInRange: NSMakeRange(i, 1)
+ withString: @"%]"];
+ i++;
+ break;
+ case '%':
+ [newString replaceCharactersInRange: NSMakeRange(i, 1)
+ withString: @"%%"];
+ i++;
+ break;
+ case ';':
+ [newString replaceCharactersInRange: NSMakeRange(i, 1)
+ withString: @"%;"];
+ i++;
+ break;
+ case ',':
+ [newString replaceCharactersInRange: NSMakeRange(i, 1)
+ withString: @"%,"];
+ i++;
+ break;
+ case '{':
+ [newString replaceCharactersInRange: NSMakeRange(i, 1)
+ withString: @"%{"];
+ i++;
+ break;
+ case '}':
+ [newString replaceCharactersInRange: NSMakeRange(i, 1)
+ withString: @"%}"];
+ i++;
+ break;
+ }
+ }
+
+ [theInputView insertText: newString];
+}
+
+- (void)sendWindowEvent: (NSString *)anEvent
+{
+ [self sendWindowEventWithArgs: anEvent, nil];
+}
+
+- (void)sendWindowEvent: (NSString *)anEvent
+ withArg: (id)anArg
+{
+ [self sendWindowEventWithArgs: anEvent, anArg, nil];
+}
+
+-(void)sendWindowEventWithArgs: (NSString *)anEvent, ...
+{
+ va_list ap;
+
+ va_start(ap, anEvent);
+ [[LispREPLController sharedController] sendEvent: [NSString stringWithFormat: @":WORLD-EVENT %@ %@",
+ [[self identifier] stringValue], anEvent]
+ arguments: ap];
+ va_end(ap);
+}
+
+- (void)worldSettingsChanged: (NSArray *)aList
+{
+ NSFont *font;
+ NSMutableDictionary *settings;
+
+ settings = [NSDictionary dictionaryWithAlist: aList];
+ [self setSettings: [MxWorldSettings settingsWithDictionary: settings]];
+
+ [theOutputView setTypingAttributes: [self defaultTextAttributes]];
+ [theOutputView setBackgroundColor: [[self settings] backgroundColor]];
+ [theInputView setBackgroundColor: [[self settings] backgroundColor]];
+ [theInputView setInsertionPointColor: [[self settings] textColor]];
+ [theInputView setTypingAttributes: [self defaultTextAttributes]];
+
+ font = [[self settings] font];
+ if (font) {
+ NSRect fontRect, frameRect;
+
+ frameRect = [[self settings] windowFrame];
+ fontRect = [font boundingRectForFont];
+ if (fontRect.size.height > 0) {
+ [[self window] setContentResizeIncrements:
+ NSMakeSize(fontRect.size.width, fontRect.size.height)];
+ frameRect.size.width *= fontRect.size.width;
+ frameRect.size.height *= fontRect.size.height;
+ }
+
+ [[self window] setFrame: frameRect display: YES];
+ }
+
+ [self redisplay];
+}
+
+// The inverse of lisp's moxie::world-event.
+- (void)windowEventFinished: (NSArray *)resultObjects
+{
+ id event;
+
+ event = [resultObjects objectAtIndex: 0];
+ if ([event isEqualToString: @":CLEAR-SCREEN"])
+ [[self outputBuffer] setString: @""];
+ else if ([event isEqualToString: @":CHANGE-SETTINGS"])
+ [self worldSettingsChanged: [resultObjects objectAtIndex: 1]];
+ else if ([event isEqualToString: @":OUTPUT-FROM-SERVER-HOOK"])
+ [self printLispResult: [resultObjects objectAtIndex: 1]];
+ else if ([event isEqualToString: @":SET-STATUS-BUFFER"])
+ [self setStatusBuffer: [resultObjects objectAtIndex: 1]];
+ else if ([event isEqualToString: @":ENABLE-LOGGING"])
+ [[self settings] setLoggingEnabled: YES];
+ else if ([event isEqualToString: @":DISABLE-LOGGING"])
+ [[self settings] setLoggingEnabled: NO];
+ else if ([event isEqualToString: @":WORLD-CONNECTED"])
+ [self worldConnected];
+ else if ([event isEqualToString: @":WORLD-DISCONNECTED"])
+ [self worldDisconnected];
+ else if ([event isEqualToString: @":WORLD-CLOSED"])
+ [self worldClosed];
+}
+@end
+
+@implementation World (Accessors)
+- (NSWindow *)window
+{
+ return [self windowForSheet];
+}
+
+- (NSString *)queuedRoomString
+{
+ return theQueuedRoomString;
+}
+
+- (void)setQueuedRoomString: (NSString *)aString
+{
+ [aString retain];
+ [theQueuedRoomString release];
+ theQueuedRoomString = aString;
+}
+
+- (MxWorldStatus)status
+{
+ return theStatus;
+}
+
+- (void)setStatus: (MxWorldStatus)aStatus
+{
+ theStatus = aStatus;
+ [[WorldStatusController sharedController] update];
+ (void)[self isDocumentEdited];
+}
+
+- (NSMutableString *)outputBuffer
+{
+ return [[theOutputView textStorage] mutableString];
+}
+
+- (NSMutableString *)inputBuffer
+{
+ return [[theInputView textStorage] mutableString];
+}
+
+- (NSMutableArray *)inputHistory
+{
+ if (theInputHistory == nil)
+ [self setInputHistory: [NSMutableArray array]];
+ return theInputHistory;
+}
+
+- (void)setInputHistory: (NSMutableArray *)aHistory
+{
+ [aHistory retain];
+ [theInputHistory release];
+ theInputHistory = aHistory;
+}
+
+- (MxWorldSettings *)settings
+{
+ if (theSettings == nil)
+ [self setSettings: [MxWorldSettings settingsFromDefaults]];
+ return theSettings;
+}
+
+- (void)setSettings: (MxWorldSettings *)someSettings
+{
+ [[NSNotificationCenter defaultCenter] removeObserver: self
+ name: MxWorldSettingsDidChangeNotification
+ object: theSettings];
+ [[NSNotificationCenter defaultCenter] addObserver: self
+ selector: @selector(settingsDidChange:)
+ name: MxWorldSettingsDidChangeNotification
+ object: someSettings];
+
+ [someSettings retain];
+ [theSettings release];
+ theSettings = someSettings;
+}
+
+- (NSTimer *)timer
+{
+ return theTimer;
+}
+
+- (void)setTimer: (NSTimer *)aTimer
+{
+ if (aTimer != theTimer) {
+ [aTimer retain];
+ [theTimer invalidate];
+ [theTimer release];
+ theTimer = aTimer;
+ }
+}
+@end
+
+@implementation World (WorldSettingsDelegate)
+- (void)settingsDidChange: (NSNotification *)aNotification
+{
+ NSString *setting;
+
+ setting = [[aNotification userInfo] objectForKey: MxSettingName];
+ if (setting) {
+ id oldValue;
+
+ [self sendWindowEvent: @":SETTING-CHANGED" withArg:
+ [NSArray arrayWithObjects:
+ [LispSymbol symbolNamed: setting], [[self settings] objectForKey: setting], nil]];
+
+ if ([setting isEqualToString: @":WINDOW-SIZE"] ||
+ [setting isEqualToString: @":WINDOW-ORIGIN"] ||
+ [setting isEqualToString: @":INPUT-VIEW-SIZE"])
+ return;
+ else if ([setting isEqualToString: @":FONT"]) {
+ NSRect fontRect;
+
+ fontRect = [[[self settings] font] boundingRectForFont];
+ if (fontRect.size.height > 0) {
+ [[self window] setContentResizeIncrements:
+ NSMakeSize(fontRect.size.width, fontRect.size.height)];
+ }
+ [self redisplay];
+ } else if ([setting isEqualToString: @":BACKGROUND-COLOR"]) {
+ [theOutputView setBackgroundColor: [[self settings] backgroundColor]];
+ [theInputView setBackgroundColor: [[self settings] backgroundColor]];
+ [self redisplay];
+ } else if ([setting isEqualToString: @":TEXT-COLOR"]) {
+ [theInputView setInsertionPointColor: [[self settings] textColor]];
+ [theInputView setTypingAttributes: [self defaultTextAttributes]];
+ [self redisplay];
+ }
+
+ oldValue = [[aNotification userInfo] objectForKey: MxSettingOldValue];
+ if (oldValue) {
+ NSString *actionName;
+ NSUndoManager *undoManager;
+
+ undoManager = [self undoManager];
+ [[undoManager prepareWithInvocationTarget: [self settings]] setObject: oldValue forKey: setting];
+
+ actionName = [NSString stringWithFormat: @"Set %@", localizedSettingName(setting)];
+ [undoManager setActionName: actionName];
+ }
+ }
+}
+@end
+
+@implementation World (LineScanner)
+#define TELNET_SE 240
+#define TELNET_NOP 241
+#define TELNET_DM 242
+#define TELNET_BREAK 243
+#define TELNET_IP 244
+#define TELNET_AO 245
+#define TELNET_AYT 246
+#define TELNET_EC 247
+#define TELNET_EL 248
+#define TELNET_GA 249
+#define TELNET_SB 250
+#define TELNET_WILL 251
+#define TELNET_WONT 252
+#define TELNET_DO 253
+#define TELNET_DONT 254
+#define TELNET_IAC 255
+
+/* These are all defined in RFCs 856 - 862 */
+#define TELNET_OPT_TRANSMIT_BINARY 0
+
+// To support this, we'll need to be able to lose the input bar.
+#define TELNET_OPT_ECHO 1
+#define TELNET_OPT_SUPPRESS_GO_AHEAD 3
+#define TELNET_OPT_STATUS 5
+#define TELNET_OPT_TIMING_MARK 6
+#define TELNET_OPT_EXTENDED_OPTIONS_LIST 255
+
+#define TELNET_OPT_STATUS_IS 0
+#define TELNET_OPT_STATUS_SEND 1
+
+// MUD extensions
+#define TELNET_OPT_MCCP 86 // Mud Client Compression Protocol
+#define TELNET_OPT_MSP 90 // Mud Sound Protocol
+#define TELNET_OPT_MXP 91 // Mud eXtension Protocol
+
+- (NSData *)handleTelnetCodesInData: (NSData *)someData
+{
+ NSMutableData *tmpData;
+ const unsigned char *buffer;
+ int i, lastLoc, dataLen;
+
+ buffer = [someData bytes];
+ dataLen = [someData length];
+ tmpData = [NSMutableData data];
+ for (lastLoc = 0, i = 0; i < dataLen; i++) {
+ if (buffer[i] == TELNET_IAC) {
+ NSMutableArray *telnetCodes;
+ NSRange iacRange;
+
+ telnetCodes = [NSMutableArray arrayWithObject: [NSNumber numberWithInt: buffer[i]]];
+ [tmpData appendBytes: buffer + lastLoc
+ length: i - lastLoc];
+ iacRange = NSMakeRange(i, 1);
+ if (++i < dataLen) {
+ iacRange.length++;
+ [telnetCodes addObject: [NSNumber numberWithInt: buffer[i]]];
+ switch (buffer[i]) {
+ case TELNET_WILL:
+ case TELNET_WONT:
+ case TELNET_DO:
+ case TELNET_DONT:
+ if (++i < dataLen) {
+ [telnetCodes addObject: [NSNumber numberWithInt: buffer[i]]];
+ iacRange.length++;
+ }
+ break;
+ case TELNET_SB:
+ NSLog(@"DEBUG: start of telnet block. should scan forward to TELNET_SE");
+ while (++i < (dataLen - 1)) {
+ iacRange.length++;
+ if (buffer[i] == TELNET_IAC && buffer[i+i] == TELNET_SE) {
+ [telnetCodes addObject: [NSNumber numberWithInt: buffer[i]]];
+ iacRange.length++;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ [self sendWindowEvent: @":telnet-option-hook" withArg: telnetCodes];
+ lastLoc = iacRange.location + iacRange.length;
+ }
+ }
+ if ((dataLen - lastLoc) > 0)
+ [tmpData appendBytes: buffer + lastLoc
+ length: dataLen - lastLoc];
+
+ return tmpData;
+}
+@end \ No newline at end of file
diff --git a/WorldController.h b/WorldController.h
new file mode 100644
index 0000000..7f25551
--- /dev/null
+++ b/WorldController.h
@@ -0,0 +1,8 @@
+/* WorldController */
+
+@interface WorldController : NSDocumentController
+- (IBAction)showPreferencesWindow:(id)sender;
+- (IBAction)showWorldSettingsWindow:(id)sender;
+- (IBAction)showWorldStatusWindow:(id)sender;
+- (IBAction)showLispREPLWindow:(id)sender;
+@end
diff --git a/WorldController.m b/WorldController.m
new file mode 100644
index 0000000..3bb132e
--- /dev/null
+++ b/WorldController.m
@@ -0,0 +1,141 @@
+#import "WorldController.h"
+#import "World.h"
+
+#import "LispREPLController.h"
+#import "PreferencesController.h"
+#import "WorldSettingsController.h"
+#import "WorldStatusController.h"
+
+#import <objc/objc-runtime.h>
+
+@implementation WorldController
+
+- (IBAction)showPreferencesWindow:(id)sender
+{
+ [[PreferencesController sharedController] showWindow: sender];
+}
+
+- (IBAction)showWorldSettingsWindow:(id)sender
+{
+ [[WorldSettingsController sharedController] showWindow: sender];
+}
+
+- (IBAction)showWorldStatusWindow:(id)sender
+{
+ [[WorldStatusController sharedController] showWindow: sender];
+}
+
+- (IBAction)showLispREPLWindow:(id)sender
+{
+ [[LispREPLController sharedController] showWindow: sender];
+}
+
+- (IBAction)cycleDocumentWindows: (id)sender
+{
+ NSArray *openDocuments;
+ NSDocument *mainDocument;
+ unsigned i, documentCount;
+
+ mainDocument = [self currentDocument];
+ openDocuments = [self documents];
+ documentCount = [openDocuments count];
+ for (i = 0; i < documentCount; i++) {
+ if ([openDocuments objectAtIndex: (i % documentCount)] == mainDocument) {
+ [[openDocuments objectAtIndex: ((i+1) % documentCount)] showWindows];
+ break;
+ }
+ }
+}
+
+#if XXX
+- (void)awakeFromNib
+{
+ NSEnumerator *startupEnum;
+ NSString *path;
+
+ startupEnum = [[[NSUserDefaults standardUserDefaults] startupWorlds] objectEnumerator];
+ while ((path = [startupEnum nextObject]) != nil) {
+ [self openDocumentWithContentsOfFile: path display: YES];
+ }
+}
+#endif
+
+- (void)applicationDidFinishLaunching: (NSNotification *)aNotification
+{
+ // Start up the embedded lisp.
+ [LispREPLController sharedController];
+ if ([[LispREPL sharedREPL] isLoaded] == NO) {
+ NSNotificationCenter *defaultCenter;
+
+ defaultCenter = [NSNotificationCenter defaultCenter];
+ [defaultCenter addObserver: self
+ selector: @selector(lispFinishedLoading:)
+ name: LispFinishedLoadingNotification
+ object: nil];
+ }
+
+ [NSColor setIgnoresAlpha: NO];
+ if ([[NSUserDefaults standardUserDefaults] startupShowWorldSelector]) {
+ [self showWorldStatusWindow: self];
+ }
+}
+
+- (void)reviewUnsavedDocumentsWithAlertTitle: (NSString *)title
+ cancellable: (BOOL)cancellable
+ delegate: (id)delegate
+ didReviewAllSelector: (SEL)didReviewAllSelector
+ contextInfo: (void *)contextInfo
+{
+ NSDocument *document;
+ NSEnumerator *docEnum;
+ unsigned count;
+
+ count = 0;
+ docEnum = [[self documents] objectEnumerator];
+ while ((document = [docEnum nextObject]) != nil) {
+ if ([document isDocumentEdited])
+ count++;
+ }
+
+ if (count > 1) {
+ NSString *alertString, *infoString;
+ int rc;
+
+ alertString = [NSString stringWithFormat:
+ @"You have %d open connections. Would you like to review them before quitting?", count];
+ infoString = [NSString stringWithFormat:
+ @"If you don't review your windows, any connections will be closed."];
+ rc = NSRunAlertPanel(alertString, infoString, @"Review Worlds...", @"Close Connections", @"Cancel");
+ switch (rc) {
+ case NSAlertDefaultReturn:
+ // Review changes.
+ [self closeAllDocumentsWithDelegate: delegate
+ didCloseAllSelector: didReviewAllSelector
+ contextInfo: contextInfo];
+ break;
+ case NSAlertAlternateReturn:
+ // Close connections.
+ objc_msgSend(delegate, didReviewAllSelector, self, YES, contextInfo);
+ break;
+ case NSAlertOtherReturn:
+ // Cancel.
+ objc_msgSend(delegate, didReviewAllSelector, self, NO, contextInfo);
+ break;
+ }
+ } else if (count == 1) {
+ // Bring up the one sheet, no matter what.
+ [[[self documents] objectAtIndex: 0] canCloseDocumentWithDelegate: delegate
+ shouldCloseSelector: didReviewAllSelector
+ contextInfo: contextInfo];
+ } else
+ objc_msgSend(delegate, didReviewAllSelector, self, YES, contextInfo);
+}
+
+- (BOOL)validateMenuItem: (NSMenuItem *)anItem
+{
+ if ([anItem action] == @selector(cycleDocumentWindows:)) {
+ return [[self documents] count] > 1;
+ }
+ return YES;
+}
+@end \ No newline at end of file
diff --git a/WorldSettingsController.h b/WorldSettingsController.h
new file mode 100644
index 0000000..67489ec
--- /dev/null
+++ b/WorldSettingsController.h
@@ -0,0 +1,28 @@
+//
+// WorldSettingsController.h
+// Moxie
+//
+// Created by Brian Cully on Thu Jan 01 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "MxWorldSettings.h"
+
+@interface WorldSettingsController : NSWindowController
+{
+ IBOutlet NSObjectController *theSettingsController;
+ IBOutlet NSTabView *theTabView;
+ IBOutlet NSTabViewItem *theHostSettingsTab;
+}
++ (WorldSettingsController *)sharedController;
+
+- (IBAction)saveSettingsAsDefault: (id)sender;
+- (IBAction)openLogDirectory: (id)sender;
+
+- (void)showHostSettingsTab;
+@end
+
+@interface WorldSettingsController (Accessors)
+- (MxWorldSettings *)settings;
+- (void)setSettings: (MxWorldSettings *)someSettings;
+@end \ No newline at end of file
diff --git a/WorldSettingsController.m b/WorldSettingsController.m
new file mode 100644
index 0000000..2ee9623
--- /dev/null
+++ b/WorldSettingsController.m
@@ -0,0 +1,113 @@
+//
+// WorldSettingsController.m
+// Moxie
+//
+// Created by Brian Cully on Thu Jan 01 2004.
+// Copyright (c) 2004 Brian Cully. All rights reserved.
+//
+
+#import "WorldSettingsController.h"
+
+#import "World.h"
+
+@implementation WorldSettingsController
++ (WorldSettingsController *)sharedController
+{
+ static WorldSettingsController *sharedController = nil;
+
+ if (sharedController == nil) {
+ sharedController = [[WorldSettingsController alloc] init];
+ }
+ return sharedController;
+}
+
+- (id)init
+{
+ self = [self initWithWindowNibName: @"WorldSettings"];
+ [self setWindowFrameAutosaveName: @"worldSettingsWindow"];
+ return self;
+}
+
+- (void)dealloc
+{
+ [[NSNotificationCenter defaultCenter] removeObserver: self];
+ [super dealloc];
+}
+
+- (void)setMainWindow: (NSWindow *)aWindow
+{
+ World *world;
+
+ world = [[aWindow windowController] document];
+ if ([world isKindOfClass: [World class]]) {
+ // XXX: this needs to be pluginified
+ [self setSettings: [world settings]];
+ }
+}
+
+- (void)windowDidLoad
+{
+ NSNotificationCenter *defaultCenter;
+
+ [super windowDidLoad];
+
+ [self setMainWindow: [NSApp mainWindow]];
+
+ defaultCenter = [NSNotificationCenter defaultCenter];
+ [defaultCenter addObserver: self
+ selector: @selector(mainWindowChanged:)
+ name: NSWindowDidBecomeMainNotification
+ object: nil];
+ [defaultCenter addObserver: self
+ selector: @selector(mainWindowResigned:)
+ name: NSWindowDidResignMainNotification
+ object: nil];
+}
+
+- (void)mainWindowChanged: (NSNotification *)aNotification
+{
+ [self setMainWindow: [aNotification object]];
+}
+
+- (void)mainWindowResigned: (NSNotification *)aNotification
+{
+ [self setMainWindow: nil];
+}
+
+- (void)changeFont: (id)sender
+{
+ NSFont *oldFont, *newFont;
+
+ oldFont = [[self settings] font];
+ newFont = [sender convertFont: oldFont];
+ [[self settings] setFont: newFont];
+}
+
+- (IBAction)saveSettingsAsDefault: (id)sender
+{
+ [[NSUserDefaults standardUserDefaults] setDefaultsFromWorldSettings: [self settings]];
+}
+
+- (IBAction)openLogDirectory: (id)sender
+{
+ [[NSWorkspace sharedWorkspace] openFile: [[NSUserDefaults standardUserDefaults] logDirectory]];
+}
+
+- (void)showHostSettingsTab
+{
+ [self showWindow: self];
+ [theTabView selectTabViewItem: theHostSettingsTab];
+}
+@end
+
+@implementation WorldSettingsController (Accessors)
+- (MxWorldSettings *)settings
+{
+ return [theSettingsController content];
+}
+
+- (void)setSettings: (MxWorldSettings *)someSettings
+{
+ [theSettingsController setContent: someSettings];
+}
+@end \ No newline at end of file
diff --git a/WorldStatusController.h b/WorldStatusController.h
new file mode 100644
index 0000000..f46e631
--- /dev/null
+++ b/WorldStatusController.h
@@ -0,0 +1,10 @@
+/* WorldStatusController */
+
+@interface WorldStatusController : NSWindowController
+{
+ IBOutlet NSTableView *theTableView;
+}
++ (WorldStatusController *)sharedController;
+
+- (void)update;
+@end \ No newline at end of file
diff --git a/WorldStatusController.m b/WorldStatusController.m
new file mode 100644
index 0000000..f931055
--- /dev/null
+++ b/WorldStatusController.m
@@ -0,0 +1,218 @@
+#import "WorldStatusController.h"
+
+#import "World.h"
+
+@interface World (TableDescription)
+- (NSMutableDictionary *)worldDescription;
+@end
+
+@implementation World (TableDescription)
+- (NSMutableDictionary *)worldDescription
+{
+ NSMutableDictionary *worldAttrs;
+ NSString *statusString;
+
+ switch ([self status]) {
+ case MxConnected:
+ statusString = @"c";
+ break;
+ case MxDisconnected:
+ statusString = @"d";
+ break;
+ case MxRecentActivity:
+ statusString = @"!";
+ break;
+ default:
+ statusString = @"";
+ }
+
+ worldAttrs = [NSMutableDictionary dictionaryWithObjects:
+ [NSArray arrayWithObjects: [self displayName], statusString, nil]
+ forKeys:
+ [NSArray arrayWithObjects: @"connection", @"status", nil]];
+
+ return worldAttrs;
+}
+@end
+
+@implementation WorldStatusController (TableViewDelegate)
+- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
+{
+ NSArray *worlds;
+ int row;
+
+ // Make the selected world the main window.
+ worlds = [[NSDocumentController sharedDocumentController] documents];
+ row = [theTableView selectedRow];
+ if (row >= 0 && (unsigned)row < [worlds count]) {
+ [[[worlds objectAtIndex: row] windowForSheet] makeKeyAndOrderFront: self];
+ [NSApp activateIgnoringOtherApps: YES];
+ }
+}
+
+- (void)tableView: (NSTableView *)aTableView
+ willDisplayCell: (id)aCell
+ forTableColumn: (NSTableColumn *)aTableColumn
+ row: (int)rowIndex
+{
+ NSArray *worlds;
+
+ worlds = [[NSDocumentController sharedDocumentController] documents];
+ if (rowIndex >= 0 && (unsigned)rowIndex < [worlds count]) {
+ NSColor *cellColor;
+ NSFont *font;
+ World *world;
+
+ font = [[NSFontManager sharedFontManager] fontWithFamily: @"Helvetica"
+ traits: NSUnboldFontMask | NSUnitalicFontMask
+ weight: 9.0
+ size: 12.0];
+ world = [worlds objectAtIndex: rowIndex];
+ switch ([world status]) {
+ case MxConnected:
+ cellColor = [[NSUserDefaults standardUserDefaults] connectedColor];
+ break;
+ case MxDisconnected:
+ cellColor = [[NSUserDefaults standardUserDefaults] disconnectedColor];
+ font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask];
+ break;
+ case MxRecentActivity:
+ cellColor = [[NSUserDefaults standardUserDefaults] recentActivityColor];
+ font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask];
+ break;
+ default:
+ cellColor = [NSColor blackColor];
+ break;
+ }
+ [aCell setFont: font];
+ [aCell setTextColor: cellColor];
+ }
+}
+@end
+
+@implementation WorldStatusController (TableViewDataSource)
+- (int)numberOfRowsInTableView: (NSTableView *)aTableView
+{
+ return [[[NSDocumentController sharedDocumentController] documents] count];
+}
+
+- (id)tableView: (NSTableView *)aTableView
+objectValueForTableColumn: (NSTableColumn *)aTableColumn
+ row: (int)rowIndex
+{
+ NSArray *worlds;
+
+ worlds = [[NSDocumentController sharedDocumentController] documents];
+ if (rowIndex >= 0 && (unsigned)rowIndex < [worlds count])
+ return [[[worlds objectAtIndex: rowIndex] worldDescription] objectForKey: [aTableColumn identifier]];
+ return nil;
+}
+@end
+
+@implementation WorldStatusController
++ (WorldStatusController *)sharedController
+{
+ static WorldStatusController *sharedController = nil;
+
+ if (sharedController == nil) {
+ sharedController = [[WorldStatusController alloc] init];
+ }
+ return sharedController;
+}
+
+- (id)init
+{
+ self = [self initWithWindowNibName: @"WorldSelector"];
+ [self setWindowFrameAutosaveName: @"worldStatusWindow"];
+ return self;
+}
+
+- (void)dealloc
+{
+ [[NSNotificationCenter defaultCenter] removeObserver: self];
+
+ [super dealloc];
+}
+
+- (void)selectWorld: (World *)aWorld
+{
+ NSArray *worlds;
+ int row;
+
+ if (aWorld) {
+ worlds = [[NSDocumentController sharedDocumentController] documents];
+ row = [worlds indexOfObject: aWorld];
+ [theTableView selectRow: row byExtendingSelection: NO];
+ } else
+ [theTableView deselectAll: self];
+}
+
+- (void)setFloating: (BOOL)isFloating
+{
+ [(NSPanel *)[self window] setFloatingPanel: isFloating];
+}
+
+- (void)setAlwaysVisible: (BOOL)isAlwaysVisible
+{
+ [(NSPanel *)[self window] setHidesOnDeactivate: isAlwaysVisible ? NO : YES];
+}
+
+- (void)windowDidLoad
+{
+ NSNotificationCenter *defaultCenter;
+
+ [super windowDidLoad];
+
+ defaultCenter = [NSNotificationCenter defaultCenter];
+ [defaultCenter addObserver: self
+ selector: @selector(userDefaultsChanged:)
+ name: NSUserDefaultsDidChangeNotification
+ object: [NSUserDefaults standardUserDefaults]];
+ [defaultCenter addObserver: self
+ selector: @selector(mainWindowChanged:)
+ name: NSWindowDidBecomeMainNotification
+ object: nil];
+ [defaultCenter addObserver: self
+ selector: @selector(windowClosed:)
+ name: NSWindowWillCloseNotification
+ object: nil];
+
+ [self setFloating: [[NSUserDefaults standardUserDefaults] selectorIsFloating]];
+ [self setAlwaysVisible: [[NSUserDefaults standardUserDefaults] selectorIsAlwaysVisible]];
+ [self selectWorld: [[NSDocumentController sharedDocumentController] currentDocument]];
+}
+
+- (void)update
+{
+ [theTableView reloadData];
+}
+
+- (void)userDefaultsChanged: (NSNotification *)aNotification
+{
+ [self setFloating: [[NSUserDefaults standardUserDefaults] selectorIsFloating]];
+ [self setAlwaysVisible: [[NSUserDefaults standardUserDefaults] selectorIsAlwaysVisible]];
+ [self update];
+}
+
+- (void)mainWindowChanged: (NSNotification *)aNotification
+{
+ World *world;
+
+ world = [[[aNotification object] windowController] document];
+ if ([world isKindOfClass: [World class]]) {
+ if ([world status] == MxRecentActivity)
+ [world setStatus: MxConnected];
+ [self update];
+ [self selectWorld: world];
+
+ [world showWindows];
+ [NSApp activateIgnoringOtherApps: YES];
+ }
+}
+
+- (void)windowClosed: (NSNotification *)aNotification
+{
+ [theTableView reloadData];
+ [self selectWorld: nil];
+}
+@end \ No newline at end of file
diff --git a/main.m b/main.m
new file mode 100644
index 0000000..5dcc906
--- /dev/null
+++ b/main.m
@@ -0,0 +1,14 @@
+//
+// main.m
+// Moxie
+//
+// Created by Brian Cully on Wed Dec 24 2003.
+// Copyright (c) 2003 Brian Cully. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, const char *argv[])
+{
+ return NSApplicationMain(argc, argv);
+}
diff --git a/version.plist b/version.plist
new file mode 100644
index 0000000..a293201
--- /dev/null
+++ b/version.plist
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>BuildVersion</key>
+ <string>17</string>
+ <key>CFBundleShortVersionString</key>
+ <string>0.1</string>
+ <key>CFBundleVersion</key>
+ <string>0.1</string>
+ <key>ProjectName</key>
+ <string>NibPBTemplates</string>
+ <key>SourceVersion</key>
+ <string>1150000</string>
+</dict>
+</plist>