Zach Beane (xach) wrote,
Zach Beane
xach

More irritant-reduction

In SBCL, ASDF hooks into the REQUIRE mechanism so you can type (require 'mysystem). On other systems you can also figure out a way to hook REQUIRE, so you can avoid typing (asdf:oos 'asdf:load-op 'mysystem).

I got tired of trying to figure out how to do this in different ways on different Lisp systems, so below is a file I've been loading from my init files to get consistent, concise ASDF loading across implementations. It also adds a crude registry maintenance system and a way to reload a system without using :FORCE. :FORCE has the downside of recompiling and reloading all other dependencies, which is never what I want.

It's a work in progress, but so far I've been pretty happy using (asdf:load* 'mysystem) and (asdf:reload 'mysystem). YMMV.

(require 'asdf)

(in-package #:asdf)

(export '(load* reload register register-permanently))

(defvar *registry-file*
  (merge-pathnames (make-pathname :directory '(:relative "asdf")
                                  :name "registry"
                                  :type "sexp")
                   (user-homedir-pathname)))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (let ((registry (probe-file *registry-file*)))
    (when registry
      (with-open-file (stream registry)
        (loop for form = (read stream nil)
              while form do (push form *central-registry*))
        (setf *central-registry*
              (remove-duplicates *central-registry* :test #'equalp))))))

(defun load* (system &key verbose)
  (oos 'load-op system :verbose verbose)
  t)

(defun reload (system)
  (let ((name (coerce-name system)))
    (remhash name *defined-systems*)
    (load* name)))

(defun register (form)
  (pushnew form *central-registry* :test #'equalp))

(defun register-permanently (form)
  (register form)
  (ensure-directories-exist *registry-file*)
  (with-open-file (stream *registry-file*
                   :direction :output
                   :if-exists :append
                   :if-does-not-exist :create)
    (prin1 form stream)
    (terpri stream)))

;;; Automatically recompile stale FASLs

(handler-bind ((style-warning #'muffle-warning))
  (defmethod perform :around ((o load-op) (c cl-source-file))
    (handler-case (call-next-method o c)
      (#+sbcl sb-ext:invalid-fasl
       #-sbcl error ()
       (perform (make-instance 'compile-op) c)
       (call-next-method)))))

Do you have any ugly local hacks that you think aren't polished enough to share, but that make your life much easier? Share them anyway, and let's clean them up and use them and improve life everywhere.

Tags: lisp
Subscribe

  • New pixel speech bubble thing

    I made a new pixel speech bubble site. It's like the old one on Wigflip, but I think it's better.

  • My blog has moved

    I've been writing over at lispblog.xach.com. I'm not going to update LiveJournal any more.

  • Common Lisp bits

    Heinrich Apfelmus has updated to the source code from Computer Models of Musical Creativity and put it on github. Looks like it's meant to work…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 8 comments