@pesterhazy ^^ not like Chez
@cgrand last night I was wondering about your thoughts on what can clients do to show objects in a "pretty way", or put in a different way: it'd be nice to be able to show objects 'a la pr
'.. for example, in clojure.main/repl, the print function is prn
, so if I eval +
i get #function[clojure.core/+]
back, and I would like to show the same in unrepl.el, but it's not derivable from the current #unrepl/object
tagged literal
the only thing I could think of was extending the #unrepl/object
so that it includes its pr
, but I don't know if there's a better way
#function
seems very new as it’s not in beta 3
(haven’t tried on RC)
hmm didn't noticed, I thought it was already stable
you are on RC1?
actually no.
sec
*clojure-version*
oss/unrepl [ JVM_OPTS='-Dclojure.server.myrepl={:port,5555,:accept,clojure.core.server/repl}' lein repl master * ] 11:54 >
nREPL server started on port 46374 on host 127.0.0.1 - <nrepl://127.0.0.1:46374>
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_101-b13
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=> +
#function[clojure.core/+]
user=> +
#function[clojure.core/+]
user=> *clojure-version*
{:major 1, :minor 8, :incremental 0, :qualifier nil}
although if I start the repl using the clojure 1.8.0 jar, I get #object
oss/unrepl [ java -Dclojure.server.myrepl="{:port 5555,:accept,clojure.core.server/repl}" -jar ~/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar master * ] 11:52 >
Clojure 1.8.0
user=> +
#object[clojure.core$_PLUS_ 0x4c2bb6e0 "clojure.core$_PLUS_@4c2bb6e0"]
(if I run cider for the unrepl repo, I also get #function )
lein repl
Initializing NoDisassemble Transformer
nREPL server started on port 52727 on host 127.0.0.1 - <nrepl://127.0.0.1:52727>
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_05-b13
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=> +
#object[clojure.core$_PLUS_ 0x4ce1ff96 "clojure.core$_PLUS_@4ce1ff96"]
so it’s cider
everything I sent was outside cider
I do have cider as a global lein plugin
let me try without it
>>> ;; Extending print-method
defined in clojure.core, to provide
;; prettier versions of some objects. This applies to anything that
;; calls print-method
, which includes return values, pr
, print
;; and the likes.
(def ^:dynamic *pretty-objects*
“If true, cider prettifies some object descriptions.
For instance, instead of printing functions as
#object[clojure.core$_PLUS_ 0x4e648e99 \“clojure.core$_PLUS_@4e648e99\“]
they are printed as
#function[clojure.core/+]
To disable this feature, do
(alter-var-root #’cider.nrepl.print-method/*pretty-objects* not)”
true)
monkey-patching print-method
, so cute
right, yeah I tried without the plugin and got #object
I feel cheated haha
So they just demunge the classname
so it seems
the thing with their #function
tag is that:
1/ it’s not namespaced
2/ it loses identity information, so you can’t tell if two closures created by the same function are the same or not
yes, agreed
(partial map inc)
#function[clojure.core/partial/fn--4759]
@volrath +
now prints #unrepl/object [#unrepl.java/class clojure.core$_PLUS_ “0x774afe65” clojure.core/+ {:bean {#unrepl/... {:get (unrepl.replG__997/fetch :G__1443)} #unrepl/... nil}}]
awesome, maybe what I can do is print the demunged version and have the #object show as a tooltip 🙂
I would keep the hash out of the tooltip
makes sense
alright
as long as your rendering hints that magic happens (special color whatever), I’m ok with it
👍
here's another related question
principle of least surprise (unlike #function
that you assumed was standard)
pretty printing in general.. cider also does it with cider-nrepl.. so that if I have a very long map or whatever, I get a pretty version of it... I was thinking on how to enable that only in my blob
and maybe only on demand, so that I can give users the ability to opt out of it
unrepl-make-blob does not yet offer a way to plug in the printer (so you have to resort to the hacksaw)
i figured...
To me pretty printing should be done on the client side. Traditional pretty printing is a bit at odd with elisions anyway (if you plan to transclude them — whic I guess you do given how you treated string elisions)
yeah I looked around for clj (or even lisp) pretty printers written in elisp, but without much luck. so that's the thing on relaying pretty printing on an elisp client.
there are definitely some border cases with pretty printing and elision, but i think it's manageable.
what are your requirements for PP?
Yes, I was thinking on something like middlewares or interceptors... or a function you could define with a session action
I haven't thought about it too much.. from a user point of view, I guess pp-ing lists, vectors, maps, and sets, will do..
I'd like to look a bit more on how cider does it, maybe see if there's something that can be improved there
@volrath think a bit more as how as a user you like your stuff printed, when you want to transition from line to column etc.
think also about interactivity: we already have elisions but maybe we can toggle the display mode of a collection, collapse it etc. (This doesn’t make up for good defaults.)
What if we had the option to render a list of similarly keyed maps as a table?
so, taking collapsing out of the equation, I see that either done in elisp (not my fav option), or as possible :aux actions to be sent to unrepl and have the processing be done in clojure
I say taking out collapsing because hiding information that it's already there should be pretty straight forward
Implementing stuff in: • Clojure: just require your helper ns on an aux connection and send it forms: pros easy cons when CLJS will come you’ll have to rewrite it (hopefully it will be cljs) • Elisp: pros works with any blob, any lang; cons elisp (it could be vim^Hworth).
Clojure pro: Vim can use it for free
cider-nrepl has been a valuable asset to vim users.
if you don’t like your host lang spawn a CLJS repl
right, the thing about the aux helper is that I wouldn't have a way to use it as a default.. so for example, let's say I allow users to choose they want their stuff PPed, then I would have to send each client input wrapped in a helper?
it's an option for sure, not discarding it, but just wondering if there's a better way
“each client input output” you meant?
input.. maybe I'm under/overthinking this. I was thinking, user types: user=> *code that generates -long- data*
; the elisp client will send (my-custom-wrapper-for-pprint *code that generates -long- data*)
so that I get the result pp-ed
I know the other option could be to wait for the :eval
message and then send an aux helper like (pprint-me-this <eval result>)
but I was thinking on avoiding the roundtrip
:thinking_face:
(my-custom-wrapper-for-pprint *code that generates -long- data*)
looks like a bad idea (unrepl-wise) because in a sense you are framing input.
yes
you could customize the blob (and with enough persuasion I will make it easier) to emit your own [:unrepl.el/pprinted xxx id]
messages.
(btw, I wasn't planning on working on pp soon, it is down the road.. but just thought on bringing up the topic)
The thing is: if your code generates long data do you want to display all the data at once?
I also thought about that a little bit yesterday.. I think the answer is maybe. I thought on making it customizable in the elisp client, let the user decide
at least at the beginning it could be as easy as a boolean value: the client will either resolve all elisions automatically or won't
I also plan to make the max-print-length customizable inside emacs.. the user can decide it there and I'll use the session helpers to adjust when I receive :hello
tbh, I think of elision as pretty printing, both are great, but should be optional
I disagree but let’s experiment!
At the Conj @chouser asked about pair programming and unrepl, I jotted down some thoughts after chatting with him today https://github.com/Unrepl/unrepl/wiki/Pair-(or-more)-Programming
hello all, I am trying to install unravel
but I got an Error: EACCES: permission denied, open 'lumo_mac.zip'
sounds familiar ?
nevermind it’s working, was a rights issue on node
and unravel
looks awesome ^^
the doc right above the repl is really cool
@baptiste-from-paris you built from master?
yep
could you give a try to parfix
(multiline + paren completion)?
@cgrand could you send a link for parfix ?
don’t find it
I believe he's referring to the parfix
branch: https://github.com/Unrepl/unravel/tree/parfix, you should have multiline and paren completion there
Yeah it’s the name of the branch.
ah
ok
@cgrand how many open-source projects do you manage and are you humain ? 😄
Thanks to you I have a sudden urge of listening to Daft Punk’s “Human after all” and Katerine’s “Robots après tout” LPs 😉
It would be cool to create a modern Bourbaki 🙂
ok, working great with ident
and that’s almost the best REPL XP that I had in a terminal
it seems that history does not work anymore
on this branch
I don’t get where unrepl
is loaded in unravel
, no lein/boot project file
You mean as a dep when building unravel
?
Well unrepl
is a protocol so you don’t have to require it. The unrepl repo is also a built tool to create server implementations of this protocol.
The artifact produced is the famous blob.
See scripts/update-unrepl
and resources/unrepl/blob.clj
@baptiste-from-paris on this branch it’s ctrl up/down for history.
ok