Aand I don't need a negotiation protocol. I need a registration hook, where the plugin gets a channel, and sends back a list of "IDs" it can handle. Whenever fuck encounters a top-level node, it runs it through the handleres registered for the node name.
And that's all fuck does. Any other names that aren't top level, are invoked by the top-level handlers.
And they all have the same shape:
fn call(&self, id: &str, node: &KdlNode) -> miette::Result<plugin::Response>
where plugin::Response is an enum:
pub enum Response {
Untouched,
Kdl(Vec<KdlNode>),
Derivation(Vec<Derivation>),
}
Something along those lines.
So, first order of business: figure out a protocol to talk over the extension<->fuck channel, because the idea is that
fuckwill ask each exetnsion about what kind of stuff it supports, and then set up appropriate channels for each.Now, the ideal thing would be if the negotiation would be automatic. I can't enforce that at compile time, because it depends on the extension, and that's a runtime thing. But I can teach the Rust side bridge to figure out which functions are exported from Fennel, and do the negotiation itself, so it doesn't need to be implemented - or even exposed - to the Fennel side.