@pesterhazy on :exception
I’d like to indicate in which phase the exception occured (`read`, eval
, print
and wtf
)
I think the payload of :exception
is going to be a map :phase
and :ex
Does it seem ok to you (as the 1st consumer)
I can't see how it could hurt
what would it be useful for though?
quickly communicating to the user if she gets an exception because of: • syntax error • application code • other (print & wtf)
the print one is interesting 🙂
one question, can I rely on the fact that each message is newline delimited?
obviously simplifies reading from the stream
Hum to me it was an impl detail, how does it simplify reading?
I get a callback for each chunk of data, but a message might be larger than buffer-size
so I need to try to read and see if it doesn't throw an exception to see if the message was complete
unless I'm missing something
I do think newline-delimited EDN is a good format anyway (similar to newline-delimited JSON)
JSON doesn't allow a literal newline in string, not sure about EDN
as far as I can see the EDN spec doesn't say
>>> Strings are enclosed in "double quotes". May span multiple lines.
annoying 🙂
EDN is very ambiguous on strings: newline may be escaped but are not required to and, officially, most control chars are not escapable (and appears as is)
can't you use octal codes?
only for char lits, not for strings (according to the spec + 1 issue answered by Rich)
ah. weird!
a more unambiguous specification for EDN would be useful
and edn/read being forked of clojure reader is very liberal and not validating at all
the reader used in CLJS is tools.reader?
that complicates things of course, because complete-form?
for EDN needs to actually read the string, I think
cljs.reader
https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/reader.cljs
Accumulate chunks until read succeeds (or fail for a reason other than EOF) is currently your best approach.
yeah, will do that
which unfortunately involves catching an exception and regex'ing the Exception text 😞
If PushbackReader/read-char
could be extended to return a special value to signify temporary end
then the reader could return a continuation
so you would get from read
(with the appropriate options), either an exception, a value or a continuation (a function expecting more input)
New version now correctly implements reading from an EDN stream
It's almost usable now!
Things I want to implement next: https://github.com/pesterhazy/unravel/blob/master/TODO.md
@pesterhazy interrupt & bg work (with 2 connections)
@pesterhazy how do you intent to make elisions expand in a CLI repl client?
I was thinking of adding a client command like \cont
Not sure...
what if you have several elisions? you would expand them all? \moar
like (repeat (range))
🙂
> (repeat (range))
< [:started-eval {:actions {:interrupt (unrepl.repl/interrupt! :session238 1), :background (unrepl.repl/background! :session238 1)}} 1]
< [:eval ((0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__242)}) (0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__243)}) (0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__244)}) (0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__245)}) (0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__246)}) (0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__247)}) (0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__248)}) (0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__249)}) (0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__250)}) (0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__251)}) <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__241)}) 1]
good point... not sure how to handle this
come to think of it, a nice interface for this would be to start an ad hoc webserver from unravel and open a browser with [+]
expandable elisions
once you are in the browser, throw a textarea in
to replace the terminal prompt?
yup
so many possibilities...
so little time
one simple thing I though of was a unravel special \pprint
to pprint the last result
why not always pprint?
I sometimes prefer pp
over pprint
it really depends on the information shown
also cloure.pprint/print-table
is also a nice display format
what I meant is that since with unrepl you get data (and not almost readable representation), the client can pprint at will — in a GUI it could be expanded, collapsed, partialy displayed as a table etc.
right that's what I meant as well
you can even make it interactive
I have to admit, working with node (lumo) is actually quite a lot of fun
@pesterhazy is your client built on lumo?
@dominicm yeah
nice 😎
@pesterhazy awesome stuff
the only thing I am missing from the lumo experience is good rock solid completion, I am tempted to create a bounty
both tab completion and cljs support are on the todo list for unrepl
@pesterhazy Just an impl detail..I would advise against tab completion only. In inf-clojure
for instance it is very nice that I can call (lumo.repl/get-completions)
to get them.
you mean it should be possible to directly call the fn determining possible completions?
@pesterhazy yes, inf-clojure
already does that https://github.com/clojure-emacs/inf-clojure/blob/master/inf-clojure.el#L669
also, emacs can read json, but inf-clojure
does not implement that at the moment
that is why I actually call (doall (map str (lumo.repl/get-completions \"%s\")))
for lumo
Unravel now shows docs for the symbol under the cursor when you type Control-O
Woah, nice
If you have a minute, give it a try and let me know if it works for you
@pesterhazy sooooo, you convinced me to be your alpha tester...is the client connecting to an nrepl?
oh sorry never mind...read the doc ! 🙂
well completion is touchy because there’s no agreement on the algorithm, but in the end given the new “multiple connections” model it will just resolve to a fn call.
WRT exception phase, isn’t that potentially confusing when an exception is thrown during printing a lazy sequence? That will probably have happened in code that the user thinks of as :eval
.