Skip to content

[load-file] Reimplement load-file again#391

Merged
alexander-yakushev merged 3 commits into
masterfrom
load-file
Sep 30, 2025
Merged

[load-file] Reimplement load-file again#391
alexander-yakushev merged 3 commits into
masterfrom
load-file

Conversation

@alexander-yakushev
Copy link
Copy Markdown
Member

@alexander-yakushev alexander-yakushev commented Sep 20, 2025

This is the first piece of the jigsaw puzzle called "how to retain the debugger instrumentation during C-c C-k" (see clojure-emacs/cider-nrepl#946, https://clojurians.slack.com/archives/C04CAKAGADU/p1757684821897969).

To make it possible for the debugger to instrument forms when doing C-c C-k we have to abandon the Compiler/load approach for load-file middleware and instead let the interruptible-eval middleware be the driver for everything. Interruptible-eval must read through the whole file form by form and call the custom eval function on each form.

By doing this there are a few risks:

  • We change a quite fundamental part of nREPL again. Not the most critical, I think – eval is still the most important, and we changed it too in the past, everything seems to be alright.
  • There could be some minor behavior changes in how load-file will work, but I tried to make it as resembling Compiler/load as possible.
  • I had to drop some alternative way to load a file which I marked as deprecated for 1.4.0. This is a short notice for sure, but nREPL updates don't move that fast anyway. Whoever might be impacted by this will likely stay on 1.0.0 or 1.3.0 for a long time and will be able to update to 1.4.0 safely still.
  • I'm also removing nrepl.helpers/load-file-command. This looks like a command-line REPL affordance to load files using the old old way. There is no mention of it in the documentation, and no occurance of using this funciton on Github. I'd just remove it and wait for anybody to complain. If this is still useful to somebody, we can provide a better helper for that.

Don't need to merge this yet as this is experimental, I should definitely dogfood this, and backwards-compatible changes are required in cider-nrepl too.


  • You've updated the changelog(that only applies to user-visible changes)

* `:column` The column number in [file] at which [code] starts.
* `:eval` A fully-qualified symbol naming a var whose function value will be used to evaluate [code], instead of ``clojure.core/eval`` (the default).
* `:file` The path to the file containing [code]. ``clojure.core/\*file*`` will be bound to this.
* `:file-name` Name of source file, e.g. io.clj
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main concern with the PR is that now looks a bit strange that we have a :file param and a :file-name param. Perhaps we should either rename the old param with a more descriptive name (as an alias, keeping backwards compatibility) or expand the description about the need for both.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll edit the docs. Renaming, even with an compatibility alias, might be too much for the holy eval. Maybe, one day, we can do a sweeping take on it where we can clean up all the cruft – rename it from interruptible-eval? (gasp!) Maybe in nREPL 2?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps. I'm mostly concerned about this from the perspective of the people looking at the current implementation as the spec, but I guess we can do a cleaner "official spec" around nREPL 2 as well.

But I agree that down the road we can revisit the name of the eval middleware and potentially the need for load-file as a separate op.

@bbatsov
Copy link
Copy Markdown
Contributor

bbatsov commented Sep 23, 2025

Overall the code changes look good to me, but you'll have to dogfood them for a while before we can merge this, given the the relative importance of this functionality. I always start with load-file before switching to more granular evals in my own Clojure workflow. (I also often use load-file to reset all breakpoints in a namespace)

@alexander-yakushev
Copy link
Copy Markdown
Member Author

So, you are saying that you rely on C-c C-k not enabling the debugger, even in forms where you have a #dbg? Or you mean that you use it to clear debugged functions that were compiled with C-u C-c C-c (so, no explicit #dbg in the code)?

@bbatsov
Copy link
Copy Markdown
Contributor

bbatsov commented Sep 23, 2025

Or you mean that you use it to clear debugged functions that were compiled with C-u C-c C-c (so, no explicit #dbg in the code)?

This - I was just sharing how I normally use load-file myself. I never got in the habit of using #dbg, as it doesn't exist in Elisp and I often switch between Clojure and Emacs Lisp. I do agree, that #dbg breakpoints should not disappear on load-file, so I'm fine with this PR in general.

@alexander-yakushev alexander-yakushev force-pushed the load-file branch 8 times, most recently from 20e5403 to 3a51f8b Compare September 23, 2025 17:38

This comment was marked as resolved.

@alexander-yakushev
Copy link
Copy Markdown
Member Author

@bbatsov I'm going to merge this and publish an alpha1 release, just need a thumbs up from @ericdallo. On my side, nothing has broken in the days I've been using this.

@bbatsov
Copy link
Copy Markdown
Contributor

bbatsov commented Sep 30, 2025

Sounds good to me.

@alexander-yakushev alexander-yakushev merged commit 2a17485 into master Sep 30, 2025
21 checks passed
@alexander-yakushev alexander-yakushev deleted the load-file branch September 30, 2025 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants