Fork me on GitHub
#unrepl
<
2018-03-08
>
kotarak11:03:28

Ah. Issue #36.

kotarak11:03:31

It keeps coming back to read tracking. 😿

cgrand11:03:18

Don’t. Make. Cats. Cry.

cgrand11:03:23

and I really want to remove unrepl/do

kotarak11:03:11

Yes. I see the problem now.

cgrand11:03:04

It’s good to hear people restating stuff, you get to see things under a different angle

kotarak12:03:50

I always forget about reading from stdin....

kotarak12:03:31

Like (read). Was happy to have it. Forgot about immediately. :face_palm:

kotarak12:03:21

Can we have a byte offset?

kotarak12:03:30

Scratch that.

cgrand12:03:47

char offset not byte

kotarak12:03:51

Typing faster than thinking.

cgrand12:03:22

with covering :readmessages it should be more frequent for the client to determine if nothing is “in flight”

kotarak12:03:31

Can I retrieve the exception from a repl? Without mocking with *1?

kotarak12:03:26

At the moment I have to reimplement c.stacktrace. Because it expects a throwable. Also the stacktrace gets elided.

cgrand12:03:05

Stop. Rewind. I need more context, I’m not following along at all

cgrand12:03:31

Do you want the exception thrown by code evaluated in unrepl or something else?

kotarak12:03:36

I get an exception via unrepl. I want to pretty print it for human consumption. But I only get an #error with elided parts which doesn't read back in in the tooling connection.

kotarak12:03:13

So I need to translate things and have a modified pretty printer to understand the translated thing.

cgrand12:03:32

It should read back. Can you reproduce it with just netcat?

kotarak12:03:50

I tried to read a (prn (Exception. ...)) in a plain repl. And it doesn't. Also the elision fails reading.

cgrand14:03:26

reproduced with a more recent blob

cgrand12:03:59

Otherwise I do think that swapping some parts of unrepl to do most of the pretty printing server-side when the client-side is feeble is a good idea

cgrand12:03:13

currently make-blob allows only actions to be customized

cgrand12:03:28

but more hardcord customizations are possible

kotarak12:03:47

So you mean just to pretty print the EDN code?

cgrand12:03:06

What’s the point of having machine-readable printings that your machine can’t print?

cgrand14:03:32

If you can’t do stuff on the client side, modify the blob to have the server do most of it.

kotarak16:03:27

Then how do I hook into things? Eg. Exception message emission?

cgrand16:03:44

Let’s take a step back

cgrand16:03:02

so full EDN is a bit too much for vim

cgrand16:03:18

but doing all the pretty printing server side is too much too (at least for elisions)

cgrand16:03:24

so why not emit some kind of markup?

kotarak16:03:07

I'm completely confused now.

kotarak16:03:38

I tried to keep vim jambowambo away from unrepl.

kotarak16:03:51

And indeed I think this would work perfectly well.

cgrand16:03:10

can’t resolve “this”

kotarak16:03:42

this == "keep vim stuff away from unrepl"

kotarak16:03:06

My only grief at the moment is, that the provided representation of the exception cannot be easily machine-read back into clojure. At least not clojure 1.8.

kotarak16:03:54

Also I somehow dislike elisions with exceptions.

kotarak16:03:03

Also: I would only care for the user repls.

kotarak16:03:23

With the tooling I'm perfectly fine with #error.

kotarak16:03:40

Anyway, in the end it's a none problem. It works already. I just have to duplicate some of the pprint code from eg. c.stacktrace.

kotarak16:03:47

I'm not sure I even want to hook into unrepl any more than the actions.

kotarak16:03:11

So far I don't see the need to.

Jakub16:03:56

Hi, is there some overview comparison between unrepl and nREPL? I haven't been able to figure it out from reading the readme and glancing over unrepl spec.

Jakub16:03:40

I like that unrepl wraps socket repl which makes it easy to plug in into CLJS environments. But if someone created a nREPL wrapper over socket repl would unrepl still have some other benefits?

cgrand16:03:35

The goal of unrepl is to be transparent to the user: no configuration, no middleware. All you need is a repl (not even a socket one, I routinely test over stdin).

cgrand16:03:26

unrepl is meant to be an implementation detail for tools.

bozhidar16:03:37

> But if someone created a nREPL wrapper over socket repl would unrepl still have some other benefits?

