Skip to content

Commit eb7cf40

Browse files
authored
feat(editor): richer JS/TS highlighting for JSDoc and methods (#2971)
* feat(editor): highlight JSDoc inside JS/TS block comments * feat(editor): colour JS/TS methods as functions and refine JSDoc highlighting - Tag class and interface method names as function definitions and give method calls, method definitions and function declaration names the function colour in all built-in themes. - Bump @lezer/highlight to 1.2.5, which fixes the precedence of context-specific highlight rules added through parser props. - Leave JSDoc braces and punctuation as comment text, handle escaped quotes in types and quoted brackets in optional defaults, and skip /*** comments like TypeScript does. - Add unit tests for JSDoc and method highlighting. * fix(themes): colour properties differently from methods Themes that reused the function colour for properties made this.foo look like a method call. Give properties the palette's property colour where it has one (Tokyo Night, Catppuccin) and the foreground otherwise, and stop colouring Noctis Lilac property definitions as functions. * fix(themes): colour JS properties apart from methods without affecting other languages propertyName is shared by CSS properties, JSON/YAML keys, Go/C++ fields and (through attributeName) HTML attributes, so giving it its own colour moved those away from how VS Code colours them. Restore the themes' propertyName colour and tag JS/TS property names with memberProperty, a sub-tag of propertyName that falls back to it in themes that don't style it. Built-in themes colour it like their VS Code counterparts.
1 parent a8dae47 commit eb7cf40

28 files changed

Lines changed: 954 additions & 29 deletions

‎bun.lock‎

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package-lock.json‎

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@
160160
"@deadlyjack/ajax": "^1.2.6",
161161
"@emmetio/codemirror6-plugin": "^0.4.1",
162162
"@lezer/common": "^1.5.2",
163-
"@lezer/highlight": "^1.2.3",
163+
"@lezer/highlight": "^1.2.5",
164164
"@lezer/lr": "^1.4.10",
165165
"@ungap/custom-elements": "^1.3.0",
166166
"@xterm/addon-attach": "^0.12.0",

‎src/cm/highlightTags.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Tag, tags as t } from "@lezer/highlight";
2+
3+
/**
4+
* Property names in JavaScript/TypeScript: `obj.foo`, object keys and class
5+
* fields. It is a sub-tag of `propertyName`, so themes that don't style it
6+
* keep their `propertyName` colour, and themes that do can colour JS
7+
* properties apart from methods without changing CSS properties, JSON/YAML
8+
* keys or other languages that share `propertyName`.
9+
*/
10+
export const memberProperty = Tag.define("memberProperty", t.propertyName);

‎src/cm/modes/javascript/index.ts‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { javascript } from "@codemirror/lang-javascript";
2+
import { LanguageSupport, LRLanguage } from "@codemirror/language";
3+
import { styleTags, tags as t } from "@lezer/highlight";
4+
import { memberProperty } from "../../highlightTags";
5+
import { jsdocWrap } from "../jsdoc";
6+
7+
const highlightTags = styleTags({
8+
// Lezer tags class and interface method names like property definitions;
9+
// tag them as functions so themes can colour methods like other editors.
10+
"MethodDeclaration/PropertyDefinition MethodDeclaration/PrivatePropertyDefinition MethodType/PropertyDefinition":
11+
t.function(t.definition(t.propertyName)),
12+
// Method calls keep their more specific `function(propertyName)` rule.
13+
PropertyName: memberProperty,
14+
PropertyDefinition: t.definition(memberProperty),
15+
});
16+
17+
/**
18+
* JavaScript/TypeScript support with JSDoc highlighting inside `/** *\/`
19+
* comments, method names tagged as functions and property names tagged as
20+
* {@link memberProperty}.
21+
*/
22+
export function javascriptSupport(
23+
config: { jsx?: boolean; typescript?: boolean } = {},
24+
): LanguageSupport {
25+
const support = javascript(config);
26+
const language = support.language;
27+
if (!(language instanceof LRLanguage)) return support;
28+
return new LanguageSupport(
29+
language.configure({ props: [highlightTags], wrap: jsdocWrap }),
30+
support.support,
31+
);
32+
}

0 commit comments

Comments
 (0)