cider-nrepl icon indicating copy to clipboard operation
cider-nrepl copied to clipboard

Incomplete specification of the info and eldoc ops

Open yuhan0 opened this issue 1 month ago • 5 comments

https://docs.cider.mx/cider-nrepl/nrepl-api/ops.html#info The specification for the info op only mentions the following keys in the return message:

:doc-block-tags-fragments - may be absent
:doc-first-sentence-fragments - may be absent
:doc-fragments - may be absent
:status - `done`

In reality, the frontend (Emacs / cider-doc) relies on various other compulsory (non-nil) keys in the map, such as :name and :ns.

When the info op is requested for ill-formed input (eg. a non-existent var), the cider-nrepl implementation signals this by returning :no-info in its status:

https://github.com/clojure-emacs/cider-nrepl/blob/11ae4eec39b3cffcb70088f7f153a8b8fb147e0e/src/cider/nrepl/middleware/info.clj#L129

This is also undocumented, but relied upon by the frontend to guard against parsing of an empty (malformed) var-info response.

https://github.com/clojure-emacs/cider/blob/810337cee931d9f14aa16550a74516f8337a47f3/cider-client.el#L691 (Relevant call stack: cider-doc-lookup -> cider-create-doc-buffer -> cider-var-info -> cider-sync-request:info)

Similarly, the eldoc op implicitly relies on a :no-eldoc status to signal an empty return value.

The problem occurs with the babashka.nrepl implementation of the protocol, which also claims to provide the info and eldoc ops, but sometimes returns an map missing many 'required' keys such as :name, and a done status. This results in varying degrees of breakage when CIDER is connected to a babashka-type REPL.

Clearly this would be a simple fix on the impl to return the appropriate :no-info / :no-eldoc statuses, but I thought it would be worth properly pinning down the return contracts before raising an issue there.

Otherwise given the current underspecified docs, it could technically be seen as a well-formed response that requires additional logic on the frontend(s) to guard against nil values.

Steps to reproduce (Emacs / Cider 1.15)

  • Create a standalone .bb file with the contents:
;; repro.bb
(ns repro)

(defn foo
  "See also: `bar`"
  [])
  • cider-jack-in with the babashka project type (C-u 3 C-c M-j)

  • cider-load-buffer, then cider-doc on the foo symbol.

  • Click the xref link for bar in the doc buffer (a non-existent var).

  • The elisp error is thrown: Wrong type argument: stringp, nil (Note: cider-doc on a non-existent symbol is wrapped in a condition-case, and falls back to a minibuffer prompt on encountering this error)

  • Also observe the broken eldoc displayed in calls to non-existent vars:

(oops  ) ; <- with cursor in form

Environment & Version information

NA

yuhan0 avatar Jul 02 '24 12:07 yuhan0