-
-
Notifications
You must be signed in to change notification settings - Fork 246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow callbacks via node-options. #1092
Conversation
I'll give it a try. 😄 The current API decouples callback functions from their associated nodes. Nodes are references by some indexing mechanism. This is "hard" to get right, is prone error wen changing the snippet and is harder to read because the relation is not obvious. Being able to define callbacks directly at the node declaration solves all these issues. I think it is also fair to say that this tends to be an approach that more and more "frameworks" follow. So it seem to be a good idea. The second part is about the ability to define callbacks for any kind of node, also for non interactive ones. The stupid counter question is: why should there be an exception? It seems like there are valid use-cases to trigger callback functionality also for non-interactive nodes. @L3MON4D3 I must admit I'm unable to tell from the code. But in which order by which "event" do these node callbacks trigger now? 🤔 Example that works for this PR: snippet(
'foo',
format(
'{foo} - {bar} - {baz}',
{
foo = text_node('foo', {
node_callbacks = { [events.enter] = function() print(1) end }
}),
bar = insert_node(1, 'bar', {
node_callbacks = { [events.leave] = function() print(2) end }
}),
baz = text_node('baz', {
node_callbacks = { [events.enter] = function() print(3) end }
}),
}
)
) The (for me) expected process would be:
|
ty!!
Well put, I'd add that conceptually, one should be able to decouple the content of a snippet, the nodes, from the expansion-parameters, which are the other parameters passed to Regarding the textNode-callbacks: I have not yet implemented them😅 Another idea for callbacks: you could make use of the existing infrastructure for functionNode, and just not return text, but do something else, eg. lsp-actions. That does not alleviate the issue with having to manually retrieve keyed nodes (right now, the only difficulty with exposing them to the callback is backward-compatibility) and you can get multiple nodes in the same callback, which is an inherent limitations of the event-callbacks. |
That is a really good point too! I used to do this and for some snippets I still do, also for re-usability sometimes. 👍
Yeah, that's what I was afraid of. So it can only work for nodes that have an explicit index. And we can't simply add such to text nodes or similar because that would be a huge breaking change to the API.
Thanks for the inspiration. I'm just not sure how this can work. But maybe you teach me. I had the idea to use an insert node for this. That would give me a proper index and with the new node snippets, that would be great. The intention was to then just programatically jump to the next node within the callback of the node itself. But that doesn't work according to my experiments. Would be not really a "clean" way in terms of how the API is designed, but would do exactly what is needed. To some degree even more simple because the cursor would be at the right location and I can heavily simplify the code action request logic as I can use the native |
Yeah, you'd still have to resort to
Oh, no, I'd suggest to just use the functionNode as a callback, so it would not insert any text s("foo", {i(1, {key=1}), i(2, {key=2}), t"bar", f(function(args) ... return "" end, {1,2})})
Ahh of course.. yes, for that the leave-callback is more appropriate 👍
Ah, so replace the textNode with an insertNode, so you can get the correct node in the callback, and then jump once more immediately?
I think this may work if you
Feel ya xD |
Thank you so much! That is amazing. In regards of this branch, I'm satisfied for the moment. 🙃 |
We're not writing Rust here after all :P Glad it works better! |
I'm afraid Rust can not solve this problem. 😉 Thank you very much to implement this feature so fast. Looking forward to get it merged. 😊 |
This circumvents the much more complicated current mechanism of setting the callback by identifying the node via jump-index in the parent.
1a589f6
to
e65f3e0
Compare
(I've decided to change this a bit from the initial version: now all callbacks that are associated with some node are executed, not just one of them) |
Currently the event-callbacks are only settable by providing the jump-index to the parent-node, which is pretty roundabout, and annoying for usage in eg.
fmt
.Calling it
node_callbacks
for now, since the option also applies tosnippetNode
, where the keycallbacks
is already taken :/Also, as of now the per-node-callbacks disable/override the parent-callbacks, maybe both should be executed?