Wednesday, November 16, 2011

25 so far

still lives, a set on Flickr.
I've been doing still lives for a flickr drawing club. You've got to have 50 by the end of the month, I just 'finished' #25. A bit lackluster, but it's nice to finally be drawing from life again regularly.

fixes for the common lisp zip package

The zip package as it exists is broken for me on sbcl and ccl on OS X 10.7.2.
I made some fixes to it early last week, but it appears the maintainer is MIA
so here's my version in the meantime. Hacking on it was pretty easy with the new
quicklisp local-projects feature, and I learned some new pathname functions I didn't
know about. Fun!

Tuesday, November 15, 2011

How To Send A Fax In South Philly

The South Philly Post Office at Broad & Moore doesn't have a fax machine. You gotta go to the check cashing place behind the Rita's Water Ice at Broad & Jackson (on Jackson).  I heard there might be one at the Staples by the Sav-A-Lot on Snyder too, but that's too far away.

Friday, November 11, 2011


Here's a little bit of elisp to enable the excellent auto-complete-mode to understand SLIME:

(defun jsn-slime-source ()
  (let* ((end (move-marker (make-marker) (slime-symbol-end-pos)))
  (beg (move-marker (make-marker) (slime-symbol-start-pos)))
  (prefix (buffer-substring-no-properties beg end))
  (completion-result (slime-contextual-completions beg end))
  (completion-set (first completion-result)))

(defvar ac-source-slime '((candidates . jsn-slime-source)))

Once these are added to your .emacs, add these two expressions to your lisp-mode

  (setq ac-sources '(ac-source-slime))

and you'll get nice modern-looking popup completions as you type.

Friday, January 28, 2011

slime clojure hack

hello, world

Came up with a functional little hack for slime and clojure today, currently called Slimer:
By defining a hook inside the clojure swank function listener-eval and a custom repl shortcut
on the emacs side, we can have the repl run temporarily through a function that replaces
the repl input with it's results, and evaluates them -- effectively acting as a macro.

2 files:


(in-ns 'swank.commands.basic)

(def **f nil)

(defslimefn listener-eval [form]
  (if **f
    (let [f  (read-string form)
          f2 (list 'quote f)
          r  (eval (list **f f2))]
      (send-repl-results-to-emacs r))
 (let [[value last-form] (eval-region form)]
   (when (and last-form (not (one-of? last-form '*1 '*2 '*3 '*e)))
     (set! *3 *2)
     (set! *2 *1)
     (set! *1 value))
   (send-repl-results-to-emacs value))))))


(defun slimer-pkg ()
  (let ((p (slime-current-package)))
    (if p (concat p "/") nil)))

(defslime-repl-shortcut nil  ("dsl")
   (lambda (str)
     (interactive (list (slime-read-from-minibuffer
    "function:" (or (slimer-pkg) ""))))
     (let ((sym (if (or (string-equal str (slimer-pkg))
   (string-equal str ""))
      "nil" str)))
 (concat "(do (in-ns 'swank.commands.basic) (def **f " sym " ))"))
       (setf (slime-lisp-package-prompt-string)
      (if (string-equal sym "nil")
        (concat sym " $$"))))

(provide 'slimer)

I warned you it was ugly.

drop the .el into your emacs load path, and the .clj in the /src of your lein project,
and then you can just (require 'slimer) on both sides, and you're ready to go!

now, the code is ugly, and may only work with my version of slime, swank, and swank-clojure etc,
so YMMV. It's a useful for me as-is, but it would be neat to see this functionality made generally
available instead of as a hack.

current setup is to provide the repl shortcut ( comma command )  "dsl" which will prompt for a
symbol in the current namespace, evaluate it, and attempt to apply it's value as a function to
subsequent forms entered at the repl, evaluating the results. If you accept the default at
the prompt i.e. just press enter -- it will return the repl to it's original behavior.

The repl prompt is also changed to the string of the expression that yielded the current function + "  $$"
during dsl mode to make it easier to use. As it is, the entered code is read and then passed, as that seems
more useful, but by removing the call to read-string in line 3 of listener-eval it could be used to operate on raw strings, which may be useful it you're attempting to use syntax clojure does not understand.

 ...anyway, the code's really ugly but it works for now. If there's something better, please let me know!