3

I'm using SLIME and common LISP (SBCL) for some weekend hacking. I've just upgraded to emacs 26.1 on Mac OS X 10.13.5. Now I've run into a problem with the setup where I'm suddenly getting:

error in process filter: progn: Wrong number of arguments: (0 . 1), 2

I've turned on debug-on-error which provided me with

Debugger entered--Lisp error: (wrong-number-of-arguments (0 . 1) 2)

* eldoc-message("%s" #("(defun name lambda-list &body body)" 1 6 (face font-lock-keyword-face) 7 11 (face font-lock-function-name-face) 24 29 (face font-lock-type-face) 30 34 (face eldoc-highlight-function-argument)))
  (progn (eldoc-message "%s" (slime-autodoc--format doc multilinep)))
  (if (eldoc-display-message-p) (progn (eldoc-message "%s" (slime-autodoc--format doc multilinep))))
  (if (eq doc :not-available) nil (if cache-p (progn (slime-autodoc--cache-put context doc))) (if (eldoc-display-message-p) (progn (eldoc-message "%s" (slime-autodoc--format doc multilinep)))))
  (let* ((--cl-rest-- doc) (doc (if (= (length --cl-rest--) 2) (car-safe (prog1 --cl-rest-- (setq --cl-rest-- (cdr --cl-rest--)))) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--))))) (cache-p (car --cl-rest--))) (if (eq doc :not-available) nil (if cache-p (progn (slime-autodoc--cache-put context doc))) (if (eldoc-display-message-p) (progn (eldoc-message "%s" (slime-autodoc--format doc multilinep))))))
  slime-autodoc--async%(("defun" "equilateral-p" ("a" "b" "c") ("setq" "candidates" ("list" "a" "b" "c")) swank::%cursor-marker%) truncate-sym-name-if-fit ("(defun name lambda-list &body ===> body <===)" t))
  apply(slime-autodoc--async% (("defun" "equilateral-p" ("a" "b" "c") ("setq" "candidates" ("list" "a" "b" "c")) swank::%cursor-marker%) truncate-sym-name-if-fit ("(defun name lambda-list &body ===> body <===)" t)))
  (lambda (&rest more) (apply 'slime-autodoc--async% (append '(("defun" "equilateral-p" ("a" "b" "c") ("setq" "candidates" ("list" "a" "b" "c")) swank::%cursor-marker%) truncate-sym-name-if-fit) more)))(("(defun name lambda-list &body ===> body <===)" t))
  funcall((lambda (&rest more) (apply 'slime-autodoc--async% (append '(("defun" "equilateral-p" ("a" "b" "c") ("setq" "candidates" ("list" "a" "b" "c")) swank::%cursor-marker%) truncate-sym-name-if-fit) more))) ("(defun name lambda-list &body ===> body <===)" t))
  (progn (set-buffer (symbol-value G15)) (funcall (symbol-value G16) result))
  (if (symbol-value G16) (progn (set-buffer (symbol-value G15)) (funcall (symbol-value G16) result)))
  (let* ((--cl-rest-- rand-13) (result (if (= (length --cl-rest--) 1) (car --cl-rest--) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--)))))) (if (symbol-value G16) (progn (set-buffer (symbol-value G15)) (funcall (symbol-value G16) result))))
  (cond ((eql op-12 ':ok) (let* ((--cl-rest-- rand-13) (result (if (= (length --cl-rest--) 1) (car --cl-rest--) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--)))))) (if (symbol-value G16) (progn (set-buffer (symbol-value G15)) (funcall (symbol-value G16) result))))) ((eql op-12 ':abort) (let* ((--cl-rest-- rand-13) (condition (if (= (length --cl-rest--) 1) (car --cl-rest--) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--)))))) (message "Evaluation aborted on %s." condition))) (t (error "slime-dcase failed: %S" tmp-14)))
  (let* ((tmp-14 G11) (op-12 (car tmp-14)) (rand-13 (cdr tmp-14))) (cond ((eql op-12 ':ok) (let* ((--cl-rest-- rand-13) (result (if (= (length --cl-rest--) 1) (car --cl-rest--) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--)))))) (if (symbol-value G16) (progn (set-buffer (symbol-value G15)) (funcall (symbol-value G16) result))))) ((eql op-12 ':abort) (let* ((--cl-rest-- rand-13) (condition (if (= (length --cl-rest--) 1) (car --cl-rest--) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--)))))) (message "Evaluation aborted on %s." condition))) (t (error "slime-dcase failed: %S" tmp-14))))
  (closure ((--cl-buffer-- . --buffer--) (--cl-cont-- . --cont--) (package) (cont lambda (&rest more) (apply 'slime-autodoc--async% (append '(("defun" "equilateral-p" ("a" "b" "c") ("setq" "candidates" ("list" "a" "b" "c")) swank::%cursor-marker%) truncate-sym-name-if-fit) more))) (sexp swank:autodoc '("defun" "equilateral-p" ("a" "b" "c") ("setq" "candidates" ("list" "a" "b" "c")) swank::%cursor-marker%) :print-right-margin 200) slime-default-connection slime-net-processes slime-buffer-connection slime-buffer-package slime-current-thread slime-dispatching-connection slime-buffer-connection t) (G15 G16 G11) (let* ((tmp-14 G11) (op-12 (car tmp-14)) (rand-13 (cdr tmp-14))) (cond ((eql op-12 ':ok) (let* ((--cl-rest-- rand-13) (result (if (= (length --cl-rest--) 1) (car --cl-rest--) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--)))))) (if (symbol-value G16) (progn (set-buffer (symbol-value G15)) (funcall (symbol-value G16) result))))) ((eql op-12 ':abort) (let* ((--cl-rest-- rand-13) (condition (if (= (length --cl-rest--) 1) (car --cl-rest--) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--)))))) (message "Evaluation aborted on %s." condition))) (t (error "slime-dcase failed: %S" tmp-14)))))(--buffer-- --cont-- (:ok ("(defun name lambda-list &body ===> body <===)" t)))
  apply((closure ((--cl-buffer-- . --buffer--) (--cl-cont-- . --cont--) (package) (cont lambda (&rest more) (apply 'slime-autodoc--async% (append '(("defun" "equilateral-p" ("a" "b" "c") ("setq" "candidates" ("list" "a" "b" "c")) swank::%cursor-marker%) truncate-sym-name-if-fit) more))) (sexp swank:autodoc '("defun" "equilateral-p" ("a" "b" "c") ("setq" "candidates" ("list" "a" "b" "c")) swank::%cursor-marker%) :print-right-margin 200) slime-default-connection slime-net-processes slime-buffer-connection slime-buffer-package slime-current-thread slime-dispatching-connection slime-buffer-connection t) (G15 G16 G11) (let* ((tmp-14 G11) (op-12 (car tmp-14)) (rand-13 (cdr tmp-14))) (cond ((eql op-12 ':ok) (let* ((--cl-rest-- rand-13) (result (if (= (length --cl-rest--) 1) (car --cl-rest--) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--)))))) (if (symbol-value G16) (progn (set-buffer (symbol-value G15)) (funcall (symbol-value G16) result))))) ((eql op-12 ':abort) (let* ((--cl-rest-- rand-13) (condition (if (= (length --cl-rest--) 1) (car --cl-rest--) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--)))))) (message "Evaluation aborted on %s." condition))) (t (error "slime-dcase failed: %S" tmp-14))))) --buffer-- --cont-- (:ok ("(defun name lambda-list &body ===> body <===)" t)))
  (lambda (&rest --cl-rest--) (apply (function (closure ((--cl-buffer-- . --buffer--) (--cl-cont-- . --cont--) (package) (cont lambda (&rest more) (apply 'slime-autodoc--async% (append '(("defun" "equilateral-p" ("a" "b" "c") ("setq" "candidates" ("list" "a" "b" "c")) swank::%cursor-marker%) truncate-sym-name-if-fit) more))) (sexp swank:autodoc '("defun" "equilateral-p" ("a" "b" "c") ("setq" "candidates" ("list" "a" "b" "c")) swank::%cursor-marker%) :print-right-margin 200) slime-default-connection slime-net-processes slime-buffer-connection slime-buffer-package slime-current-thread slime-dispatching-connection slime-buffer-connection t) (G15 G16 G11) (let* ((tmp-14 G11) (op-12 (car tmp-14)) (rand-13 (cdr tmp-14))) (cond ((eql op-12 ':ok) (let* ((--cl-rest-- rand-13) (result (if (= (length --cl-rest--) 1) (car --cl-rest--) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--)))))) (if (symbol-value G16) (progn (set-buffer (symbol-value G15)) (funcall (symbol-value G16) result))))) ((eql op-12 ':abort) (let* ((--cl-rest-- rand-13) (condition (if (= (length --cl-rest--) 1) (car --cl-rest--) (signal 'wrong-number-of-arguments (list nil (length --cl-rest--)))))) (message "Evaluation aborted on %s." condition))) (t (error "slime-dcase failed: %S" tmp-14)))))) '--buffer-- '--cont-- --cl-rest--))((:ok ("(defun name lambda-list &body ===> body <===)" t)))
  slime-dispatch-event((:return (:ok ("(defun name lambda-list &body ===> body <===)" t)) 6) #<process SLIME Lisp>)
  slime-process-available-input(#<process SLIME Lisp>)
  slime-net-filter(#<process SLIME Lisp> "000045(:return (:ok (\"(defun name lambda-list &body ===> body <===)\" t)) 6)")

So my current belief is that eldoc is choking on the interpolated string being passed to the function eldoc-message.

What I'm not clear on is:

  1. Am I barking up the wrong tree here? I'm concerned that the function isn't explicitly mentioning progn
  2. Am I correct in thinking the # should be followed by a single quote mark to make it a lambda?
1
  • 1
    eldoc-message used to take any number of arguments, since Emacs 26, it takes 0 or 1 argument, however, you are supplying 2 arguments.
    – xuchunyang
    Commented Jun 26, 2018 at 9:12

2 Answers 2

2

A cleaner way, where you don't have to run mismatched SLIME and SWANK versions (which is asking for trouble), is to override the relevant function in SLIME that calls eldoc-message. Elisp is still a LISP after all.

This overrides slime-autodoc--async% with the version found in SLIME 2.21, just add it your .emacs (or any file you load):

;; fix for slime <v2.21 in emacs 26 (eldoc-message now only takes 1 arg)
(when (version< slime-version "2.21")
  (defun slime-autodoc--async%-fixed (context multilinep doc)
    (cl-destructuring-bind (doc cache-p) doc
      (unless (eq doc :not-available)
        (when cache-p
          (slime-autodoc--cache-put context doc))
        ;; Now that we've got our information,
        ;; get it to the user ASAP.
        (when (eldoc-display-message-p)
          (eldoc-message (slime-autodoc--format doc multilinep))))))

  (advice-add 'slime-autodoc--async% :override #'slime-autodoc--async%-fixed))

The above will fix the freezing when moving around when connected to a SWANK server, if you want to fix all instances of the bug you'll need to override a couple more functions:

;; fix for slime <v2.21 in emacs 26 (eldoc-message now only takes 1 arg)
(when (version< slime-version "2.21")
  (defun slime-autodoc--async%-fixed (context multilinep doc)
    (cl-destructuring-bind (doc cache-p) doc
      (unless (eq doc :not-available)
        (when cache-p
          (slime-autodoc--cache-put context doc))
        ;; Now that we've got our information,
        ;; get it to the user ASAP.
        (when (eldoc-display-message-p)
          (eldoc-message (slime-autodoc--format doc multilinep))))))

  (defun slime-autodoc-manually-fixed ()
    "Like autodoc informtion forcing multiline display."
    (interactive)
    (let ((doc (slime-autodoc t)))
      (cond (doc (eldoc-message doc))
        (t (eldoc-message nil)))))

  (defun slime-autodoc-space-fixed (n)
    "Like `slime-space' but nicer."
    (interactive "p")
    (self-insert-command n)
    (let ((doc (slime-autodoc)))
      (when doc
    (eldoc-message doc))))

  (advice-add 'slime-autodoc--async% :override #'slime-autodoc--async%-fixed)
  (advice-add 'slime-autodoc-manually :override #'slime-autodoc-manually-fixed)
  (advice-add 'slime-autodoc-space :override #'slime-autodoc-space-fixed))
2

For part one of this question the answer is no I was not barking up the wrong tree. To understand a little of why I have assembled my notes below.

SLIME did indeed had an issue with eldoc.

Eldoc changed it's documentation methods as described in the emacs NEWS file. This bug sheds some more light on it.

Slime did indeed violate the new contract as documented here,here, and most importantly for me here. The key phrase being

Now that Emacs 26.1 is out it would be nice to make a new release available via quicklisp.

I'm not certain about it but a quick check says I'm at the latest and greatest quicklisp.

; SLIME 2.21
CL-USER> (ql:update-dist "quicklisp")
You already have the latest version of "quicklisp": 2018-04-30.
NIL
CL-USER> (ql:update-client)
The most up-to-date client, version 2017-03-06, is already installed.
T

So after my latest update of slime from package mode I now have SLIME at:

slime              20180630.1721 

Which means I'm running swank and slime somewhat apart from generating this error:

Versions differ: 2.21 (slime) vs. 2.20 (swank). Continue? (y or n) y

But I can live with that over endless pauses for errors to bubble up into the UI.

Hope this helps someone else.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.