Open ayazhafiz opened 2 years ago
Well, this is very impressive, having other languages conform to the twoslash API shape is a clever idea! (It's very similar to how I built multi-langauge support into Danger JS.
I'm semi hesitant on the idea of supporting multiple languages not because it's a bad concept, but because of how much the docs and my ease of maintenance is tied to it being 1 platform which I understand very deeply (and used to be able to put full-time effort into.)
That said, having a non-hostile fork for this would also be a weird concept (a lot of the hard work of setting up the HTML is done and hasn't changed in a long time (excluding #145)) but I'm wary of rust and other languages feeling like a 2nd class citizen when this is so cool and should have the chance to shine properly.
I had recommended someone take the ideas of twoslash to create an LSIF version https://github.com/shikijs/twoslash/issues/110 but I can't help but feel like allowing LSIF inputs is also a direction we should take it shiki-twoslash.
I think it's now quite difficult to make changes to the underlaying twoslash lib (because I don't have write access to that repo anymore) but TypeScript doesn't conform to LSP anyway, having it as an exception seems OK (we could add code in here which goes from the ts implementation to a more standard feeling one)
So, things worth thinking about before we commit:
Will it be easy for a rust person to be able to set up an environment where this is usable with tools they use?
E.g. shiki-twoslash uses the node_modules from your app inside the VFS, what does that sort of thing look like for other languages?
Where does the documentation live? Should the main site be teaching how to work in rust or other languages, I'd probably have to change shiki-twoslashes definition to be about 'language information' instead
Do we try to make the twoslash syntax fit well with other languages?
I think // ^?
is solid in all languages and probably // @filename
but does // @errors
and the host of compiler options I guess could just be arbitrary key: value
comments known to be ignored.
( Sorry for such long-term thinking on a prototype but I intend to be maintaining this for many years and this is probably the biggest idea that'd be added to the project since its launch )
I agree with you, there is a ton of value in the rendering portion (which is the novel and interesting bit) and I think it would be really nice to reuse the work you've already done to generate annotations for any language semantics.
Thank you for taking the time to note your ideas and concerns; I agree with all of them. With them in mind, I think a plugin model along the lines I proposed in the original comment would work well to alleviate them. In greater detail:
my ease of maintenance is tied to it being 1 platform which I understand very deeply (and used to be able to put full-time effort into
One perspective is that shiki-twoslash is a rendering engine for static code information - indeed that is already what it is, it just happens to be specialized for the TS/JS use case. But the library itself does not do semantic analysis over TS/JS; @typescript/twoslash does that. So, by providing a mechanism to insert custom semantic analyzers for other languages, shiki-twoslash can continue to avoid having to care too much about what languages there are, and instead say "okay, just give me an opaque function by which I can produce analysis information, and I'll render something nice for you". So I don't think this model changes too much. Indeed you can see the diff of my current fork - it's not large.
Will it be easy for a rust person to be able to set up an environment where this is usable with tools they use?
Yes. The current tool I have demands that you put a binary to produce the rust code analysis (this one) somewhere in your PATH and install a JS model that links against it, but then you're off to the races.
Importantly, with the model I am proposing here (which is not the one currently implemented in my fork), shiki-twoslash does not need to worry about the ergonomics of the language-plugins. shiki-twoslash would only have to detect what language a piece of code is, and pass that code to the appropriate plugin, so the usability experience is the concern of the plugin. Of course then there is the problem of setting a standard for high-quality plugins, but I don't think that's actually so hard.
Where does the documentation live? Should the main site be teaching how to work in rust or other languages
I think it would make sense to give an introduction and say "also, you can use these N other plugins for different languages!" but expect that the plugins have more thorough usage documentation. Again, this enforces shiki-twoslash being the rendering engine rather than the semantic analysis tool.
Do we try to make the twoslash syntax fit well with other languages?
I think // ^? is solid in all languages and probably // @filename but does // @errors and the host of compiler options I guess could just be arbitrary key: value comments known to be ignored.
This is a really good question. I could see arguments both ways. Maybe the cop-out answer is to say the syntax is plugin-defined, but of course it's good to have some cohesion. I don't know. Maybe there is a requirement that ^?
and ^|
are supported, but the rest is defined by the plugin?
Here from #49 and happy to pitch in too ⋔
Hey Orta, would have any interest in extending this library to support generation for multiple languages?
I recently added support for Rust to this library in a local fork (here is the patched branch and the Rust library generating a
TwoSlashResult
). It indeed works - here's an example screenshot (I'll replace with a real URL when I can share it widely, EDIT: here's the live example):My current implementation is a bit hacky, but before I do more work to improve it I'd like to gauge whether this is kind of use case is something you'd be interested in accepting patches for. If indeed you are interested in this, I think the following model would make sense:
(code: string, extension: string, options: unknown) => TwoSlashReturn
that should be run over code blocks with certain language fences.TwoSlashReturn
to better fit formats that can be returned by any LSP server, for example something more similar to LSIF. I don't think this is as big of a deal as the above point, because the current interface is easy-enough to marshal into.Let me know what you think!
Related to #110