TypeScript-powered Code Blocks #120
Description
Things I want for all code blocks inside website v2:
- Accurate Syntax Highlighting for complex TS (ex)
- Hover support for symbols (ex)
- Inline reporting of errors (ex)
- The ability to tell a code block to switch from TS code to any arbitrary part of the tsc emit (ex)
- a JS file
- a d.ts file
- a source map
- The ability to create a working imports inside a codeblock (TS/JS/DTS)
- The ability to highlight lines, a line, or a range inside the line (ex)
Sidegoal:
Make this not directly tied to the website so that anyone with a Gatsby blog can re-use this for their own docs with very little setup.
Places with existing infra this can build from:
-
orta/lsif-tsc-remark-example- an example of using the LSIF format (static language server protocol) to extract metadata. Overall, I think it's too much to go through the entire tsc-lsif, we could probably just steal the syntax for hover tokens and diagnostics and call it enough maybe. -
microsoft/TypeScript-New-Handbookthe handbook has a good set of existing examples for this, these could be re-formatted into Gatsby/remark plugins. -
andrewbranch/gatsby-remark-vscodere-using VSCode at build time to handle the syntax highlighting. -
andrewbranch/blog- uses the typescript API to inline annotate embedded TypeScript ( long form on how it works )
/cc Andrew Branch (@andrewbranch) Ryan Cavanaugh (@RyanCavanaugh)
Activity
orta commentedon Nov 9, 2019
Bikeshed: There are a bunch of ways in which embedded the complier metadata
Andrew Branch (@andrewbranch)'s JSON after language
and prefixed HTML comments (maybe with YML?)
Ryan Cavanaugh (@RyanCavanaugh)'s fourslash inspired inline comments:
My re-use of Jekyll-style which embed yml at the top of a code block:
I feel somewhat tied between fourslash-y or yml front-matter personally.After thinking about it a bit more, I'm in favor of fourslash-eskorta commentedon Nov 9, 2019
One thing that Andrew's blog does is that it allows for typescript files to to work across code samples, e.g.
Where at build time
shape.tscontains both the two code samples, this reduces example code duplication - but is it something this should support? For example the tsconfig page as it is would break today because you can't re-use filenames or examples with different compiler flags.robpalme commentedon Nov 9, 2019
In addition to passing compiler flags as comments, it would be great to also be able to control the tsc version.
This would help for tsc bug reporting and easing comms around tsc behaviour change over time.
felixfbecker commentedon Nov 9, 2019
Something that might help with getting the hover tooltip: We have tsserver exposed over WebSockets at wss://typescript.sourcegraph.com. It speaks the Language Server Protocol, and can accept arbitrary
textDocument/didOpencalls followed bytextDocument/hoverto get a Hover result. Without needing to clone a repo (but only sending over the snippet) I would expect this to be almost instant response.For the UI part of this - the library that renders the hover tooltips on sourcegraph.com and in our browser extension is stand-alone and open source: https://github.com/sourcegraph/codeintellify (I always hoped one day it would be useful exactly for open source documentation snippets!)
orta commentedon Nov 12, 2019
What a great idea Felix Becker (@felixfbecker)! if this were not for the TypeScript website primarily, I'd definitely be into that - we'll probably need a bunch of weird features like the above. ❤️
andrewbranch commentedon Nov 12, 2019
A few random thoughts:
For (i), the answer is mostly the compiler API, but there are other providers you’ll need to get data from too—syntax highlighting isn’t going to come from the compiler (I tried it once; it doesn’t give good results), and line or span highlighting is going to be some kind of separate annotation. So for (ii), even if you want to use LSIF for part of this, you’ll probably need to embed the LSIF data within a top-level data structure that also holds syntax highlighting and other auxiliary data. Then (iii) is just a fun UI-building problem.
I should also mention that gatsby-remark-vscode is (appropriately) only designed to work within the Gatsby stack, and currently it only outputs HTML, essentially robbing you of the opportunity to do steps (ii) and (iii) yourself. I’m in the process of allowing users to query GraphQL for its tokenization results, which would let you compose its info with other data sources (ii) and render it all however you want (iii). But, if you’d rather work with something lower level or not gatsby-specific, but higher level than vscode-textmate, you could try shiki.
RyanCavanaugh commentedon Nov 12, 2019
Something I'd also like is for a bot to show up on GitHub issues and show the typechecking/emit results of any code blocks in the OP, along with a short version history (e.g. "This behavior is unchanged since version 3.1")
felixfbecker commentedon Nov 12, 2019
Orta Therox (@orta) do you mean specifying the compiler options? I think that can work like this:
textDocument/didOpenwithfile:///tsconfig.jsonpassing the contenttextDocument/didOpenwithfile:///snippet.tswith the content of the snippettextDocument/hoveron hovers with the position to get a hover onBut if you can/want to precompute this data, that makes sense, and there would be no need to involve language servers then.
codeintellifycould still be of help here hopefully - it can handle the mouseover events and render the hover from a (statically embedded) LSP Hover result (you can completely control the rendering and styling if you want).Andrew Branch (@andrewbranch) since I've used LSIF and LSP a lot, maybe I can answer some of the questions: LSIF is probably a good bet (and is just JSON). Both LSIF and LSP use the
Hovertype, which usually contains a markdown string. That markdown string (and any code snippets inside) can then be rendered by any client markdown renderer and syntax highlighter, e.g.markedandhighlight.jsis what we use. That usually is good enough, as highlight.js is good at still handling these kind of "incomplete" code excerpts common in markdown.I'm happy to answer any other questions or share my knowledge here if it's helpful - I think having hover tooltips in docs would be an amazing way to show how what makes TypeScript great!
orta commentedon Nov 13, 2019
Felix Becker (@felixfbecker) - yeah, I want to pre-compute everything on the site, and it's not definitely not outside the realm of possibility that we'll want to run this sort of code against betas and PR builds also (like we do for the playground) - so having it all live in the build process is pretty much a must for me
Ryan Cavanaugh (@RyanCavanaugh) Andrew Branch (@andrewbranch) Yeah - thanks, I think this can be split into a multi-step process then:
a library which takes a dumb fourslash-y string and returns the tsc emit, diagnostics and highlight metadata. This can be used both on the site, and in GitHub actions or bots etc. Then can be bootstrapped by the new handbook but with docs & tests etc. You can see this in Adds a new library for code samples #129
a remark plugin that runs the library above when it finds
'''tswhich would be JS (or ts, or whatever)a separate remark plugin that takes TS/JS code and pulls out the spans in a way that we can then statically generate hover metadata for in some format
the syntax highlighting plugin which should probably be last in the list of remarks and be responsible for generating the HTML
the site can provide an example on how to make a JS front-end for showing the hover info
Each of these move it forwards
orta commentedon Nov 27, 2019
There's been quite a lot of progress on this:
Example
orta commentedon Apr 16, 2020
This is for all intents and purposes, done and the modules are shipped to npm