Cider: (slurp *in*) can't be interrupted

Created on 9 Jun 2018  路  18Comments  路  Source: clojure-emacs/cider

This is just creating a ticket for https://stackoverflow.com/questions/50493580/cider-for-emacs-stdin

It seems that slurping from the stdin right now can't be interrupted, which should certainly be possible.

bug good first issue

Most helpful comment

@TimoFreiberg I made a few articles about how to start debugging and contributing: http://hackingcider.com/ (particularly setting up CIDER for development )

Also, feel free to chat in #cider on the Clojure slack

All 18 comments

I would like to contribute a bit to CIDER but I have no idea where to start with this issue. Could you/someone give me some pointers?

@TimoFreiberg I made a few articles about how to start debugging and contributing: http://hackingcider.com/ (particularly setting up CIDER for development )

Also, feel free to chat in #cider on the Clojure slack

thanks @dpsutton! M-x nrepl-toggle-message-loggin was the missing link for me :)

The problem seems to be:

  • when trying to read the entire contents of in, nrepl always replies to a new stdin message with :status "need-input"
  • therefore, CIDER always reopens the minibuffer to read from it (cider-need-input always gets called, see https://github.com/clojure-emacs/cider/blob/master/cider-client.el#L596)
  • nrepl interprets an empty stdin as EOF: https://github.com/clojure/tools.nrepl/blob/master/src/test/clojure/clojure/tools/nrepl_test.clj#L403
  • cider-need-input always appends a newline to the input (which seems correct), therefore there is no way to send an empty stdin

Possible solutions seem to be:

  • Catching the signal 'quit from C-g and sending nil/an empty list to nrepl
  • Adding a C-c binding to the minibuffer which will also send nil/an empty list

I'll try that approach, feedback appreciated :)

Excellent research!

Yeah, I think we should do both.

cider-need-input always appends a newline to the input (which seems correct), therefore there is no way to send an empty stdin

Btw, I'm not quite sure about this. Why is it correct to always add a final newline?

Btw, I'm not quite sure about this. Why is it correct to always add a final newline?

Otherwise it would be impossible to enter an empty line into stdin

You can just use \n. :-) But yeah - that's a good point. Otherwise we'll need some different keybinding (e.g. many chats have Shift+Enter for this). The approached proposed by you sounds better for sure.

Happy to hear that :)
I'm gonna try to get it working, it might take a while since I'm new to emacs hacking ;)

You can see here how to tweak the minibuffer setup for stdin https://github.com/clojure-emacs/cider/blob/master/cider-common.el#L87

Btw, if you're the mood for more detective/bug fixing I can suggest 2 more small issues that are somewhat related:

I'll take a look :+1:

Current status:
I bound C-c C-c to abort-recursive-edit.
C-c C-c and C-g successfully stops the stdin-loop:

https://gist.github.com/TimoFreiberg/34d7efa24f2966daff44601ce6c4753e#file-nrepl-exception

There's a problem though: calling (slurp *in*) again throws the following error:
https://gist.github.com/TimoFreiberg/34d7efa24f2966daff44601ce6c4753e#file-nrepl-messages-cider-issue-2317
probably because the stdin reader gets closed after reading an empty message.

Probably you're right. Not sure where would be best to handle this.

Btw, I'm curious if we can somehow add a way to conclude the input read by the minibuffer with EOF (e.g. with some keybinding) to prevent the need to send a second "termination" message.

Oh, actually it's quite obvious. slurp closes *in* and nrepl just doesn't reopen it.

Yeah I've been thinking about that as well.
slurp reads until it encounters EOF, which nrepl sends when stdin is empty: https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/middleware/session.clj#L233
nrepl only does that when an empty message is sent, so I think an empty termination message is the only way unless nrepl changes

Well, improving things in nREPL is certainly doable now https://github.com/nrepl/nrepl/

CIDER will switch to using the new nREPL server pretty soon.

Anyways, for now we should probably go with a termination message, until the transition to the "new" nREPL is completed.

I've got it now.

So we accept that users can close the nREPL stdin and maybe fix/improve that in the new nREPL project?

So we accept that users can close the nREPL stdin

Just for now.

maybe fix/improve that in the new nREPL project?

We should certainly fix this there, my point was mainly that some people will keep using the legacy project for a while, so ideally we have to be compatible with it as well.

CIDER will stop supporting the legacy nREPL as soon as I find some time to focus on this. :-)

Was this page helpful?
0 / 5 - 0 ratings