diff --git a/README.md b/README.md index 25fe1db7e2..9ed3c8814c 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Add this code to your page: - [Client-side!](https://livecodes.io/docs/why#client-side) - Very [configurable](https://livecodes.io/docs/configuration/) - Developer-friendly build-free environment -- Powerful [SDK](https://livecodes.io/docs/sdk/) (available for [vanilla JavaScript, TypeScript](https://livecodes.io/docs/sdk/js-ts), [React](https://livecodes.io/docs/sdk/react), [Vue](https://livecodes.io/docs/sdk/vue), [Svelte](https://livecodes.io/docs/sdk/svelte) and [Solid](https://livecodes.io/docs/sdk/solid)) +- Powerful [SDK](https://livecodes.io/docs/sdk/) (available for [vanilla JavaScript, TypeScript](https://livecodes.io/docs/sdk/js-ts), [React](https://livecodes.io/docs/sdk/react), [Vue](https://livecodes.io/docs/sdk/vue), [Svelte](https://livecodes.io/docs/sdk/svelte), [Solid](https://livecodes.io/docs/sdk/solid) and [Ripple](https://livecodes.io/docs/sdk/ripple)) - Comprehensive [Documentations](https://livecodes.io/docs/) - Focused on [privacy and security](https://livecodes.io/docs/features/security) - Free and [Open-Source](https://livecodes.io/docs/license) @@ -156,7 +156,7 @@ createPlayground('#container', { }); ``` -The [JavaScript SDK](https://livecodes.io/docs/sdk/js-ts) is framework/library agnostic. However, wrapper components are also provided for popular libraries (currently [React](https://livecodes.io/docs/sdk/react) and [Vue](https://livecodes.io/docs/sdk/vue)). The SDK can be used in [Svelte](https://livecodes.io/docs/sdk/svelte) and [Solid](https://livecodes.io/docs/sdk/solid) directly without wrappers. [TypeScript support](https://livecodes.io/docs/sdk/js-ts#typescript-types) provides type-safety and a great developer experience. +The [JavaScript SDK](https://livecodes.io/docs/sdk/js-ts) is framework/library agnostic. However, wrapper components are also provided for popular libraries (currently [React](https://livecodes.io/docs/sdk/react) and [Vue](https://livecodes.io/docs/sdk/vue)). The SDK can be used in [Svelte](https://livecodes.io/docs/sdk/svelte), [Solid](https://livecodes.io/docs/sdk/solid) and [Ripple](https://livecodes.io/docs/sdk/ripple) directly without wrappers. [TypeScript support](https://livecodes.io/docs/sdk/js-ts#typescript-types) provides type-safety and a great developer experience. React SDK example: ([open in LiveCodes](https://livecodes.io/?x=code/N4IgLglmA2CmIC4QBkIDdYGED2ATWAzgAQBKsAhgMZhEDKAIgNJH4C22IANCPgZQE4QADpGwA7RCC4gAFhVySAPK1hhyRSjPL8CqgLwAdEAFUAKgDEAtAA4jRAPQA+A2OWr1Y8isMg0EWADuQtj8YHaU4mCwYmA+ARC4YDJ6+H6UsJbxiTKcRBBiUBDk0JZ8xbB6AIwAdAAMdk7SMmCs0ACCYGA6ktDkYgDmPtHhvQQEPkbSav0EiADaALrcVJAYAKK4UCGSfIIi0qzaANYArkKIoL0DJ+T98EjNrdIRMdFgkiAAvtwEYACecAuICu-Rud0klDGz0ibw+3xAu2E7wQlz6oNu9xAACsCAAPaGvGKSCCsYKhIioDA4XhEABm-GwrCIAHJoOhYBFePZ+BRqMyANwGfguIUuF6-DTiWkQfpEPREYCisREIiHfinIQIBVKlUqkFg2Ba5lqo64bABMTMzg63UvKIxI0AYiIAAlYNBoNgiAB1ELQXAAQitNu+Ss+guFYnFNAACr0-v0GScxLg5UQABQASjljiIikpWDwhElYmlg2ALzLnyIfkCPh5BBO0DCIAcjgjLlguLJNHwtPITdj8cT2GTuA7EnhvwBhDkqlmCEWPwESIXS5AkIIMYbqg+3CEDPSYxCa6WG5Ov0ZtFUkAGC+A8JJPfv8P+QkIF1fhDA9+BaINkhvoQK77NwdqwkgXzcBgOgQOIkgAMwIVM2DYNAv7ROQABGcAKEgxTQNIKzshC4gEGh8A-GoYAXhCnq6AonyfEAA)) diff --git a/docs/docs/languages/ripple.mdx b/docs/docs/languages/ripple.mdx new file mode 100644 index 0000000000..0d20e38610 --- /dev/null +++ b/docs/docs/languages/ripple.mdx @@ -0,0 +1,439 @@ +--- +toc_max_heading_level: 4 +--- + +# Ripple + +[Ripple](https://www.ripplejs.com/) is a TypeScript UI framework that takes the best parts of React, Solid and Svelte and combines them into one package. + +Ripple components can be used in LiveCodes as documented in the [Ripple docs](https://github.com/trueadm/ripple). See below for usage. + +## Demo + +import LiveCodes from '../../src/components/LiveCodes.tsx'; +import RunInLiveCodes from '../../src/components/RunInLiveCodes.tsx'; + +export const demo = { + activeEditor: 'script', + script: { + language: 'ripple', + content: `import { track } from 'ripple'; + +export default component Counter() { + let count = track(0); + let doubled = track(() => @count * 2); + +
+

{'Counter'}

+

{\`Count: \${@count}\`}

+

{\`Doubled: \${@doubled}\`}

+ + + +
+ + +}`, + }, +} + + + + +## Mounting + +### Auto-rendering + +A component is mounted and rendered automatically as a Ripple component (without having to [manually mount](#manual-mount) it) if the following conditions are met: + +- The component is exported as the default export. +- No [imports from `"./script"`](#exports) in markup editor. +- Auto-rendering is not [disabled](#disabling-auto-rendering). + +### Root Element + +To mount the application instance to a specific DOM element use `"livecodes-app"` as the element `id` in the HTML. Otherwise, if that element is not found, a new `div` element is added to `document.body` and is used to mount the instance. +In case you need more control, you can [manually mount](#manual-mount) the instance. + +Example: + +export const customRoot = { + markup: { + language: 'html', + content: `

Custom Root Element

+
+
...other page content
+`, + }, + script: { + language: 'ripple', + content: `import { track } from 'ripple'; + +export default component App() { + let name = track('Ripple'); +
{\`I'm a \${@name} component\`}
+ +} +`, + }, +}; + + + + +### Manual Mount + +Exports from Ripple code can be imported in [markup editor](../features/projects.mdx#markup-editor) from `"./Component.ripple"` and used to mount the application instance manually. +See [Exports](#exports) for details. + +Example: + +export const manualMount = { + markup: { + language: 'html', + content: `

Manual Mount

+
+
...other page content
+ + +`, + }, + script: { + language: 'ripple', + content: `export component App(props: { name: string }) { +
{\`I'm a \${props.name} component\`}
+ +} +`, + }, +}; + + + +### Disabling Auto-rendering + +To disable [auto-rendering](#auto-rendering), set the [custom settings](#custom-settings) `disableAutoRender` property to `true`. + +```json title="Custom Settings" +{ + "ripple": { + "disableAutoRender": true + } +} +``` + +## Importing Modules + +### NPM Modules + +npm modules can be imported as described in the section about [module resolution](../features/module-resolution.mdx), including bare module imports and importing from different CDNs. Stylesheets imported in the `script` block are added as `` tags in the page `head` (see [below](#importing-stylesheets)). + +Module imports can be customized using import maps as described in [module resolution](../features/module-resolution.mdx#custom-module-resolution) documentations. + +Example: + +export const importsDemo = { + ripple: `import { track, effect } from "ripple"; +import confetti from "canvas-confetti"; + +export default component App() { +
+ let count = track(0); + + effect(() => { + if (@count === 2) confetti(); + }); + + + + if (@count > 1) { +
{'Greater than 1!'}
+ } +
+ + +} +`, +}; + + + +### External Components + +External Ripple components can be imported. +The import URL can be either: +- An absolute URL ending with `.ripple` extension. +- A [bare module import](../features/module-resolution.mdx#bare-module-imports) for a published npm module with full path to the component with extension. +- A [data URL](../features/data-urls.mdx) starting with `data:text/ripple`. + +Any bare or relative imports in the imported files are resolved and compiled recursively. +If a processor is enabled (e.g. Tailwind CSS), classes in the imported files are detected and used in the generated CSS (see [CSS Frameworks](#css-frameworks) section below). + +Example: ([source](https://github.com/hatemhosny/ripple-tailwind-counter-demo)) + +export const externalComponents = { + activeEditor: 'script', + script: { + language: 'ripple', + content: `// import from npm modules +import { track } from 'ripple'; +import { Counter } from 'ripple-tailwind-counter-demo/src/Counter.ripple'; +// alternatively use absolute URLs +// import { Counter } from 'https://raw.githubusercontent.com/hatemhosny/ripple-tailwind-counter-demo/refs/heads/main/src/Counter.ripple'; + +export default component App() { + let name = track("World"); + + setTimeout(() => { + @name = "Ripple + Tailwind!"; + }, 2000); + + +} +`, + }, + processors: ['tailwindcss'], +} + + + +### Exports + +Values exported from [script editor](../features/projects.mdx#script-editor) (default or named) can be imported in the [markup editor](../features/projects.mdx#markup-editor) by importing from `"./script"` (with no extension). + +This can be useful, for example, for [manually mounting](#manual-mount) components in the markup editor. + +:::info note + +When values are imported from `"./script"`, [auto-rendering](#auto-rendering) is disabled, because it is assumed that you want to take control over component rendering. + +::: + +## Styles + +CSS can be applied to the component using various ways: + +### Component Styles + +Styles in a `style` tag in a Ripple component are applied to that component only. + +CSS processors (e.g. SCSS, Stylus) can be used by specifying a `lang` attribute for the `style` tag. + +Example: + +export const styleTag = { + ripple: `export default component App() { +

{'Hello World!'}