bozhidar16:03:05

@kloud Why would do something like this? You’ll still need middleware, so you’d gain very little. What would be more impactful would be to just update the implementation to target Clojure 1.7 and support ClojureScript natively (something that was obviously not possible when nREPL was created).

Jakub17:03:24

@U051BLM8F I am working on a clojurescript shell and would like to create a backend so that it could be possible to use it with different readline frontends.

Jakub17:03:59

For this one needs more strucuted protocal, so socket repl is not suitable. And there is no clojurescript implementation for nREPL. So I was wondering if unrepl can be utilized since it seems to have cljs support.

bozhidar17:03:41

What’s wrong with using piggieback? That’s nREPL’s classic way to support ClojureScript. Unless you need support for a self-hosted repl, which is not an option right now.

Jakub17:03:05

Yeah, we are running self-hosted on top of lumo.

cgrand17:03:21

regular expression of the message stream :unrepl/hello (:prompt :read (:started-eval (:eval | :exception))?)*

cgrand17:03:52

previsouly was :unrepl/hello (:prompt (:read :started-eval (:eval | :exception))*)*

kotarak17:03:00

I get this: unrepl.repl$pkrTyzbcFcA3scs1I83X8tI0iM0.proxy$clojure.lang.LineNumberingPushbackReader$ILookup$ILocatedReader$ff3fd87c cannot be cast to clojure.lang.IFn

kotarak17:03:10

With the latest commit.

cgrand17:03:25

when doing what?

kotarak17:03:34

in set_file_line_col

ghadi17:03:41

is that a bitcoin hash?

kotarak17:03:41

set source

cgrand17:03:11

@ghadi no it’s dependency sha1ding

cgrand17:03:04

what’s the 🍎 for? I would have expected rotten 🍅

kotarak17:03:54

It's used from vv-vZOFetlbOcKtaQ-vCp699gbSDFw.vimpire.nails

kotarak17:03:04

Notice the fangs.

dominicm17:03:13

I like the metaphors.

kotarak17:03:35

@cgrand Is it possible, that I don't get eval and friends for :set-source?

cgrand17:03:59

that’s unrepl/do dark arts

kotarak17:03:25

Baron Samedi comes to haunt the voodoo priests who opened a tomb without his permission.

kotarak17:03:44

Let's hope your machine doesn't crash and take it into oblivion before you can push. 🙂

cgrand18:03:30

also: since there are more prompts now, prompts will announce the next eval-id

kotarak18:03:05

What will trigger now a prompt?

cgrand18:03:59

you get a prompt after ignored characters (possibly 0 soon, when interrupted from aux) or after evaluation

kotarak20:03:11

vimpire does now read tracking. That means commands are framed based on their submission. This is mostly interesting for the tooling repl.

kotarak20:03:42

For the repl buffer that means the prompt is only shown once at the end after all submitted commands are executed.

kotarak20:03:11

It also means that something like: user=> (read) (+ 1 2) will break the connection.

kotarak20:03:51

Is that a progress?

cgrand21:03:34

@kotarak can you outline your algorithm?

kotarak22:03:24

The connection starts out in state prompt. Then input is sent. This happens in a queued context. Agent-like. A context may contain several forms. In particular the context also contains the length of input and callbacks for the events. This is important because vim channels are asynchronous. The conn is put into state evaling. The read event is used to reduce the remaining length. Eval checks whether there is input remaining. If so, the conn is kept in evaling state. The prompt handler sees the evaling state and does nothing. The next form is read. In particular are the proper callbacks still in place. Then we come back to eval eventually. Now assume, the input for the context is exhausted. Then the context is popped from the queue. And the connection is put into awaiting-prompt state. On the next prompt the handler recognises this. It switches the connection back to prompt state and triggers the execution of the next context in the queue (if any). And then things start over.

kotarak22:03:06

One special case: if the prompt handler sees the combination of evaling and exhausted input it assumes unrepl/do or whitespace only input and pops the context from the queue itself. The only way the prompt handler can see exhausted input is by skipping the eval handler.

kotarak22:03:13

The repl buffer is built on this. With some special handlers for output and exceptions. However, eg. a (read) does not generate read events. So "user=> (read) :foo" will break the connection state because the :foo will be consumed without the conn knowing about it. So it will wait forever for the "remaining" five chars to be read.