Deleting InstancesTopWorking Within a FileEnhancing Your Development EnvironmentGoTo Top

Enhancing Your Development Environment

Now that you are experienced creating and deleting unit and space instances in GBBopen, we will take a short break before working further on our random-walk application. In the exercises thus far, we have been working directly in Common Lisp's REPL. As our application develops, we want to save our code in files. In this exercise, we will provide recommendations for making your GBBopen and Common Lisp environment more productive. Even if you have already customized your Common Lisp setup, I recommend surveying this exercise for useful GBBopen tips.


This exercise shows you how to:


Step 1: Autoloading GBBopen's initiate.lisp file

Thus far, we have entered the forms:

  cl-user> (load "<install-dir>/initiate.lisp")
     ...
  cl-user> :gbbopen-user
     ...
  gbbopen-user>
to compile and load needed GBBopen components and to set the current package to :gbbopen-user. We can set up our Common Lisp environment so that we can do this (and eventually compile and load our random-walk application) by issuing only a single REPL command.

Customizing your Common Lisp initialization file

I'm lazy and would rather not have to explicitly load the <install-dir>/initiate.lisp file each time I start a new Common Lisp session. So, I have my Common Lisp's initialization file load it for me. To make it easy to similarly customize different Common Lisp implementations, I use the following strategy:

  1. I create a file, shared-init.lisp, in my home directory, containing the following:
      (in-package :common-lisp-user)
    
      ;; My personal preferences.  Note: Allegro CL requires 
      ;; tpl:setq-default during initialization to retain changes
      ;; to these global variables (done in .clinit.cl):
      (setf *print-case* ':downcase)
      (setf *compile-verbose* 't)
      (setf *load-verbose* 't)
    
      (let ((defaults *load-truename*))
        (load (make-pathname 
                ;; where GBBopen is installed:
                :directory '(:absolute "usr" "local" "gbbopen")
                :name "initiate"
                :type "lisp"
                :defaults defaults)))
    

    The :directory argument to make-pathname is a Common Lisp absolute pathname that is portable across all operating systems. I installed my GBBopen in /usr/local/gbbopen/, and I specified this with the "usr", "local", and "gbbopen" elements in the :directory argument. Change these elements as appropriate for the location of your GBBopen installation.

  2. For each Common Lisp implementation that I use, I create a personal initialization file that performs any implementation-specific initializations and then loads shared-init.lisp. For example, here is the .clisprc initialization file that I use for CLISP:
      (in-package :common-lisp-user)
    
      ;; enable maximum ANSI compliance:
      (setf custom:*ansi* 't)
    
      (let ((defaults *load-truename*))
        (load (make-pathname 
                :name "shared-init"
                :type "lisp"
                :defaults defaults)))
    

    SBCL has a very strict interpretation of *load-truename* semantics, so my .sbclrc initialization file is:

      (in-package :common-lisp-user)
    
      ;; *load-truename* returns nil when used in SBCL's .sbclrc 
      ;; initialization file, so use (user-homedir-pathname):
      (let ((defaults (user-homedir-pathname)))
        (load (make-pathname 
                :name "shared-init"
                :type "lisp"
                :defaults defaults)))
    

    Here is my .clinit.cl initialization file for Allegro CL:

      (in-package :common-lisp-user)
    
      ;; Allegro CL requires tpl:setq-default during initialization
      ;; to retain changes to these global variables:
      (tpl:setq-default *print-case* ':downcase)
      (tpl:setq-default *compile-verbose* 't)
      (tpl:setq-default *load-verbose* 't)
    
      (let ((defaults *load-truename*))
        (load (make-pathname 
                :name "shared-init"
                :type "lisp"
                :defaults defaults)))
    

    The initialization file names for various Common Lisp implementations are:

           ABCL        .abclrc
    Allegro CL .clinit.cl
    CLISP .clisprc
    Clozure CL ccl-init.lisp
    CMUCL init.lisp
    Digitool MCL (see below)
    ECL .eclrc
    LispWorks .lispworks
    SBCL .sbclrc
    Scieneer CL init.lisp
    XCL .xclrc

    Digitool MCL does not look for an initialization file in the user's home directory. Instead it loads the file init.lisp in it's installation directory. One approach is to have that file load a personal initialization file, say mcl-init.lisp, from the user's home directory, if a mcl-init.lisp file is present.

    The Personal Edition of LispWorks does not load initialization files, requiring you to manually load your .lispworks file each time you start up LispWorks.

    The interpretation of where a user's “home” directory is located is inconsistent on Windows. Ideally, the “home directory” location used for the Common Lisp implementation's initialization file and the result of the Common Lisp function user-homedir-pathname should be consistent. Then, by using the shared-init.lisp scheme, you only need to determine where the initialization file should be for each Common Lisp implementation that you use, and then you can have those implementation-specific initialization files load your shared-init.lisp file from whichever directory you deem as your “home” directory.

    Here is a quick way to have Common Lisp tell you where it thinks your “home” directory is located:

      cl-user> (not (princ (truename (user-homedir-pathname))))
      C:\Documents and Settings\corkill\
      nil
      cl-user>
    
    Alternatively, loading GBBopen's <install-dir>/initiate.lisp file will display the “home” directory.

    We will refer to this directory from now on as your “homedir” directory.


     
  3. With this setup in place, all that is needed to use GBBopen is to start up a Common Lisp and type a GBBopen command, such as :gbbopen-user. My fingers thank me!

Step 2: Set up HyperDoc and HyperSpec access

If you are using Emacs in your Common Lisp development environment, you can make it easy to bring up appropriate Common Lisp and GBBopen documentation in your browser. The file <install-dir>/browse-hyperdoc.el defines an interactive Emacs command named browse-hyperdoc and binds it to META-? (on most keyboards, META-? means pressing both Alt and ? keys at the same time) . To enable this Emacs command, add a command to load <install-dir>/browse-hyperdoc.el in your .emacs initialization file:

  ;; GBBopen hyperdoc (where GBBopen was installed):
  (load "<install-dir>/browse-hyperdoc")

If there is no .emacs file present in your home directory, simply create one containing the above command. Once again, Windows users need to worry about where Emacs looks for their “home” directory.

While you are editing your .emacs file, you might also want to add a command to load GBBopen's Emacs indentation customizations:

  ;; GBBopen indentations (where GBBopen was installed):
  (load "<install-dir>/gbbopen-indent")

Adding the Common Lisp HyperSpec

The hyperspec.el utility is included in the SLIME and ILISP distributions. However, if hyperspec.el is not already part of your Emacs, you can download it and explicitly load it from your .emacs initialization file. Once hyperspec.el is present, GBBopen's browse-hyperdoc Emacs command will automatically defer to the Common Lisp HyperSpec when given a non-GBBopen entity.

I prefer to download a local copy of the Common Lisp HyperSpec using the down-loadable archive provided by LispWorks, LTD. This allows me to quickly reference the HyperSpec without a network connection. I set the value of common-lisp-hyperspec-root in my .emacs initialization file to a URL that points to my local copy of the HyperSpec:

  (setf common-lisp-hyperspec-root "file:/usr/local/CLHS/")

Non-Emacs access

If you are not using an Emacs-based environment, GBBopen provides a Common Lisp function, browse-hyperdoc, that can be used to access GBBopen HyperDoc pages from Common Lisp. GBBopen's :os-interface module must be loaded to make browse-hyperdoc available. For example:

  cl-user> :os-interface
  ;; Loading <install-dir>/startup.lisp
     ...
  ;; Loading <install-dir>/<platform-dir>/tools/os-interface.fasl
  gbbopen-tools> (browse-hyperdoc 'define-unit-class)
  t
  gbbopen-tools>
will display the GBBopen HyperDoc page for define-unit-class in your browser. Note that the :gbbopen-user module requires (and therefore loads) the :os-interface module, so if you have loaded :gbbopen-user, you do not need to do anything further in order to call browse-hyperdoc.


The GBBopen Project


Deleting InstancesTopWorking Within a FileEnhancing Your Development EnvironmentGoTo Top