@volrath thanks!
@volrath yes the documentation for :prompt
is out of sync
Ok
I was looking at compliment (https://github.com/alexander-yakushev/compliment).
Some thoughts:
• completion if a half static/half dynamic task, does the in-process tooling should take care of the static part?
• a separate concern is vim editors with crippled scripting where there’s a push to offload brains to the tooled process (they need a proper isolation)
So basically can we start with just a :completion
action that takes a string (or a tagged-lit regex) and returns a list of matches? And without specifying much (in the string case) how the match is done (strict prefix, fuzzy, even fuzzier)
(and an unrepl source for compliment could be added, allowing compliment to be used... on the editor side)
I don’t see myself commiting fine-grained actions in unrepl.
sounds good. I also think that a :completion
action could be generic enough to accommodate for completion libraries like compliment. One thing though, maybe I didn't understand well what you meant by a "tagged-lit regex", but I'm guessing that the action should take at least two parameters: the whole string/form the user's been typing and a cursor position, so that completion libraries can take advantage of context. in case of compliment: https://github.com/alexander-yakushev/compliment/wiki/Context
@thheller I'm sorry you had to deal with that print.cljc
. It basically came about when I asked "what's the next thing we need to make a cljs unrepl happen", and someone said "port print.clj", so I fired up Lumo in inf-clojure and start going through it top to bottom, making sure I could evaluate each form without errors. After that I wasn't sure how to continue as it seemed there were some other pieces missing (I guess that would be cljs-js-repl which I wasn't aware of at the time).
I’m the someone 🙂
I'll be working more on unrepl.el this weekend. Current status there is that I've started writing a Clojure/EDN parser from scratch out of frustration with edn.el. This will likely become its own Emacs package as it seems some other tooling could benefit from a good parser as well. But so there's a bit of yak shaving to be done at the moment. After that I want to implement proper tracking of eval/echo, which should make it possible to get proper in-buffer evaluation with results in an overlay, as well as other tooling-related evaluation that does something else with the result than show it in the repl.
@cgrand I think it was someone else repeating what you had said previously 🙂
@plexus ok fine, blame the messenger!
I don't blame anyone, I think it's all worthwhile, just want to make sure people don't expect too much from print.cljc
@volrath it’s not what I have on my mind (for compliment, I was thinking of just providing enough to implement a new source, and have compliement run in the editor, not in the “server” process) So I was thinking “small string” while you are thinking “whole form + cursor position”, it’s coarse grained too and I didn’t consider it. Interesting.
the clojure/edn parser will be a hand written shift-reduce parser, which will be able to give a partial syntax tree in case of parse errors, and which can be used to either parse EDN to elisp lists/vectors/hashes, or Clojure to a tools.analyzer style AST. It uses an internal stack instead of using recursion, which means it doesn't overflow the elisp stack (which edn.el is prone to do)
Also I'll be speaking (remotely) about unrepl/unrepl.el at the London Emacs Meetup on the 26th. There will be video afterwards. I'm in charge of the recording and editing though so it might take a while 🙂
the elisp stack is rather shallow? Anyway sounds promising
yeah it's rather shallow, also edn.el is based on the PEG parser generator library, which seems to use many more stack frames than necessary
@plexus no worries .. I’m rather surprised that this actually works in lumo since it should be using the same tools.reader
I do?
No idea to be honest, I would have to dive in again.
If the selection is wrapped in a do
before evaluation it may explain the behaviour
@cgrand, I agree about starting with a simple approach
yes but which one?
hehe I'm typing slowly today
I started with this brain-dead approach: https://github.com/pesterhazy/unravel/blob/master/src/unravel/loop.cljs#L70
one question could be how that falls short
on the completer side, it only does non-fuzzy prefix-completion; on the "gathering candidates" side, it looks at namespaces and local or qualified vars
how could this be improved?
- moving into unrepl source code
- more candidate gathering sources (keywords? method names?)
- better completion algorithms (allow for typos, allow for missing characters ("repfir" will match "replace-first"))
- more generality
- cljs support (but that would require cljs support in unrepl first)
- better sorting of matches
- adding annotations to matches (fn signature, first line of docstring)
“gathering candidates side” is in CLJS?
plexus: I put comments on your commit but it’s more for me than for you: things to keep in mind when I merge some of your changes.
Yeah
so you agree with me that that part should not be part of unrepl, right?
can you explain a bit more what you're suggesting?
Turns out there are rough edges to the repl experience in bootstrap
i want to be sure what I'm agreeing to
@pesterhazy unrepl only exposes stuff that the client can’t do, so only completion of dynamic things (namespaces, vars, maybe classes)
keywords, locals etc are done by the client
sounds right to me
just to be clear that I'm understanding, the client would gather keywords by e.g. scanning the file for #":[a-z-]*"
the client cannot do that effectively with namespaces because it needs to inspect the dynamic runtime environment
Yes
we don't want to extend unrepl's scope too much, so our principle would be to expose the data the client needs and cannot get by itself, but nothing more
so one thing to add would be a completion function. E.g. (unrepl/candidates-by-prefix "fil")
would return [{:symbol 'filter :docstring "..."} ,,,]
?
wth? does unrepl suddenly do completions?
@thheller 🙂 tryiing to find a tradeoff between “do nothing” and “do just enough for the client to be independent” (again, commands are optional and they are an openset etc.)
yeah, talked with Paulus. Misunderstanding on my part
@thheller curious as to what made you feel okay with it.
not my decision to make … I’ll be building the language server and expose RPC-ish commands like clj/eval
and cljs/eval
those will throw if you try to (read)
as all this is not going to be a REPL
strictly for tools not humans (not actually strict RPC, message based with async notifications and RPC)
I have a simple socket REPL for humans that exposes enough information to make autocomplete and stuff work
but the autocomplete will then go over the RPC thing, not the REPL
very different goal than unrepl
trying to figure out how the upgrade
works with CLJS makes my head hurt too much
One could also imagine advertising the language server endpoint in unrepl hello.
yeah the thing I just can’t figure out is how the upgrade can work for CLJS without actually controlling how its started
the send a blob approach just doesn’t work since eval is in JS
The loop on the js side has to be made upgradable
but there is no loop on the JS side
au contraire! Javascript is loops all the way down
Lambda the ultimate GOTO
The message queue from which the strings (js code) to eval are received has to be public and have a .pushListener method and maintains a stack of listeners, only the top one is active.