Command line editing and auto completion with CMUCL, SBCL, or AllegroCL

This is for the rare cases when you don't use SLIME but invoke CMUCL (works also for other Lisps like SBCL or AllegroCL) directly from the command line:

  1. Get rlwrap and build it.
  2. Put something like
      export BREAK_CHARS="\"#'(),;\`\\|!?[]{}"
      alias cmucl="rlwrap -b \$BREAK_CHARS cmucl"
    
    into your ~/.bashrc (or ~/.profile or whatever).
  3. Create a file ~/.cmucl_completions using the following ugly piece of code:
      (with-open-file (!!!-stream "/home/edi/.cmucl_completions"
                                  :direction :output
                                  :if-exists :supersede)
        (let ((!!!-seen (make-hash-table :size 6000 :test #'equal))
              (!!!-cl-package (find-package "CL"))
              (!!!-cl-user-package (find-package "CL-USER")))
          (loop for !!!-package in (list-all-packages)
                do (let ((!!!-prefixes
                           (if (or (eq !!!-package !!!-cl-package)
                                   (eq !!!-package !!!-cl-user-package))
                             (list "")
                             (mapcar #'(lambda (!!!-prefix)
                                         (concatenate 'string
                                                      (string-downcase !!!-prefix)
                                                      ":"))
                                     (if (package-nicknames !!!-package)
                                       (package-nicknames !!!-package)
                                       (list (package-name !!!-package)))))))
                     (loop for !!!-symbol being the symbols of !!!-package
                           for !!!-symbol-name = (symbol-name !!!-symbol)
                           when (or (eq (nth-value 1
                                          (find-symbol !!!-symbol-name
                                                       !!!-package))
                                        :external)
                                    (eq !!!-package !!!-cl-user-package))
                           do (loop for !!!-prefix in !!!-prefixes
                                    do (let ((!!!-completion
                                               (format nil
                                                       "~A~A~%"
                                                       !!!-prefix
                                                       (string-downcase !!!-symbol))))
                                         (unless (or (gethash !!!-completion !!!-seen)
                                                     (string= "!!!-"
                                                              !!!-symbol-name
                                                              :end2 (min
                                                                     (length !!!-symbol-name)
                                                                     4)))
                                           (setf (gethash !!!-completion !!!-seen)
                                                   t)
                                           (princ !!!-completion !!!-stream)))))))))
    
    This code should be run from a freshly started image.
  4. Optionally adjust your ~/.inputrc file (actually the file where $INPUTRC points to). I added the line
      TAB: complete
    
    because rlwrap binds this key to menu-complete. Maybe you'll also want
      set completion-ignore-case on
    

Note that recent readline versions include an example program rlfe that does almost the same thing as rlwrap. I think rlwrap is nicer, though.

$Header: /usr/local/cvsrep/weitz.de/completions.html,v 1.6 2007/12/03 06:36:04 edi Exp $

BACK TO MY HOMEPAGE