Skip to content

Enlighten Mode Causes Nrepl Eval to Accumulate Erroneous Information #3831

@aeonik

Description

@aeonik

Expected behavior

When evaluating code in CIDER, the nREPL eval request payload should contain file, line, and column information only once per evaluation.

Actual behavior

The nREPL eval request payload contains duplicate file, line, and column entries. Each subsequent evaluation appends additional copies of the position information to the same payload, leading to increasingly bloated request messages.

Steps to reproduce the problem

  1. Enable cider-enlighten-mode
  2. Evaluate any Clojure code in a file buffer (e.g., using C-x C-e or C-c C-c)
  3. Check the nREPL communication logs or debug output
  4. Observe multiple duplicate entries for "file", "line", and "column" keys in the eval request payload
  5. Subsequent evaluations will show even more duplicates

Root cause and fix

I think I figured it out, and fixed enlighten mode. This is the normal nrepl eval code, https://github.com/clojure-emacs/cider/blob/573b11209140e8cd87507abdaf2bedf2648fcb4a/nrepl-client.el#L1023C1-L1037C37

(defun nrepl--eval-request (input &optional ns line column)
 "Prepare :eval request message for INPUT.
NS provides context for the request.
If LINE and COLUMN are non-nil and current buffer is a file buffer, \"line\",
\"column\" and \"file\" are added to the message."
 (nconc (and ns `("ns" ,ns))
        `("op" "eval"
          "code" ,(substring-no-properties input))
        (when cider-enlighten-mode
          '("enlighten" "true"))
        (let ((file (or (buffer-file-name) (buffer-name))))
          (when (and line column file)
            `("file" ,file
              "line" ,line
              "column" ,column)))))

I switched it to this:

(defun nrepl--eval-request (input &optional ns line column)
 "Prepare :eval request message for INPUT.
NS provides context for the request.
If LINE and COLUMN are non-nil and current buffer is a file buffer, \"line\",
\"column\" and \"file\" are added to the message."
 (apply #'append
        (list (and ns `("ns" ,ns))
              `("op" "eval"
                "code" ,(substring-no-properties input))
              (when cider-enlighten-mode
                '("enlighten" "true"))
              (let ((file (or (buffer-file-name) (buffer-name))))
                (when (and line column file)
                  `("file" ,file
                    "line" ,line
                    "column" ,column))))))

And enlighten mode is fixed.
Background: I was looking at the nrepl logs with enlighten mode on, and I noticed that eval was accumulating a lot of extra redundant information:

(-->
 id                             "757"
 op                             "eval"
 session                        "0f1663da-6e89-4780-9742-dec54a6e2885"
 time-stamp                     "2025-08-02 14:09:28.437118000"
 code                           "(defn get-legacy-instance-mapping
 "Returns legacy instance..."
 column                         1
 column                         1
 column                         1
 column                         1
 enlighten                      "true"
 file                           "/Users/aeonik/Projects/joystick_fixer/src/aeonik/contr..."
 file                           "/Users/aeonik/Projects/joystick_fixer/src/aeonik/contr..."
 file                           "/Users/aeonik/Projects/joystick_fixer/src/aeonik/contr..."
 file                           "/Users/aeonik/Projects/joystick_fixer/src/aeonik/contr..."
 line                           49
 line                           49
 line                           49
 line                           49
 nrepl.middleware.print/options (dict ...)
 nrepl.middleware.print/print   "cider.nrepl.pprint/pr"
 nrepl.middleware.print/quota   1048576
 nrepl.middleware.print/stream? nil
 ns                             #("aeonik.controlmap.core" 0 22 (face font-lock-type-face cider-block-dynamic-font-lock t cider-locals nil help-echo cider--help-echo fontified nil))
)

Something relating to nconc was accumulating values on every eval. The issue is caused by the destructive nconc function modifying shared list structures across multiple function calls, particularly the quoted list '("enlighten" "true") which gets reused and modified. Using apply #'append creates fresh lists each time instead of destructively modifying existing ones. Though I am not sure if this is the best solution, just something that worked during testing.

Environment & Version information

CIDER version information

CIDER 1.18.0 (Athens), nREPL 1.3.1
Clojure 1.12.0, Java 24.0.1

Emacs version

30.1

Operating system

macOS 15.5 Darwin 24.5.0 arm64 (also reproduced on Linux)

JDK distribution

Java 24.0.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions