tsdoc icon indicating copy to clipboard operation
tsdoc copied to clipboard

VS Code extension for TSDoc

Open maasha opened this issue 5 years ago • 11 comments

e.g.

interface SquareConfig {
    color?: string;
    width?: number;
}

maasha avatar Nov 26 '19 08:11 maasha

Something like this:

/**
 * Describes a JavaScript object that specifies the configuration of a square.
 * @remarks
 * Use this interface with the {@link Renderer.drawShape} method.
 * @public
 */
interface SquareConfig {
    /**
     * An HTML color code such as `#00000` for black, etc.
     */
    color?: string;
    /**
     * The width of the square, measured in pixels.
     * If the width is omitted, then by default the square will be sized to fill its container.
     */
    width?: number;
}

@maasha Is that what you were looking for?

octogonz avatar Nov 27 '19 05:11 octogonz

That is pretty standard, but I was wondering if alternatively one could use an @attr tag which could be used to briefly describe the attributes of the interface:

/**
 * Describes a JavaScript object that specifies the configuration of a square.
 * @attr color An HTML color code such as `#00000` for black, etc.
 * @attr width The width of the square, measured in pixels.
 * @remarks
 * Use this interface with the {@link Renderer.drawShape} method.
 * @public
 */
interface SquareConfig {
    color?: string;
    width?: number;
}

This would show up nicely on hover vscode (and Atom and others) for a quick overview of the interface:

image

maasha avatar Nov 27 '19 07:11 maasha

As far as TSDoc goes, I think we would prefer to fix VS Code so that it properly displays the documentation for the interface members. Whereas if we were to add an alternative syntax that is functionally equivalent to the main syntax, this would make the standard harder to learn and harder for implementors to parse.

Btw in your screenshot I don't think VS Code is actually understanding the @attr tag - it merely shows the comment content verbatim.

octogonz avatar Nov 27 '19 07:11 octogonz

Right, I did notice that vscode renders any tag the same - and that is actually what made me wonder in the first place. I can agree to stick to the "main syntax" and then we wait for vscode team to improve the interface information displayed on hover? Will they do this?

maasha avatar Nov 27 '19 07:11 maasha

We might start by making a TSDoc extension for VS Code (similar to the recently released plugin for ESLint). This approach would also allow us to render the docs more nicely similar to what the playground does.

Before I would work on that myself, I have some higher priorities I've been wanting to wrap up, such as finishing the declaration reference parser and posting a spec that documents the TSDoc grammar in detail.

octogonz avatar Nov 27 '19 07:11 octogonz

Awesome, let me know if you need testers

maasha avatar Nov 27 '19 07:11 maasha

I played around with this a bit today. Making a VS Code extension is very easy to do! In about 30 mins I was able to create a simple prototype that finds the nearest TSDoc comment and generates some markdown which gets rendered as a vscode.Hover object:

tsdoc-extension

This was just an experiment, not a real solution.

But if someone's feeling bored, making a TSDoc extension might be a pretty rewarding project. I probably don't have time to undertake it myself, but I'm happy to help out with the design and any parsing/rendering aspects. (For example, for the TSDoc->Markdown part, maybe we can extract the MarkdownEmitter.ts from API Documenter and make it into a reusable library.)

CC @jsamr

octogonz avatar Feb 19 '21 00:02 octogonz

If someone wants to help push this along but doesn't want to implement it, writing up a dev plan would also be useful:

  • Which UI elements should be used to display the TSDoc preview?

  • How does it get rendered? Does it hover above the current selection (as shown above)? What if we need to scroll? Or is it its own panel (Webview API?) that docks next to your editor? (And how do you open it?)

  • How are the docs rendered? For example, for a class, do we show the class members like API Documenter does? Or only show the class summary/remarks like the TSDoc playground does?

  • Does the extension report syntax errors? I use the eslint-plugin-tsdoc which already reports issues via the ESLint extension for VS Code. How should these coexist?

  • How do we detect the nearest doc comment? Should we communicate with the TypeScript language service to get that information? (How to do it?) My prototype simply used document.getText().lastIndexOf("/**", position.character), but this is not correct and will get easily confused by JavaScript quoting/escapin. Alternatively our plugin could have its own dependency on TypeScript, or a more lightweight parser such as Prettier or ESPrima.

A little research to answer these questions might save a lot of time for the implementation.

octogonz avatar Feb 19 '21 00:02 octogonz

@octogonz Thanks for the elaborated presentation of these issues. Not sure I have the time to tackle this, but who knows.

I would add one remark: this extension would be useful for consumers of libraries which documentation has been bundled with API extractor. But how would this extension figure out which standard is this library declaration file(s) following? it would be nice if API extractor added an unambiguous comment header to convey which documentation standard this file is complying to.

jsamr avatar Feb 19 '21 12:02 jsamr

I would add one remark: this extension would be useful for consumers of libraries which documentation has been bundled with API extractor. But how would this extension figure out which standard is this library declaration file(s) following? it would be nice if API extractor added an unambiguous comment header to convey which documentation standard this file is complying to.

The tsdoc.json file solves this problem. It's a source file used by build tools such as ESLint, but it could also be included with your NPM package when it is published, allowing consumers to determine whether your doc comments implement TSDoc syntax or not (and what tags are supported).

API Extractor writes its own file tsdoc-metadata.json in your output folder, which looks like this:

<your project>/dist/tsdoc-metadata.json

// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
// It should be published with your NPM package.  It should not be tracked by Git.
{
  "tsdocVersion": "0.12",
  "toolPackages": [
    {
      "packageName": "@microsoft/api-extractor",
      "packageVersion": "7.13.1"
    }
  ]
}

The tsdoc-metadata.json convention predates tsdoc.json. If I remember right API Extractor uses it to determine whether an NPM library was built with API Extractor (and thus can be expected to implement the AEDoc tags for TSDoc). The tsdoc-metadata.json file records the version of the the TSDoc engine, which is not captured by tsdoc.json, but otherwise I think tsdoc-metadata.json could eventually be replaced by tsdoc.json.

octogonz avatar Feb 20 '21 04:02 octogonz

I currently also do not have the time to implement this feature myself, but I think a TSDOC extension would very helpful.

Just a note for when this gets implemented. I think it would be amazing if this extension would also show return type comments in the vscode.hover object. This is currently missing when using the native jsdocs support. To see what I mean, check out the GIF below, or test it yourself using this example repository. For JSDOC this can be solved using this solution, but I think it would be nice if the TSDoc extension could automatically do this based on the return type interface.

return type comment problem

rickstaa avatar Sep 26 '21 14:09 rickstaa