When writing Common Lisp code, I use SLIME. In particular, I compile the buffer containing definitions of functions by using C-C C-k, and then switch to the REPL to run thos
Fare Rideau wrote a nifty unix utility CL-Launch, which enables executing lisp software from the command line. It has integrated Quicklisp support and works on most of the Common Lisp implementations.
Example script may look like this:
#!/usr/bin/cl -sp "hunchentoot" -Q -E main
(defun main (argv)
(format t "~A: ~{~A ~}~%" (truename ".") argv)
(hunchentoot:start
(make-instance 'hunchentoot:acceptor
:document-root (truename ".")
:port 8080))
(do ((x #\s (read-char)))
((char-equal x #\q) nil)))
After adding +x permissions to script and invoking it, it will start http server in the current directory. "-sp" flag indicates package you want to load, so it's fairly clean way of abstracting shell script from the package.
For more details refer: http://cliki.net/CL-Launch
You can use the following trick:
Define a dispatch function for shebang:
(set-dispatch-macro-character #\# #\!
(lambda (stream c n)
(declare (ignore c n))
(read-line stream)
`(eval-when (:compile-toplevel :load-toplevel :execute)
(pushnew :noscript *features*))))
In your script file use #-:noscript
:
#!/usr/local/bin/sbcl --script
(defun test (a) (print a))
(test 1)
#-:noscript (test 2)
#+:noscript (test 3)
Executing ./test.lisp
will print 1 and 2, while C-c C-k will output 1 and 3.
EDITS
This trick should work, because the shebang line is removed altogether by sbcl --script
, but not removed, when the file is loaded through SLIME or other mechanisms.
The drawback of this approach is that we condition on absence of :noscript
in features, and not presence of :script
. To amend it, pushing of the appropriate feature should be done in sbcl --script
processing itself.
I had the same question and I have just stumbled upon this discussion. At least with sbcl it seems I can use (sb-ext:posix-getenv "_")
. When run in slime it returns /usr/bin/emacs
(or whatever the path to emacs is) and otherwise the command I use to invoke the script. So it is always possible to differentiate between slime and script invocation until you're an emacs contributor :)
If you want to get the full pathname of the script you are invoking, you can use (truename (sb-ext:posix-getenv "_"))
. However, when run from slime it will return the effective emacs pathname, e.g. /usr/bin/emacs-24.5
, so this might be less convenient.