5
votes

I am trying to get Emacs, SLIME and quicklisp to work together properly. I have the following environment set up:

  • Installed Emacs
  • Installed SLIME in Emacs
  • Installed SBCL
  • Installed quicklisp
  • Run (quicklisp-quickstart:install) in SBCL
  • Run (ql:add-to-init-file) in SBCL
  • Run (ql:quickload "quicklisp-slime-helper") in SBCL
  • Installed package cl-csv using (ql:quickload "cl-csv") in SBCL
  • Added (setq inferior-lisp-program "sbcl") to .emacs
  • Added (load (expand-file-name "~/quicklisp/slime-helper.el")) to .emacs
  • Restarted everything

I have a test.lisp file that starts with (ql:quickload "cl-csv") to load the package and use it. When I load the file into Emacs and run SLIME, then try to compile it using slime-compile-and-load-file, I get the error in SBCL that Package CL-CSV does not exist.

What have I missed to get these pieces working together properly?

3
can you provide your source file? (or at least the part with quickload and reference to cl-csv)Vsevolod Dyomkin
you can't really "load" a Common Lisp file into Emacs. But you can edit it.Rainer Joswig

3 Answers

7
votes

If you compile a file which contains a statement

(ql:quickload "cl-csv")

then this call will be compiled, but not executed. That's what a compiler usually does: it compiles, but does not execute. Thus if you use some Lisp package (a namespace) later in the same file - a package which would be introduced in the system cl-csv - then it might not be present, if you have not loaded it before, by loading the system.

There are two typical solutions to this:

  • put the loading command in a file which one compiles (optionally) and/or loads before
  • use EVAL-WHEN with :compile-toplevel, :load-toplevel and :execute

Note that cl-csv is a system, organizing source files. A package is a Lisp namespace for organizing Lisp symbols. A package and a system can have the same name, but they really are two different things.

5
votes

Calling ql:quickload directly is good for tests and while interacting with your development environment. If you use some systems a lot, you may quickload them inside your initialization file (in your case, ~/.sbclrc).

However, your purpose when programming is generally to develop a new system (a library, or an application, but as far as Common Lisp is concerned, this is a "system"). You generally do not need to have explicit (ql:quickload ...) calls inside your source code. Instead, you define a system where you declare dependencies and your code assumes that the appropriate dependencies are loaded.

  • Create and enter directory "my-system"
  • Create and edit "my-system.asd"

    (in-package :asdf-user)
    (defsystem :my-system
       :depends-on (:cl-csv))
    

Quicklisp can find your system if you link the directory inside ~/quicklisp/local-projects/. So the next time you restart your Lisp and want to develop on my-system, you can perform (ql:quickload :my-system) which will load all the declared dependencies.

0
votes

Reinstall quicklisp at the Emacs' SLIME REPL.

The problem is that Emacs Slime (REPL) doesn't know neither whether quicklisp is installed nor where it is installed. All you have to do to fix the problem is to reinstall quicklisp at the Emacs' slime repl. ("quicklisp.lisp" file should be in the SLIME REPL's current working folder.)

M-x slime 
CL-USER> (load "quicklisp.lisp")
CL-USER> (quicklisp-quickstart:install)
CL-USER> (ql:add-to-init-file)
CL-USER> (ql:quickload "quicklisp-slime-helper")    

e.g.) My "~/.emacs" file:

(use-package slime
  :ensure t
  :defer t
  :init
    (setq inferior-lisp-program "clisp")
  :config      
    (slime-setup '(slime-fancy slime-company))
  :hook
  (slime-mode . slime-company)
  (slime-mode . (lambda ()
                  (load (expand-file-name "D:/util/emacs27/quicklisp/slime-helper.el"))
                  (add-to-list 'slime-contribs 'slime-fancy)
                  (add-to-list 'slime-contribs 'inferior-slime))))

(use-package slime-company
  :after slime
  :bind-keymap 
    ("C-n" . company-select-next)
    ("C-p" . company-select-previous)
    ("C-d" . company-show-doc-buffer)
    ("M-." . company-show-location)
  :config (setq slime-company-completion 'fuzzy
                slime-company-after-completion 'slime-company-just-one-space))

Then, quicklisp will be reinstalled in the Emacs's HOME directory ("~/"). Now, you have installed the same quicklisp in the (a) Windows 10's HOME and (a) the Emacs' HOME. If you use quicklisp only at the Emacs' Slime REPL, the copy in the Windows 10' HOME is useless, and you can delete it.