Skip to content

Conversation

wilbrt
Copy link

@wilbrt wilbrt commented Sep 6, 2025

Change cider-ns-refresh to use a Clojure REPL whenever one exists, by wrapping the function body in a with-current-buffer with the clj-repl connection if it exists. If not, throw a no-repls-user-error. Fixes #3834.

Not sure if this is a reasonable way to handle this, so all critiques and comments are more than welcome, thanks!


Before submitting the PR make sure the following things have been done (and denote this
by checking the relevant checkboxes):

  • The commits are consistent with our contribution guidelines
  • You've added tests (if possible) to cover your change(s)
  • All tests are passing (eldev test)
  • All code passes the linter (eldev lint) which is based on elisp-lint and includes
  • You've updated the changelog (if adding/changing user-visible functionality)
  • You've updated the user manual (if adding/changing user-visible functionality)

Thanks!

If you're just starting out to hack on CIDER you might find this section of its
manual
extremely useful.

@wilbrt wilbrt force-pushed the 3834-ns-refresh-to-use-clj-repl branch from 90b2135 to 6d723a1 Compare September 6, 2025 10:25
@bbatsov
Copy link
Member

bbatsov commented Sep 9, 2025

Hmm, seems to me something's wrong with cider-map-repls, as I see it's invoked with :clj in this context which should be enough if things were working properly. (basically it filters out the non-Clojure connections)

@wilbrt
Copy link
Author

wilbrt commented Sep 9, 2025

There doesn't seem to be anything wrong with cider-map-repls. It's just that the lines
(cider-ensure-op-supported "refresh") (cider-ensure-op-supported "cider.clj-reload/reload") (cider-ns-refresh--save-modified-buffers) throw when the current buffers cider-current-repl does not give a Clojure repl.

I thought about extending the cider-ensure-op-supported-function to take an optional parameter for the repl type we want to use but figured it would change existing functionality too much for this kind of change.

@vemv
Copy link
Member

vemv commented Sep 26, 2025

It's just that the lines
(cider-ensure-op-supported "refresh") (cider-ensure-op-supported "cider.clj-reload/reload") (cider-ns-refresh--save-modified-buffers) throw when the current buffers cider-current-repl does not give a Clojure repl.

Well, it seems to me that we should solve that root cause then.

Would moving the cider-ensure-op-supported calls inside the existing cider-map-repls loop work?

...If it didn't , maybe we could try adding a parameter so that the connection being looped over is relayed.

@vemv
Copy link
Member

vemv commented Sep 26, 2025

Thinking about it, a nice API addition for cider-map-repls would not only include the language, but also the expected capabilities:

- (cider-map-repls :clj (lambda (...
+ (cider-map-repls '(:clj "refresh" "cider.clj-reload/reload") (lambda (...

That would-be variant would loop over the clj connections that had those specific capabilities, without throwing an error in non-matching connections.

@wilbrt wilbrt force-pushed the 3834-ns-refresh-to-use-clj-repl branch from 6d723a1 to 23b2c17 Compare September 26, 2025 14:32
@wilbrt
Copy link
Author

wilbrt commented Sep 26, 2025

Thinking about it, a nice API addition for cider-map-repls would not only include the language, but also the expected capabilities:

- (cider-map-repls :clj (lambda (...
+ (cider-map-repls '(:clj "refresh" "cider.clj-reload/reload") (lambda (...

That would-be variant would loop over the clj connections that had those specific capabilities, without throwing an error in non-matching connections.

I think this solution would be optimal, I'll try implementing it!

@wilbrt wilbrt force-pushed the 3834-ns-refresh-to-use-clj-repl branch from 23b2c17 to f65ea20 Compare September 26, 2025 16:14
@wilbrt
Copy link
Author

wilbrt commented Sep 26, 2025

Thinking about it, a nice API addition for cider-map-repls would not only include the language, but also the expected capabilities:

- (cider-map-repls :clj (lambda (...
+ (cider-map-repls '(:clj "refresh" "cider.clj-reload/reload") (lambda (...

That would-be variant would loop over the clj connections that had those specific capabilities, without throwing an error in non-matching connections.

The latest commit presents a proposal for the kind of API mentioned in your comment. Though I was not sure what to do about the (cider-ns-refresh--save-modified-buffers) call as it does not fit the "inject operation name"-schema.

(t 'ensure)))
(repls (cider-repls type ensure)))
(mapcar function repls))))
(mapcar (lambda (repl)
Copy link
Member

Choose a reason for hiding this comment

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

This throws an error for non-matching connections, which seems undesirable.

My suggestion was that the ops-to-support act as a 'filter', selecting the acceptable repls that we'll iterate over.

Taking a look at the function body, it seems to me that the cleanest approach would be to:

  • also introduce a ops-to-support parameter to the cider-repls function
  • relay that parameter from here

This way, we still have the flexibility to be 'strict' (error-throwing) or not, by reusing the existing ensure logic.

Copy link
Author

Choose a reason for hiding this comment

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

I hope I understood the idea correctly 😅 . It seems that at least the cider-toggle-trace-ns uses the cider-map-repls with cider-ensure-op-supported inside the lambda, do you think that that should be changed to be inline with the new API as part of this, as part of another task or not at all?

Copy link
Member

@vemv vemv left a comment

Choose a reason for hiding this comment

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

It seems that at least the cider-toggle-trace-ns uses the cider-map-repls with cider-ensure-op-supported inside the lambda, do you think that that should be changed to be inline with the new API as part of this, as part of another task or not at all?

Seems okay to include as part of this PR, provided that you try it out

| `cider-ns-refresh`
| kbd:[C-c M-n (M-)r]
| Reload all modified files on the classpath. If invoked with a prefix argument, reload all files on the classpath. If invoked with a double prefix argument, clear the state of the namespace tracker before reloading.
| Reload all modified files on the classpath. If invoked with a prefix argument, reload all files on the classpath. If invoked with a double prefix argument, clear the state of the namespace tracker before reloading. Uses a clojure REPL whenever one exists.
Copy link
Member

Choose a reason for hiding this comment

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

This addition seems outdated by now, maybe leaving it as before would be enough

Copy link
Member

@vemv vemv left a comment

Choose a reason for hiding this comment

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

Fantatic work, thanks!

Just be sure to update the changelog, PR description, and please add tests (especially if there was existing coverage in these areas)

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.

cider-ns-refresh should always use Clojure REPL
3 participants