+ + +} +` +} + + + + +### Style Editor + +Styles added in the [style editor](../features/projects.mdx#style-editor) are applied globally to the [result page](../features/result.mdx). This can use different **languages/processors** supported in LiveCodes including CSS, SCSS, Less, Stylus, ..etc. See [style documentation](../features/css.mdx) for more details. + +And of course, styles and stylesheets added in [markup editor](../features/projects.mdx#markup-editor) are also applied globally. + +### Importing Stylesheets + +Stylesheets imported in [script editor](../features/projects.mdx#script-editor) are added as `` tags in the page `head`. +The stylesheet URL can be an absolute URL or a path in the npm package. The URL has to end with `".css"`. + +example: + +export const stylesDemo = { + ripple: `import "bootstrap/dist/css/bootstrap.css";\n\nexport default component App() {\n

{'Hello World!'}

\n}\n`, +}; + + + +### CSS Modules + +CSS modules are supported and are [documented separately](./cssmodules.mdx). Make sure to enable CSS modules (from style editor menu or in [`processors`](../configuration/configuration-object.mdx#processors) property of [configuration object](../configuration/configuration-object.mdx)). + +Demo: + +export const cssModulesDemo = { + activeEditor: 'script', + style: { language: 'css', content: `.title {\n color: green;\n font-family: sans-serif;\n}\n` }, + script: { + language: 'ripple', + content: `import classes from './style.module.css';\n\nexport default component() {\n

\n {'Hello, CSS Modules!'}\n

\n}\n`, + }, + processors: ['cssmodules'], +}; + + + +### CSS Frameworks + +[CSS Frameworks](../features/css.mdx#css-processors) supported in LiveCodes (e.g. [Tailwind CSS](./tailwindcss.mdx), [UnoCSS](./unocss.mdx), [WindiCSS](./windicss.mdx)) can detect class names added in Ripple components. +Make sure that the required utility is enabled (from style editor menu or in `processors` property of [configuration object](../configuration/configuration-object.mdx#processors)). + +Example: + +export const tailwindDemo = { + activeEditor: 'script', + script: { + language: 'ripple', + content: `import { track } from 'ripple'; + +export default component Counter() { + let count = track(0); + +
+

{'Ripple + Tailwind CSS'}

+
+ + {@count} + +
+ +
+ + +} +`, + }, + processors: ['tailwindcss'], +}; + + + +## Language Info + +### Name + +`ripple` + +### Extensions + +`.ripple` + +### Editor + +`script` + +## Compiler + +The official [Ripple compiler](https://github.com/trueadm/ripple). + +### Version + +`ripple`: v0.2.15 + +## Code Formatting + +Using [Prettier](https://prettier.io/). + +## Custom Settings + +[Custom settings](../advanced/custom-settings.mdx) can be added to the property `ripple`. +These include: + +- `"disableAutoRender"` - [disables auto-rendering](#disabling-auto-rendering) (default: `false`). +- `"version"` - specifies the version of Ripple compiler (default: `"latest"`). + +Example: + +```json title="Custom Settings" +{ + "ripple": { + "version": "0.2.15" + } +} +``` + +Please note that custom settings should be valid JSON (i.e. functions are not allowed). + +## Starter Template + +https://livecodes.io/?template=ripple + + + +## Links + +- [Ripple](https://ripplejs.com/) +- [Ripple documentations](https://github.com/trueadm/ripple) diff --git a/docs/docs/sdk/index.mdx b/docs/docs/sdk/index.mdx index db5b604aef..e1e6a53b36 100644 --- a/docs/docs/sdk/index.mdx +++ b/docs/docs/sdk/index.mdx @@ -10,7 +10,7 @@ The Software Development Kit (SDK) provides an easy, yet powerful, interface to The SDK is provided as a light-weight ([less than 5kb gzipped](https://bundlephobia.com/package/livecodes)), zero-dependencies [npm package](#npm-package), that is also available from [CDNs](#cdn). It can be used to create playgrounds with a wide variety of [configurations](../configuration/configuration-object.mdx) and [embed options](js-ts.mdx#embed-options). In addition, [SDK methods](js-ts.mdx#sdk-methods) allow programmatic communication and control of the playgrounds during runtime. -The [JavaScript SDK](js-ts.mdx) is framework/library agnostic. However, wrapper components are also provided for popular libraries (currently [React](react.mdx) and [Vue](vue.mdx)). The SDK can be used in [Svelte](svelte.mdx) and [Solid](solid.mdx) directly without wrappers. [TypeScript support](js-ts.mdx#typescript-types) provides type-safety and a great developer experience. +The [JavaScript SDK](js-ts.mdx) is framework/library agnostic. However, wrapper components are also provided for popular libraries (currently [React](react.mdx) and [Vue](vue.mdx)). The SDK can be used in [Svelte](svelte.mdx), [Solid](solid.mdx) and [Ripple](ripple.mdx) directly without wrappers. [TypeScript support](js-ts.mdx#typescript-types) provides type-safety and a great developer experience. ## SDK Demo @@ -99,14 +99,11 @@ In the full [standalone app](../getting-started.mdx#standalone-app), the JavaScr The SDK is currently provided in the following variations: - [JavaScript/TypeScript](./js-ts.mdx) - - [React](./react.mdx) - - [Vue](./vue.mdx) - - [Svelte](./svelte.mdx) - - [Solid](./solid.mdx) +- [Ripple](./ripple.mdx) ## Headless Mode diff --git a/docs/docs/sdk/js-ts.mdx b/docs/docs/sdk/js-ts.mdx index 1eb4ef14f4..4c12e7b659 100644 --- a/docs/docs/sdk/js-ts.mdx +++ b/docs/docs/sdk/js-ts.mdx @@ -602,4 +602,5 @@ export const sdkDemo = { - [React SDK](./react.mdx) - [Vue SDK](./vue.mdx) - [Using SDK in Svelte](./svelte.mdx) +- [Using SDK in Ripple](./ripple.mdx) - [Embedded Playgrounds](../features/embeds.mdx) diff --git a/docs/docs/sdk/react.mdx b/docs/docs/sdk/react.mdx index ef8177c3ea..1c54af2d5d 100644 --- a/docs/docs/sdk/react.mdx +++ b/docs/docs/sdk/react.mdx @@ -149,4 +149,5 @@ export const reactSDKDemo = { - [Vue SDK](./vue.mdx) - [Using SDK in Svelte](./svelte.mdx) - [Using SDK in Solid](./solid.mdx) +- [Using SDK in Ripple](./ripple.mdx) - [Embedded Playgrounds](../features/embeds.mdx) diff --git a/docs/docs/sdk/ripple.mdx b/docs/docs/sdk/ripple.mdx new file mode 100644 index 0000000000..cb42b14e5c --- /dev/null +++ b/docs/docs/sdk/ripple.mdx @@ -0,0 +1,82 @@ +# Ripple + +import LiveCodes from '../../src/components/LiveCodes.tsx'; +import RunInLiveCodes from '../../src/components/RunInLiveCodes.tsx'; + +The [JS/TS SDK](js-ts.mdx) can be used directly in [Ripple](https://ripplejs.com) components without the need for any wrappers. + +## Installation + +Please refer to the [SDK installation](./index.mdx#installation) section. + +## Usage + +This is an example of using the LiveCodes JS SDK in a Ripple component: + +```jsx title="App.ripple" +import { createPlayground, type EmbedOptions, type Playground } from 'livecodes'; + +export default component App() { + const options: EmbedOptions = { + params: { + html: '

Hello World!

', + css: 'h1 {color: blue;}', + js: 'console.log("Hello, Ripple!")', + console: 'open', + }, + }; + + let playground: Playground | null = null; + const onMount = (container: HTMLElement) => { + createPlayground(container, options).then((sdk) => { + playground = sdk; // now the SDK is available + }); + return () => playground?.destroy(); + }; + +
+} +``` + +export const rippleSDKDemo = { + ripple: `import { createPlayground, type EmbedOptions, type Playground } from 'livecodes'; + +export default component App() { + const options: EmbedOptions = { + params: { + html: '

Hello World!

', + css: 'h1 {color: blue;}', + js: 'console.log("Hello, Ripple!")', + console: 'open', + }, + }; + + let playground: Playground | null = null; + const onMount = (container: HTMLElement) => { + createPlayground(container, options).then((sdk) => { + playground = sdk; // now the SDK is available + }); + return () => playground?.destroy(); + }; + +
+} +`, +}; + + + +[Embed options](./js-ts.mdx#embed-options), [SDK methods](./js-ts.mdx#sdk-methods) and [TypeScript types](./js-ts.mdx#typescript-types) are available as described in the [JS/TS SDK documentations](./js-ts.mdx). + +## Demo + + + +## Related + +- [SDK Installation](./index.mdx#installation) +- [JS/TS SDK](./js-ts.mdx) +- [React SDK](./react.mdx) +- [Vue SDK](./vue.mdx) +- [Using SDK in Svelte](./svelte.mdx) +- [Embedded Playgrounds](../features/embeds.mdx) diff --git a/docs/docs/sdk/svelte.mdx b/docs/docs/sdk/svelte.mdx index ff903030b9..43362a5709 100644 --- a/docs/docs/sdk/svelte.mdx +++ b/docs/docs/sdk/svelte.mdx @@ -98,4 +98,5 @@ However, it is recommended to cleanup when the node is unmounted, like that: - [React SDK](./react.mdx) - [Vue SDK](./vue.mdx) - [Using SDK in Solid](./solid.mdx) +- [Using SDK in Ripple](./ripple.mdx) - [Embedded Playgrounds](../features/embeds.mdx) diff --git a/docs/docs/sdk/vue.mdx b/docs/docs/sdk/vue.mdx index 9a2a572a27..a8f9133d05 100644 --- a/docs/docs/sdk/vue.mdx +++ b/docs/docs/sdk/vue.mdx @@ -164,4 +164,5 @@ export const vueSDKDemo = { - [React SDK](./react.mdx) - [Using SDK in Svelte](./svelte.mdx) - [Using SDK in Solid](./solid.mdx) +- [Using SDK in Ripple](./ripple.mdx) - [Embedded Playgrounds](../features/embeds.mdx) diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 815f2cddfb..9acc45ced2 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -290,6 +290,7 @@ const config: Config = { plugin: ['typedoc-plugin-missing-exports'], excludeExternals: true, internalModule: '_internal', + skipErrorChecking: true, }, ], [ diff --git a/docs/sidebars.ts b/docs/sidebars.ts index 1b147ba905..7c39ba1d65 100644 --- a/docs/sidebars.ts +++ b/docs/sidebars.ts @@ -85,7 +85,15 @@ const sidebars: SidebarsConfig = { type: 'doc', id: 'sdk/index', }, - items: ['sdk/js-ts', 'sdk/react', 'sdk/vue', 'sdk/svelte', 'sdk/solid', 'sdk/headless'], + items: [ + 'sdk/js-ts', + 'sdk/react', + 'sdk/vue', + 'sdk/svelte', + 'sdk/solid', + 'sdk/ripple', + 'sdk/headless', + ], }, { type: 'category', diff --git a/docs/src/components/HomepageFeatures.tsx b/docs/src/components/HomepageFeatures.tsx index 000ff383af..eda2f7a788 100644 --- a/docs/src/components/HomepageFeatures.tsx +++ b/docs/src/components/HomepageFeatures.tsx @@ -152,8 +152,9 @@ const FeatureList3: FeatureItem[] = [ playgrounds and allows easy communication with them. The SDK is available for vanilla JS/TS,{' '} React, Vue,{' '} - Svelte and Solid. There is also - a headless mode for full control over the UI. + Svelte, Solid and{' '} + Ripple. There is also a{' '} + headless mode for full control over the UI. ), }, diff --git a/docs/src/components/LanguageSliders.tsx b/docs/src/components/LanguageSliders.tsx index 960c4933a6..e7ec272e72 100644 --- a/docs/src/components/LanguageSliders.tsx +++ b/docs/src/components/LanguageSliders.tsx @@ -69,6 +69,7 @@ export default function Sliders() { { name: 'solid.tsx', title: 'Solid (TS)' }, { name: 'riot', title: 'Riot.js' }, { name: 'malina', title: 'Malina.js' }, + { name: 'ripple', title: 'Ripple' }, { name: 'coffeescript', title: 'CoffeeScript' }, { name: 'livescript', title: 'LiveScript' }, { name: 'civet', title: 'Civet' }, diff --git a/docs/src/components/LiveCodes.tsx b/docs/src/components/LiveCodes.tsx index 1c9d1ee716..350192fe00 100644 --- a/docs/src/components/LiveCodes.tsx +++ b/docs/src/components/LiveCodes.tsx @@ -85,6 +85,20 @@ export default function App() { return
; } +`.trimStart(); + + const rippleCode = ` +import { createPlayground, type EmbedOptions } from 'livecodes'; + +export default component App() { + const options: EmbedOptions = ${stringify(options).split('\n').join('\n ')}; + const onMount = (container: HTMLElement) => { + createPlayground(container, options); + }; + +
+} + `.trimStart(); return ( @@ -111,6 +125,7 @@ export default function App() { vue={vueCode} svelte={svelteCode} solid={solidCode} + ripple={rippleCode} > )} diff --git a/docs/src/components/ShowCode.tsx b/docs/src/components/ShowCode.tsx index 20770a74b6..94df3fd368 100644 --- a/docs/src/components/ShowCode.tsx +++ b/docs/src/components/ShowCode.tsx @@ -15,6 +15,7 @@ export default function ShowCode(props: { vue: string; svelte: string; solid: string; + ripple: string; }): ReactNode { const [jsCode, setJsCode] = useState(props.js); const [tsCode, setTsCode] = useState(props.ts); @@ -22,6 +23,7 @@ export default function ShowCode(props: { const [vueCode, setVueCode] = useState(props.vue); const [svelteCode, setSvelteCode] = useState(props.svelte); const [solidCode, setSolidCode] = useState(props.solid); + const [rippleCode, setRippleCode] = useState(props.ripple); const codeBlockTitleHeight = '3.7rem'; const [codeCollapsed, setCodeCollapsed] = useState(true); @@ -60,6 +62,7 @@ export default function ShowCode(props: { setVueCode(format(vueCode, 'html')); setSvelteCode(format(svelteCode, 'html')); setSolidCode(format(solidCode, 'tsx')); + setRippleCode(format(rippleCode, 'tsx')); } }, []); @@ -103,6 +106,9 @@ export default function ShowCode(props: { {solidCode} + + {rippleCode} + diff --git a/docs/src/components/TemplateList.tsx b/docs/src/components/TemplateList.tsx index a246d4d47a..25d77c5114 100644 --- a/docs/src/components/TemplateList.tsx +++ b/docs/src/components/TemplateList.tsx @@ -23,6 +23,7 @@ const templates = [ { name: 'astro', title: 'Astro Starter', thumbnail: 'astro.svg' }, { name: 'riot', title: 'Riot.js Starter', thumbnail: 'riot.svg' }, { name: 'malina', title: 'Malina.js Starter', thumbnail: 'malina.svg' }, + { name: 'ripple', title: 'Ripple Starter', thumbnail: 'ripple-0.png' }, { name: 'jquery', title: 'jQuery Starter', thumbnail: 'jquery.svg' }, { name: 'backbone', title: 'Backbone Starter', thumbnail: 'backbone.svg' }, { name: 'knockout', title: 'Knockout Starter', thumbnail: 'knockout.svg' }, diff --git a/eslint.config.mjs b/eslint.config.mjs index aab8c872fb..bdb275ecf3 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -32,6 +32,7 @@ export default [ '**/.jest', '**/.storybook', 'functions/vendors', + 'src/livecodes/editor/monaco/languages/monaco-lang-ripple.ts', ], }, ...fixupConfigRules( diff --git a/scripts/build.js b/scripts/build.js index 60b1976642..17e4f13c3c 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -160,6 +160,7 @@ const esmBuild = () => 'editor/monaco/languages/monaco-lang-astro.ts', 'editor/monaco/languages/monaco-lang-clio.ts', 'editor/monaco/languages/monaco-lang-imba.ts', + 'editor/monaco/languages/monaco-lang-ripple.ts', // 'editor/monaco/languages/monaco-lang-sql.ts', 'editor/monaco/languages/monaco-lang-wat.ts', 'editor/codemirror/codemirror.ts', @@ -237,6 +238,8 @@ const iifeBuild = () => 'languages/python-wasm/lang-python-wasm-script.ts', 'languages/rescript/lang-rescript-formatter.ts', 'languages/riot/lang-riot-compiler.ts', + 'languages/ripple/lang-ripple-compiler.ts', + 'languages/ripple/lang-ripple-formatter.ts', 'languages/ruby-wasm/lang-ruby-wasm-script.ts', 'languages/scss/lang-scss-compiler.ts', 'languages/solid/lang-solid-compiler.ts', diff --git a/src/livecodes/UI/command-menu-actions.ts b/src/livecodes/UI/command-menu-actions.ts index 708f5ba1f7..be3be12b67 100644 --- a/src/livecodes/UI/command-menu-actions.ts +++ b/src/livecodes/UI/command-menu-actions.ts @@ -266,6 +266,7 @@ export const getCommandMenuActions = ({ 'preact', 'svelte', 'solid', + 'ripple', 'lit', 'stencil', 'mdx', diff --git a/src/livecodes/assets/templates/ripple.png b/src/livecodes/assets/templates/ripple.png new file mode 100644 index 0000000000..9a58b221f2 Binary files /dev/null and b/src/livecodes/assets/templates/ripple.png differ diff --git a/src/livecodes/compiler/import-map.ts b/src/livecodes/compiler/import-map.ts index a915cd0040..ae70efb17c 100644 --- a/src/livecodes/compiler/import-map.ts +++ b/src/livecodes/compiler/import-map.ts @@ -144,6 +144,14 @@ export const isScriptImport = (mod: string) => mod.toLowerCase().endsWith('.vue') || mod.toLowerCase().endsWith('.svelte'))); +const isStyleImport = (mod: string) => + mod.toLowerCase().startsWith('./style') || + mod.toLowerCase().endsWith('.css') || + mod.toLowerCase().endsWith('.scss') || + mod.toLowerCase().endsWith('.sass') || + mod.toLowerCase().endsWith('.less') || + mod.toLowerCase().endsWith('.styl'); + const modulesCache: Record = {}; const fetchModule = async (mod: string) => { if (modulesCache[mod]) { @@ -176,7 +184,7 @@ export const replaceSFCImports = async ( const isExtensionless = (mod: string) => mod.startsWith('.') && !mod.split('/')[mod.split('/').length - 1].includes('.'); const sfcImports = getImports(code).filter( - (mod) => isSfc(mod) || isExtensionless(mod) || mod.startsWith('.'), + (mod) => !isStyleImport(mod) && (isSfc(mod) || isExtensionless(mod) || mod.startsWith('.')), ); const projectImportMap = { ...config.imports, diff --git a/src/livecodes/editor/monaco/languages/monaco-lang-ripple.ts b/src/livecodes/editor/monaco/languages/monaco-lang-ripple.ts new file mode 100644 index 0000000000..3a663d5443 --- /dev/null +++ b/src/livecodes/editor/monaco/languages/monaco-lang-ripple.ts @@ -0,0 +1,8876 @@ +// from https://github.com/trueadm/ripple/blob/main/packages/ripple-vscode-plugin/syntaxes/ripple.tmLanguage.json +// and https://github.com/trueadm/ripple/blob/main/packages/ripple-vscode-plugin/language-configuration.json +// and 'https://cdn.jsdelivr.net/gh/zikaari/monaco-textmate-languages@master/grammars/css/css.tmLanguage.json' +// Config onEnterRules cause errors - currently disabled + +export default { + syntax: { + information_for_contributors: [ + 'This file has been converted from https://github.com/microsoft/TypeScript-TmLanguage/blob/master/TypeScriptReact.tmLanguage', + 'If you want to provide a fix or improvement, please create a pull request against the original repository.', + 'Once accepted there, we are happy to receive an update request.', + ], + version: + 'https://github.com/microsoft/TypeScript-TmLanguage/commit/48f608692aa6d6ad7bd65b478187906c798234a8', + name: 'Ripple', + scopeName: 'source.ripple', + patterns: [ + { + include: '#directives', + }, + { + include: '#statements', + }, + { + include: '#shebang', + }, + ], + repository: { + shebang: { + name: 'comment.line.shebang.js', + match: '\\A(#!).*(?=$)', + captures: { + '1': { + name: 'punctuation.definition.comment.js', + }, + }, + }, + statements: { + patterns: [ + { + include: '#declaration', + }, + { + include: '#control-statement', + }, + { + include: '#after-operator-block-as-object-literal', + }, + { + include: '#decl-block', + }, + { + include: '#label', + }, + { + include: '#expression', + }, + { + include: '#punctuation-semicolon', + }, + { + include: '#string', + }, + { + include: '#comment', + }, + ], + }, + 'component-statements': { + patterns: [ + { + include: '#jsx', + }, + { + include: '#declaration', + }, + { + include: '#component-control-statement', + }, + { + include: '#component-decl-block', + }, + { + include: '#label', + }, + { + include: '#expression', + }, + { + include: '#punctuation-semicolon', + }, + { + include: '#string', + }, + { + include: '#comment', + }, + ], + }, + declaration: { + patterns: [ + { + include: '#decorator', + }, + { + include: '#var-expr', + }, + { + include: '#server-block', + }, + { + include: '#component-declaration', + }, + { + include: '#fragment-declaration', + }, + { + include: '#function-declaration', + }, + { + include: '#class-declaration', + }, + { + include: '#interface-declaration', + }, + { + include: '#enum-declaration', + }, + { + include: '#namespace-declaration', + }, + { + include: '#type-alias-declaration', + }, + { + include: '#import-equals-declaration', + }, + { + include: '#import-declaration', + }, + { + include: '#export-declaration', + }, + { + name: 'storage.modifier.js', + match: + '(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))', + beginCaptures: { + '1': { + name: 'meta.definition.variable.js entity.name.function.js', + }, + '2': { + name: 'keyword.operator.definiteassignment.js', + }, + }, + end: '(?=$|^|[;,=}]|((?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))', + beginCaptures: { + '1': { + name: 'meta.definition.variable.js variable.other.constant.js entity.name.function.js', + }, + }, + end: '(?=$|^|[;,=}]|((?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))', + captures: { + '1': { + name: 'storage.modifier.js', + }, + '2': { + name: 'keyword.operator.rest.js', + }, + '3': { + name: 'entity.name.function.js variable.language.this.js', + }, + '4': { + name: 'entity.name.function.js', + }, + '5': { + name: 'keyword.operator.optional.js', + }, + }, + }, + { + match: + '(?x)(?:(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))', + captures: { + '1': { + name: 'meta.definition.property.js entity.name.function.js', + }, + '2': { + name: 'keyword.operator.optional.js', + }, + '3': { + name: 'keyword.operator.definiteassignment.js', + }, + }, + }, + { + name: 'meta.definition.property.js variable.object.property.js', + match: '\\#?[_$[:alpha:]][_$[:alnum:]]*', + }, + { + name: 'keyword.operator.optional.js', + match: '\\?', + }, + { + name: 'keyword.operator.definiteassignment.js', + match: '\\!', + }, + ], + }, + 'variable-initializer': { + patterns: [ + { + begin: '(?\\s*$)', + beginCaptures: { + '1': { + name: 'keyword.operator.assignment.js', + }, + }, + end: '(?=$|^|[,);}\\]]|((?]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])', + beginCaptures: { + '1': { + name: 'storage.modifier.js', + }, + '2': { + name: 'storage.modifier.js', + }, + '3': { + name: 'storage.modifier.js', + }, + '4': { + name: 'storage.modifier.async.js', + }, + '5': { + name: 'keyword.operator.new.js', + }, + '6': { + name: 'keyword.generator.asterisk.js', + }, + }, + end: '(?=\\}|;|,|$)|(?<=\\})', + patterns: [ + { + include: '#method-declaration-name', + }, + { + include: '#function-body', + }, + ], + }, + { + name: 'meta.method.declaration.js', + begin: + '(?x)(?]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])', + beginCaptures: { + '1': { + name: 'storage.modifier.js', + }, + '2': { + name: 'storage.modifier.js', + }, + '3': { + name: 'storage.modifier.js', + }, + '4': { + name: 'storage.modifier.async.js', + }, + '5': { + name: 'storage.type.property.js', + }, + '6': { + name: 'keyword.generator.asterisk.js', + }, + }, + end: '(?=\\}|;|,|$)|(?<=\\})', + patterns: [ + { + include: '#method-declaration-name', + }, + { + include: '#function-body', + }, + ], + }, + ], + }, + 'object-literal-method-declaration': { + name: 'meta.method.declaration.js', + begin: + '(?x)(?]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])', + beginCaptures: { + '1': { + name: 'storage.modifier.async.js', + }, + '2': { + name: 'storage.type.property.js', + }, + '3': { + name: 'keyword.generator.asterisk.js', + }, + }, + end: '(?=\\}|;|,)|(?<=\\})', + patterns: [ + { + include: '#method-declaration-name', + }, + { + include: '#function-body', + }, + { + begin: + '(?x)(?]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])', + beginCaptures: { + '1': { + name: 'storage.modifier.async.js', + }, + '2': { + name: 'storage.type.property.js', + }, + '3': { + name: 'keyword.generator.asterisk.js', + }, + }, + end: '(?=\\(|\\<)', + patterns: [ + { + include: '#method-declaration-name', + }, + ], + }, + ], + }, + 'method-declaration-name': { + begin: + '(?x)(?=((\\b(?)', + captures: { + '1': { + name: 'storage.modifier.async.js', + }, + '2': { + name: 'variable.parameter.js', + }, + }, + }, + { + name: 'meta.arrow.js', + begin: + '(?x) (?:\n (? is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n )\n)', + beginCaptures: { + '1': { + name: 'storage.modifier.async.js', + }, + }, + end: '(?==>|\\{|(^\\s*(export|function|class|interface|let|var|(?:\\busing(?=\\s+(?!in\\b|of\\b(?!\\s*(?:of\\b|=)))[_$[:alpha:]])\\b)|(?:\\bawait\\s+(?:\\busing(?=\\s+(?!in\\b|of\\b(?!\\s*(?:of\\b|=)))[_$[:alpha:]])\\b)\\b)|const|import|enum|namespace|module|type|abstract|declare)\\s+))', + patterns: [ + { + include: '#comment', + }, + { + include: '#type-parameters', + }, + { + include: '#function-parameters', + }, + { + include: '#arrow-return-type', + }, + { + include: '#possibly-arrow-return-type', + }, + ], + }, + { + name: 'meta.arrow.js', + begin: '=>', + beginCaptures: { + '0': { + name: 'storage.type.function.arrow.js', + }, + }, + end: '((?<=\\}|\\S)(?)|((?!\\{)(?=\\S)))(?!\\/[\\/\\*])', + patterns: [ + { + include: '#single-line-comment-consuming-line-ending', + }, + { + include: '#decl-block', + }, + { + include: '#expression', + }, + ], + }, + ], + }, + 'indexer-declaration': { + name: 'meta.indexer.declaration.js', + begin: + '(?:(?]|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^yield|[^\\._$[:alnum:]]yield|^throw|[^\\._$[:alnum:]]throw|^in|[^\\._$[:alnum:]]in|^of|[^\\._$[:alnum:]]of|^typeof|[^\\._$[:alnum:]]typeof|&&|\\|\\||\\*)\\s*(\\{)', + beginCaptures: { + '1': { + name: 'punctuation.definition.block.js', + }, + }, + end: '\\}', + endCaptures: { + '0': { + name: 'punctuation.definition.block.js', + }, + }, + patterns: [ + { + include: '#object-member', + }, + ], + }, + 'object-literal': { + name: 'meta.objectliteral.js', + begin: '\\{', + beginCaptures: { + '0': { + name: 'punctuation.definition.block.js', + }, + }, + end: '\\}', + endCaptures: { + '0': { + name: 'punctuation.definition.block.js', + }, + }, + patterns: [ + { + include: '#object-member', + }, + ], + }, + 'object-member': { + patterns: [ + { + include: '#comment', + }, + { + include: '#object-literal-method-declaration', + }, + { + name: 'meta.object.member.js meta.object-literal.key.js', + begin: '(?=\\[)', + end: '(?=:)|((?<=[\\]])(?=\\s*[\\(\\<]))', + patterns: [ + { + include: '#comment', + }, + { + include: '#array-literal', + }, + { + include: '#tuple-literal', + }, + ], + }, + { + name: 'meta.object.member.js meta.object-literal.key.js', + begin: '(?=[\\\'\\"\\`])', + end: '(?=:)|((?<=[\\\'\\"\\`])(?=((\\s*[\\(\\<,}])|(\\s+(as|satisfies)\\s+))))', + patterns: [ + { + include: '#comment', + }, + { + include: '#string', + }, + ], + }, + { + name: 'meta.object.member.js meta.object-literal.key.js', + begin: + '(?x)(?=(\\b(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))', + captures: { + '0': { + name: 'meta.object-literal.key.js', + }, + '1': { + name: 'entity.name.function.js', + }, + }, + }, + { + name: 'meta.object.member.js', + match: + '(?:[_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*:)', + captures: { + '0': { + name: 'meta.object-literal.key.js', + }, + }, + }, + { + name: 'meta.object.member.js', + begin: '\\.\\.\\.', + beginCaptures: { + '0': { + name: 'keyword.operator.spread.js', + }, + }, + end: '(?=,|\\})', + patterns: [ + { + include: '#expression', + }, + ], + }, + { + name: 'meta.object.member.js', + match: '([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=,|\\}|$|\\/\\/|\\/\\*)', + captures: { + '1': { + name: 'variable.other.readwrite.js', + }, + }, + }, + { + name: 'meta.object.member.js', + match: '(?]|\\|\\||\\&\\&|\\!\\=\\=|$|^|((?]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)\\(\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))', + beginCaptures: { + '1': { + name: 'storage.modifier.async.js', + }, + }, + end: '(?<=\\))', + patterns: [ + { + include: '#type-parameters', + }, + { + begin: '\\(', + beginCaptures: { + '0': { + name: 'meta.brace.round.js', + }, + }, + end: '\\)', + endCaptures: { + '0': { + name: 'meta.brace.round.js', + }, + }, + patterns: [ + { + include: '#expression-inside-possibly-arrow-parens', + }, + ], + }, + ], + }, + { + begin: + '(?<=:)\\s*(async)?\\s*(\\()(?=\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))', + beginCaptures: { + '1': { + name: 'storage.modifier.async.js', + }, + '2': { + name: 'meta.brace.round.js', + }, + }, + end: '\\)', + endCaptures: { + '0': { + name: 'meta.brace.round.js', + }, + }, + patterns: [ + { + include: '#expression-inside-possibly-arrow-parens', + }, + ], + }, + { + begin: '(?<=:)\\s*(async)?\\s*(?=\\<\\s*$)', + beginCaptures: { + '1': { + name: 'storage.modifier.async.js', + }, + }, + end: '(?<=\\>)', + patterns: [ + { + include: '#type-parameters', + }, + ], + }, + { + begin: + '(?<=\\>)\\s*(\\()(?=\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))', + beginCaptures: { + '1': { + name: 'meta.brace.round.js', + }, + }, + end: '\\)', + endCaptures: { + '0': { + name: 'meta.brace.round.js', + }, + }, + patterns: [ + { + include: '#expression-inside-possibly-arrow-parens', + }, + ], + }, + { + include: '#possibly-arrow-return-type', + }, + { + include: '#expression', + }, + ], + }, + { + include: '#punctuation-comma', + }, + { + include: '#decl-block', + }, + ], + }, + 'ternary-expression': { + begin: '(?!\\?\\.\\s*[^[:digit:]])(\\?)(?!\\?)', + beginCaptures: { + '1': { + name: 'keyword.operator.ternary.js', + }, + }, + end: '\\s*(:)', + endCaptures: { + '1': { + name: 'keyword.operator.ternary.js', + }, + }, + patterns: [ + { + include: '#expression', + }, + ], + }, + 'function-call': { + patterns: [ + { + begin: + '(?=(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))\\s*(?:(\\?\\.\\s*)|(\\!))?((<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?\\())', + end: '(?<=\\))(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))\\s*(?:(\\?\\.\\s*)|(\\!))?((<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?\\())', + patterns: [ + { + name: 'meta.function-call.js', + begin: + '(?=(([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))', + end: '(?=\\s*(?:(\\?\\.\\s*)|(\\!))?((<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?\\())', + patterns: [ + { + include: '#function-call-target', + }, + ], + }, + { + include: '#comment', + }, + { + include: '#function-call-optionals', + }, + { + include: '#type-arguments', + }, + { + include: '#paren-expression', + }, + ], + }, + { + begin: + '(?=(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))(<\\s*[\\{\\[\\(]\\s*$))', + end: '(?<=\\>)(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\\)]))(<\\s*[\\{\\[\\(]\\s*$))', + patterns: [ + { + name: 'meta.function-call.js', + begin: + '(?=(([_$[:alpha:]][_$[:alnum:]]*)(\\s*\\??\\.\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*))', + end: '(?=(<\\s*[\\{\\[\\(]\\s*$))', + patterns: [ + { + include: '#function-call-target', + }, + ], + }, + { + include: '#comment', + }, + { + include: '#function-call-optionals', + }, + { + include: '#type-arguments', + }, + ], + }, + ], + }, + 'function-call-target': { + patterns: [ + { + include: '#support-function-call-identifiers', + }, + { + name: 'entity.name.function.js', + match: '(\\#?[_$[:alpha:]][_$[:alnum:]]*)', + }, + ], + }, + 'function-call-optionals': { + patterns: [ + { + name: 'meta.function-call.js punctuation.accessor.optional.js', + match: '\\?\\.', + }, + { + name: 'meta.function-call.js keyword.operator.definiteassignment.js', + match: '\\!', + }, + ], + }, + 'support-function-call-identifiers': { + patterns: [ + { + include: '#literal', + }, + { + include: '#support-objects', + }, + { + include: '#object-identifiers', + }, + { + include: '#punctuation-accessor', + }, + { + name: 'keyword.operator.expression.import.js', + match: + '(?:(?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?]|\\|\\||\\&\\&|\\!\\=\\=|$|(===|!==|==|!=)|(([\\&\\~\\^\\|]\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s+instanceof(?![_$[:alnum:]])(?:(?=\\.\\.\\.)|(?!\\.)))|((?]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?\\(\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))', + beginCaptures: { + '1': { + name: 'storage.modifier.async.js', + }, + }, + end: '(?<=\\))', + patterns: [ + { + include: '#paren-expression-possibly-arrow-with-typeparameters', + }, + ], + }, + { + begin: + '(?<=[(=,]|=>|^return|[^\\._$[:alnum:]]return)\\s*(async)?(?=\\s*((((<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?\\()|(<)|((<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)))\\s*$)', + beginCaptures: { + '1': { + name: 'storage.modifier.async.js', + }, + }, + end: '(?<=\\))', + patterns: [ + { + include: '#paren-expression-possibly-arrow-with-typeparameters', + }, + ], + }, + { + include: '#possibly-arrow-return-type', + }, + ], + }, + 'paren-expression-possibly-arrow-with-typeparameters': { + patterns: [ + { + include: '#type-parameters', + }, + { + begin: '\\(', + beginCaptures: { + '0': { + name: 'meta.brace.round.js', + }, + }, + end: '\\)', + endCaptures: { + '0': { + name: 'meta.brace.round.js', + }, + }, + patterns: [ + { + include: '#expression-inside-possibly-arrow-parens', + }, + ], + }, + ], + }, + 'expression-inside-possibly-arrow-parens': { + patterns: [ + { + include: '#expressionWithoutIdentifiers', + }, + { + include: '#comment', + }, + { + include: '#string', + }, + { + include: '#decorator', + }, + { + include: '#destructuring-parameter', + }, + { + match: + '(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)) |\n# typeannotation is fn type: < | () | (... | (param: | (param, | (param? | (param= | (param) =>\n(:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))) |\n(:\\s*(=>|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(<[^<>]*>)|[^<>(),=])+=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n)))', + captures: { + '1': { + name: 'storage.modifier.js', + }, + '2': { + name: 'keyword.operator.rest.js', + }, + '3': { + name: 'entity.name.function.js variable.language.this.js', + }, + '4': { + name: 'entity.name.function.js', + }, + '5': { + name: 'keyword.operator.optional.js', + }, + }, + }, + { + match: + '(?x)(?:(?]|\\|\\||\\&\\&|\\!\\=\\=|$|((?>=|>>>=|\\|=', + }, + { + name: 'keyword.operator.bitwise.shift.js', + match: '<<|>>>|>>', + }, + { + name: 'keyword.operator.comparison.js', + match: '===|!==|==|!=', + }, + { + name: 'keyword.operator.relational.js operator.relational.ripple-force entity.name.operator.relational.ripple', + match: '<=|>=|<>|<|>', + }, + { + match: '(?<=[_$[:alnum:]])(\\!)\\s*(?:(/=)|(?:(/)(?![/*])))', + captures: { + '1': { + name: 'keyword.operator.logical.js', + }, + '2': { + name: 'keyword.operator.assignment.compound.js', + }, + '3': { + name: 'keyword.operator.arithmetic.js', + }, + }, + }, + { + name: 'keyword.operator.logical.js', + match: '\\!|&&|\\|\\||\\?\\?', + }, + { + name: 'keyword.operator.bitwise.js', + match: '\\&|~|\\^|\\|', + }, + { + name: 'keyword.operator.assignment.js', + match: '\\=', + }, + { + name: 'keyword.operator.decrement.js', + match: '--', + }, + { + name: 'keyword.operator.increment.js', + match: '\\+\\+', + }, + { + name: 'keyword.operator.arithmetic.js', + match: '%|\\*|/|-|\\+', + }, + { + begin: + '(?<=[_$[:alnum:])\\]])\\s*(?=(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)+(?:(/=)|(?:(/)(?![/*]))))', + end: '(?:(/=)|(?:(/)(?!\\*([^\\*]|(\\*[^\\/]))*\\*\\/)))', + endCaptures: { + '1': { + name: 'keyword.operator.assignment.compound.js', + }, + '2': { + name: 'keyword.operator.arithmetic.js', + }, + }, + patterns: [ + { + include: '#comment', + }, + ], + }, + { + match: '(?<=[_$[:alnum:])\\]])\\s*(?:(/=)|(?:(/)(?![/*])))', + captures: { + '1': { + name: 'keyword.operator.assignment.compound.js', + }, + '2': { + name: 'keyword.operator.arithmetic.js', + }, + }, + }, + ], + }, + 'typeof-operator': { + begin: + '(?:&|{\\?]|(extends\\s+)|$|;|^\\s*$|(?:^\\s*(?:abstract|async|(?:\\bawait\\s+(?:\\busing(?=\\s+(?!in\\b|of\\b(?!\\s*(?:of\\b|=)))[_$[:alpha:]])\\b)\\b)|break|case|catch|class|const|continue|declare|do|else|enum|export|finally|function|for|goto|if|import|interface|let|module|namespace|switch|return|throw|try|type|(?:\\busing(?=\\s+(?!in\\b|of\\b(?!\\s*(?:of\\b|=)))[_$[:alpha:]])\\b)|var|while)\\b))', + patterns: [ + { + include: '#type-arguments', + }, + { + include: '#expression', + }, + ], + }, + literal: { + patterns: [ + { + include: '#numeric-literal', + }, + { + include: '#boolean-literal', + }, + { + include: '#null-literal', + }, + { + include: '#undefined-literal', + }, + { + include: '#numericConstant-literal', + }, + { + include: '#array-literal', + }, + { + include: '#tuple-literal', + }, + { + include: '#record-literal', + }, + { + include: '#this-literal', + }, + { + include: '#super-literal', + }, + ], + }, + 'array-literal': { + name: 'meta.array.literal.js', + begin: '\\s*(\\[)', + beginCaptures: { + '1': { + name: 'meta.brace.square.js', + }, + }, + end: '\\]', + endCaptures: { + '0': { + name: 'meta.brace.square.js', + }, + }, + patterns: [ + { + include: '#expression', + }, + { + include: '#punctuation-comma', + }, + ], + }, + 'tuple-literal': { + name: 'meta.tuple.literal.js', + begin: '(#)(\\[)', + beginCaptures: { + '1': { + name: 'keyword.control.tuple.js', + }, + '2': { + name: 'meta.brace.square.js', + }, + }, + end: '\\]', + endCaptures: { + '0': { + name: 'meta.brace.square.js', + }, + }, + patterns: [ + { + include: '#expression', + }, + { + include: '#punctuation-comma', + }, + ], + }, + 'record-literal': { + name: 'meta.record.literal.js', + begin: '(#)(\\{)', + beginCaptures: { + '1': { + name: 'keyword.control.record.js', + }, + '2': { + name: 'punctuation.definition.block.js', + }, + }, + end: '\\}', + endCaptures: { + '0': { + name: 'punctuation.definition.block.js', + }, + }, + patterns: [ + { + include: '#object-member', + }, + ], + }, + 'numeric-literal': { + patterns: [ + { + name: 'constant.numeric.hex.js', + match: '\\b(?]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\\())\n |\n (?:(EPSILON|MAX_SAFE_INTEGER|MAX_VALUE|MIN_SAFE_INTEGER|MIN_VALUE|NEGATIVE_INFINITY|POSITIVE_INFINITY)\\b(?!\\$)))', + captures: { + '1': { + name: 'punctuation.accessor.js', + }, + '2': { + name: 'punctuation.accessor.optional.js', + }, + '3': { + name: 'support.variable.property.js', + }, + '4': { + name: 'support.constant.js', + }, + }, + }, + { + match: + '(?)\n )) |\n ((async\\s*)?(\n ((<\\s*$)|([\\(]\\s*((([\\{\\[]\\s*)?$)|((\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})\\s*((:\\s*\\{?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))))) |\n # sure shot arrow functions even if => is on new line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)?\n [(]\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n) |\n(\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends\n) |\n# arrow function possible to detect only with => on same line\n(\n (<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*(((const\\s+)?[_$[:alpha:]])|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*)? # typeparameters\n \\(\\s*(\\/\\*([^\\*]|(\\*[^\\/]))*\\*\\/\\s*)*(([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\.\\.\\.\\s*[_$[:alpha:]]))([^()\\\'\\"\\`]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))*)?\\) # parameters\n (\\s*:\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+)? # return type\n \\s*=> # arrow operator\n)\n ))\n))', + captures: { + '1': { + name: 'punctuation.accessor.js', + }, + '2': { + name: 'punctuation.accessor.optional.js', + }, + '3': { + name: 'entity.name.function.js', + }, + }, + }, + { + match: + '(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(\\#?[[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])', + captures: { + '1': { + name: 'punctuation.accessor.js', + }, + '2': { + name: 'punctuation.accessor.optional.js', + }, + '3': { + name: 'variable.other.constant.property.js', + }, + }, + }, + { + match: '(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(\\#?[_$[:alpha:]][_$[:alnum:]]*)', + captures: { + '1': { + name: 'punctuation.accessor.js', + }, + '2': { + name: 'punctuation.accessor.optional.js', + }, + '3': { + name: 'variable.other.property.js', + }, + }, + }, + { + name: 'variable.other.constant.js', + match: '([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])', + }, + { + name: 'variable.other.readwrite.js', + match: '[_$[:alpha:]][_$[:alnum:]]*', + }, + ], + }, + 'object-identifiers': { + patterns: [ + { + name: 'support.class.js', + match: '([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\\??\\.\\s*prototype\\b(?!\\$))', + }, + { + match: + '(?x)(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))\\s*(?:\n (\\#?[[:upper:]][_$[:digit:][:upper:]]*) |\n (\\#?[_$[:alpha:]][_$[:alnum:]]*)\n)(?=\\s*\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*)', + captures: { + '1': { + name: 'punctuation.accessor.js', + }, + '2': { + name: 'punctuation.accessor.optional.js', + }, + '3': { + name: 'variable.other.constant.object.property.js', + }, + '4': { + name: 'variable.other.object.property.js', + }, + }, + }, + { + match: + '(?x)(?:\n ([[:upper:]][_$[:digit:][:upper:]]*) |\n ([_$[:alpha:]][_$[:alnum:]]*)\n)(?=\\s*\\??\\.\\s*\\#?[_$[:alpha:]][_$[:alnum:]]*)', + captures: { + '1': { + name: 'variable.other.constant.object.js', + }, + '2': { + name: 'variable.other.object.js', + }, + }, + }, + ], + }, + 'type-annotation': { + patterns: [ + { + name: 'meta.type.annotation.js', + begin: '(:)(?=\\s*\\S)', + beginCaptures: { + '1': { + name: 'keyword.operator.type.annotation.js', + }, + }, + end: '(?])|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))', + patterns: [ + { + include: '#type', + }, + ], + }, + { + name: 'meta.type.annotation.js', + begin: '(:)', + beginCaptures: { + '1': { + name: 'keyword.operator.type.annotation.js', + }, + }, + end: '(?])|(?=^\\s*$)|((?<=[\\}>\\]\\)]|[_$[:alpha:]])\\s*(?=\\{)))', + patterns: [ + { + include: '#type', + }, + ], + }, + ], + }, + 'parameter-type-annotation': { + patterns: [ + { + name: 'meta.type.annotation.js', + begin: '(:)', + beginCaptures: { + '1': { + name: 'keyword.operator.type.annotation.js', + }, + }, + end: '(?=[,)])|(?==[^>])', + patterns: [ + { + include: '#type', + }, + ], + }, + ], + }, + 'return-type': { + patterns: [ + { + name: 'meta.return.type.js', + begin: '(?<=\\))\\s*(:)(?=\\s*\\S)', + beginCaptures: { + '1': { + name: 'keyword.operator.type.annotation.js', + }, + }, + end: '(?|\\{|(^\\s*(export|function|class|interface|let|var|(?:\\busing(?=\\s+(?!in\\b|of\\b(?!\\s*(?:of\\b|=)))[_$[:alpha:]])\\b)|(?:\\bawait\\s+(?:\\busing(?=\\s+(?!in\\b|of\\b(?!\\s*(?:of\\b|=)))[_$[:alpha:]])\\b)\\b)|const|import|enum|namespace|module|type|abstract|declare)\\s+))', + patterns: [ + { + include: '#arrow-return-type-body', + }, + ], + }, + 'possibly-arrow-return-type': { + begin: + '(?<=\\)|^)\\s*(:)(?=\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*=>)', + beginCaptures: { + '1': { + name: 'meta.arrow.js meta.return.type.arrow.js keyword.operator.type.annotation.js', + }, + }, + end: '(?==>|\\{|(^\\s*(export|function|class|interface|let|var|(?:\\busing(?=\\s+(?!in\\b|of\\b(?!\\s*(?:of\\b|=)))[_$[:alpha:]])\\b)|(?:\\bawait\\s+(?:\\busing(?=\\s+(?!in\\b|of\\b(?!\\s*(?:of\\b|=)))[_$[:alpha:]])\\b)\\b)|const|import|enum|namespace|module|type|abstract|declare)\\s+))', + contentName: 'meta.arrow.js meta.return.type.arrow.js', + patterns: [ + { + include: '#arrow-return-type-body', + }, + ], + }, + 'arrow-return-type-body': { + patterns: [ + { + begin: '(?<=[:])(?=\\s*\\{)', + end: '(?<=\\})', + patterns: [ + { + include: '#type-object', + }, + ], + }, + { + include: '#type-predicate-operator', + }, + { + include: '#type', + }, + ], + }, + 'type-parameters': { + name: 'meta.type.parameters.js', + begin: '(<)', + beginCaptures: { + '1': { + name: 'punctuation.definition.typeparameters.begin.js', + }, + }, + end: '(>)', + endCaptures: { + '1': { + name: 'punctuation.definition.typeparameters.end.js', + }, + }, + patterns: [ + { + include: '#comment', + }, + { + name: 'storage.modifier.js', + match: + '(?)', + }, + ], + }, + 'type-arguments': { + name: 'meta.type.parameters.js', + begin: '\\<', + beginCaptures: { + '0': { + name: 'punctuation.definition.typeparameters.begin.js', + }, + }, + end: '\\>', + endCaptures: { + '0': { + name: 'punctuation.definition.typeparameters.end.js', + }, + }, + patterns: [ + { + include: '#type-arguments-body', + }, + ], + }, + 'type-arguments-body': { + patterns: [ + { + match: + '(?)\n ))\n ))\n)) |\n(:\\s*(?\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*)))|((\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])\\s*((:\\s*\\[?$)|((\\s*([^<>\\(\\)\\{\\}]|\\<([^<>]|\\<([^<>]|\\<[^<>]+\\>)+\\>)+\\>|\\([^\\(\\)]+\\)|\\{[^\\{\\}]+\\})+\\s*)?=\\s*))))))))', + captures: { + '1': { + name: 'storage.modifier.js', + }, + '2': { + name: 'keyword.operator.rest.js', + }, + '3': { + name: 'entity.name.function.js variable.language.this.js', + }, + '4': { + name: 'entity.name.function.js', + }, + '5': { + name: 'keyword.operator.optional.js', + }, + }, + }, + { + match: + '(?x)(?:(?)', + patterns: [ + { + include: '#comment', + }, + { + include: '#type-parameters', + }, + ], + }, + { + name: 'meta.type.constructor.js', + begin: + '(?)\n ))\n )\n )\n)', + end: '(?<=\\))', + patterns: [ + { + include: '#function-parameters', + }, + ], + }, + ], + }, + 'type-function-return-type': { + patterns: [ + { + name: 'meta.type.function.return.js', + begin: '(=>)(?=\\s*\\S)', + beginCaptures: { + '1': { + name: 'storage.type.function.arrow.js', + }, + }, + end: '(?)(?:\\?]|//|$)', + patterns: [ + { + include: '#type-function-return-type-core', + }, + ], + }, + { + name: 'meta.type.function.return.js', + begin: '=>', + beginCaptures: { + '0': { + name: 'storage.type.function.arrow.js', + }, + }, + end: '(?)(?]|//|^\\s*$)|((?<=\\S)(?=\\s*$)))', + patterns: [ + { + include: '#type-function-return-type-core', + }, + ], + }, + ], + }, + 'type-function-return-type-core': { + patterns: [ + { + include: '#comment', + }, + { + begin: '(?<==>)(?=\\s*\\{)', + end: '(?<=\\})', + patterns: [ + { + include: '#type-object', + }, + ], + }, + { + include: '#type-predicate-operator', + }, + { + include: '#type', + }, + ], + }, + 'type-operators': { + patterns: [ + { + include: '#typeof-operator', + }, + { + include: '#type-infer', + }, + { + begin: '([&|])(?=\\s*\\{)', + beginCaptures: { + '0': { + name: 'keyword.operator.type.js', + }, + }, + end: '(?<=\\})', + patterns: [ + { + include: '#type-object', + }, + ], + }, + { + begin: '[&|]', + beginCaptures: { + '0': { + name: 'keyword.operator.type.js', + }, + }, + end: '(?=\\S)', + }, + { + name: 'keyword.operator.expression.keyof.js', + match: + '(?)', + endCaptures: { + '1': { + name: 'meta.type.parameters.js punctuation.definition.typeparameters.end.js', + }, + }, + contentName: 'meta.type.parameters.js', + patterns: [ + { + include: '#type-arguments-body', + }, + ], + }, + { + begin: '([_$[:alpha:]][_$[:alnum:]]*)\\s*(<)', + beginCaptures: { + '1': { + name: 'entity.name.type.js', + }, + '2': { + name: 'meta.type.parameters.js punctuation.definition.typeparameters.begin.js', + }, + }, + end: '(>)', + endCaptures: { + '1': { + name: 'meta.type.parameters.js punctuation.definition.typeparameters.end.js', + }, + }, + contentName: 'meta.type.parameters.js', + patterns: [ + { + include: '#type-arguments-body', + }, + ], + }, + { + match: '([_$[:alpha:]][_$[:alnum:]]*)\\s*(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))', + captures: { + '1': { + name: 'entity.name.type.module.js', + }, + '2': { + name: 'punctuation.accessor.js', + }, + '3': { + name: 'punctuation.accessor.optional.js', + }, + }, + }, + { + name: 'entity.name.type.js', + match: '[_$[:alpha:]][_$[:alnum:]]*', + }, + ], + }, + 'punctuation-comma': { + name: 'punctuation.separator.comma.js', + match: ',', + }, + 'punctuation-semicolon': { + name: 'punctuation.terminator.statement.js', + match: ';', + }, + 'punctuation-accessor': { + match: '(?:(\\.)|(\\?\\.(?!\\s*[[:digit:]])))', + captures: { + '1': { + name: 'punctuation.accessor.js', + }, + '2': { + name: 'punctuation.accessor.optional.js', + }, + }, + }, + string: { + patterns: [ + { + include: '#qstring-single', + }, + { + include: '#qstring-double', + }, + { + include: '#template', + }, + ], + }, + 'qstring-double': { + name: 'string.quoted.double.js', + begin: '"', + beginCaptures: { + '0': { + name: 'punctuation.definition.string.begin.js', + }, + }, + end: '(")|((?:[^\\\\\\n])$)', + endCaptures: { + '1': { + name: 'punctuation.definition.string.end.js', + }, + '2': { + name: 'invalid.illegal.newline.js', + }, + }, + patterns: [ + { + include: '#string-character-escape', + }, + ], + }, + 'qstring-single': { + name: 'string.quoted.single.js', + begin: "'", + beginCaptures: { + '0': { + name: 'punctuation.definition.string.begin.js', + }, + }, + end: "(\\')|((?:[^\\\\\\n])$)", + endCaptures: { + '1': { + name: 'punctuation.definition.string.end.js', + }, + '2': { + name: 'invalid.illegal.newline.js', + }, + }, + patterns: [ + { + include: '#string-character-escape', + }, + ], + }, + 'string-character-escape': { + name: 'constant.character.escape.js', + match: + '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|u\\{[0-9A-Fa-f]+\\}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)', + }, + template: { + patterns: [ + { + include: '#template-call', + }, + { + contentName: 'string.template.js', + begin: '([_$[:alpha:]][_$[:alnum:]]*)?(`)', + beginCaptures: { + '1': { + name: 'entity.name.function.tagged-template.js', + }, + '2': { + name: 'string.template.js punctuation.definition.string.template.begin.js', + }, + }, + end: '`', + endCaptures: { + '0': { + name: 'string.template.js punctuation.definition.string.template.end.js', + }, + }, + patterns: [ + { + include: '#template-substitution-element', + }, + { + include: '#string-character-escape', + }, + ], + }, + ], + }, + 'template-call': { + patterns: [ + { + begin: + '(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)', + end: '(?=`)', + patterns: [ + { + begin: + '(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))', + end: '(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)', + patterns: [ + { + include: '#support-function-call-identifiers', + }, + { + name: 'entity.name.function.tagged-template.js', + match: '([_$[:alpha:]][_$[:alnum:]]*)', + }, + ], + }, + { + include: '#type-arguments', + }, + ], + }, + { + begin: + '([_$[:alpha:]][_$[:alnum:]]*)?\\s*(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)`)', + beginCaptures: { + '1': { + name: 'entity.name.function.tagged-template.js', + }, + }, + end: '(?=`)', + patterns: [ + { + include: '#type-arguments', + }, + ], + }, + ], + }, + 'template-substitution-element': { + name: 'meta.template.expression.js', + begin: '\\$\\{', + beginCaptures: { + '0': { + name: 'punctuation.definition.template-expression.begin.js', + }, + }, + end: '\\}', + endCaptures: { + '0': { + name: 'punctuation.definition.template-expression.end.js', + }, + }, + patterns: [ + { + include: '#expression', + }, + ], + contentName: 'meta.embedded.line.js', + }, + 'type-string': { + patterns: [ + { + include: '#qstring-single', + }, + { + include: '#qstring-double', + }, + { + include: '#template-type', + }, + ], + }, + 'template-type': { + patterns: [ + { + include: '#template-call', + }, + { + contentName: 'string.template.js', + begin: '([_$[:alpha:]][_$[:alnum:]]*)?(`)', + beginCaptures: { + '1': { + name: 'entity.name.function.tagged-template.js', + }, + '2': { + name: 'string.template.js punctuation.definition.string.template.begin.js', + }, + }, + end: '`', + endCaptures: { + '0': { + name: 'string.template.js punctuation.definition.string.template.end.js', + }, + }, + patterns: [ + { + include: '#template-type-substitution-element', + }, + { + include: '#string-character-escape', + }, + ], + }, + ], + }, + 'template-type-substitution-element': { + name: 'meta.template.expression.js', + begin: '\\$\\{', + beginCaptures: { + '0': { + name: 'punctuation.definition.template-expression.begin.js', + }, + }, + end: '\\}', + endCaptures: { + '0': { + name: 'punctuation.definition.template-expression.end.js', + }, + }, + patterns: [ + { + include: '#type', + }, + ], + contentName: 'meta.embedded.line.js', + }, + regex: { + patterns: [ + { + name: 'string.regexp.js', + begin: + '(?|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[\\()]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\]|\\(([^\\)\\\\]|\\\\.)+\\))+\\/([dgimsuvy]+|(?![\\/\\*])|(?=\\/\\*))(?!\\s*[a-zA-Z0-9_$]))', + beginCaptures: { + '1': { + name: 'punctuation.definition.string.begin.js', + }, + }, + end: '(/)([dgimsuvy]*)', + endCaptures: { + '1': { + name: 'punctuation.definition.string.end.js', + }, + '2': { + name: 'keyword.other.js', + }, + }, + patterns: [ + { + include: '#regexp', + }, + ], + }, + { + name: 'string.regexp.js', + begin: + '((?', + captures: { + '0': { + name: 'keyword.other.back-reference.regexp', + }, + '1': { + name: 'variable.other.regexp', + }, + }, + }, + { + name: 'keyword.operator.quantifier.regexp', + match: '[?+*]|\\{(\\d+,\\d+|\\d+,|,\\d+|\\d+)\\}\\??', + }, + { + name: 'keyword.operator.or.regexp', + match: '\\|', + }, + { + name: 'meta.group.assertion.regexp', + begin: '(\\()((\\?=)|(\\?!)|(\\?<=)|(\\?))?', + beginCaptures: { + '0': { + name: 'punctuation.definition.group.regexp', + }, + '1': { + name: 'punctuation.definition.group.no-capture.regexp', + }, + '2': { + name: 'variable.other.regexp', + }, + }, + end: '\\)', + endCaptures: { + '0': { + name: 'punctuation.definition.group.regexp', + }, + }, + patterns: [ + { + include: '#regexp', + }, + ], + }, + { + name: 'constant.other.character-class.set.regexp', + begin: '(\\[)(\\^)?', + beginCaptures: { + '1': { + name: 'punctuation.definition.character-class.regexp', + }, + '2': { + name: 'keyword.operator.negation.regexp', + }, + }, + end: '(\\])', + endCaptures: { + '1': { + name: 'punctuation.definition.character-class.regexp', + }, + }, + patterns: [ + { + name: 'constant.other.character-class.range.regexp', + match: + '(?:.|(\\\\(?:[0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}))|(\\\\c[A-Z])|(\\\\.))\\-(?:[^\\]\\\\]|(\\\\(?:[0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}))|(\\\\c[A-Z])|(\\\\.))', + captures: { + '1': { + name: 'constant.character.numeric.regexp', + }, + '2': { + name: 'constant.character.control.regexp', + }, + '3': { + name: 'constant.character.escape.backslash.regexp', + }, + '4': { + name: 'constant.character.numeric.regexp', + }, + '5': { + name: 'constant.character.control.regexp', + }, + '6': { + name: 'constant.character.escape.backslash.regexp', + }, + }, + }, + { + include: '#regex-character-class', + }, + ], + }, + { + include: '#regex-character-class', + }, + ], + }, + 'regex-character-class': { + patterns: [ + { + name: 'constant.other.character-class.regexp', + match: '\\\\[wWsSdDtrnvf]|\\.', + }, + { + name: 'constant.character.numeric.regexp', + match: '\\\\([0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4})', + }, + { + name: 'constant.character.control.regexp', + match: '\\\\c[A-Z]', + }, + { + name: 'constant.character.escape.backslash.regexp', + match: '\\\\.', + }, + ], + }, + comment: { + patterns: [ + { + name: 'comment.block.documentation.js', + begin: '/\\*\\*(?!/)', + beginCaptures: { + '0': { + name: 'punctuation.definition.comment.js', + }, + }, + end: '\\*/', + endCaptures: { + '0': { + name: 'punctuation.definition.comment.js', + }, + }, + patterns: [ + { + include: '#docblock', + }, + ], + }, + { + name: 'comment.block.js', + begin: '(/\\*)(?:\\s*((@)internal)(?=\\s|(\\*/)))?', + beginCaptures: { + '1': { + name: 'punctuation.definition.comment.js', + }, + '2': { + name: 'storage.type.internaldeclaration.js', + }, + '3': { + name: 'punctuation.decorator.internaldeclaration.js', + }, + }, + end: '\\*/', + endCaptures: { + '0': { + name: 'punctuation.definition.comment.js', + }, + }, + }, + { + begin: '(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)', + beginCaptures: { + '1': { + name: 'punctuation.whitespace.comment.leading.js', + }, + '2': { + name: 'comment.line.double-slash.js', + }, + '3': { + name: 'punctuation.definition.comment.js', + }, + '4': { + name: 'storage.type.internaldeclaration.js', + }, + '5': { + name: 'punctuation.decorator.internaldeclaration.js', + }, + }, + end: '(?=$)', + contentName: 'comment.line.double-slash.js', + }, + ], + }, + 'single-line-comment-consuming-line-ending': { + begin: '(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)', + beginCaptures: { + '1': { + name: 'punctuation.whitespace.comment.leading.js', + }, + '2': { + name: 'comment.line.double-slash.js', + }, + '3': { + name: 'punctuation.definition.comment.js', + }, + '4': { + name: 'storage.type.internaldeclaration.js', + }, + '5': { + name: 'punctuation.decorator.internaldeclaration.js', + }, + }, + end: '(?=^)', + contentName: 'comment.line.double-slash.js', + }, + directives: { + name: 'comment.line.triple-slash.directive.js', + begin: + '^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name|resolution-mode)\\s*=\\s*((\\\'([^\\\'\\\\]|\\\\.)*\\\')|(\\"([^\\"\\\\]|\\\\.)*\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)', + beginCaptures: { + '1': { + name: 'punctuation.definition.comment.js', + }, + }, + end: '(?=$)', + patterns: [ + { + name: 'meta.tag.js', + begin: '(<)(reference|amd-dependency|amd-module)', + beginCaptures: { + '1': { + name: 'punctuation.definition.tag.directive.js', + }, + '2': { + name: 'entity.name.tag.directive.js', + }, + }, + end: '/>', + endCaptures: { + '0': { + name: 'punctuation.definition.tag.directive.js', + }, + }, + patterns: [ + { + name: 'entity.other.attribute-name.directive.js', + match: 'path|types|no-default-lib|lib|name|resolution-mode', + }, + { + name: 'keyword.operator.assignment.js', + match: '=', + }, + { + include: '#string', + }, + ], + }, + ], + }, + docblock: { + patterns: [ + { + match: '(?x)\n((@)(?:access|api))\n\\s+\n(private|protected|public)\n\\b', + captures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + '3': { + name: 'constant.language.access-type.jsdoc', + }, + }, + }, + { + match: + '(?x)\n((@)author)\n\\s+\n(\n [^@\\s<>*/]\n (?:[^@<>*/]|\\*[^/])*\n)\n(?:\n \\s*\n (<)\n ([^>\\s]+)\n (>)\n)?', + captures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + '3': { + name: 'entity.name.type.instance.jsdoc', + }, + '4': { + name: 'punctuation.definition.bracket.angle.begin.jsdoc', + }, + '5': { + name: 'constant.other.email.link.underline.jsdoc', + }, + '6': { + name: 'punctuation.definition.bracket.angle.end.jsdoc', + }, + }, + }, + { + match: + '(?x)\n((@)borrows) \\s+\n((?:[^@\\s*/]|\\*[^/])+) # \n\\s+ (as) \\s+ # as\n((?:[^@\\s*/]|\\*[^/])+) # ', + captures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + '3': { + name: 'entity.name.type.instance.jsdoc', + }, + '4': { + name: 'keyword.operator.control.jsdoc', + }, + '5': { + name: 'entity.name.type.instance.jsdoc', + }, + }, + }, + { + name: 'meta.example.jsdoc', + begin: '((@)example)\\s+', + end: '(?=@|\\*/)', + beginCaptures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + }, + patterns: [ + { + match: '^\\s\\*\\s+', + }, + { + contentName: 'constant.other.description.jsdoc', + begin: '\\G(<)caption(>)', + beginCaptures: { + '0': { + name: 'entity.name.tag.inline.jsdoc', + }, + '1': { + name: 'punctuation.definition.bracket.angle.begin.jsdoc', + }, + '2': { + name: 'punctuation.definition.bracket.angle.end.jsdoc', + }, + }, + end: '()|(?=\\*/)', + endCaptures: { + '0': { + name: 'entity.name.tag.inline.jsdoc', + }, + '1': { + name: 'punctuation.definition.bracket.angle.begin.jsdoc', + }, + '2': { + name: 'punctuation.definition.bracket.angle.end.jsdoc', + }, + }, + }, + { + match: '[^\\s@*](?:[^*]|\\*[^/])*', + captures: { + '0': { + name: 'source.embedded.js', + }, + }, + }, + ], + }, + { + match: + '(?x) ((@)kind) \\s+ (class|constant|event|external|file|function|member|mixin|module|namespace|typedef) \\b', + captures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + '3': { + name: 'constant.language.symbol-type.jsdoc', + }, + }, + }, + { + match: + '(?x)\n((@)see)\n\\s+\n(?:\n # URL\n (\n (?=https?://)\n (?:[^\\s*]|\\*[^/])+\n )\n |\n # JSDoc namepath\n (\n (?!\n # Avoid matching bare URIs (also acceptable as links)\n https?://\n |\n # Avoid matching {@inline tags}; we match those below\n (?:\\[[^\\[\\]]*\\])? # Possible description [preceding]{@tag}\n {@(?:link|linkcode|linkplain|tutorial)\\b\n )\n # Matched namepath\n (?:[^@\\s*/]|\\*[^/])+\n )\n)', + captures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + '3': { + name: 'variable.other.link.underline.jsdoc', + }, + '4': { + name: 'entity.name.type.instance.jsdoc', + }, + }, + }, + { + match: + '(?x)\n((@)template)\n\\s+\n# One or more valid identifiers\n(\n [A-Za-z_$] # First character: non-numeric word character\n [\\w$.\\[\\]]* # Rest of identifier\n (?: # Possible list of additional identifiers\n \\s* , \\s*\n [A-Za-z_$]\n [\\w$.\\[\\]]*\n )*\n)', + captures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + '3': { + name: 'variable.other.jsdoc', + }, + }, + }, + { + begin: '(?x)((@)template)\\s+(?={)', + beginCaptures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + }, + end: '(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])', + patterns: [ + { + include: '#jsdoctype', + }, + { + name: 'variable.other.jsdoc', + match: '([A-Za-z_$][\\w$.\\[\\]]*)', + }, + ], + }, + { + match: + '(?x)\n(\n (@)\n (?:arg|argument|const|constant|member|namespace|param|var)\n)\n\\s+\n(\n [A-Za-z_$]\n [\\w$.\\[\\]]*\n)', + captures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + '3': { + name: 'variable.other.jsdoc', + }, + }, + }, + { + begin: '((@)typedef)\\s+(?={)', + beginCaptures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + }, + end: '(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])', + patterns: [ + { + include: '#jsdoctype', + }, + { + name: 'entity.name.type.instance.jsdoc', + match: '(?:[^@\\s*/]|\\*[^/])+', + }, + ], + }, + { + begin: + '((@)(?:arg|argument|const|constant|member|namespace|param|prop|property|var))\\s+(?={)', + beginCaptures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + }, + end: '(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])', + patterns: [ + { + include: '#jsdoctype', + }, + { + name: 'variable.other.jsdoc', + match: '([A-Za-z_$][\\w$.\\[\\]]*)', + }, + { + name: 'variable.other.jsdoc', + match: + '(?x)\n(\\[)\\s*\n[\\w$]+\n(?:\n (?:\\[\\])? # Foo[ ].bar properties within an array\n \\. # Foo.Bar namespaced parameter\n [\\w$]+\n)*\n(?:\n \\s*\n (=) # [foo=bar] Default parameter value\n \\s*\n (\n # The inner regexes are to stop the match early at */ and to not stop at escaped quotes\n (?>\n "(?:(?:\\*(?!/))|(?:\\\\(?!"))|[^*\\\\])*?" | # [foo="bar"] Double-quoted\n \'(?:(?:\\*(?!/))|(?:\\\\(?!\'))|[^*\\\\])*?\' | # [foo=\'bar\'] Single-quoted\n \\[ (?:(?:\\*(?!/))|[^*])*? \\] | # [foo=[1,2]] Array literal\n (?:(?:\\*(?!/))|\\s(?!\\s*\\])|\\[.*?(?:\\]|(?=\\*/))|[^*\\s\\[\\]])* # Everything else\n )*\n )\n)?\n\\s*(?:(\\])((?:[^*\\s]|\\*[^\\s/])+)?|(?=\\*/))', + captures: { + '1': { + name: 'punctuation.definition.optional-value.begin.bracket.square.jsdoc', + }, + '2': { + name: 'keyword.operator.assignment.jsdoc', + }, + '3': { + name: 'source.embedded.js', + }, + '4': { + name: 'punctuation.definition.optional-value.end.bracket.square.jsdoc', + }, + '5': { + name: 'invalid.illegal.syntax.jsdoc', + }, + }, + }, + ], + }, + { + begin: + '(?x)\n(\n (@)\n (?:define|enum|exception|export|extends|lends|implements|modifies\n |namespace|private|protected|returns?|satisfies|suppress|this|throws|type\n |yields?)\n)\n\\s+(?={)', + beginCaptures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + }, + end: '(?=\\s|\\*/|[^{}\\[\\]A-Za-z_$])', + patterns: [ + { + include: '#jsdoctype', + }, + ], + }, + { + match: + '(?x)\n(\n (@)\n (?:alias|augments|callback|constructs|emits|event|fires|exports?\n |extends|external|function|func|host|lends|listens|interface|memberof!?\n |method|module|mixes|mixin|name|requires|see|this|typedef|uses)\n)\n\\s+\n(\n (?:\n [^{}@\\s*] | \\*[^/]\n )+\n)', + captures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + '3': { + name: 'entity.name.type.instance.jsdoc', + }, + }, + }, + { + contentName: 'variable.other.jsdoc', + begin: "((@)(?:default(?:value)?|license|version))\\s+(([''\"]))", + beginCaptures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + '3': { + name: 'variable.other.jsdoc', + }, + '4': { + name: 'punctuation.definition.string.begin.jsdoc', + }, + }, + end: '(\\3)|(?=$|\\*/)', + endCaptures: { + '0': { + name: 'variable.other.jsdoc', + }, + '1': { + name: 'punctuation.definition.string.end.jsdoc', + }, + }, + }, + { + match: '((@)(?:default(?:value)?|license|tutorial|variation|version))\\s+([^\\s*]+)', + captures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + '3': { + name: 'variable.other.jsdoc', + }, + }, + }, + { + name: 'storage.type.class.jsdoc', + match: + '(?x) (@) (?:abstract|access|alias|api|arg|argument|async|attribute|augments|author|beta|borrows|bubbles |callback|chainable|class|classdesc|code|config|const|constant|constructor|constructs|copyright |default|defaultvalue|define|deprecated|desc|description|dict|emits|enum|event|example|exception |exports?|extends|extension(?:_?for)?|external|externs|file|fileoverview|final|fires|for|func |function|generator|global|hideconstructor|host|ignore|implements|implicitCast|inherit[Dd]oc |inner|instance|interface|internal|kind|lends|license|listens|main|member|memberof!?|method |mixes|mixins?|modifies|module|name|namespace|noalias|nocollapse|nocompile|nosideeffects |override|overview|package|param|polymer(?:Behavior)?|preserve|private|prop|property|protected |public|read[Oo]nly|record|require[ds]|returns?|see|since|static|struct|submodule|summary |suppress|template|this|throws|todo|tutorial|type|typedef|unrestricted|uses|var|variation |version|virtual|writeOnce|yields?) \\b', + captures: { + '1': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + }, + }, + { + include: '#inline-tags', + }, + { + match: '((@)(?:[_$[:alpha:]][_$[:alnum:]]*))(?=\\s+)', + captures: { + '1': { + name: 'storage.type.class.jsdoc', + }, + '2': { + name: 'punctuation.definition.block.tag.jsdoc', + }, + }, + }, + ], + }, + brackets: { + patterns: [ + { + begin: '{', + end: '}|(?=\\*/)', + patterns: [ + { + include: '#brackets', + }, + ], + }, + { + begin: '\\[', + end: '\\]|(?=\\*/)', + patterns: [ + { + include: '#brackets', + }, + ], + }, + ], + }, + 'inline-tags': { + patterns: [ + { + name: 'constant.other.description.jsdoc', + match: '(\\[)[^\\]]+(\\])(?={@(?:link|linkcode|linkplain|tutorial))', + captures: { + '1': { + name: 'punctuation.definition.bracket.square.begin.jsdoc', + }, + '2': { + name: 'punctuation.definition.bracket.square.end.jsdoc', + }, + }, + }, + { + name: 'entity.name.type.instance.jsdoc', + begin: '({)((@)(?:link(?:code|plain)?|tutorial))\\s*', + beginCaptures: { + '1': { + name: 'punctuation.definition.bracket.curly.begin.jsdoc', + }, + '2': { + name: 'storage.type.class.jsdoc', + }, + '3': { + name: 'punctuation.definition.inline.tag.jsdoc', + }, + }, + end: '}|(?=\\*/)', + endCaptures: { + '0': { + name: 'punctuation.definition.bracket.curly.end.jsdoc', + }, + }, + patterns: [ + { + match: '\\G((?=https?://)(?:[^|}\\s*]|\\*[/])+)(\\|)?', + captures: { + '1': { + name: 'variable.other.link.underline.jsdoc', + }, + '2': { + name: 'punctuation.separator.pipe.jsdoc', + }, + }, + }, + { + match: '\\G((?:[^{}@\\s|*]|\\*[^/])+)(\\|)?', + captures: { + '1': { + name: 'variable.other.description.jsdoc', + }, + '2': { + name: 'punctuation.separator.pipe.jsdoc', + }, + }, + }, + ], + }, + ], + }, + jsdoctype: { + patterns: [ + { + contentName: 'entity.name.type.instance.jsdoc', + begin: '\\G({)', + beginCaptures: { + '0': { + name: 'entity.name.type.instance.jsdoc', + }, + '1': { + name: 'punctuation.definition.bracket.curly.begin.jsdoc', + }, + }, + end: '((}))\\s*|(?=\\*/)', + endCaptures: { + '1': { + name: 'entity.name.type.instance.jsdoc', + }, + '2': { + name: 'punctuation.definition.bracket.curly.end.jsdoc', + }, + }, + patterns: [ + { + include: '#brackets', + }, + ], + }, + ], + }, + jsx: { + patterns: [ + { + include: '#jsx-tag-style', + }, + { + include: '#jsx-tag-without-attributes', + }, + { + include: '#jsx-tag', + }, + ], + }, + 'jsx-tag-without-attributes-in-expression': { + begin: + '(?:*]|&&|\\|\\||\\?|\\*\\/|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*(?=(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?))', + end: '(?!(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?))', + patterns: [ + { + include: '#jsx-tag-without-attributes', + }, + ], + }, + 'jsx-tag-without-attributes': { + name: 'meta.tag.without-attributes.js', + begin: + '(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?)', + end: '()', + beginCaptures: { + '1': { + name: 'punctuation.definition.tag.begin.js', + }, + '2': { + name: 'entity.name.tag.namespace.js', + }, + '3': { + name: 'punctuation.separator.namespace.js', + }, + '4': { + name: 'entity.name.tag.js', + }, + '5': { + name: 'support.class.component.js', + }, + '6': { + name: 'punctuation.definition.tag.end.js', + }, + }, + endCaptures: { + '1': { + name: 'punctuation.definition.tag.begin.js', + }, + '2': { + name: 'entity.name.tag.namespace.js', + }, + '3': { + name: 'punctuation.separator.namespace.js', + }, + '4': { + name: 'entity.name.tag.js', + }, + '5': { + name: 'support.class.component.js', + }, + '6': { + name: 'punctuation.definition.tag.end.js', + }, + }, + contentName: 'meta.jsx.children.js', + patterns: [ + { + include: '#jsx-children', + }, + ], + }, + 'jsx-tag-in-expression': { + begin: + '(?x)\n (?:*]|&&|\\|\\||\\?|\\*\\/|^await|[^\\._$[:alnum:]]await|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^yield|[^\\._$[:alnum:]]yield|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?))', + end: '(?!(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?))', + patterns: [ + { + include: '#jsx-tag', + }, + ], + }, + 'jsx-tag-style': { + name: 'style.tag.js', + begin: '(<)\\s*(style)\\b(?![^>]*/>)(?=[^>]*>)', + beginCaptures: { + '1': { + name: 'punctuation.definition.tag.begin.js', + }, + '2': { + name: 'entity.name.tag.js', + }, + }, + end: '()', + endCaptures: { + '1': { + name: 'punctuation.definition.tag.begin.js', + }, + '2': { + name: 'entity.name.tag.js', + }, + '3': { + name: 'punctuation.definition.tag.end.js', + }, + }, + patterns: [ + { + begin: '(>)', + beginCaptures: { + '1': { + name: 'punctuation.definition.tag.end.js', + }, + }, + end: '(?=)', + contentName: 'source.css', + patterns: [ + { + include: 'source.css', + }, + ], + }, + { + begin: '(?<=]*/>)', + end: '(?=>)', + patterns: [ + { + include: '#jsx-tag-attributes', + }, + ], + }, + ], + }, + 'jsx-tag': { + name: 'meta.tag.js', + begin: + '(?=(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?))', + end: '(/>)|(?:())', + endCaptures: { + '1': { + name: 'punctuation.definition.tag.end.js', + }, + '2': { + name: 'punctuation.definition.tag.begin.js', + }, + '3': { + name: 'entity.name.tag.namespace.js', + }, + '4': { + name: 'punctuation.separator.namespace.js', + }, + '5': { + name: 'entity.name.tag.js', + }, + '6': { + name: 'support.class.component.js', + }, + '7': { + name: 'punctuation.definition.tag.end.js', + }, + }, + patterns: [ + { + begin: + '(<)\\s*(?:([_$[:alpha:]][-_$[:alnum:].]*)(?)', + beginCaptures: { + '1': { + name: 'punctuation.definition.tag.begin.js', + }, + '2': { + name: 'entity.name.tag.namespace.js', + }, + '3': { + name: 'punctuation.separator.namespace.js', + }, + '4': { + name: 'entity.name.tag.js', + }, + '5': { + name: 'support.class.component.js', + }, + }, + end: '(?=[/]?>)', + patterns: [ + { + include: '#comment', + }, + { + include: '#type-arguments', + }, + { + include: '#jsx-tag-attributes', + }, + ], + }, + { + begin: '(>)', + beginCaptures: { + '1': { + name: 'punctuation.definition.tag.end.js', + }, + }, + end: '(?=)', + patterns: [ + { + include: '#comment', + }, + { + include: '#jsx-tag-attribute-name', + }, + { + include: '#jsx-tag-attribute-assignment', + }, + { + include: '#jsx-string-double-quoted', + }, + { + include: '#jsx-string-single-quoted', + }, + { + include: '#jsx-evaluated-code', + }, + { + include: '#jsx-tag-attributes-illegal', + }, + ], + }, + 'jsx-tag-attribute-name': { + match: + '(?x)\n \\s*\n (?:([_$[:alpha:]][-_$[:alnum:].]*)(:))?\n ([_$[:alpha:]][-_$[:alnum:]]*)\n (?=\\s|=|/?>|/\\*|//)', + captures: { + '1': { + name: 'entity.other.attribute-name.namespace.js', + }, + '2': { + name: 'punctuation.separator.namespace.js', + }, + '3': { + name: 'entity.other.attribute-name.js', + }, + }, + }, + 'jsx-tag-attribute-assignment': { + name: 'keyword.operator.assignment.js', + match: '=(?=\\s*(?:\'|"|{|/\\*|//|\\n))', + }, + 'jsx-string-double-quoted': { + name: 'string.quoted.double.js', + begin: '"', + end: '"', + beginCaptures: { + '0': { + name: 'punctuation.definition.string.begin.js', + }, + }, + endCaptures: { + '0': { + name: 'punctuation.definition.string.end.js', + }, + }, + patterns: [ + { + include: '#jsx-entities', + }, + ], + }, + 'jsx-string-single-quoted': { + name: 'string.quoted.single.js', + begin: "'", + end: "'", + beginCaptures: { + '0': { + name: 'punctuation.definition.string.begin.js', + }, + }, + endCaptures: { + '0': { + name: 'punctuation.definition.string.end.js', + }, + }, + patterns: [ + { + include: '#jsx-entities', + }, + ], + }, + 'server-block': { + name: 'meta.server-block.js', + begin: '(#server)\\s*(\\{)', + beginCaptures: { + '1': { + name: 'storage.type.server.js', + }, + '2': { + name: 'punctuation.definition.block.js', + }, + }, + end: '\\}', + endCaptures: { + '0': { + name: 'punctuation.definition.block.js', + }, + }, + patterns: [ + { + include: '#statements', + }, + ], + }, + 'server-member-expression': { + name: 'meta.server-member-expression.js', + match: '(#server)(\\.)([_$[:alpha:]][_$[:alnum:]]*)', + captures: { + '1': { + name: 'storage.type.server.js', + }, + '2': { + name: 'punctuation.accessor.js', + }, + '3': { + name: 'entity.name.function.js', + }, + }, + }, + 'jsx-ref-modifier': { + name: 'storage.modifier.js', + match: '\\b(ref)(?=\\s+[_$[:alpha:]])', + captures: { + '1': { + name: 'storage.modifier.js', + }, + }, + }, + 'jsx-tag-attributes-illegal': { + name: 'invalid.illegal.attribute.js', + match: '\\S+', + }, + }, + }, + + config: { + // Note that this file should stay in sync with 'typescript-language-basics/language-configuration.json' + // onEnterRules cause errors - currently disabled + comments: { + lineComment: '//', + blockComment: ['/*', '*/'], + }, + brackets: [ + ['${', '}'], + ['{', '}'], + ['[', ']'], + ['(', ')'], + ], + autoClosingPairs: [ + { + open: '{', + close: '}', + }, + { + open: '[', + close: ']', + }, + { + open: '(', + close: ')', + }, + { + open: "'", + close: "'", + notIn: ['string', 'comment'], + }, + { + open: '"', + close: '"', + notIn: ['string'], + }, + { + open: '`', + close: '`', + notIn: ['string', 'comment'], + }, + { + open: '/**', + close: ' */', + notIn: ['string'], + }, + ], + surroundingPairs: [ + ['{', '}'], + ['[', ']'], + ['(', ')'], + ["'", "'"], + ['"', '"'], + ['`', '`'], + ['<', '>'], + ], + autoCloseBefore: ';:.,=}])>` \n\t', + folding: { + markers: { + start: '^\\s*//\\s*#?region\\b', + end: '^\\s*//\\s*#?endregion\\b', + }, + }, + wordPattern: { + pattern: + '(-?\\d*\\.\\d\\w*)|([^\\`\\~\\@\\!\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\\'\\"\\,\\.\\<\\>/\\?\\s]+)', + }, + indentationRules: { + decreaseIndentPattern: { + pattern: '^\\s*[\\}\\]\\)].*$', + }, + increaseIndentPattern: { + pattern: '^.*(\\{[^}]*|\\([^)]*|\\[[^\\]]*)$', + }, + // e.g. * ...| or */| or *-----*/| + unIndentedLinePattern: { + pattern: + '^(\\t|[ ])*[ ]\\*[^/]*\\*/\\s*$|^(\\t|[ ])*[ ]\\*/\\s*$|^(\\t|[ ])*[ ]\\*([ ]([^\\*]|\\*(?!/))*)?$', + }, + indentNextLinePattern: { + pattern: '^((.*=>\\s*)|((.*[^\\w]+|\\s*)(if|while|for)\\s*\\(.*\\)\\s*))$', + }, + }, + // onEnterRules: [ + // { + // // e.g. /** | */ + // beforeText: { + // pattern: '^\\s*/\\*\\*(?!/)([^\\*]|\\*(?!/))*$', + // }, + // afterText: { + // pattern: '^\\s*\\*/$', + // }, + // action: { + // indent: 'indentOutdent', + // appendText: ' * ', + // }, + // }, + // { + // // e.g. /** ...| + // beforeText: { + // pattern: '^\\s*/\\*\\*(?!/)([^\\*]|\\*(?!/))*$', + // }, + // action: { + // indent: 'none', + // appendText: ' * ', + // }, + // }, + // { + // // e.g. * ...| + // beforeText: { + // pattern: '^(\\t|[ ])*[ ]\\*([ ]([^\\*]|\\*(?!/))*)?$', + // }, + // previousLineText: { + // pattern: '(?=^(\\s*(/\\*\\*|\\*)).*)(?=(?!(\\s*\\*/)))', + // }, + // action: { + // indent: 'none', + // appendText: '* ', + // }, + // }, + // { + // // e.g. */| + // beforeText: { + // pattern: '^(\\t|[ ])*[ ]\\*/\\s*$', + // }, + // action: { + // indent: 'none', + // removeText: 1, + // }, + // }, + // { + // // e.g. *-----*/| + // beforeText: { + // pattern: '^(\\t|[ ])*[ ]\\*[^/]*\\*/\\s*$', + // }, + // action: { + // indent: 'none', + // removeText: 1, + // }, + // }, + // { + // beforeText: { + // pattern: '^\\s*(\\bcase\\s.+:|\\bdefault:)$', + // }, + // afterText: { + // pattern: '^(?!\\s*(\\bcase\\b|\\bdefault\\b))', + // }, + // action: { + // indent: 'indent', + // }, + // }, + // { + // // Decrease indentation after single line if/else if/else, for, or while + // previousLineText: '^\\s*(((else ?)?if|for|while)\\s*\\(.*\\)\\s*|else\\s*)$', + // // But make sure line doesn't have braces or is not another if statement + // beforeText: '^\\s+([^{i\\s]|i(?!f\\b))', + // action: { + // indent: 'outdent', + // }, + // }, + // // Indent when pressing enter from inside () + // { + // beforeText: '^.*\\([^\\)]*$', + // afterText: '^\\s*\\).*$', + // action: { + // indent: 'indentOutdent', + // appendText: '\t', + // }, + // }, + // // Indent when pressing enter from inside {} + // { + // beforeText: '^.*\\{[^\\}]*$', + // afterText: '^\\s*\\}.*$', + // action: { + // indent: 'indentOutdent', + // appendText: '\t', + // }, + // }, + // // Indent when pressing enter from inside [] + // { + // beforeText: '^.*\\[[^\\]]*$', + // afterText: '^\\s*\\].*$', + // action: { + // indent: 'indentOutdent', + // appendText: '\t', + // }, + // }, + // // Add // when pressing enter from inside line comment + // { + // beforeText: { + // pattern: '(?>>', + name: 'invalid.deprecated.combinator.css', + }, + { + match: '>>|>|\\+|~', + name: 'keyword.operator.combinator.css', + }, + ], + }, + commas: { + match: ',', + name: 'punctuation.separator.list.comma.css', + }, + 'comment-block': { + begin: '/\\*', + beginCaptures: { + '0': { + name: 'punctuation.definition.comment.begin.css', + }, + }, + end: '\\*/', + endCaptures: { + '0': { + name: 'punctuation.definition.comment.end.css', + }, + }, + name: 'comment.block.css', + }, + escapes: { + patterns: [ + { + match: '\\\\[0-9a-fA-F]{1,6}', + name: 'constant.character.escape.codepoint.css', + }, + { + begin: '\\\\$\\s*', + end: '^(?<:=]|\\)|/\\*) # Terminates cleanly', + }, + 'media-feature-keywords': { + match: + '(?xi)\n(?<=^|\\s|:|\\*/)\n(?: portrait # Orientation\n | landscape\n | progressive # Scan types\n | interlace\n | fullscreen # Display modes\n | standalone\n | minimal-ui\n | browser\n)\n(?=\\s|\\)|$)', + name: 'support.constant.property-value.css', + }, + 'media-query': { + begin: '\\G', + end: '(?=\\s*[{;])', + patterns: [ + { + include: '#comment-block', + }, + { + include: '#escapes', + }, + { + include: '#media-types', + }, + { + match: '(?i)(?<=\\s|^|,|\\*/)(only|not)(?=\\s|{|/\\*|$)', + name: 'keyword.operator.logical.$1.media.css', + }, + { + match: '(?i)(?<=\\s|^|\\*/|\\))and(?=\\s|/\\*|$)', + name: 'keyword.operator.logical.and.media.css', + }, + { + match: ',(?:(?:\\s*,)+|(?=\\s*[;){]))', + name: 'invalid.illegal.comma.css', + }, + { + include: '#commas', + }, + { + begin: '\\(', + beginCaptures: { + '0': { + name: 'punctuation.definition.parameters.begin.bracket.round.css', + }, + }, + end: '\\)', + endCaptures: { + '0': { + name: 'punctuation.definition.parameters.end.bracket.round.css', + }, + }, + patterns: [ + { + include: '#media-features', + }, + { + include: '#media-feature-keywords', + }, + { + match: ':', + name: 'punctuation.separator.key-value.css', + }, + { + match: '>=|<=|=|<|>', + name: 'keyword.operator.comparison.css', + }, + { + captures: { + '1': { + name: 'constant.numeric.css', + }, + '2': { + name: 'keyword.operator.arithmetic.css', + }, + '3': { + name: 'constant.numeric.css', + }, + }, + match: '(\\d+)\\s*(/)\\s*(\\d+)', + name: 'meta.ratio.css', + }, + { + include: '#numeric-values', + }, + { + include: '#comment-block', + }, + ], + }, + ], + }, + 'media-query-list': { + begin: '(?=\\s*[^{;])', + end: '(?=\\s*[{;])', + patterns: [ + { + include: '#media-query', + }, + ], + }, + 'media-types': { + captures: { + '1': { + name: 'support.constant.media.css', + }, + '2': { + name: 'invalid.deprecated.constant.media.css', + }, + }, + match: + '(?xi)\n(?<=^|\\s|,|\\*/)\n(?:\n # Valid media types\n (all|print|screen|speech)\n |\n # Deprecated in Media Queries 4: http://dev.w3.org/csswg/mediaqueries/#media-types\n (aural|braille|embossed|handheld|projection|tty|tv)\n)\n(?=$|[{,\\s;]|/\\*)', + }, + 'numeric-values': { + patterns: [ + { + captures: { + '1': { + name: 'punctuation.definition.constant.css', + }, + }, + match: '(#)(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\\b', + name: 'constant.other.color.rgb-value.hex.css', + }, + { + captures: { + '1': { + name: 'keyword.other.unit.percentage.css', + }, + '2': { + name: 'keyword.other.unit.${2:/downcase}.css', + }, + }, + match: + '(?xi) (?+~|] # - Followed by another selector\n | /\\* # - Followed by a block comment\n )\n |\n # Name contains unescaped ASCII symbol\n (?: # Check for acceptable preceding characters\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # - Valid selector character\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # - Escape sequence\n )*\n (?: # Invalid punctuation\n [!"\'%&(*;+~|] # - Another selector\n | /\\* # - A block comment\n)', + name: 'entity.other.attribute-name.class.css', + }, + { + captures: { + '1': { + name: 'punctuation.definition.entity.css', + }, + '2': { + patterns: [ + { + include: '#escapes', + }, + ], + }, + }, + match: + '(?x)\n(\\#)\n(\n -?\n (?![0-9])\n (?:[-a-zA-Z0-9_]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+\n)\n(?=$|[\\s,.\\#)\\[:{>+~|]|/\\*)', + name: 'entity.other.attribute-name.id.css', + }, + { + begin: '\\[', + beginCaptures: { + '0': { + name: 'punctuation.definition.entity.begin.bracket.square.css', + }, + }, + end: '\\]', + endCaptures: { + '0': { + name: 'punctuation.definition.entity.end.bracket.square.css', + }, + }, + name: 'meta.attribute-selector.css', + patterns: [ + { + include: '#comment-block', + }, + { + include: '#string', + }, + { + captures: { + '1': { + name: 'storage.modifier.ignore-case.css', + }, + }, + match: '(?<=["\'\\s]|^|\\*/)\\s*([iI])\\s*(?=[\\s\\]]|/\\*|$)', + }, + { + captures: { + '1': { + name: 'string.unquoted.attribute-value.css', + patterns: [ + { + include: '#escapes', + }, + ], + }, + }, + match: '(?x)(?<==)\\s*((?!/\\*)(?:[^\\\\"\'\\s\\]]|\\\\.)+)', + }, + { + include: '#escapes', + }, + { + match: '[~|^$*]?=', + name: 'keyword.operator.pattern.css', + }, + { + match: '\\|', + name: 'punctuation.separator.css', + }, + { + captures: { + '1': { + name: 'entity.other.namespace-prefix.css', + patterns: [ + { + include: '#escapes', + }, + ], + }, + }, + match: + "(?x)\n# Qualified namespace prefix\n( -?(?!\\d)(?:[\\w-]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+\n| \\*\n)\n# Lookahead to ensure there's a valid identifier ahead\n(?=\n \\| (?!\\s|=|$|\\])\n (?: -?(?!\\d)\n | [\\\\\\w-]\n | [^\\x00-\\x7F]\n )\n)", + }, + { + captures: { + '1': { + name: 'entity.other.attribute-name.css', + patterns: [ + { + include: '#escapes', + }, + ], + }, + }, + match: + '(?x)\n(-?(?!\\d)(?>[\\w-]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+)\n\\s*\n(?=[~|^\\]$*=]|/\\*)', + }, + ], + }, + { + include: '#pseudo-classes', + }, + { + include: '#pseudo-elements', + }, + { + include: '#functional-pseudo-classes', + }, + { + match: + '(?x) (?\\s,.\\#|){:\\[]|/\\*|$)', + name: 'entity.name.tag.css', + }, + 'unicode-range': { + captures: { + '0': { + name: 'constant.other.unicode-range.css', + }, + '1': { + name: 'punctuation.separator.dash.unicode-range.css', + }, + }, + match: '(? ? 'csharp' : language.startsWith('vue') ? 'vue' - : ['svelte', 'malina', 'riot'].includes(language) - ? ('razor' as Language) // avoid mixing code between markup & script editors when formatting - : mapLanguage(language); + : language === 'ripple' + ? 'ripple' + : ['svelte', 'malina', 'riot'].includes(language) + ? ('razor' as Language) // avoid mixing code between markup & script editors when formatting + : mapLanguage(language); try { (window as any).monaco = (window as any).monaco || (await loadMonaco()).monaco; @@ -254,6 +260,7 @@ export const createEditor = async (options: EditorOptions): Promise astro: baseUrl + '{{hash:monaco-lang-astro.js}}', clio: baseUrl + '{{hash:monaco-lang-clio.js}}', imba: baseUrl + '{{hash:monaco-lang-imba.js}}', + ripple: baseUrl + '{{hash:monaco-lang-ripple.js}}', // sql: baseUrl + '{{hash:monaco-lang-sql.js}}', // TODO: add autocomplete wat: baseUrl + '{{hash:monaco-lang-wat.js}}', }; @@ -275,6 +282,54 @@ export const createEditor = async (options: EditorOptions): Promise setTheme(currentTheme, currentEditorTheme); }; + async function registerFromTextMate( + langs: Array<{ + name: string; + scopeName: string; + syntax: string; + }>, + ) { + await addVueSupport(); // a workaround for TextMate syntax + + const { loadWASM } = await import(onigasmUrl); + const { Registry } = await import(monacoTextmateUrl); + const { wireTmGrammars } = await import(monacoEditorTextmateUrl); + + await loadWASM(onigasmWasmUrl); + + const registry = new Registry({ + getGrammarDefinition: async (scopeName: string) => ({ + format: 'json', + content: langs.find((l) => l.scopeName === scopeName)?.syntax ?? '', + }), + }); + + const grammars = new Map(); + for (const { name, scopeName } of langs) { + grammars.set(name, scopeName); + monaco.languages.register({ id: name }); + } + await wireTmGrammars(monaco, registry, grammars, editor); + } + + const addRippleSupport = async (syntaxes: { + ripple: Record; + css: Record; + }) => { + await registerFromTextMate([ + { + name: 'ripple', + scopeName: 'source.ripple', + syntax: JSON.stringify(syntaxes.ripple), + }, + { + name: 'CSS', + scopeName: 'source.css', + syntax: JSON.stringify(syntaxes.css), + }, + ]); + }; + const loadMonacoLanguage = async (lang: Language) => { if (monacoMapLanguage(lang) === 'vue') { await addVueSupport(); @@ -290,6 +345,10 @@ export const createEditor = async (options: EditorOptions): Promise if (mod.tokens) { monaco.languages.setMonarchTokensProvider(lang, mod.tokens); } + if (lang === 'ripple') { + await addRippleSupport({ ripple: (mod as any).syntax, css: (mod as any).cssSyntax }); + return; + } } }; diff --git a/src/livecodes/formatter/format.worker.ts b/src/livecodes/formatter/format.worker.ts index a6769c2bd9..99aaa06d56 100644 --- a/src/livecodes/formatter/format.worker.ts +++ b/src/livecodes/formatter/format.worker.ts @@ -1,6 +1,6 @@ import { defaultConfig } from '../config/default-config'; import { languages, parserPlugins, prettierUrl } from '../languages'; -import type { FormatFn, FormatterConfig, Language, Parser } from '../models'; +import type { Config, FormatFn, FormatterConfig, Language, Parser } from '../models'; import type { FormatterMessage, FormatterMessageEvent } from './models'; const worker: Worker = self as any; @@ -9,6 +9,7 @@ declare const prettierPlugins: { [key: string]: { parsers: any } }; declare const importScripts: (...args: string[]) => void; let baseUrl: string; +let initialConfig: Config; const parsers: { [key: string]: Parser } = {}; const plugins: { [key: string]: any } = {}; const formatters: { [key: string]: FormatFn } = {}; @@ -46,7 +47,7 @@ const load = (languages: Language[]) => { } }; -function loadParser(language: Language): Parser | undefined { +async function loadParser(language: Language): Promise { if (!(self as any).prettier) { loadPrettier(); } @@ -60,26 +61,33 @@ function loadParser(language: Language): Parser | undefined { if (!(self as any).prettierPlugins) { (self as any).prettierPlugins = {}; } - parser.plugins = parser.pluginUrls - .map((pluginUrl) => { - if (plugins[pluginUrl]) return true; - try { - importScripts(pluginUrl); - plugins[pluginUrl] = true; - if (!prettierPlugins.pug && (self as any).pluginPug) { - prettierPlugins.pug = (self as any).pluginPug; + parser.plugins = ( + await Promise.all( + parser.pluginUrls.map(async (pluginUrl) => { + if (plugins[pluginUrl]) return true; + if (language === 'ripple') { + const p = await import(pluginUrl); + prettierPlugins[language] = p; + return true; } - if (!prettierPlugins.java && (self as any).pluginJava?.default) { - prettierPlugins.java = (self as any).pluginJava.default; + try { + importScripts(pluginUrl); + plugins[pluginUrl] = true; + if (!prettierPlugins.pug && (self as any).pluginPug) { + prettierPlugins.pug = (self as any).pluginPug; + } + if (!prettierPlugins.java && (self as any).pluginJava?.default) { + prettierPlugins.java = (self as any).pluginJava.default; + } + return true; + } catch { + // eslint-disable-next-line no-console + console.warn('Failed to load formatter for: ' + language); + return false; } - return true; - } catch (err) { - // eslint-disable-next-line no-console - console.warn('Failed to load formatter for: ' + language); - return false; - } - }) - .filter(Boolean); + }), + ) + ).filter(Boolean); if (parser.plugins.length > 0) { parsers[language] = parser; @@ -87,7 +95,7 @@ function loadParser(language: Language): Parser | undefined { return parser; } -const loadFormatter = (language: Language): FormatFn | undefined => { +const loadFormatter = async (language: Language): Promise => { if (language in formatters) { return formatters[language]; } @@ -95,7 +103,7 @@ const loadFormatter = (language: Language): FormatFn | undefined => { const formatter = getFormatter(language); if (!formatter) return; - formatters[language] = formatter.factory(baseUrl, language); + formatters[language] = await formatter.factory(baseUrl, language, initialConfig); return formatters[language]; }; @@ -108,7 +116,7 @@ const format = async ( const unFormatted = { formatted: value, cursorOffset }; if (getParser(language) != null) { - const parser = loadParser(language); + const parser = await loadParser(language); const options = { useTabs: formatterConfig.useTabs ?? defaultConfig.useTabs, tabWidth: formatterConfig.tabSize ?? defaultConfig.tabSize, @@ -116,17 +124,19 @@ const format = async ( singleQuote: formatterConfig.singleQuote ?? defaultConfig.singleQuote, trailingComma: formatterConfig.trailingComma === false ? 'none' : 'all', }; - return ( - (await (self as any).prettier.formatWithCursor(value, { - parser: parser?.name, - plugins: prettierPlugins, - cursorOffset, - ...options, - })) || unFormatted - ); + let formatted = await (self as any).prettier.formatWithCursor(value, { + parser: parser?.name, + plugins: prettierPlugins, + cursorOffset, + ...options, + }); + if (typeof parser?.postFormat === 'function') { + formatted = await parser.postFormat(formatted); + } + return formatted || unFormatted; } if (getFormatter(language) != null) { - const formatFn = loadFormatter(language); + const formatFn = await loadFormatter(language); const result = await formatFn?.(value, cursorOffset); return result || unFormatted; } @@ -139,7 +149,8 @@ worker.addEventListener( const message = event.data; if (message.type === 'init') { - baseUrl = message.baseUrl; + baseUrl = message.payload.baseUrl; + initialConfig = message.payload.config; } if (message.type === 'load') { diff --git a/src/livecodes/formatter/formatter.ts b/src/livecodes/formatter/formatter.ts index 82e0441558..f9a24737c8 100644 --- a/src/livecodes/formatter/formatter.ts +++ b/src/livecodes/formatter/formatter.ts @@ -1,14 +1,14 @@ -import type { FormatFn, Language } from '../models'; +import type { Config, FormatFn, Language } from '../models'; import { getAppCDN } from '../services/modules'; import type { Formatter, FormatterMessage, FormatterMessageEvent } from './models'; -export const createFormatter = (baseUrl: string): Formatter => { +export const createFormatter = (baseUrl: string, config: Config): Formatter => { let worker: Worker | undefined; const initWorker = () => { if (worker) return; worker = new Worker(baseUrl + '{{hash:format.worker.js}}' + '?appCDN=' + getAppCDN()); - const configMessage: FormatterMessage = { type: 'init', baseUrl }; + const configMessage: FormatterMessage = { type: 'init', payload: { baseUrl, config } }; worker.postMessage(configMessage); }; diff --git a/src/livecodes/formatter/get-formatter.ts b/src/livecodes/formatter/get-formatter.ts index cdec830d79..31e587a10b 100644 --- a/src/livecodes/formatter/get-formatter.ts +++ b/src/livecodes/formatter/get-formatter.ts @@ -8,13 +8,13 @@ export const getFormatter = (config: Config, baseUrl: string, lazy: boolean): Fo if (readonly || mode === 'codeblock' || mode === 'result') { return createFakeFormatter(); } else if (lazy) { - return createLazyFormatter(baseUrl); + return createLazyFormatter(baseUrl, config); } else { - return createFormatter(baseUrl); + return createFormatter(baseUrl, config); } }; -const createLazyFormatter = (baseUrl: string) => { +const createLazyFormatter = (baseUrl: string, config: Config) => { const fakeFormatter = createFakeFormatter(); let formatter = fakeFormatter; @@ -34,7 +34,7 @@ const createLazyFormatter = (baseUrl: string) => { }; const loadFormatter = function () { - formatter = createFormatter(baseUrl); + formatter = createFormatter(baseUrl, config); lazyFormatter.load = formatter.load; lazyFormatter.getFormatFn = formatter.getFormatFn; lazyFormatter.destroy = formatter.destroy; diff --git a/src/livecodes/formatter/models.ts b/src/livecodes/formatter/models.ts index a384b00fd8..0fc780083a 100644 --- a/src/livecodes/formatter/models.ts +++ b/src/livecodes/formatter/models.ts @@ -1,4 +1,4 @@ -import type { FormatFn, FormatterConfig, Language } from '../models'; +import type { Config, FormatFn, FormatterConfig, Language } from '../models'; export interface Formatter { load: (languages: Language[]) => Promise; @@ -21,7 +21,10 @@ export type FormatterMessage = export interface InitMessage { type: 'init'; - baseUrl: string; + payload: { + baseUrl: string; + config: Config; + }; } export interface LoadMessage { diff --git a/src/livecodes/html/language-info.html b/src/livecodes/html/language-info.html index 8f2f43bbb9..c8a8f80999 100644 --- a/src/livecodes/html/language-info.html +++ b/src/livecodes/html/language-info.html @@ -1549,6 +1549,30 @@

Riot.js

+
+

Ripple

+
the elegant TypeScript UI framework
+ +

Ruby

Ruby running in the browser using Opal.
diff --git a/src/livecodes/i18n/locales/en/language-info.lokalise.json b/src/livecodes/i18n/locales/en/language-info.lokalise.json index 96cdb1c91c..0a2d8d3d98 100644 --- a/src/livecodes/i18n/locales/en/language-info.lokalise.json +++ b/src/livecodes/i18n/locales/en/language-info.lokalise.json @@ -760,6 +760,18 @@ "notes": "", "translation": "Riot.js" }, + "ripple.desc": { + "notes": "", + "translation": "the elegant TypeScript UI framework" + }, + "ripple.link": { + "notes": "### ###\n
  • \n\n### ###\n\n\n### ###\n
  • \n\n### ###\n\n\n### ###\n
  • \n\n### ###\n\n\n### ###\n
  • \n\n### ###\n\n\n", + "translation": " Ripple official website Ripple documentation LiveCodes documentation Load starter template " + }, + "ripple.name": { + "notes": "", + "translation": "Ripple" + }, "ruby.desc": { "notes": "", "translation": "Ruby running in the browser using Opal." diff --git a/src/livecodes/i18n/locales/en/language-info.ts b/src/livecodes/i18n/locales/en/language-info.ts index fe234c34a3..175e1f4a08 100644 --- a/src/livecodes/i18n/locales/en/language-info.ts +++ b/src/livecodes/i18n/locales/en/language-info.ts @@ -328,6 +328,11 @@ const languageInfo = { link: '<1> <2>Riot.js official website <3> <4>Riot.js documentation <5> <6>Load starter template ', name: 'Riot.js', }, + ripple: { + desc: 'the elegant TypeScript UI framework', + link: '<1> <2>Ripple official website <3> <4>Ripple documentation <5> <6>LiveCodes documentation <7> <8>Load starter template ', + name: 'Ripple', + }, ruby: { desc: 'Ruby running in the browser using Opal.', link: '<1> <2>Ruby official website <3> <4>Ruby documentation <5><6>Opal official website <7> <8>Opal standard library CDN <9> <10>Learn X in Y minutes, where X=ruby <11> <12>LiveCodes Documentations <13> <14>Load starter template ', diff --git a/src/livecodes/i18n/locales/en/translation.lokalise.json b/src/livecodes/i18n/locales/en/translation.lokalise.json index 83f8a79203..281288e576 100644 --- a/src/livecodes/i18n/locales/en/translation.lokalise.json +++ b/src/livecodes/i18n/locales/en/translation.lokalise.json @@ -2752,6 +2752,10 @@ "notes": "", "translation": "Riot.js Starter" }, + "templates.starter.ripple": { + "notes": "", + "translation": "Ripple Starter" + }, "templates.starter.ruby": { "notes": "", "translation": "Ruby Starter" diff --git a/src/livecodes/i18n/locales/en/translation.ts b/src/livecodes/i18n/locales/en/translation.ts index 9e7810b549..99e54316bb 100644 --- a/src/livecodes/i18n/locales/en/translation.ts +++ b/src/livecodes/i18n/locales/en/translation.ts @@ -1034,6 +1034,7 @@ const translation = { reason: 'Reason Starter', rescript: 'ReScript Starter', riot: 'Riot.js Starter', + ripple: 'Ripple Starter', ruby: 'Ruby Starter', 'ruby-wasm': 'Ruby (Wasm) Starter', scheme: 'Scheme Starter', diff --git a/src/livecodes/languages/languages.ts b/src/livecodes/languages/languages.ts index 54e3479030..a75d030b7d 100644 --- a/src/livecodes/languages/languages.ts +++ b/src/livecodes/languages/languages.ts @@ -60,6 +60,7 @@ import { reason } from './reason'; import { rescript } from './rescript'; import { richtext } from './richtext'; import { riot } from './riot'; +import { ripple } from './ripple'; import { ruby } from './ruby'; import { rubyWasm } from './ruby-wasm'; import { scheme } from './scheme'; @@ -129,6 +130,7 @@ export const languages: LanguageSpecs[] = [ solidTsx, riot, malina, + ripple, coffeescript, livescript, civet, diff --git a/src/livecodes/languages/ripple/index.ts b/src/livecodes/languages/ripple/index.ts new file mode 100644 index 0000000000..ace98a13ca --- /dev/null +++ b/src/livecodes/languages/ripple/index.ts @@ -0,0 +1 @@ +export * from './lang-ripple'; diff --git a/src/livecodes/languages/ripple/lang-ripple-compiler.ts b/src/livecodes/languages/ripple/lang-ripple-compiler.ts new file mode 100644 index 0000000000..05c2dca0e2 --- /dev/null +++ b/src/livecodes/languages/ripple/lang-ripple-compiler.ts @@ -0,0 +1,99 @@ +import { compileBlocks } from '../../compiler/compile-blocks'; +import { createImportMap, replaceSFCImports } from '../../compiler/import-map'; +import { getCompileResult } from '../../compiler/utils'; +import type { CompilerFunction, Config } from '../../models'; +import { modulesService } from '../../services/modules'; +import { pkgInfoService } from '../../services/pkgInfo'; +import { getLanguageByAlias } from '../utils'; + +(self as any).createRippleCompiler = async (initialConfig: Config): Promise => { + const MAIN_FILE = 'Component.ripple'; + let importedContent = ''; + let imports: Record = {}; + + const getModuleName = (v: string) => + v.startsWith('pr:ripple@') || v.startsWith('pkg.pr.new:ripple@') + ? v // 'pr:ripple@f8bdb34' + : `ripple@${v}`; // '0.2.25' + + let version: string = + initialConfig.customSettings.ripple?.version || + (await pkgInfoService.getPkgLatestVersion('ripple')); + let compile: (code: string, filename: string) => Promise<{ js: { code: string }; css: string }>; + const updateCompiler = async (currentVersion: string) => { + if (typeof compile === 'function' && currentVersion === version) return; + const modName = getModuleName(currentVersion + '/compiler'); + const mod = await import(modulesService.getModuleUrl(modName)); + compile = mod.compile; + version = currentVersion; + }; + + const compileRipple = async ( + code: string, + { config, filename }: { config: Config; filename: string }, + ) => { + if (filename === MAIN_FILE) { + importedContent = ''; + imports = {}; + } + if (!code.trim()) return getCompileResult(''); + + const newVersion = config.customSettings.ripple?.version || version; + await updateCompiler(newVersion); + + const isRipple = (mod: string) => + mod.toLowerCase().endsWith('.ripple') || mod.toLowerCase().startsWith('data:text/ripple'); + + const fullCode = await replaceSFCImports(code, { + config, + filename, + getLanguageByAlias, + isSfc: isRipple, + compileSFC: async ( + code: string, + { config, filename }: { config: Config; filename: string }, + ) => { + const compiled = (await compileRipple(code, { config, filename })).code; + importedContent += `\n${filename}\n\n${code}\n`; + return compiled; + }, + }); + const processedCode = await compileBlocks(fullCode, 'style', config); + const { js, css } = await compile(processedCode, filename); + + const cssCode = + css === '' + ? '' + : ` +const styles = document.createElement('style'); +styles.innerHTML = ${JSON.stringify(css)}; +document.head.appendChild(styles); +`; + + if (filename === MAIN_FILE) { + const moduleUrl = modulesService.getUrl(getModuleName(version)); + imports = { + ...createImportMap(importedContent, config), + ripple: `${moduleUrl}/src/runtime/index-client.js`, + 'ripple/internal/client': `${moduleUrl}/src/runtime/internal/client/index.js`, + 'ripple/jsx-runtime': `${moduleUrl}/src/jsx-runtime.js`, + [`${moduleUrl}/src/runtime/internal/client/constants`]: `${moduleUrl}/src/runtime/internal/client/constants.js`, + [`${moduleUrl}/src/runtime/internal/client/runtime`]: `${moduleUrl}/src/runtime/internal/client/runtime.js`, + clsx: modulesService.getModuleUrl('clsx'), + devalue: modulesService.getModuleUrl('devalue'), + 'esm-env': modulesService.getModuleUrl('esm-env'), + }; + } + + return { + code: `${js.code}\n${cssCode}`, + info: { importedContent, imports }, + }; + }; + + return (code, { config }) => + compileRipple(code, { + config, + filename: MAIN_FILE, + }); +}; diff --git a/src/livecodes/languages/ripple/lang-ripple-formatter.ts b/src/livecodes/languages/ripple/lang-ripple-formatter.ts new file mode 100644 index 0000000000..acfd929041 --- /dev/null +++ b/src/livecodes/languages/ripple/lang-ripple-formatter.ts @@ -0,0 +1,28 @@ +import { defaultConfig } from '../../config/default-config'; +import type { Config, FormatFn } from '../../models'; +import { modulesService } from '../../services/modules'; +import { pkgInfoService } from '../../services/pkgInfo'; +import { prettierEsmUrl } from '../../vendors'; + +(self as any).createRippleFormatter = async (initialConfig: Config): Promise => { + const version = + initialConfig.customSettings?.ripple?.version || + (await pkgInfoService.getPkgLatestVersion('ripple')); + const pluginUrl = + version.startsWith('pr:ripple@') || version.startsWith('pkg.pr.new:ripple@') + ? modulesService.getModuleUrl(version.replace('ripple', '@ripple-ts/prettier-plugin')) + : modulesService.getModuleUrl('@ripple-ts/prettier-plugin@' + version); + + const [prettier, ripplePlugin] = await Promise.all([import(prettierEsmUrl), import(pluginUrl)]); + return async (code, cursorOffset, formatterConfig) => + prettier.formatWithCursor(code, { + parser: 'ripple', + plugins: [ripplePlugin], + cursorOffset, + useTabs: formatterConfig?.useTabs ?? defaultConfig.useTabs, + tabWidth: formatterConfig?.tabSize ?? defaultConfig.tabSize, + semi: formatterConfig?.semicolons ?? defaultConfig.semicolons, + singleQuote: formatterConfig?.singleQuote ?? defaultConfig.singleQuote, + trailingComma: formatterConfig?.trailingComma === false ? 'none' : 'all', + }); +}; diff --git a/src/livecodes/languages/ripple/lang-ripple.ts b/src/livecodes/languages/ripple/lang-ripple.ts new file mode 100644 index 0000000000..88289925c6 --- /dev/null +++ b/src/livecodes/languages/ripple/lang-ripple.ts @@ -0,0 +1,21 @@ +import type { LanguageSpecs } from '../../models'; + +export const ripple: LanguageSpecs = { + name: 'ripple', + title: 'Ripple', + formatter: { + factory: async (baseUrl, _language, config) => { + (self as any).importScripts(baseUrl + '{{hash:lang-ripple-formatter.js}}'); + return (self as any).createRippleFormatter(config); + }, + }, + compiler: { + factory: (config, baseUrl) => { + (self as any).importScripts(baseUrl + '{{hash:lang-ripple-compiler.js}}'); + return (self as any).createRippleCompiler(config); + }, + }, + extensions: ['ripple'], + editor: 'script', + editorLanguage: 'jsx', +}; diff --git a/src/livecodes/languages/ripple/ripple-runtime.ts b/src/livecodes/languages/ripple/ripple-runtime.ts new file mode 100644 index 0000000000..80653677e6 --- /dev/null +++ b/src/livecodes/languages/ripple/ripple-runtime.ts @@ -0,0 +1,9 @@ +export const rippleRuntime = ` +import { mount } from 'ripple'; +import App from "./script"; +(() => { + mount(App, { + target: document.querySelector("#livecodes-app") || document.body.appendChild(document.createElement('div')), + }); +})(); +`; diff --git a/src/livecodes/result/result-page.ts b/src/livecodes/result/result-page.ts index c269305b90..6d98d66344 100644 --- a/src/livecodes/result/result-page.ts +++ b/src/livecodes/result/result-page.ts @@ -11,6 +11,7 @@ import { import { cssPresets, getLanguageCompiler, getLanguageExtension } from '../languages'; import { reactRuntime } from '../languages/jsx/react-runtime'; import { reactNativeRuntime } from '../languages/react-native/react-native-runtime'; +import { rippleRuntime } from '../languages/ripple/ripple-runtime'; import { solidRuntime } from '../languages/solid/solid-runtime'; import { hasCustomJsxRuntime } from '../languages/typescript'; import type { Cache, CompileInfo, Config, EditorId, Language } from '../models'; @@ -217,6 +218,7 @@ export const createResultPage = async ({ 'react-native-tsx': reactNativeRuntime, solid: solidRuntime, 'solid.tsx': solidRuntime, + ripple: rippleRuntime, }; const jsxRuntime = jsxRuntimes[code.script.language] || ''; const reactImport = @@ -446,7 +448,7 @@ export const createResultPage = async ({ } } - // React JSX runtime + // JSX runtime if (shouldInsertJsxRuntime) { const jsxRuntimeScript = dom.createElement('script'); jsxRuntimeScript.type = 'module'; diff --git a/src/livecodes/services/pkgInfo.ts b/src/livecodes/services/pkgInfo.ts index 5096143cb3..41b36f493c 100644 --- a/src/livecodes/services/pkgInfo.ts +++ b/src/livecodes/services/pkgInfo.ts @@ -217,9 +217,17 @@ const getPkgDefaultFiles = async ( }; }; +const getPkgLatestVersion = async (pkgName: string): Promise => { + const pkg = await fetch(`${apiEndpoint}/packages/npm/${pkgName}`, { headers: jsDelivrHeaders }) + .then((res) => res.json()) + .catch(() => ({})); + return pkg.tags?.latest || 'latest'; +}; + export const pkgInfoService: CDNService = { search, getPkgInfo, getPkgFiles, getPkgDefaultFiles, + getPkgLatestVersion, }; diff --git a/src/livecodes/templates/starter/index.ts b/src/livecodes/templates/starter/index.ts index 9f8a22eb10..4d7b358570 100644 --- a/src/livecodes/templates/starter/index.ts +++ b/src/livecodes/templates/starter/index.ts @@ -53,6 +53,7 @@ import { reactStarter } from './react-starter'; import { reasonStarter } from './reason-starter'; import { rescriptStarter } from './rescript-starter'; import { riotStarter } from './riot-starter'; +import { rippleStarter } from './ripple-starter'; import { rubyStarter } from './ruby-starter'; import { rubyWasmStarter } from './ruby-wasm-starter'; import { schemeStarter } from './scheme-starter'; @@ -90,6 +91,7 @@ export const starterTemplates = [ astroStarter, riotStarter, malinaStarter, + rippleStarter, jqueryStarter, backboneStarter, knockoutStarter, diff --git a/src/livecodes/templates/starter/ripple-starter.ts b/src/livecodes/templates/starter/ripple-starter.ts new file mode 100644 index 0000000000..bbe8451d88 --- /dev/null +++ b/src/livecodes/templates/starter/ripple-starter.ts @@ -0,0 +1,50 @@ +import type { Template } from '../../models'; + +export const rippleStarter: Template = { + name: 'ripple', + title: window.deps.translateString('templates.starter.ripple', 'Ripple Starter'), + thumbnail: 'assets/templates/ripple.png', + activeEditor: 'script', + markup: { + language: 'html', + content: '', + }, + style: { + language: 'css', + content: '', + }, + script: { + language: 'ripple', + content: ` +import { track } from 'ripple'; + +component Counter(props: { name: string }) { +
    +

    {\`Hello, \${props.@name}!\`}

    + + + const count = track(0); +

    {\`You clicked \${@count} times.\`}

    + +
    + + +} + +export default component App() { + const name = track("World"); + setTimeout(() => @name = "Ripple", 2000); + +} +`.trimStart(), + }, +}; diff --git a/src/livecodes/vendors.ts b/src/livecodes/vendors.ts index b09950faa6..183990be43 100644 --- a/src/livecodes/vendors.ts +++ b/src/livecodes/vendors.ts @@ -297,8 +297,12 @@ export const mjmlUrl = /* @__PURE__ */ getUrl('mjml-browser@4.15.3/lib/index.js' export const monacoBaseUrl = /* @__PURE__ */ getUrl('@live-codes/monaco-editor@0.3.0/'); +export const monacoEditorTextmateUrl = /* @__PURE__ */ getModuleUrl('monaco-editor-textmate@4.0.0'); + export const monacoEmacsUrl = /* @__PURE__ */ getUrl('monaco-emacs@0.3.0/dist/monaco-emacs.js'); +export const monacoTextmateUrl = /* @__PURE__ */ getModuleUrl('monaco-textmate@3.0.1'); + export const monacoThemesBaseUrl = /* @__PURE__ */ getUrl('monaco-themes@0.4.4/themes/'); export const monacoVimUrl = /* @__PURE__ */ getUrl('monaco-vim@0.4.1/dist/monaco-vim.js'); @@ -317,6 +321,10 @@ export const normalizeCssUrl = /* @__PURE__ */ getUrl('normalize.css@8.0.1/norma export const nunjucksBaseUrl = /* @__PURE__ */ getUrl('nunjucks@3.2.4/browser/'); +export const onigasmUrl = /* @__PURE__ */ getModuleUrl('onigasm@2.2.5'); + +export const onigasmWasmUrl = /* @__PURE__ */ getUrl('onigasm@2.2.5/lib/onigasm.wasm'); + export const opalBaseUrl = /* @__PURE__ */ getUrl('https://cdn.opalrb.com/opal/1.8.2/'); export const parinferUrl = /* @__PURE__ */ getUrl('parinfer@3.13.1/parinfer.js'); @@ -337,6 +345,8 @@ export const postcssImportUrlUrl = /* @__PURE__ */ getUrl( export const prettierBaseUrl = /* @__PURE__ */ getUrl('prettier@3.3.2/'); +export const prettierEsmUrl = /* @__PURE__ */ getModuleUrl('prettier@3.3.2/standalone'); + export const prettierPhpUrl = /* @__PURE__ */ getUrl('@prettier/plugin-php@0.22.2/standalone.js'); export const prismBaseUrl = /* @__PURE__ */ getUrl('prismjs@1.29.0/components/'); diff --git a/src/sdk/models.ts b/src/sdk/models.ts index adebd1a1ae..ea8a23caa9 100644 --- a/src/sdk/models.ts +++ b/src/sdk/models.ts @@ -1247,6 +1247,7 @@ export type ParserName = | 'babel-ts' | 'babel-flow' | 'glimmer' + | 'ripple' | 'html' | 'markdown' | 'css' @@ -1260,6 +1261,10 @@ export interface Parser { name: ParserName; plugins?: any[]; pluginUrls: string[]; + postFormat?: (parsed: { + formatted: string; + cursorOffset: number; + }) => Promise<{ formatted: string; cursorOffset: number }>; } export type FormatFn = ( value: string, @@ -1268,7 +1273,7 @@ export type FormatFn = ( ) => Promise<{ formatted: string; cursorOffset: number }>; export interface LanguageFormatter { - factory: (baseUrl: string, language: Language) => FormatFn; + factory: (baseUrl: string, language: Language, config: Config) => FormatFn | Promise; } export type CssPresetId = '' | 'normalize.css' | 'reset-css'; @@ -1392,6 +1397,7 @@ export type TemplateName = | 'preact' | 'svelte' | 'solid' + | 'ripple' | 'lit' | 'stencil' | 'mdx' @@ -2078,6 +2084,7 @@ export interface CDNService { getPkgInfo: (pkgName: string) => Promise; getPkgFiles: (pkgName: string) => Promise<{ default?: string; files: string[] } | APIError>; getPkgDefaultFiles: (pkgName: string) => Promise<{ js?: string; css?: string } | APIError>; + getPkgLatestVersion: (pkgName: string) => Promise; } export interface WorkerMessageEvent extends MessageEvent { diff --git a/typos.toml b/typos.toml index 629bd22d2b..b71e8ea5b4 100644 --- a/typos.toml +++ b/typos.toml @@ -8,6 +8,7 @@ extend-exclude = [ "src/livecodes/services/google-fonts.ts", # Font name "src/livecodes/templates/starter/blockly-starter.ts", # Random string id "functions/vendors/*.js", # Built files + "src/livecodes/editor/monaco/languages/monaco-lang-ripple.ts" ] [default]