diff --git a/.changeset/sweet-berries-begin.md b/.changeset/sweet-berries-begin.md new file mode 100644 index 00000000000..2f9ffab8cce --- /dev/null +++ b/.changeset/sweet-berries-begin.md @@ -0,0 +1,38 @@ +--- +'@astrojs/starlight': minor +--- + +Adds Expressive Code as Starlight’s default code block renderer + +⚠️ **Potentially breaking change:** +This addition changes how Markdown code blocks are rendered. By default, Starlight will now use [Expressive Code](https://github.com/expressive-code/expressive-code/tree/main/packages/astro-expressive-code). +If you were already customizing how code blocks are rendered and don't want to use the [features provided by Expressive Code](https://starlight.astro.build/guides/authoring-content/#expressive-code-features), you can preserve the previous behavior by setting the new config option `expressiveCode` to `false`. + +If you had previously added Expressive Code manually to your Starlight project, you can now remove the manual set-up in `astro.config.mjs`: + +- Move your configuration to Starlight’s new `expressiveCode` option. +- Remove the `astro-expressive-code` integration. + +For example: + +```diff +import starlight from '@astrojs/starlight'; +import { defineConfig } from 'astro/config'; +- import expressiveCode from 'astro-expressive-code'; + +export default defineConfig({ + integrations: [ +- expressiveCode({ +- themes: ['rose-pine'], +- }), + starlight({ + title: 'My docs', ++ expressiveCode: { ++ themes: ['rose-pine'], ++ }, + }), + ], +}); +``` + +Note that the built-in Starlight version of Expressive Code sets some opinionated defaults that are different from the `astro-expressive-code` defaults. You may need to set some `styleOverrides` if you wish to keep styles exactly the same. diff --git a/docs/src/content/docs/guides/authoring-content.md b/docs/src/content/docs/guides/authoring-content.md index 52f2b8b3f51..37ddc2ba66a 100644 --- a/docs/src/content/docs/guides/authoring-content.md +++ b/docs/src/content/docs/guides/authoring-content.md @@ -202,9 +202,148 @@ var fun = function lang(l) { ``` ```` -```md -Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this. -``` +### Expressive Code features + +Starlight uses [Expressive Code](https://github.com/expressive-code/expressive-code/tree/main/packages/astro-expressive-code) to extend formatting possibilities for code blocks. +Expressive Code’s text markers and window frames plugins are enabled by default. +Code block rendering can be configured using Starlight’s [`expressiveCode` configuration option](/reference/configuration/#expressivecode). + +#### Text markers + +You can highlight specific lines or parts of your code blocks using [Expressive Code text markers](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md#usage-in-markdown--mdx-documents) on the opening line of your code block. +Use curly braces (`{ }`) to highlight entire lines, and quotation marks to highlight strings of text. + +There are three highlighting styles: neutral for calling attention to code, green for indicating inserted code, and red for indicating deleted code. +Both text and entire lines can be marked using the default marker, or in combination with `ins=` and `del=` to produce the desired highlighting. + +Expressive Code provides several options for customizing the visual appearance of your code samples. +Many of these can be combined, for highly illustrative code samples. +Please explore the [Expressive Code documentation](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md) for the extensive options available. +Some of the most common examples are shown below: + +- [Mark entire lines & line ranges using the `{ }` marker](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md#marking-entire-lines--line-ranges): + + ```js {2-3} + function demo() { + // This line (#2) and the next one are highlighted + return 'This is line #3 of this snippet'; + } + ``` + + ````md + ```js {2-3} + function demo() { + // This line (#2) and the next one are highlighted + return 'This is line #3 of this snippet'; + } + ``` + ```` + +- [Mark selections of text using the `" "` marker or regular expressions](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md#marking-entire-lines--line-ranges): + + ```js "Individual terms" /Even.*supported/ + // Individual terms can be highlighted, too + function demo() { + return 'Even regular expressions are supported'; + } + ``` + + ````md + ```js "Individual terms" /Even.*supported/ + // Individual terms can be highlighted, too + function demo() { + return 'Even regular expressions are supported'; + } + ``` + ```` + +- [Mark text or lines as inserted or deleted with `ins` or `del`](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md#selecting-marker-types-mark-ins-del): + + ```js "return true;" ins="inserted" del="deleted" + function demo() { + console.log('These are inserted and deleted marker types'); + // The return statement uses the default marker type + return true; + } + ``` + + ````md + ```js "return true;" ins="inserted" del="deleted" + function demo() { + console.log('These are inserted and deleted marker types'); + // The return statement uses the default marker type + return true; + } + ``` + ```` + +- [Combine syntax highlighting with `diff`-like syntax](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-text-markers/README.md#combining-syntax-highlighting-with-diff-like-syntax): + + ```diff lang="js" + function thisIsJavaScript() { + // This entire block gets highlighted as JavaScript, + // and we can still add diff markers to it! + - console.log('Old code to be removed') + + console.log('New and shiny code!') + } + ``` + + ````md + ```diff lang="js" + function thisIsJavaScript() { + // This entire block gets highlighted as JavaScript, + // and we can still add diff markers to it! + - console.log('Old code to be removed') + + console.log('New and shiny code!') + } + ``` + ```` + +#### Frames and titles + +Code blocks can be rendered inside a window-like frame. +A frame that looks like a terminal window will be used for shell scripting languages (e.g. `bash` or `sh`). +Other languages display inside a code editor-style frame if they include a title. + +A code block’s optional title can be set either with a `title="..."` attribute following the code block's opening backticks and language identifier, or with a file name comment in the first lines of the code. + +- [Add a file name tab with a comment](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-frames/README.md#code-editor-window-frames) + + ```js + // my-test-file.js + console.log('Hello World!'); + ``` + + ````md + ```js + // my-test-file.js + console.log('Hello World!'); + ``` + ```` + +- [Add a title to a Terminal window](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-frames/README.md#terminal-window-frames) + + ```bash title="Installing dependencies…" + npm install + ``` + + ````md + ```bash title="Installing dependencies…" + npm install + ``` + ```` + +- [Disable window frames with `frame="none"`](https://github.com/expressive-code/expressive-code/blob/main/packages/%40expressive-code/plugin-frames/README.md#overriding-frame-types) + + ```bash frame="none" + echo "This is not rendered as a terminal despite using the bash language" + ``` + + ````md + ```bash frame="none" + echo "This is not rendered as a terminal despite using the bash language" + ``` + ```` ## Other common Markdown features diff --git a/docs/src/content/docs/guides/i18n.mdx b/docs/src/content/docs/guides/i18n.mdx index 587e034b5f6..42166c7a9b0 100644 --- a/docs/src/content/docs/guides/i18n.mdx +++ b/docs/src/content/docs/guides/i18n.mdx @@ -205,6 +205,17 @@ You can provide translations for additional languages you support — or overrid } ``` + Starlight’s code blocks are powered by the [Expressive Code](https://github.com/expressive-code/expressive-code) library. + You can set translations for its UI strings in the same JSON file using `expressiveCode` keys: + + ```json + { + "expressiveCode.copyButtonCopied": "Copied!", + "expressiveCode.copyButtonTooltip": "Copy to clipboard", + "expressiveCode.terminalWindowFallbackTitle": "Terminal window" + } + ``` + Starlight’s search modal is powered by the [Pagefind](https://pagefind.app/) library. You can set translations for Pagefind’s UI in the same JSON file using `pagefind` keys: diff --git a/docs/src/content/docs/reference/configuration.mdx b/docs/src/content/docs/reference/configuration.mdx index 8d1dfe6aca0..9f27bf36bd2 100644 --- a/docs/src/content/docs/reference/configuration.mdx +++ b/docs/src/content/docs/reference/configuration.mdx @@ -346,6 +346,72 @@ starlight({ }); ``` +### `expressiveCode` + +**type:** `StarlightExpressiveCodeOptions | boolean` +**default:** `true` + +Starlight uses [Expressive Code](https://github.com/expressive-code/expressive-code/tree/main/packages/astro-expressive-code) to render code blocks and add support for highlighting parts of code examples, adding filenames to code blocks, and more. +See the [“Code blocks” guide](/guides/authoring-content/#code-blocks) to learn how to use Expressive Code syntax in your Markdown and MDX content. + +You can use any of the standard [Expressive Code configuration options](https://github.com/expressive-code/expressive-code/blob/main/packages/astro-expressive-code/README.md#configuration) as well as some Starlight-specific properties, by setting them in Starlight’s `expressiveCode` option. +For example, set Expressive Code’s `styleOverrides` option to override the default CSS. This enables customizations like giving your code blocks rounded corners: + +```js ins={2-4} +starlight({ + expressiveCode: { + styleOverrides: { borderRadius: '0.5rem' }, + }, +}); +``` + +If you want to disable Expressive Code, set `expressiveCode: false` in your Starlight config: + +```js ins={2} +starlight({ + expressiveCode: false, +}); +``` + +In addition to the standard Expressive Code options, you can also set the following Starlight-specific properties in your `expressiveCode` config to further customize theme behavior for your code blocks : + +#### `themes` + +**type:** `Array` +**default:** `['starlight-dark', 'starlight-light']` + +Set the themes used to style code blocks. +See the [Expressive Code `themes` documentation](https://github.com/expressive-code/expressive-code/blob/main/packages/astro-expressive-code/README.md#themes) for details of the supported theme formats. + +Starlight uses the dark and light variants of Sarah Drasner’s [Night Owl theme](https://github.com/sdras/night-owl-vscode-theme) by default. + +If you provide at least one dark and one light theme, Starlight will automatically keep the active code block theme in sync with the current site theme. +Configure this behavior with the [`useStarlightDarkModeSwitch`](#usestarlightdarkmodeswitch) option. + +#### `useStarlightDarkModeSwitch` + +**type:** `boolean` +**default:** `true` + +When `true`, code blocks automatically switch between light and dark themes when the site theme changes. +When `false`, you must manually add CSS to handle switching between multiple themes. + +:::note +When setting `themes`, you must provide at least one dark and one light theme for the Starlight dark mode switch to work. +::: + +#### `useStarlightUiThemeColors` + +**type:** `boolean` +**default:** `true` if `themes` is not set, otherwise `false` + +When `true`, Starlight's CSS variables are used for the colors of code block UI elements (backgrounds, buttons, shadows etc.), matching the [site color theme](/guides/css-and-tailwind/#theming). +When `false`, the colors provided by the active syntax highlighting theme are used for these elements. + +:::note +When using custom themes and setting this to `true`, you must provide at least one dark and one light theme to ensure proper color contrast. +::: + ### `head` **type:** [`HeadConfig[]`](#headconfig) diff --git a/packages/starlight/index.ts b/packages/starlight/index.ts index 01dc25f1e6c..64567b38faa 100644 --- a/packages/starlight/index.ts +++ b/packages/starlight/index.ts @@ -4,6 +4,7 @@ import { spawn } from 'node:child_process'; import { dirname, relative } from 'node:path'; import { fileURLToPath } from 'node:url'; import { starlightAsides } from './integrations/asides'; +import { starlightExpressiveCode } from './integrations/expressive-code'; import { starlightSitemap } from './integrations/sitemap'; import { vitePluginStarlightUserConfig } from './integrations/virtual-user-config'; import { errorMap } from './utils/error-map'; @@ -37,6 +38,15 @@ export default function StarlightIntegration(opts: StarlightUserConfig): AstroIn entryPoint: '@astrojs/starlight/index.astro', }); const integrations: AstroIntegration[] = []; + if (!config.integrations.find(({ name }) => name === 'astro-expressive-code')) { + integrations.push( + ...starlightExpressiveCode({ + starlightConfig: userConfig, + astroConfig: config, + useTranslations, + }) + ); + } if (!config.integrations.find(({ name }) => name === '@astrojs/sitemap')) { integrations.push(starlightSitemap(userConfig)); } diff --git a/packages/starlight/integrations/asides.ts b/packages/starlight/integrations/asides.ts index a97a610ae0a..9d0c9bf70b7 100644 --- a/packages/starlight/integrations/asides.ts +++ b/packages/starlight/integrations/asides.ts @@ -7,6 +7,7 @@ import { remove } from 'unist-util-remove'; import { visit } from 'unist-util-visit'; import type { StarlightConfig } from '../types'; import type { createTranslationSystemFromFs } from '../utils/translations-fs'; +import { pathToLocale } from './shared/pathToLocale'; interface AsidesOptions { starlightConfig: { locales: StarlightConfig['locales'] }; @@ -14,33 +15,6 @@ interface AsidesOptions { useTranslations: ReturnType; } -function pathToLocale( - slug: string | undefined, - config: AsidesOptions['starlightConfig'] -): string | undefined { - const locales = Object.keys(config.locales || {}); - const baseSegment = slug?.split('/')[0]; - if (baseSegment && locales.includes(baseSegment)) return baseSegment; - return undefined; -} - -/** get current lang from file full path */ -function getLocaleFromPath( - unformattedPath: string | undefined, - { starlightConfig, astroConfig }: AsidesOptions -): string | undefined { - const srcDir = new URL(astroConfig.srcDir, astroConfig.root); - const docsDir = new URL('content/docs/', srcDir); - const path = unformattedPath - // Format path to unix style path. - ?.replace(/\\/g, '/') - // Strip docs path leaving only content collection file ID. - // Example: /Users/houston/repo/src/content/docs/en/guide.md => en/guide.md - .replace(docsDir.pathname, ''); - const locale = pathToLocale(path, starlightConfig); - return locale; -} - /** Hacky function that generates an mdast HTML tree ready for conversion to HTML by rehype. */ function h(el: string, attrs: Properties = {}, children: any[] = []): P { const { tagName, properties } = _h(el, attrs); @@ -123,7 +97,7 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> { }; const transformer: Transformer = (tree, file) => { - const locale = getLocaleFromPath(file.history[0], options); + const locale = pathToLocale(file.history[0], options); const t = options.useTranslations(locale); visit(tree, (node, index, parent) => { if (!parent || index === null || node.type !== 'containerDirective') { diff --git a/packages/starlight/integrations/expressive-code/exports.ts b/packages/starlight/integrations/expressive-code/exports.ts new file mode 100644 index 00000000000..9955b8e0cae --- /dev/null +++ b/packages/starlight/integrations/expressive-code/exports.ts @@ -0,0 +1,36 @@ +/** + * @file This file is exported by Starlight as `@astrojs/starlight/expressive-code` + * and can be used in your site's configuration to customize Expressive Code. + * + * It provides access to all of the Expressive Code classes and functions without having + * to install `astro-expressive-code` as an additional dependency into your project + * (and thereby risiking version conflicts). + * + * For example, you can use this to load custom themes from a JSONC file (JSON with comments) + * that would otherwise be difficult to import, and pass them to the `themes` option: + * + * @example + * ```js + * // astro.config.mjs + * import fs from 'node:fs'; + * import { defineConfig } from 'astro/config'; + * import starlight from '@astrojs/starlight'; + * import { ExpressiveCodeTheme } from '@astrojs/starlight/expressive-code'; + * + * const jsoncString = fs.readFileSync(new URL(`./my-theme.jsonc`, import.meta.url), 'utf-8'); + * const myTheme = ExpressiveCodeTheme.fromJSONString(jsoncString); + * + * export default defineConfig({ + * integrations: [ + * starlight({ + * title: 'My Starlight site', + * expressiveCode: { + * themes: [myTheme], + * }, + * }), + * ], + * }); + * ``` + */ + +export * from 'astro-expressive-code'; diff --git a/packages/starlight/integrations/expressive-code/index.ts b/packages/starlight/integrations/expressive-code/index.ts new file mode 100644 index 00000000000..bbe2fdf6cc7 --- /dev/null +++ b/packages/starlight/integrations/expressive-code/index.ts @@ -0,0 +1,152 @@ +import { + astroExpressiveCode, + type AstroExpressiveCodeOptions, + addClassName, +} from 'astro-expressive-code'; +import type { AstroConfig, AstroIntegration } from 'astro'; +import type { StarlightConfig } from '../../types'; +import type { createTranslationSystemFromFs } from '../../utils/translations-fs'; +import { pathToLocale } from '../shared/pathToLocale'; +import { applyStarlightUiThemeColors, preprocessThemes, type ThemeObjectOrBundledThemeName } from './theming'; +import { addTranslations } from './translations'; + +export type StarlightExpressiveCodeOptions = Omit & { + /** + * Set the themes used to style code blocks. + * + * See the [Expressive Code `themes` documentation](https://github.com/expressive-code/expressive-code/blob/main/packages/astro-expressive-code/README.md#themes) + * for details of the supported theme formats. + * + * Starlight uses the dark and light variants of Sarah Drasner’s + * [Night Owl theme](https://github.com/sdras/night-owl-vscode-theme) by default. + * + * If you provide at least one dark and one light theme, Starlight will automatically keep + * the active code block theme in sync with the current site theme. Configure this behavior + * with the [`useStarlightDarkModeSwitch`](#usestarlightdarkmodeswitch) option. + * + * Defaults to `['starlight-dark', 'starlight-light']`. + */ + themes?: ThemeObjectOrBundledThemeName[] | undefined + /** + * When `true`, code blocks automatically switch between light and dark themes when the + * site theme changes. + * + * When `false`, you must manually add CSS to handle switching between multiple themes. + * + * **Note**: When setting `themes`, you must provide at least one dark and one light theme + * for the Starlight dark mode switch to work. + * + * Defaults to `true`. + */ + useStarlightDarkModeSwitch?: boolean | undefined; + /** + * When `true`, Starlight's CSS variables are used for the colors of code block UI elements + * (backgrounds, buttons, shadows etc.), matching the + * [site color theme](/guides/css-and-tailwind/#theming). + * + * When `false`, the colors provided by the active syntax highlighting theme are used for + * these elements. + * + * Defaults to `true` if the `themes` option is not set (= you are using Starlight's + * default themes), and `false` otherwise. + * + * **Note**: When manually setting this to `true` with your custom set of `themes`, you must + * provide at least one dark and one light theme to ensure proper color contrast. + */ + useStarlightUiThemeColors?: boolean | undefined; +}; + +export const starlightExpressiveCode = ({ + astroConfig, + starlightConfig, + useTranslations, +}: { + astroConfig: Pick; + starlightConfig: StarlightConfig; + useTranslations: ReturnType; +}): AstroIntegration[] => { + const { locales, expressiveCode } = starlightConfig; + if (expressiveCode === false) return []; + const config: StarlightExpressiveCodeOptions = + typeof expressiveCode === 'object' ? expressiveCode : {}; + + const { + themes: themesInput, + customizeTheme, + styleOverrides: { textMarkers: textMarkersStyleOverrides, ...otherStyleOverrides } = {}, + useStarlightDarkModeSwitch, + useStarlightUiThemeColors = config.themes === undefined, + plugins = [], + ...rest + } = config; + + // Handle the `themes` option + const themes = preprocessThemes(themesInput); + if (useStarlightUiThemeColors === true && themes.length < 2) { + console.warn( + `*** Warning: Using the config option "useStarlightUiThemeColors: true" ` + + `with a single theme is not recommended. For better color contrast, ` + + `please provide at least one dark and one light theme.\n` + ); + } + + // Add the `not-content` class to all rendered blocks to prevent them from being affected + // by Starlight's default content styles + plugins.push({ + name: 'Starlight Plugin', + hooks: { + postprocessRenderedBlock: ({ renderData }) => { + addClassName(renderData.blockAst, 'not-content'); + }, + }, + }); + + // Add Expressive Code UI translations (if any) for all defined locales + addTranslations(locales, useTranslations); + + return [ + astroExpressiveCode({ + themes, + customizeTheme: (theme) => { + if (useStarlightUiThemeColors) { + applyStarlightUiThemeColors(theme); + } + if (customizeTheme) { + theme = customizeTheme(theme) ?? theme; + } + return theme; + }, + themeCssSelector: (theme, { styleVariants }) => { + // If one dark and one light theme are available, and the user has not disabled it, + // generate theme CSS selectors compatible with Starlight's dark mode switch + if (useStarlightDarkModeSwitch !== false && styleVariants.length >= 2) { + const baseTheme = styleVariants[0]?.theme; + const altTheme = styleVariants.find((v) => v.theme.type !== baseTheme?.type)?.theme; + if (theme === baseTheme || theme === altTheme) return `[data-theme='${theme.type}']`; + } + // Return the default selector + return `[data-theme='${theme.name}']`; + }, + styleOverrides: { + borderRadius: '0px', + borderWidth: '1px', + codePaddingBlock: '0.75rem', + codePaddingInline: '1rem', + codeFontFamily: 'var(--__sl-font-mono)', + codeFontSize: 'var(--sl-text-code)', + codeLineHeight: 'var(--sl-line-height)', + uiFontFamily: 'var(--__sl-font)', + textMarkers: { + lineDiffIndicatorMarginLeft: '0.25rem', + defaultChroma: '45', + backgroundOpacity: '60%', + ...textMarkersStyleOverrides, + }, + ...otherStyleOverrides, + }, + getBlockLocale: ({ file }) => pathToLocale(file.path, { starlightConfig, astroConfig }), + plugins, + ...rest, + }), + ]; +}; diff --git a/packages/starlight/integrations/expressive-code/themes/night-owl-dark.jsonc b/packages/starlight/integrations/expressive-code/themes/night-owl-dark.jsonc new file mode 100644 index 00000000000..a1b87a5ca98 --- /dev/null +++ b/packages/starlight/integrations/expressive-code/themes/night-owl-dark.jsonc @@ -0,0 +1,1834 @@ +/** + * Night Owl VS Code Theme - https://github.com/sdras/night-owl-vscode-theme + * + * MIT License + * + * Copyright (c) 2018 Sarah Drasner + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +{ + "name": "Night Owl No Italics", + "type": "dark", + "semanticHighlighting": false, + "colors": { + "contrastBorder": "#122d42", + "focusBorder": "#122d42", + "foreground": "#d6deeb", + "widget.shadow": "#011627", + "selection.background": "#4373c2", + "errorForeground": "#EF5350", + "button.background": "#7e57c2cc", + "button.foreground": "#ffffffcc", + "button.hoverBackground": "#7e57c2", + "dropdown.background": "#011627", + "dropdown.border": "#5f7e97", + "dropdown.foreground": "#ffffffcc", + "input.background": "#0b253a", + "input.border": "#5f7e97", + "input.foreground": "#ffffffcc", + "input.placeholderForeground": "#5f7e97", + "inputOption.activeBorder": "#ffffffcc", + "punctuation.definition.generic.begin.html": "#ef5350f2", + "inputValidation.errorBackground": "#AB0300F2", + "inputValidation.errorBorder": "#EF5350", + "inputValidation.infoBackground": "#00589EF2", + "inputValidation.infoBorder": "#64B5F6", + "inputValidation.warningBackground": "#675700F2", + "inputValidation.warningBorder": "#FFCA28", + "scrollbar.shadow": "#010b14", + "scrollbarSlider.activeBackground": "#084d8180", + "scrollbarSlider.background": "#084d8180", + "scrollbarSlider.hoverBackground": "#084d8180", + "badge.background": "#5f7e97", + "badge.foreground": "#ffffff", + "progress.background": "#7e57c2", + "breadcrumb.foreground": "#A599E9", + "breadcrumb.focusForeground": "#ffffff", + "breadcrumb.activeSelectionForeground": "#FFFFFF", + "breadcrumbPicker.background": "#001122", + "list.activeSelectionBackground": "#234d708c", + "list.activeSelectionForeground": "#ffffff", + "list.invalidItemForeground": "#975f94", + "list.dropBackground": "#011627", + "list.focusBackground": "#010d18", + "list.focusForeground": "#ffffff", + "list.highlightForeground": "#ffffff", + "list.hoverBackground": "#011627", + "list.hoverForeground": "#ffffff", + "list.inactiveSelectionBackground": "#0e293f", + "list.inactiveSelectionForeground": "#5f7e97", + "activityBar.background": "#011627", + "activityBar.dropBackground": "#5f7e97", + "activityBar.foreground": "#5f7e97", + "activityBar.border": "#011627", + "activityBarBadge.background": "#44596b", + "activityBarBadge.foreground": "#ffffff", + "sideBar.background": "#011627", + "sideBar.foreground": "#89a4bb", + "sideBar.border": "#011627", + "sideBarTitle.foreground": "#5f7e97", + "sideBarSectionHeader.background": "#011627", + "sideBarSectionHeader.foreground": "#5f7e97", + "editorGroup.emptyBackground": "#011627", + "editorGroup.border": "#011627", + "editorGroup.dropBackground": "#7e57c273", + "editorGroupHeader.noTabsBackground": "#011627", + "editorGroupHeader.tabsBackground": "#011627", + "editorGroupHeader.tabsBorder": "#262A39", + "tab.activeBackground": "#0b2942", + "tab.activeForeground": "#d2dee7", + "tab.border": "#272B3B", + "tab.activeBorder": "#262A39", + "tab.unfocusedActiveBorder": "#262A39", + "tab.inactiveBackground": "#01111d", + "tab.inactiveForeground": "#5f7e97", + "tab.unfocusedActiveForeground": "#5f7e97", + "tab.unfocusedInactiveForeground": "#5f7e97", + "editor.background": "#011627", + "editor.foreground": "#d6deeb", + "editorLineNumber.foreground": "#4b6479", + "editorLineNumber.activeForeground": "#C5E4FD", + "editorCursor.foreground": "#80a4c2", + "editor.selectionBackground": "#1d3b53", + "editor.selectionHighlightBackground": "#5f7e9779", + "editor.inactiveSelectionBackground": "#7e57c25a", + "editor.wordHighlightBackground": "#f6bbe533", + "editor.wordHighlightStrongBackground": "#e2a2f433", + "editor.findMatchBackground": "#5f7e9779", + "editor.findMatchHighlightBackground": "#1085bb5d", + "editor.findRangeHighlightBackground": null, + "editor.hoverHighlightBackground": "#7e57c25a", + "editor.lineHighlightBackground": "#0003", + "editor.lineHighlightBorder": null, + "editorLink.activeForeground": null, + "editor.rangeHighlightBackground": "#7e57c25a", + "editorWhitespace.foreground": null, + "editorIndentGuide.background": "#5e81ce52", + "editorIndentGuide.activeBackground": "#7E97AC", + "editorRuler.foreground": "#5e81ce52", + "editorCodeLens.foreground": "#5e82ceb4", + "editorBracketMatch.background": "#5f7e974d", + "editorBracketMatch.border": null, + "editorOverviewRuler.currentContentForeground": "#7e57c2", + "editorOverviewRuler.incomingContentForeground": "#7e57c2", + "editorOverviewRuler.commonContentForeground": "#7e57c2", + "editorError.foreground": "#EF5350", + "editorError.border": null, + "editorWarning.foreground": "#b39554", + "editorWarning.border": null, + "editorGutter.background": "#011627", + "editorGutter.modifiedBackground": "#e2b93d", + "editorGutter.addedBackground": "#9CCC65", + "editorGutter.deletedBackground": "#EF5350", + "diffEditor.insertedTextBackground": "#99b76d23", + "diffEditor.insertedTextBorder": "#c5e47833", + "diffEditor.removedTextBackground": "#ef535033", + "diffEditor.removedTextBorder": "#ef53504d", + "editorWidget.background": "#021320", + "editorWidget.border": "#5f7e97", + "editorSuggestWidget.background": "#2C3043", + "editorSuggestWidget.border": "#2B2F40", + "editorSuggestWidget.foreground": "#d6deeb", + "editorSuggestWidget.highlightForeground": "#ffffff", + "editorSuggestWidget.selectedBackground": "#5f7e97", + "editorHoverWidget.background": "#011627", + "editorHoverWidget.border": "#5f7e97", + "debugExceptionWidget.background": "#011627", + "debugExceptionWidget.border": "#5f7e97", + "editorMarkerNavigation.background": "#0b2942", + "editorMarkerNavigationError.background": "#EF5350", + "editorMarkerNavigationWarning.background": "#FFCA28", + "peekView.border": "#5f7e97", + "peekViewEditor.background": "#011627", + "peekViewEditor.matchHighlightBackground": "#7e57c25a", + "peekViewResult.background": "#011627", + "peekViewResult.fileForeground": "#5f7e97", + "peekViewResult.lineForeground": "#5f7e97", + "peekViewResult.matchHighlightBackground": "#ffffffcc", + "peekViewResult.selectionBackground": "#2E3250", + "peekViewResult.selectionForeground": "#5f7e97", + "peekViewTitle.background": "#011627", + "peekViewTitleDescription.foreground": "#697098", + "peekViewTitleLabel.foreground": "#5f7e97", + "merge.currentHeaderBackground": "#5f7e97", + "merge.currentContentBackground": null, + "merge.incomingHeaderBackground": "#7e57c25a", + "merge.incomingContentBackground": null, + "merge.border": null, + "panel.background": "#011627", + "panel.border": "#5f7e97", + "panelTitle.activeBorder": "#5f7e97", + "panelTitle.activeForeground": "#ffffffcc", + "panelTitle.inactiveForeground": "#d6deeb80", + "statusBar.background": "#011627", + "statusBar.foreground": "#5f7e97", + "statusBar.border": "#262A39", + "statusBar.debuggingBackground": "#202431", + "statusBar.debuggingForeground": null, + "statusBar.debuggingBorder": "#1F2330", + "statusBar.noFolderForeground": null, + "statusBar.noFolderBackground": "#011627", + "statusBar.noFolderBorder": "#25293A", + "statusBarItem.activeBackground": "#202431", + "statusBarItem.hoverBackground": "#202431", + "statusBarItem.prominentBackground": "#202431", + "statusBarItem.prominentHoverBackground": "#202431", + "titleBar.activeBackground": "#011627", + "titleBar.activeForeground": "#eeefff", + "titleBar.inactiveBackground": "#010e1a", + "titleBar.inactiveForeground": null, + "notifications.background": "#01111d", + "notifications.border": "#262a39", + "notificationCenter.border": "#262a39", + "notificationToast.border": "#262a39", + "notifications.foreground": "#ffffffcc", + "notificationLink.foreground": "#80CBC4", + "extensionButton.prominentForeground": "#ffffffcc", + "extensionButton.prominentBackground": "#7e57c2cc", + "extensionButton.prominentHoverBackground": "#7e57c2", + "pickerGroup.foreground": "#d1aaff", + "pickerGroup.border": "#011627", + "terminal.ansiWhite": "#ffffff", + "terminal.ansiBlack": "#011627", + "terminal.ansiBlue": "#82AAFF", + "terminal.ansiCyan": "#21c7a8", + "terminal.ansiGreen": "#22da6e", + "terminal.ansiMagenta": "#C792EA", + "terminal.ansiRed": "#EF5350", + "terminal.ansiYellow": "#c5e478", + "terminal.ansiBrightWhite": "#ffffff", + "terminal.ansiBrightBlack": "#575656", + "terminal.ansiBrightBlue": "#82AAFF", + "terminal.ansiBrightCyan": "#7fdbca", + "terminal.ansiBrightGreen": "#22da6e", + "terminal.ansiBrightMagenta": "#C792EA", + "terminal.ansiBrightRed": "#EF5350", + "terminal.ansiBrightYellow": "#ffeb95", + "terminal.selectionBackground": "#1b90dd4d", + "terminalCursor.background": "#234d70", + "textCodeBlock.background": "#4f4f4f", + "debugToolBar.background": "#011627", + "welcomePage.buttonBackground": "#011627", + "welcomePage.buttonHoverBackground": "#011627", + "walkThrough.embeddedEditorBackground": "#011627", + "gitDecoration.modifiedResourceForeground": "#a2bffc", + "gitDecoration.deletedResourceForeground": "#EF535090", + "gitDecoration.untrackedResourceForeground": "#c5e478ff", + "gitDecoration.ignoredResourceForeground": "#395a75", + "gitDecoration.conflictingResourceForeground": "#ffeb95cc", + "source.elm": "#5f7e97", + "string.quoted.single.js": "#ffffff", + "meta.objectliteral.js": "#82AAFF" + }, + "tokenColors": [ + { + "name": "Changed", + "scope": [ + "markup.changed", + "meta.diff.header.git", + "meta.diff.header.from-file", + "meta.diff.header.to-file" + ], + "settings": { + "foreground": "#a2bffc" + } + }, + { + "name": "Deleted", + "scope": "markup.deleted.diff", + "settings": { + "foreground": "#EF535090" + } + }, + { + "name": "Inserted", + "scope": "markup.inserted.diff", + "settings": { + "foreground": "#c5e478ff" + } + }, + { + "name": "Global settings", + "settings": { + "background": "#011627", + "foreground": "#d6deeb" + } + }, + { + "name": "Comment", + "scope": "comment", + "settings": { + "foreground": "#637777", + "fontStyle": "" + } + }, + { + "name": "String", + "scope": "string", + "settings": { + "foreground": "#ecc48d" + } + }, + { + "name": "String Quoted", + "scope": ["string.quoted", "variable.other.readwrite.js"], + "settings": { + "foreground": "#ecc48d" + } + }, + { + "name": "Support Constant Math", + "scope": "support.constant.math", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Number", + "scope": ["constant.numeric", "constant.character.numeric"], + "settings": { + "foreground": "#F78C6C", + "fontStyle": "" + } + }, + { + "name": "Built-in constant", + "scope": [ + "constant.language", + "punctuation.definition.constant", + "variable.other.constant" + ], + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "User-defined constant", + "scope": ["constant.character", "constant.other"], + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "Constant Character Escape", + "scope": "constant.character.escape", + "settings": { + "foreground": "#F78C6C" + } + }, + { + "name": "RegExp String", + "scope": ["string.regexp", "string.regexp keyword.other"], + "settings": { + "foreground": "#5ca7e4" + } + }, + { + "name": "Comma in functions", + "scope": "meta.function punctuation.separator.comma", + "settings": { + "foreground": "#5f7e97" + } + }, + { + "name": "Variable", + "scope": "variable", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Keyword", + "scope": ["punctuation.accessor", "keyword"], + "settings": { + "foreground": "#c792ea", + "fontStyle": "" + } + }, + { + "name": "Storage", + "scope": [ + "storage", + "meta.var.expr", + "meta.class meta.method.declaration meta.var.expr storage.type.js", + "storage.type.property.js", + "storage.type.property.ts", + "storage.type.property.tsx" + ], + "settings": { + "foreground": "#c792ea", + "fontStyle": "" + } + }, + { + "name": "Storage type", + "scope": "storage.type", + "settings": { + "foreground": "#c792ea" + } + }, + { + "name": "Storage type", + "scope": "storage.type.function.arrow.js", + "settings": { + "fontStyle": "" + } + }, + { + "name": "Class name", + "scope": ["entity.name.class", "meta.class entity.name.type.class"], + "settings": { + "foreground": "#ffcb8b" + } + }, + { + "name": "Inherited class", + "scope": "entity.other.inherited-class", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Function name", + "scope": "entity.name.function", + "settings": { + "foreground": "#c792ea", + "fontStyle": "" + } + }, + { + "name": "Meta Tag", + "scope": ["punctuation.definition.tag", "meta.tag"], + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "HTML Tag names", + "scope": [ + "entity.name.tag", + "meta.tag.other.html", + "meta.tag.other.js", + "meta.tag.other.tsx", + "entity.name.tag.tsx", + "entity.name.tag.js", + "entity.name.tag", + "meta.tag.js", + "meta.tag.tsx", + "meta.tag.html" + ], + "settings": { + "foreground": "#caece6", + "fontStyle": "" + } + }, + { + "name": "Tag attribute", + "scope": "entity.other.attribute-name", + "settings": { + "fontStyle": "", + "foreground": "#c5e478" + } + }, + { + "name": "Entity Name Tag Custom", + "scope": "entity.name.tag.custom", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Library (function & constant)", + "scope": ["support.function", "support.constant"], + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "Support Constant Property Value meta", + "scope": "support.constant.meta.property-value", + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "Library class/type", + "scope": ["support.type", "support.class"], + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Support Variable DOM", + "scope": "support.variable.dom", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Invalid", + "scope": "invalid", + "settings": { + "background": "#ff2c83", + "foreground": "#ffffff" + } + }, + { + "name": "Invalid deprecated", + "scope": "invalid.deprecated", + "settings": { + "foreground": "#ffffff", + "background": "#d3423e" + } + }, + { + "name": "Keyword Operator", + "scope": "keyword.operator", + "settings": { + "foreground": "#7fdbca", + "fontStyle": "" + } + }, + { + "name": "Keyword Operator Relational", + "scope": "keyword.operator.relational", + "settings": { + "foreground": "#c792ea", + "fontStyle": "" + } + }, + { + "name": "Keyword Operator Assignment", + "scope": "keyword.operator.assignment", + "settings": { + "foreground": "#c792ea" + } + }, + { + "name": "Keyword Operator Arithmetic", + "scope": "keyword.operator.arithmetic", + "settings": { + "foreground": "#c792ea" + } + }, + { + "name": "Keyword Operator Bitwise", + "scope": "keyword.operator.bitwise", + "settings": { + "foreground": "#c792ea" + } + }, + { + "name": "Keyword Operator Increment", + "scope": "keyword.operator.increment", + "settings": { + "foreground": "#c792ea" + } + }, + { + "name": "Keyword Operator Ternary", + "scope": "keyword.operator.ternary", + "settings": { + "foreground": "#c792ea" + } + }, + { + "name": "Double-Slashed Comment", + "scope": "comment.line.double-slash", + "settings": { + "foreground": "#637777" + } + }, + { + "name": "Object", + "scope": "object", + "settings": { + "foreground": "#cdebf7" + } + }, + { + "name": "Null", + "scope": "constant.language.null", + "settings": { + "foreground": "#ff5874" + } + }, + { + "name": "Meta Brace", + "scope": "meta.brace", + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "Meta Delimiter Period", + "scope": "meta.delimiter.period", + "settings": { + "foreground": "#c792ea", + "fontStyle": "" + } + }, + { + "name": "Punctuation Definition String", + "scope": "punctuation.definition.string", + "settings": { + "foreground": "#d9f5dd" + } + }, + { + "name": "Punctuation Definition String Markdown", + "scope": "punctuation.definition.string.begin.markdown", + "settings": { + "foreground": "#ff5874" + } + }, + { + "name": "Boolean", + "scope": "constant.language.boolean", + "settings": { + "foreground": "#ff5874" + } + }, + { + "name": "Object Comma", + "scope": "object.comma", + "settings": { + "foreground": "#ffffff" + } + }, + { + "name": "Variable Parameter Function", + "scope": "variable.parameter.function", + "settings": { + "foreground": "#7fdbca", + "fontStyle": "" + } + }, + { + "name": "Support Type Property Name & entity name tags", + "scope": [ + "support.type.vendor.property-name", + "support.constant.vendor.property-value", + "support.type.property-name", + "meta.property-list entity.name.tag" + ], + "settings": { + "foreground": "#80CBC4", + "fontStyle": "" + } + }, + { + "name": "Entity Name tag reference in stylesheets", + "scope": "meta.property-list entity.name.tag.reference", + "settings": { + "foreground": "#57eaf1" + } + }, + { + "name": "Constant Other Color RGB Value Punctuation Definition Constant", + "scope": "constant.other.color.rgb-value punctuation.definition.constant", + "settings": { + "foreground": "#F78C6C" + } + }, + { + "name": "Constant Other Color", + "scope": "constant.other.color", + "settings": { + "foreground": "#FFEB95" + } + }, + { + "name": "Keyword Other Unit", + "scope": "keyword.other.unit", + "settings": { + "foreground": "#FFEB95" + } + }, + { + "name": "Meta Selector", + "scope": "meta.selector", + "settings": { + "foreground": "#c792ea", + "fontStyle": "" + } + }, + { + "name": "Entity Other Attribute Name Id", + "scope": "entity.other.attribute-name.id", + "settings": { + "foreground": "#FAD430" + } + }, + { + "name": "Meta Property Name", + "scope": "meta.property-name", + "settings": { + "foreground": "#80CBC4" + } + }, + { + "name": "Doctypes", + "scope": ["entity.name.tag.doctype", "meta.tag.sgml.doctype"], + "settings": { + "foreground": "#c792ea", + "fontStyle": "" + } + }, + { + "name": "Punctuation Definition Parameters", + "scope": "punctuation.definition.parameters", + "settings": { + "foreground": "#d9f5dd" + } + }, + { + "name": "Keyword Control Operator", + "scope": "keyword.control.operator", + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "Keyword Operator Logical", + "scope": "keyword.operator.logical", + "settings": { + "foreground": "#c792ea", + "fontStyle": "" + } + }, + { + "name": "Variable Instances", + "scope": [ + "variable.instance", + "variable.other.instance", + "variable.readwrite.instance", + "variable.other.readwrite.instance", + "variable.other.property" + ], + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "Variable Property Other object property", + "scope": ["variable.other.object.property"], + "settings": { + "foreground": "#faf39f", + "fontStyle": "" + } + }, + { + "name": "Variable Property Other object", + "scope": ["variable.other.object.js"], + "settings": { + "fontStyle": "" + } + }, + { + "name": "Entity Name Function", + "scope": ["entity.name.function"], + "settings": { + "foreground": "#82AAFF", + "fontStyle": "" + } + }, + { + "name": "Keyword Operator Comparison, returns, imports, and Keyword Operator Ruby", + "scope": [ + "keyword.control.conditional.js", + "keyword.operator.comparison", + "keyword.control.flow.js", + "keyword.control.flow.ts", + "keyword.control.flow.tsx", + "keyword.control.ruby", + "keyword.control.def.ruby", + "keyword.control.loop.js", + "keyword.control.loop.ts", + "keyword.control.import.js", + "keyword.control.import.ts", + "keyword.control.import.tsx", + "keyword.control.from.js", + "keyword.control.from.ts", + "keyword.control.from.tsx", + "keyword.control.conditional.js", + "keyword.control.conditional.ts", + "keyword.control.switch.js", + "keyword.control.switch.ts", + "keyword.operator.instanceof.js", + "keyword.operator.expression.instanceof.ts", + "keyword.operator.expression.instanceof.tsx" + ], + "settings": { + "foreground": "#c792ea", + "fontStyle": "" + } + }, + { + "name": "Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords", + "scope": [ + "support.constant", + "keyword.other.special-method", + "keyword.other.new", + "keyword.other.debugger", + "keyword.control" + ], + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "Support Function", + "scope": "support.function", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Invalid Broken", + "scope": "invalid.broken", + "settings": { + "foreground": "#020e14", + "background": "#F78C6C" + } + }, + { + "name": "Invalid Unimplemented", + "scope": "invalid.unimplemented", + "settings": { + "background": "#8BD649", + "foreground": "#ffffff" + } + }, + { + "name": "Invalid Illegal", + "scope": "invalid.illegal", + "settings": { + "foreground": "#ffffff", + "background": "#ec5f67" + } + }, + { + "name": "Language Variable", + "scope": "variable.language", + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "Support Variable Property", + "scope": "support.variable.property", + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "Variable Function", + "scope": "variable.function", + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "Variable Interpolation", + "scope": "variable.interpolation", + "settings": { + "foreground": "#ec5f67" + } + }, + { + "name": "Meta Function Call", + "scope": "meta.function-call", + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "Punctuation Section Embedded", + "scope": "punctuation.section.embedded", + "settings": { + "foreground": "#d3423e" + } + }, + { + "name": "Punctuation Tweaks", + "scope": [ + "punctuation.terminator.expression", + "punctuation.definition.arguments", + "punctuation.definition.array", + "punctuation.section.array", + "meta.array" + ], + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "More Punctuation Tweaks", + "scope": [ + "punctuation.definition.list.begin", + "punctuation.definition.list.end", + "punctuation.separator.arguments", + "punctuation.definition.list" + ], + "settings": { + "foreground": "#d9f5dd" + } + }, + { + "name": "Template Strings", + "scope": "string.template meta.template.expression", + "settings": { + "foreground": "#d3423e" + } + }, + { + "name": "Backtics(``) in Template Strings", + "scope": "string.template punctuation.definition.string", + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "Italics", + "scope": "italic", + "settings": { + "foreground": "#c792ea", + "fontStyle": "italic" + } + }, + { + "name": "Bold", + "scope": "bold", + "settings": { + "foreground": "#c5e478", + "fontStyle": "bold" + } + }, + { + "name": "Quote", + "scope": "quote", + "settings": { + "foreground": "#697098", + "fontStyle": "" + } + }, + { + "name": "Raw Code", + "scope": "raw", + "settings": { + "foreground": "#80CBC4" + } + }, + { + "name": "CoffeScript Variable Assignment", + "scope": "variable.assignment.coffee", + "settings": { + "foreground": "#31e1eb" + } + }, + { + "name": "CoffeScript Parameter Function", + "scope": "variable.parameter.function.coffee", + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "CoffeeScript Assignments", + "scope": "variable.assignment.coffee", + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "C# Readwrite Variables", + "scope": "variable.other.readwrite.cs", + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "C# Classes & Storage types", + "scope": ["entity.name.type.class.cs", "storage.type.cs"], + "settings": { + "foreground": "#ffcb8b" + } + }, + { + "name": "C# Namespaces", + "scope": "entity.name.type.namespace.cs", + "settings": { + "foreground": "#B2CCD6" + } + }, + { + "name": "C# Unquoted String Zone", + "scope": "string.unquoted.preprocessor.message.cs", + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "C# Region", + "scope": [ + "punctuation.separator.hash.cs", + "keyword.preprocessor.region.cs", + "keyword.preprocessor.endregion.cs" + ], + "settings": { + "foreground": "#ffcb8b", + "fontStyle": "bold" + } + }, + { + "name": "C# Other Variables", + "scope": "variable.other.object.cs", + "settings": { + "foreground": "#B2CCD6" + } + }, + { + "name": "C# Enum", + "scope": "entity.name.type.enum.cs", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Dart String", + "scope": [ + "string.interpolated.single.dart", + "string.interpolated.double.dart" + ], + "settings": { + "foreground": "#FFCB8B" + } + }, + { + "name": "Dart Class", + "scope": "support.class.dart", + "settings": { + "foreground": "#FFCB8B" + } + }, + { + "name": "Tag names in Stylesheets", + "scope": [ + "entity.name.tag.css", + "entity.name.tag.less", + "entity.name.tag.custom.css", + "support.constant.property-value.css" + ], + "settings": { + "foreground": "#ff6363", + "fontStyle": "" + } + }, + { + "name": "Wildcard(*) selector in Stylesheets", + "scope": [ + "entity.name.tag.wildcard.css", + "entity.name.tag.wildcard.less", + "entity.name.tag.wildcard.scss", + "entity.name.tag.wildcard.sass" + ], + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "CSS Keyword Other Unit", + "scope": "keyword.other.unit.css", + "settings": { + "foreground": "#FFEB95" + } + }, + { + "name": "Attribute Name for CSS", + "scope": [ + "meta.attribute-selector.css entity.other.attribute-name.attribute", + "variable.other.readwrite.js" + ], + "settings": { + "foreground": "#F78C6C" + } + }, + { + "name": "Elixir Classes", + "scope": [ + "source.elixir support.type.elixir", + "source.elixir meta.module.elixir entity.name.class.elixir" + ], + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "Elixir Functions", + "scope": "source.elixir entity.name.function", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Elixir Constants", + "scope": [ + "source.elixir constant.other.symbol.elixir", + "source.elixir constant.other.keywords.elixir" + ], + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "Elixir String Punctuations", + "scope": "source.elixir punctuation.definition.string", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Elixir", + "scope": [ + "source.elixir variable.other.readwrite.module.elixir", + "source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir" + ], + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Elixir Binary Punctuations", + "scope": "source.elixir .punctuation.binary.elixir", + "settings": { + "foreground": "#c792ea", + "fontStyle": "" + } + }, + { + "name": "Closure Constant Keyword", + "scope": "constant.keyword.clojure", + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "Go Function Calls", + "scope": "source.go meta.function-call.go", + "settings": { + "foreground": "#DDDDDD" + } + }, + { + "name": "Go Keywords", + "scope": [ + "source.go keyword.package.go", + "source.go keyword.import.go", + "source.go keyword.function.go", + "source.go keyword.type.go", + "source.go keyword.struct.go", + "source.go keyword.interface.go", + "source.go keyword.const.go", + "source.go keyword.var.go", + "source.go keyword.map.go", + "source.go keyword.channel.go", + "source.go keyword.control.go" + ], + "settings": { + "foreground": "#c792ea" + } + }, + { + "name": "Go Constants e.g. nil, string format (%s, %d, etc.)", + "scope": [ + "source.go constant.language.go", + "source.go constant.other.placeholder.go" + ], + "settings": { + "foreground": "#ff5874" + } + }, + { + "name": "C++ Functions", + "scope": [ + "entity.name.function.preprocessor.cpp", + "entity.scope.name.cpp" + ], + "settings": { + "foreground": "#7fdbcaff" + } + }, + { + "name": "C++ Meta Namespace", + "scope": ["meta.namespace-block.cpp"], + "settings": { + "foreground": "#e0dec6" + } + }, + { + "name": "C++ Language Primitive Storage", + "scope": ["storage.type.language.primitive.cpp"], + "settings": { + "foreground": "#ff5874" + } + }, + { + "name": "C++ Preprocessor Macro", + "scope": ["meta.preprocessor.macro.cpp"], + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "C++ Variable Parameter", + "scope": ["variable.parameter"], + "settings": { + "foreground": "#ffcb8b" + } + }, + { + "name": "Powershell Variables", + "scope": ["variable.other.readwrite.powershell"], + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "Powershell Function", + "scope": ["support.function.powershell"], + "settings": { + "foreground": "#7fdbcaff" + } + }, + { + "name": "ID Attribute Name in HTML", + "scope": "entity.other.attribute-name.id.html", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "HTML Punctuation Definition Tag", + "scope": "punctuation.definition.tag.html", + "settings": { + "foreground": "#6ae9f0" + } + }, + { + "name": "HTML Doctype", + "scope": "meta.tag.sgml.doctype.html", + "settings": { + "foreground": "#c792ea", + "fontStyle": "" + } + }, + { + "name": "JavaScript Classes", + "scope": "meta.class entity.name.type.class.js", + "settings": { + "foreground": "#ffcb8b" + } + }, + { + "name": "JavaScript Method Declaration e.g. `constructor`", + "scope": "meta.method.declaration storage.type.js", + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "JavaScript Terminator", + "scope": "terminator.js", + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "JavaScript Meta Punctuation Definition", + "scope": "meta.js punctuation.definition.js", + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "Entity Names in Code Documentations", + "scope": [ + "entity.name.type.instance.jsdoc", + "entity.name.type.instance.phpdoc" + ], + "settings": { + "foreground": "#5f7e97" + } + }, + { + "name": "Other Variables in Code Documentations", + "scope": ["variable.other.jsdoc", "variable.other.phpdoc"], + "settings": { + "foreground": "#78ccf0" + } + }, + { + "name": "JavaScript module imports and exports", + "scope": [ + "variable.other.meta.import.js", + "meta.import.js variable.other", + "variable.other.meta.export.js", + "meta.export.js variable.other" + ], + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "JavaScript Variable Parameter Function", + "scope": "variable.parameter.function.js", + "settings": { + "foreground": "#7986E7" + } + }, + { + "name": "JavaScript[React] Variable Other Object", + "scope": [ + "variable.other.object.js", + "variable.other.object.jsx", + "variable.object.property.js", + "variable.object.property.jsx" + ], + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "JavaScript Variables", + "scope": ["variable.js", "variable.other.js"], + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "JavaScript Entity Name Type", + "scope": ["entity.name.type.js", "entity.name.type.module.js"], + "settings": { + "foreground": "#ffcb8b", + "fontStyle": "" + } + }, + { + "name": "JavaScript Support Classes", + "scope": "support.class.js", + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "JSON Property Names", + "scope": "support.type.property-name.json", + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "JSON Support Constants", + "scope": "support.constant.json", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "JSON Property values (string)", + "scope": "meta.structure.dictionary.value.json string.quoted.double", + "settings": { + "foreground": "#c789d6" + } + }, + { + "name": "Strings in JSON values", + "scope": "string.quoted.double.json punctuation.definition.string.json", + "settings": { + "foreground": "#80CBC4" + } + }, + { + "name": "Specific JSON Property values like null", + "scope": "meta.structure.dictionary.json meta.structure.dictionary.value constant.language", + "settings": { + "foreground": "#ff5874" + } + }, + { + "name": "JavaScript Other Variable", + "scope": "variable.other.object.js", + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "Ruby Variables", + "scope": ["variable.other.ruby"], + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "Ruby Class", + "scope": ["entity.name.type.class.ruby"], + "settings": { + "foreground": "#ecc48d" + } + }, + { + "name": "Ruby Hashkeys", + "scope": "constant.language.symbol.hashkey.ruby", + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "LESS Tag names", + "scope": "entity.name.tag.less", + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "LESS Keyword Other Unit", + "scope": "keyword.other.unit.css", + "settings": { + "foreground": "#FFEB95" + } + }, + { + "name": "Attribute Name for LESS", + "scope": "meta.attribute-selector.less entity.other.attribute-name.attribute", + "settings": { + "foreground": "#F78C6C" + } + }, + { + "name": "Markdown Headings", + "scope": [ + "markup.heading.markdown", + "markup.heading.setext.1.markdown", + "markup.heading.setext.2.markdown" + ], + "settings": { + "foreground": "#82b1ff" + } + }, + { + "name": "Markdown Italics", + "scope": "markup.italic.markdown", + "settings": { + "foreground": "#c792ea", + "fontStyle": "italic" + } + }, + { + "name": "Markdown Bold", + "scope": "markup.bold.markdown", + "settings": { + "foreground": "#c5e478", + "fontStyle": "bold" + } + }, + { + "name": "Markdown Quote + others", + "scope": "markup.quote.markdown", + "settings": { + "foreground": "#697098", + "fontStyle": "" + } + }, + { + "name": "Markdown Raw Code + others", + "scope": "markup.inline.raw.markdown", + "settings": { + "foreground": "#80CBC4" + } + }, + { + "name": "Markdown Links", + "scope": [ + "markup.underline.link.markdown", + "markup.underline.link.image.markdown" + ], + "settings": { + "foreground": "#ff869a" + } + }, + { + "name": "Markdown Link Title and Description", + "scope": [ + "string.other.link.title.markdown", + "string.other.link.description.markdown" + ], + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "Markdown Punctuation", + "scope": [ + "punctuation.definition.string.markdown", + "punctuation.definition.string.begin.markdown", + "punctuation.definition.string.end.markdown", + "meta.link.inline.markdown punctuation.definition.string" + ], + "settings": { + "foreground": "#82b1ff" + } + }, + { + "name": "Markdown MetaData Punctuation", + "scope": ["punctuation.definition.metadata.markdown"], + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "Markdown List Punctuation", + "scope": ["beginning.punctuation.definition.list.markdown"], + "settings": { + "foreground": "#82b1ff" + } + }, + { + "name": "Markdown Inline Raw String", + "scope": "markup.inline.raw.string.markdown", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "PHP Variables", + "scope": "variable.other.php", + "settings": { + "foreground": "#bec5d4" + } + }, + { + "name": "Support Classes in PHP", + "scope": "support.class.php", + "settings": { + "foreground": "#ffcb8b" + } + }, + { + "name": "Punctuations in PHP function calls", + "scope": "meta.function-call.php punctuation", + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "PHP Global Variables", + "scope": "variable.other.global.php", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Declaration Punctuation in PHP Global Variables", + "scope": "variable.other.global.php punctuation.definition.variable", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Language Constants in Python", + "scope": "constant.language.python", + "settings": { + "foreground": "#ff5874" + } + }, + { + "name": "Python Function Parameter and Arguments", + "scope": [ + "variable.parameter.function.python", + "meta.function-call.arguments.python" + ], + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "Python Function Call", + "scope": [ + "meta.function-call.python", + "meta.function-call.generic.python" + ], + "settings": { + "foreground": "#B2CCD6" + } + }, + { + "name": "Punctuations in Python", + "scope": "punctuation.python", + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "Decorator Functions in Python", + "scope": "entity.name.function.decorator.python", + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Python Language Variable", + "scope": "source.python variable.language.special", + "settings": { + "foreground": "#8EACE3" + } + }, + { + "name": "Python import control keyword", + "scope": "keyword.control", + "settings": { + "foreground": "#c792ea" + } + }, + { + "name": "SCSS Variable", + "scope": [ + "variable.scss", + "variable.sass", + "variable.parameter.url.scss", + "variable.parameter.url.sass" + ], + "settings": { + "foreground": "#c5e478" + } + }, + { + "name": "Variables in SASS At-Rules", + "scope": [ + "source.css.scss meta.at-rule variable", + "source.css.sass meta.at-rule variable" + ], + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "Variables in SASS At-Rules", + "scope": [ + "source.css.scss meta.at-rule variable", + "source.css.sass meta.at-rule variable" + ], + "settings": { + "foreground": "#bec5d4" + } + }, + { + "name": "Attribute Name for SASS", + "scope": [ + "meta.attribute-selector.scss entity.other.attribute-name.attribute", + "meta.attribute-selector.sass entity.other.attribute-name.attribute" + ], + "settings": { + "foreground": "#F78C6C" + } + }, + { + "name": "Tag names in SASS", + "scope": ["entity.name.tag.scss", "entity.name.tag.sass"], + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "SASS Keyword Other Unit", + "scope": ["keyword.other.unit.scss", "keyword.other.unit.sass"], + "settings": { + "foreground": "#FFEB95" + } + }, + { + "name": "TypeScript[React] Variables and Object Properties", + "scope": [ + "variable.other.readwrite.alias.ts", + "variable.other.readwrite.alias.tsx", + "variable.other.readwrite.ts", + "variable.other.readwrite.tsx", + "variable.other.object.ts", + "variable.other.object.tsx", + "variable.object.property.ts", + "variable.object.property.tsx", + "variable.other.ts", + "variable.other.tsx", + "variable.tsx", + "variable.ts" + ], + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "TypeScript[React] Entity Name Types", + "scope": ["entity.name.type.ts", "entity.name.type.tsx"], + "settings": { + "foreground": "#ffcb8b" + } + }, + { + "name": "TypeScript[React] Node Classes", + "scope": ["support.class.node.ts", "support.class.node.tsx"], + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "TypeScript[React] Entity Name Types as Parameters", + "scope": [ + "meta.type.parameters.ts entity.name.type", + "meta.type.parameters.tsx entity.name.type" + ], + "settings": { + "foreground": "#5f7e97" + } + }, + { + "name": "TypeScript[React] Import/Export Punctuations", + "scope": [ + "meta.import.ts punctuation.definition.block", + "meta.import.tsx punctuation.definition.block", + "meta.export.ts punctuation.definition.block", + "meta.export.tsx punctuation.definition.block" + ], + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "TypeScript[React] Punctuation Decorators", + "scope": [ + "meta.decorator punctuation.decorator.ts", + "meta.decorator punctuation.decorator.tsx" + ], + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "TypeScript[React] Punctuation Decorators", + "scope": "meta.tag.js meta.jsx.children.tsx", + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "YAML Entity Name Tags", + "scope": "entity.name.tag.yaml", + "settings": { + "foreground": "#7fdbca" + } + }, + { + "name": "JavaScript Variable Other ReadWrite", + "scope": ["variable.other.readwrite.js", "variable.parameter"], + "settings": { + "foreground": "#d7dbe0" + } + }, + { + "name": "Support Class Component", + "scope": ["support.class.component.js", "support.class.component.tsx"], + "settings": { + "foreground": "#f78c6c", + "fontStyle": "" + } + }, + { + "name": "Text nested in React tags", + "scope": [ + "meta.jsx.children", + "meta.jsx.children.js", + "meta.jsx.children.tsx" + ], + "settings": { + "foreground": "#d6deeb" + } + }, + { + "name": "TypeScript Classes", + "scope": "meta.class entity.name.type.class.tsx", + "settings": { + "foreground": "#ffcb8b" + } + }, + { + "name": "TypeScript Entity Name Type", + "scope": ["entity.name.type.tsx", "entity.name.type.module.tsx"], + "settings": { + "foreground": "#ffcb8b" + } + }, + { + "name": "TypeScript Class Variable Keyword", + "scope": [ + "meta.class.ts meta.var.expr.ts storage.type.ts", + "meta.class.tsx meta.var.expr.tsx storage.type.tsx" + ], + "settings": { + "foreground": "#C792EA" + } + }, + { + "name": "TypeScript Method Declaration e.g. `constructor`", + "scope": [ + "meta.method.declaration storage.type.ts", + "meta.method.declaration storage.type.tsx" + ], + "settings": { + "foreground": "#82AAFF" + } + }, + { + "name": "normalize font style of certain components", + "scope": [ + "meta.property-list.css meta.property-value.css variable.other.less", + "meta.property-list.scss variable.scss", + "meta.property-list.sass variable.sass", + "meta.brace", + "keyword.operator.operator", + "keyword.operator.or.regexp", + "keyword.operator.expression.in", + "keyword.operator.relational", + "keyword.operator.assignment", + "keyword.operator.comparison", + "keyword.operator.type", + "keyword.operator", + "keyword", + "punctuation.definintion.string", + "punctuation", + "variable.other.readwrite.js", + "storage.type", + "source.css", + "string.quoted" + ], + "settings": { + "fontStyle": "" + } + } + ] +} diff --git a/packages/starlight/integrations/expressive-code/themes/night-owl-light.jsonc b/packages/starlight/integrations/expressive-code/themes/night-owl-light.jsonc new file mode 100644 index 00000000000..f35155b686e --- /dev/null +++ b/packages/starlight/integrations/expressive-code/themes/night-owl-light.jsonc @@ -0,0 +1,1730 @@ +/** + * Night Owl VS Code Theme - https://github.com/sdras/night-owl-vscode-theme + * + * MIT License + * + * Copyright (c) 2018 Sarah Drasner + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +{ + "name": "Night Owl Light", + "type": "light", + "semanticHighlighting": false, + "colors": { + "foreground": "#403f53", + "focusBorder": "#93A1A1", + "errorForeground": "#403f53", + "selection.background": "#7a8181ad", + "descriptionForeground": "#403f53", + "widget.shadow": "#d9d9d9", + "titleBar.activeBackground": "#F0F0F0", + "notifications.background": "#F0F0F0", + "notifications.foreground": "#403f53", + "notificationLink.foreground": "#994cc3", + "notifications.border": "#CCCCCC", + "notificationCenter.border": "#CCCCCC", + "notificationToast.border": "#CCCCCC", + "notificationCenterHeader.foreground": "#403f53", + "notificationCenterHeader.background": "#F0F0F0", + "button.background": "#2AA298", + "button.foreground": "#F0F0F0", + "dropdown.background": "#F0F0F0", + "dropdown.foreground": "#403f53", + "dropdown.border": "#d9d9d9", + "input.background": "#F0F0F0", + "input.foreground": "#403f53", + "input.border": "#d9d9d9", + "input.placeholderForeground": "#93A1A1", + "inputOption.activeBorder": "#2AA298", + "inputValidation.infoBorder": "#D0D0D0", + "inputValidation.infoBackground": "#F0F0F0", + "inputValidation.warningBackground": "#daaa01", + "inputValidation.warningBorder": "#E0AF02", + "inputValidation.errorBackground": "#f76e6e", + "inputValidation.errorBorder": "#de3d3b", + "badge.background": "#2AA298", + "badge.foreground": "#F0F0F0", + "progressBar.background": "#2AA298", + "list.activeSelectionBackground": "#d3e8f8", + "list.activeSelectionForeground": "#403f53", + "list.inactiveSelectionBackground": "#E0E7EA", + "list.inactiveSelectionForeground": "#403f53", + "list.focusBackground": "#d3e8f8", + "list.hoverBackground": "#d3e8f8", + "list.focusForeground": "#403f53", + "list.hoverForeground": "#403f53", + "list.highlightForeground": "#403f53", + "list.errorForeground": "#E64D49", + "list.warningForeground": "#daaa01", + "activityBar.background": "#F0F0F0", + "activityBar.foreground": "#403f53", + "activityBar.dropBackground": "#D0D0D0", + "activityBarBadge.background": "#403f53", + "activityBarBadge.foreground": "#F0F0F0", + "activityBar.border": "#F0F0F0", + "sideBar.background": "#F0F0F0", + "sideBar.foreground": "#403f53", + "sideBarTitle.foreground": "#403f53", + "sideBar.border": "#F0F0F0", + "scrollbar.shadow": "#CCCCCC", + "tab.border": "#F0F0F0", + "tab.activeBackground": "#F6F6F6", + "tab.activeForeground": "#403f53", + "tab.inactiveForeground": "#403f53", + "tab.inactiveBackground": "#F0F0F0", + "editorGroup.border": "#F0F0F0", + "editorGroup.background": "#F6F6F6", + "editorGroupHeader.tabsBackground": "#F0F0F0", + "editorGroupHeader.tabsBorder": "#F0F0F0", + "editorGroupHeader.noTabsBackground": "#F0F0F0", + "tab.activeModifiedBorder": "#2AA298", + "tab.inactiveModifiedBorder": "#93A1A1", + "tab.unfocusedActiveModifiedBorder": "#93A1A1", + "tab.unfocusedInactiveModifiedBorder": "#93A1A1", + "editor.background": "#FBFBFB", + "editor.foreground": "#403f53", + "editorCursor.foreground": "#90A7B2", + "editorLineNumber.foreground": "#90A7B2", + "editorLineNumber.activeForeground": "#403f53", + "editor.selectionBackground": "#E0E0E0", + "editor.selectionHighlightBackground": "#339cec33", + "editor.wordHighlightBackground": "#339cec33", + "editor.wordHighlightStrongBackground": "#007dd659", + "editor.findMatchBackground": "#93A1A16c", + "editor.findMatchHighlightBackground": "#93a1a16c", + "editor.findRangeHighlightBackground": "#7497a633", + "editor.hoverHighlightBackground": "#339cec33", + "editor.lineHighlightBackground": "#F0F0F0", + "editor.rangeHighlightBackground": "#7497a633", + "editorWhitespace.foreground": "#d9d9d9", + "editorIndentGuide.background": "#d9d9d9", + "editorCodeLens.foreground": "#403f53", + "editorBracketMatch.background": "#d3e8f8", + "editorBracketMatch.border": "#2AA298", + "editorError.foreground": "#E64D49", + "editorError.border": "#FBFBFB", + "editorWarning.foreground": "#daaa01", + "editorWarning.border": "#daaa01", + "editorGutter.addedBackground": "#49d0c5", + "editorGutter.modifiedBackground": "#6fbef6", + "editorGutter.deletedBackground": "#f76e6e", + "editorRuler.foreground": "#d9d9d9", + "editorOverviewRuler.errorForeground": "#E64D49", + "editorOverviewRuler.warningForeground": "#daaa01", + "editorWidget.background": "#F0F0F0", + "editorWidget.border": "#d9d9d9", + "editorSuggestWidget.background": "#F0F0F0", + "editorSuggestWidget.foreground": "#403f53", + "editorSuggestWidget.highlightForeground": "#403f53", + "editorSuggestWidget.selectedBackground": "#d3e8f8", + "editorSuggestWidget.border": "#d9d9d9", + "editorHoverWidget.background": "#F0F0F0", + "editorHoverWidget.border": "#d9d9d9", + "debugExceptionWidget.background": "#F0F0F0", + "debugExceptionWidget.border": "#d9d9d9", + "editorMarkerNavigation.background": "#D0D0D0", + "editorMarkerNavigationError.background": "#f76e6e", + "editorMarkerNavigationWarning.background": "#daaa01", + "debugToolBar.background": "#F0F0F0", + "pickerGroup.border": "#d9d9d9", + "pickerGroup.foreground": "#403f53", + "extensionButton.prominentBackground": "#2AA298", + "extensionButton.prominentForeground": "#F0F0F0", + "statusBar.background": "#F0F0F0", + "statusBar.border": "#F0F0F0", + "statusBar.debuggingBackground": "#F0F0F0", + "statusBar.debuggingForeground": "#403f53", + "statusBar.foreground": "#403f53", + "statusBar.noFolderBackground": "#F0F0F0", + "statusBar.noFolderForeground": "#403f53", + "panel.background": "#F0F0F0", + "panel.border": "#d9d9d9", + "peekView.border": "#d9d9d9", + "peekViewEditor.background": "#F6F6F6", + "peekViewEditorGutter.background": "#F6F6F6", + "peekViewEditor.matchHighlightBackground": "#49d0c5", + "peekViewResult.background": "#F0F0F0", + "peekViewResult.fileForeground": "#403f53", + "peekViewResult.lineForeground": "#403f53", + "peekViewResult.matchHighlightBackground": "#49d0c5", + "peekViewResult.selectionBackground": "#E0E7EA", + "peekViewResult.selectionForeground": "#403f53", + "peekViewTitle.background": "#F0F0F0", + "peekViewTitleLabel.foreground": "#403f53", + "peekViewTitleDescription.foreground": "#403f53", + "terminal.ansiBrightBlack": "#403f53", + "terminal.ansiBlack": "#403f53", + "terminal.ansiBrightBlue": "#288ed7", + "terminal.ansiBlue": "#288ed7", + "terminal.ansiBrightCyan": "#2AA298", + "terminal.ansiCyan": "#2AA298", + "terminal.ansiBrightGreen": "#08916a", + "terminal.ansiGreen": "#08916a", + "terminal.ansiBrightMagenta": "#d6438a", + "terminal.ansiMagenta": "#d6438a", + "terminal.ansiBrightRed": "#de3d3b", + "terminal.ansiRed": "#de3d3b", + "terminal.ansiBrightWhite": "#F0F0F0", + "terminal.ansiWhite": "#F0F0F0", + "terminal.ansiBrightYellow": "#daaa01", + "terminal.ansiYellow": "#E0AF02", + "terminal.background": "#F6F6F6", + "terminal.foreground": "#403f53" + }, + "tokenColors": [ + { + "name": "Changed", + "scope": [ + "markup.changed", + "meta.diff.header.git", + "meta.diff.header.from-file", + "meta.diff.header.to-file" + ], + "settings": { + "foreground": "#a2bffc" + } + }, + { + "name": "Deleted", + "scope": "markup.deleted.diff", + "settings": { + "foreground": "#EF535090" + } + }, + { + "name": "Inserted", + "scope": "markup.inserted.diff", + "settings": { + "foreground": "#4876d6ff" + } + }, + { + "name": "Global settings", + "settings": { + "background": "#011627", + "foreground": "#403f53" + } + }, + { + "name": "Comment", + "scope": "comment", + "settings": { + "foreground": "#989fb1" + } + }, + { + "name": "String", + "scope": "string", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "String Quoted", + "scope": ["string.quoted", "variable.other.readwrite.js"], + "settings": { + "foreground": "#c96765" + } + }, + { + "name": "Support Constant Math", + "scope": "support.constant.math", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Number", + "scope": ["constant.numeric", "constant.character.numeric"], + "settings": { + "foreground": "#aa0982", + "fontStyle": "" + } + }, + { + "name": "Built-in constant", + "scope": [ + "constant.language", + "punctuation.definition.constant", + "variable.other.constant" + ], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "User-defined constant", + "scope": ["constant.character", "constant.other"], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Constant Character Escape", + "scope": "constant.character.escape", + "settings": { + "foreground": "#aa0982" + } + }, + { + "name": "RegExp String", + "scope": ["string.regexp", "string.regexp keyword.other"], + "settings": { + "foreground": "#5ca7e4" + } + }, + { + "name": "Comma in functions", + "scope": "meta.function punctuation.separator.comma", + "settings": { + "foreground": "#5f7e97" + } + }, + { + "name": "Variable", + "scope": "variable", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Keyword", + "scope": ["punctuation.accessor", "keyword"], + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Storage", + "scope": [ + "storage", + "meta.var.expr", + "meta.class meta.method.declaration meta.var.expr storage.type.js", + "storage.type.property.js", + "storage.type.property.ts", + "storage.type.property.tsx" + ], + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Storage type", + "scope": "storage.type", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Storage type", + "scope": "storage.type.function.arrow.js", + "settings": { + "fontStyle": "" + } + }, + { + "name": "Class name", + "scope": ["entity.name.class", "meta.class entity.name.type.class"], + "settings": { + "foreground": "#111111" + } + }, + { + "name": "Inherited class", + "scope": "entity.other.inherited-class", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Function name", + "scope": "entity.name.function", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Meta Tag", + "scope": ["punctuation.definition.tag", "meta.tag"], + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "HTML Tag names", + "scope": [ + "entity.name.tag", + "meta.tag.other.html", + "meta.tag.other.js", + "meta.tag.other.tsx", + "entity.name.tag.tsx", + "entity.name.tag.js", + "entity.name.tag", + "meta.tag.js", + "meta.tag.tsx", + "meta.tag.html" + ], + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Tag attribute", + "scope": "entity.other.attribute-name", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Entity Name Tag Custom", + "scope": "entity.name.tag.custom", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Library (function & constant)", + "scope": ["support.function", "support.constant"], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Support Constant Property Value meta", + "scope": "support.constant.meta.property-value", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Library class/type", + "scope": ["support.type", "support.class"], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Support Variable DOM", + "scope": "support.variable.dom", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Invalid", + "scope": "invalid", + "settings": { + "foreground": "#ff2c83" + } + }, + { + "name": "Invalid deprecated", + "scope": "invalid.deprecated", + "settings": { + "foreground": "#d3423e" + } + }, + { + "name": "Keyword Operator", + "scope": "keyword.operator", + "settings": { + "foreground": "#0c969b", + "fontStyle": "" + } + }, + { + "name": "Keyword Operator Relational", + "scope": "keyword.operator.relational", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Keyword Operator Assignment", + "scope": "keyword.operator.assignment", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Keyword Operator Arithmetic", + "scope": "keyword.operator.arithmetic", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Keyword Operator Bitwise", + "scope": "keyword.operator.bitwise", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Keyword Operator Increment", + "scope": "keyword.operator.increment", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Keyword Operator Ternary", + "scope": "keyword.operator.ternary", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Double-Slashed Comment", + "scope": "comment.line.double-slash", + "settings": { + "foreground": "#939dbb" + } + }, + { + "name": "Object", + "scope": "object", + "settings": { + "foreground": "#cdebf7" + } + }, + { + "name": "Null", + "scope": "constant.language.null", + "settings": { + "foreground": "#bc5454" + } + }, + { + "name": "Meta Brace", + "scope": "meta.brace", + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "Meta Delimiter Period", + "scope": "meta.delimiter.period", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Punctuation Definition String", + "scope": "punctuation.definition.string", + "settings": { + "foreground": "#111111" + } + }, + { + "name": "Punctuation Definition String Markdown", + "scope": "punctuation.definition.string.begin.markdown", + "settings": { + "foreground": "#bc5454" + } + }, + { + "name": "Boolean", + "scope": "constant.language.boolean", + "settings": { + "foreground": "#bc5454" + } + }, + { + "name": "Object Comma", + "scope": "object.comma", + "settings": { + "foreground": "#ffffff" + } + }, + { + "name": "Variable Parameter Function", + "scope": "variable.parameter.function", + "settings": { + "foreground": "#0c969b", + "fontStyle": "" + } + }, + { + "name": "Support Type Property Name & entity name tags", + "scope": [ + "support.type.vendor.property-name", + "support.constant.vendor.property-value", + "support.type.property-name", + "meta.property-list entity.name.tag" + ], + "settings": { + "foreground": "#0c969b", + "fontStyle": "" + } + }, + { + "name": "Entity Name tag reference in stylesheets", + "scope": "meta.property-list entity.name.tag.reference", + "settings": { + "foreground": "#57eaf1" + } + }, + { + "name": "Constant Other Color RGB Value Punctuation Definition Constant", + "scope": "constant.other.color.rgb-value punctuation.definition.constant", + "settings": { + "foreground": "#aa0982" + } + }, + { + "name": "Constant Other Color", + "scope": "constant.other.color", + "settings": { + "foreground": "#aa0982" + } + }, + { + "name": "Keyword Other Unit", + "scope": "keyword.other.unit", + "settings": { + "foreground": "#aa0982" + } + }, + { + "name": "Meta Selector", + "scope": "meta.selector", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Entity Other Attribute Name Id", + "scope": "entity.other.attribute-name.id", + "settings": { + "foreground": "#aa0982" + } + }, + { + "name": "Meta Property Name", + "scope": "meta.property-name", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Doctypes", + "scope": ["entity.name.tag.doctype", "meta.tag.sgml.doctype"], + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Punctuation Definition Parameters", + "scope": "punctuation.definition.parameters", + "settings": { + "foreground": "#111111" + } + }, + { + "name": "Keyword Control Operator", + "scope": "keyword.control.operator", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Keyword Operator Logical", + "scope": "keyword.operator.logical", + "settings": { + "foreground": "#994cc3", + "fontStyle": "" + } + }, + { + "name": "Variable Instances", + "scope": [ + "variable.instance", + "variable.other.instance", + "variable.readwrite.instance", + "variable.other.readwrite.instance", + "variable.other.property" + ], + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Variable Property Other object property", + "scope": ["variable.other.object.property"], + "settings": { + "foreground": "#111111" + } + }, + { + "name": "Variable Property Other object", + "scope": ["variable.other.object.js"], + "settings": { + "fontStyle": "" + } + }, + { + "name": "Entity Name Function", + "scope": ["entity.name.function"], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Keyword Operator Comparison, imports, returns and Keyword Operator Ruby", + "scope": [ + "keyword.operator.comparison", + "keyword.control.flow.js", + "keyword.control.flow.ts", + "keyword.control.flow.tsx", + "keyword.control.ruby", + "keyword.control.module.ruby", + "keyword.control.class.ruby", + "keyword.control.def.ruby", + "keyword.control.loop.js", + "keyword.control.loop.ts", + "keyword.control.import.js", + "keyword.control.import.ts", + "keyword.control.import.tsx", + "keyword.control.from.js", + "keyword.control.from.ts", + "keyword.control.from.tsx", + "keyword.operator.instanceof.js", + "keyword.operator.expression.instanceof.ts", + "keyword.operator.expression.instanceof.tsx" + ], + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Keyword Control Conditional", + "scope": [ + "keyword.control.conditional.js", + "keyword.control.conditional.ts", + "keyword.control.switch.js", + "keyword.control.switch.ts" + ], + "settings": { + "foreground": "#994cc3", + "fontStyle": "" + } + }, + { + "name": "Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords", + "scope": [ + "support.constant", + "keyword.other.special-method", + "keyword.other.new", + "keyword.other.debugger", + "keyword.control" + ], + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Support Function", + "scope": "support.function", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Invalid Broken", + "scope": "invalid.broken", + "settings": { + "foreground": "#aa0982" + } + }, + { + "name": "Invalid Unimplemented", + "scope": "invalid.unimplemented", + "settings": { + "foreground": "#8BD649" + } + }, + { + "name": "Invalid Illegal", + "scope": "invalid.illegal", + "settings": { + "foreground": "#c96765" + } + }, + { + "name": "Language Variable", + "scope": "variable.language", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Support Variable Property", + "scope": "support.variable.property", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Variable Function", + "scope": "variable.function", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Variable Interpolation", + "scope": "variable.interpolation", + "settings": { + "foreground": "#ec5f67" + } + }, + { + "name": "Meta Function Call", + "scope": "meta.function-call", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Punctuation Section Embedded", + "scope": "punctuation.section.embedded", + "settings": { + "foreground": "#d3423e" + } + }, + { + "name": "Punctuation Tweaks", + "scope": [ + "punctuation.terminator.expression", + "punctuation.definition.arguments", + "punctuation.definition.array", + "punctuation.section.array", + "meta.array" + ], + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "More Punctuation Tweaks", + "scope": [ + "punctuation.definition.list.begin", + "punctuation.definition.list.end", + "punctuation.separator.arguments", + "punctuation.definition.list" + ], + "settings": { + "foreground": "#111111" + } + }, + { + "name": "Template Strings", + "scope": "string.template meta.template.expression", + "settings": { + "foreground": "#d3423e" + } + }, + { + "name": "Backtics(``) in Template Strings", + "scope": "string.template punctuation.definition.string", + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "Italics", + "scope": "italic", + "settings": { + "foreground": "#994cc3", + "fontStyle": "italic" + } + }, + { + "name": "Bold", + "scope": "bold", + "settings": { + "foreground": "#4876d6", + "fontStyle": "bold" + } + }, + { + "name": "Quote", + "scope": "quote", + "settings": { + "foreground": "#697098" + } + }, + { + "name": "Raw Code", + "scope": "raw", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "CoffeScript Variable Assignment", + "scope": "variable.assignment.coffee", + "settings": { + "foreground": "#31e1eb" + } + }, + { + "name": "CoffeScript Parameter Function", + "scope": "variable.parameter.function.coffee", + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "CoffeeScript Assignments", + "scope": "variable.assignment.coffee", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "C# Readwrite Variables", + "scope": "variable.other.readwrite.cs", + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "C# Classes & Storage types", + "scope": ["entity.name.type.class.cs", "storage.type.cs"], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "C# Namespaces", + "scope": "entity.name.type.namespace.cs", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Tag names in Stylesheets", + "scope": [ + "entity.name.tag.css", + "entity.name.tag.less", + "entity.name.tag.custom.css", + "support.constant.property-value.css" + ], + "settings": { + "foreground": "#c96765", + "fontStyle": "" + } + }, + { + "name": "Wildcard(*) selector in Stylesheets", + "scope": [ + "entity.name.tag.wildcard.css", + "entity.name.tag.wildcard.less", + "entity.name.tag.wildcard.scss", + "entity.name.tag.wildcard.sass" + ], + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "CSS Keyword Other Unit", + "scope": "keyword.other.unit.css", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Attribute Name for CSS", + "scope": [ + "meta.attribute-selector.css entity.other.attribute-name.attribute", + "variable.other.readwrite.js" + ], + "settings": { + "foreground": "#aa0982" + } + }, + { + "name": "Elixir Classes", + "scope": [ + "source.elixir support.type.elixir", + "source.elixir meta.module.elixir entity.name.class.elixir" + ], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Elixir Functions", + "scope": "source.elixir entity.name.function", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Elixir Constants", + "scope": [ + "source.elixir constant.other.symbol.elixir", + "source.elixir constant.other.keywords.elixir" + ], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Elixir String Punctuations", + "scope": "source.elixir punctuation.definition.string", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Elixir", + "scope": [ + "source.elixir variable.other.readwrite.module.elixir", + "source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir" + ], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Elixir Binary Punctuations", + "scope": "source.elixir .punctuation.binary.elixir", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Closure Constant Keyword", + "scope": "constant.keyword.clojure", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Go Function Calls", + "scope": "source.go meta.function-call.go", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Go Keywords", + "scope": [ + "source.go keyword.package.go", + "source.go keyword.import.go", + "source.go keyword.function.go", + "source.go keyword.type.go", + "source.go keyword.struct.go", + "source.go keyword.interface.go", + "source.go keyword.const.go", + "source.go keyword.var.go", + "source.go keyword.map.go", + "source.go keyword.channel.go", + "source.go keyword.control.go" + ], + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "Go Constants e.g. nil, string format (%s, %d, etc.)", + "scope": [ + "source.go constant.language.go", + "source.go constant.other.placeholder.go" + ], + "settings": { + "foreground": "#bc5454" + } + }, + { + "name": "C++ Functions", + "scope": [ + "entity.name.function.preprocessor.cpp", + "entity.scope.name.cpp" + ], + "settings": { + "foreground": "#0c969bff" + } + }, + { + "name": "C++ Meta Namespace", + "scope": ["meta.namespace-block.cpp"], + "settings": { + "foreground": "#111111" + } + }, + { + "name": "C++ Language Primitive Storage", + "scope": ["storage.type.language.primitive.cpp"], + "settings": { + "foreground": "#bc5454" + } + }, + { + "name": "C++ Preprocessor Macro", + "scope": ["meta.preprocessor.macro.cpp"], + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "C++ Variable Parameter", + "scope": ["variable.parameter"], + "settings": { + "foreground": "#111111" + } + }, + { + "name": "Powershell Variables", + "scope": ["variable.other.readwrite.powershell"], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Powershell Function", + "scope": ["support.function.powershell"], + "settings": { + "foreground": "#0c969bff" + } + }, + { + "name": "ID Attribute Name in HTML", + "scope": "entity.other.attribute-name.id.html", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "HTML Punctuation Definition Tag", + "scope": "punctuation.definition.tag.html", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "HTML Doctype", + "scope": "meta.tag.sgml.doctype.html", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "JavaScript Classes", + "scope": "meta.class entity.name.type.class.js", + "settings": { + "foreground": "#111111" + } + }, + { + "name": "JavaScript Method Declaration e.g. `constructor`", + "scope": "meta.method.declaration storage.type.js", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "JavaScript Terminator", + "scope": "terminator.js", + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "JavaScript Meta Punctuation Definition", + "scope": "meta.js punctuation.definition.js", + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "Entity Names in Code Documentations", + "scope": [ + "entity.name.type.instance.jsdoc", + "entity.name.type.instance.phpdoc" + ], + "settings": { + "foreground": "#5f7e97" + } + }, + { + "name": "Other Variables in Code Documentations", + "scope": ["variable.other.jsdoc", "variable.other.phpdoc"], + "settings": { + "foreground": "#78ccf0" + } + }, + { + "name": "JavaScript module imports and exports", + "scope": [ + "variable.other.meta.import.js", + "meta.import.js variable.other", + "variable.other.meta.export.js", + "meta.export.js variable.other" + ], + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "JavaScript Variable Parameter Function", + "scope": "variable.parameter.function.js", + "settings": { + "foreground": "#7986E7" + } + }, + { + "name": "JavaScript[React] Variable Other Object", + "scope": [ + "variable.other.object.js", + "variable.other.object.jsx", + "variable.object.property.js", + "variable.object.property.jsx" + ], + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "JavaScript Variables", + "scope": ["variable.js", "variable.other.js"], + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "JavaScript Entity Name Type", + "scope": ["entity.name.type.js", "entity.name.type.module.js"], + "settings": { + "foreground": "#111111", + "fontStyle": "" + } + }, + { + "name": "JavaScript Support Classes", + "scope": "support.class.js", + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "JSON Property Names", + "scope": "support.type.property-name.json", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "JSON Support Constants", + "scope": "support.constant.json", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "JSON Property values (string)", + "scope": "meta.structure.dictionary.value.json string.quoted.double", + "settings": { + "foreground": "#c789d6" + } + }, + { + "name": "Strings in JSON values", + "scope": "string.quoted.double.json punctuation.definition.string.json", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Specific JSON Property values like null", + "scope": "meta.structure.dictionary.json meta.structure.dictionary.value constant.language", + "settings": { + "foreground": "#bc5454" + } + }, + { + "name": "JavaScript Other Variable", + "scope": "variable.other.object.js", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Ruby Variables", + "scope": ["variable.other.ruby"], + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "Ruby Class", + "scope": ["entity.name.type.class.ruby"], + "settings": { + "foreground": "#c96765" + } + }, + { + "name": "Ruby Hashkeys", + "scope": "constant.language.symbol.hashkey.ruby", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Ruby Symbols", + "scope": "constant.language.symbol.ruby", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "LESS Tag names", + "scope": "entity.name.tag.less", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "LESS Keyword Other Unit", + "scope": "keyword.other.unit.css", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Attribute Name for LESS", + "scope": "meta.attribute-selector.less entity.other.attribute-name.attribute", + "settings": { + "foreground": "#aa0982" + } + }, + { + "name": "Markdown Headings", + "scope": [ + "markup.heading.markdown", + "markup.heading.setext.1.markdown", + "markup.heading.setext.2.markdown" + ], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Markdown Italics", + "scope": "markup.italic.markdown", + "settings": { + "foreground": "#994cc3", + "fontStyle": "italic" + } + }, + { + "name": "Markdown Bold", + "scope": "markup.bold.markdown", + "settings": { + "foreground": "#4876d6", + "fontStyle": "bold" + } + }, + { + "name": "Markdown Quote + others", + "scope": "markup.quote.markdown", + "settings": { + "foreground": "#697098" + } + }, + { + "name": "Markdown Raw Code + others", + "scope": "markup.inline.raw.markdown", + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Markdown Links", + "scope": [ + "markup.underline.link.markdown", + "markup.underline.link.image.markdown" + ], + "settings": { + "foreground": "#ff869a" + } + }, + { + "name": "Markdown Link Title and Description", + "scope": [ + "string.other.link.title.markdown", + "string.other.link.description.markdown" + ], + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "Markdown Punctuation", + "scope": [ + "punctuation.definition.string.markdown", + "punctuation.definition.string.begin.markdown", + "punctuation.definition.string.end.markdown", + "meta.link.inline.markdown punctuation.definition.string" + ], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Markdown MetaData Punctuation", + "scope": ["punctuation.definition.metadata.markdown"], + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Markdown List Punctuation", + "scope": ["beginning.punctuation.definition.list.markdown"], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Markdown Inline Raw String", + "scope": "markup.inline.raw.string.markdown", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "PHP Variables", + "scope": ["variable.other.php", "variable.other.property.php"], + "settings": { + "foreground": "#111111" + } + }, + { + "name": "Support Classes in PHP", + "scope": "support.class.php", + "settings": { + "foreground": "#111111" + } + }, + { + "name": "Punctuations in PHP function calls", + "scope": "meta.function-call.php punctuation", + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "PHP Global Variables", + "scope": "variable.other.global.php", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Declaration Punctuation in PHP Global Variables", + "scope": "variable.other.global.php punctuation.definition.variable", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Language Constants in Python", + "scope": "constant.language.python", + "settings": { + "foreground": "#bc5454" + } + }, + { + "name": "Python Function Parameter and Arguments", + "scope": [ + "variable.parameter.function.python", + "meta.function-call.arguments.python" + ], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Python Function Call", + "scope": [ + "meta.function-call.python", + "meta.function-call.generic.python" + ], + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "Punctuations in Python", + "scope": "punctuation.python", + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "Decorator Functions in Python", + "scope": "entity.name.function.decorator.python", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Python Language Variable", + "scope": "source.python variable.language.special", + "settings": { + "foreground": "#aa0982" + } + }, + { + "name": "Python import control keyword", + "scope": "keyword.control", + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "SCSS Variable", + "scope": [ + "variable.scss", + "variable.sass", + "variable.parameter.url.scss", + "variable.parameter.url.sass" + ], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Variables in SASS At-Rules", + "scope": [ + "source.css.scss meta.at-rule variable", + "source.css.sass meta.at-rule variable" + ], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "Variables in SASS At-Rules", + "scope": [ + "source.css.scss meta.at-rule variable", + "source.css.sass meta.at-rule variable" + ], + "settings": { + "foreground": "#111111" + } + }, + { + "name": "Attribute Name for SASS", + "scope": [ + "meta.attribute-selector.scss entity.other.attribute-name.attribute", + "meta.attribute-selector.sass entity.other.attribute-name.attribute" + ], + "settings": { + "foreground": "#aa0982" + } + }, + { + "name": "Tag names in SASS", + "scope": ["entity.name.tag.scss", "entity.name.tag.sass"], + "settings": { + "foreground": "#0c969b" + } + }, + { + "name": "SASS Keyword Other Unit", + "scope": ["keyword.other.unit.scss", "keyword.other.unit.sass"], + "settings": { + "foreground": "#994cc3" + } + }, + { + "name": "TypeScript[React] Variables and Object Properties", + "scope": [ + "variable.other.readwrite.alias.ts", + "variable.other.readwrite.alias.tsx", + "variable.other.readwrite.ts", + "variable.other.readwrite.tsx", + "variable.other.object.ts", + "variable.other.object.tsx", + "variable.object.property.ts", + "variable.object.property.tsx", + "variable.other.ts", + "variable.other.tsx", + "variable.tsx", + "variable.ts" + ], + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "TypeScript[React] Entity Name Types", + "scope": ["entity.name.type.ts", "entity.name.type.tsx"], + "settings": { + "foreground": "#111111" + } + }, + { + "name": "TypeScript[React] Node Classes", + "scope": ["support.class.node.ts", "support.class.node.tsx"], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "TypeScript[React] Entity Name Types as Parameters", + "scope": [ + "meta.type.parameters.ts entity.name.type", + "meta.type.parameters.tsx entity.name.type" + ], + "settings": { + "foreground": "#5f7e97" + } + }, + { + "name": "TypeScript[React] Import/Export Punctuations", + "scope": [ + "meta.import.ts punctuation.definition.block", + "meta.import.tsx punctuation.definition.block", + "meta.export.ts punctuation.definition.block", + "meta.export.tsx punctuation.definition.block" + ], + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "TypeScript[React] Punctuation Decorators", + "scope": [ + "meta.decorator punctuation.decorator.ts", + "meta.decorator punctuation.decorator.tsx" + ], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "TypeScript[React] Punctuation Decorators", + "scope": "meta.tag.js meta.jsx.children.tsx", + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "YAML Entity Name Tags", + "scope": "entity.name.tag.yaml", + "settings": { + "foreground": "#111111" + } + }, + { + "name": "JavaScript Variable Other ReadWrite", + "scope": ["variable.other.readwrite.js", "variable.parameter"], + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "Support Class Component", + "scope": ["support.class.component.js", "support.class.component.tsx"], + "settings": { + "foreground": "#aa0982", + "fontStyle": "" + } + }, + { + "name": "Text nested in React tags", + "scope": [ + "meta.jsx.children", + "meta.jsx.children.js", + "meta.jsx.children.tsx" + ], + "settings": { + "foreground": "#403f53" + } + }, + { + "name": "TypeScript Classes", + "scope": "meta.class entity.name.type.class.tsx", + "settings": { + "foreground": "#111111" + } + }, + { + "name": "TypeScript Entity Name Type", + "scope": ["entity.name.type.tsx", "entity.name.type.module.tsx"], + "settings": { + "foreground": "#111111" + } + }, + { + "name": "TypeScript Class Variable Keyword", + "scope": [ + "meta.class.ts meta.var.expr.ts storage.type.ts", + "meta.class.tsx meta.var.expr.tsx storage.type.tsx" + ], + "settings": { + "foreground": "#C792EA" + } + }, + { + "name": "TypeScript Method Declaration e.g. `constructor`", + "scope": [ + "meta.method.declaration storage.type.ts", + "meta.method.declaration storage.type.tsx" + ], + "settings": { + "foreground": "#4876d6" + } + }, + { + "name": "normalize font style of certain components", + "scope": [ + "meta.property-list.css meta.property-value.css variable.other.less", + "meta.property-list.scss variable.scss", + "meta.property-list.sass variable.sass", + "meta.brace", + "keyword.operator.operator", + "keyword.operator.or.regexp", + "keyword.operator.expression.in", + "keyword.operator.relational", + "keyword.operator.assignment", + "keyword.operator.comparison", + "keyword.operator.type", + "keyword.operator", + "keyword", + "punctuation.definintion.string", + "punctuation", + "variable.other.readwrite.js", + "storage.type", + "source.css", + "string.quoted" + ], + "settings": { + "fontStyle": "" + } + } + ] +} diff --git a/packages/starlight/integrations/expressive-code/theming.ts b/packages/starlight/integrations/expressive-code/theming.ts new file mode 100644 index 00000000000..d132afb266f --- /dev/null +++ b/packages/starlight/integrations/expressive-code/theming.ts @@ -0,0 +1,109 @@ +import fs from 'node:fs'; +import { + ExpressiveCodeTheme, + type ThemeObjectOrShikiThemeName, +} from 'astro-expressive-code'; + +export type BundledThemeName = 'starlight-dark' | 'starlight-light'; + +export type ThemeObjectOrBundledThemeName = ThemeObjectOrShikiThemeName | BundledThemeName; + +/** + * Converts the Starlight `themes` config option into a format understood by Expressive Code, + * loading any bundled themes and using the Starlight defaults if no themes were provided. + */ +export function preprocessThemes( + themes: ThemeObjectOrBundledThemeName[] | undefined +): ThemeObjectOrShikiThemeName[] { + // Try to gracefully handle cases where the user forgot to use an array in the config + themes = themes && !Array.isArray(themes) ? [themes] : themes; + // If no themes were provided, use our bundled default themes + if (!themes || !themes.length) themes = ['starlight-dark', 'starlight-light']; + + return themes.map((theme) => { + // If the current entry is the name of a bundled theme, load it + if (theme === 'starlight-dark' || theme === 'starlight-light') { + const bundledThemeFile = + theme === 'starlight-dark' ? 'night-owl-dark.jsonc' : 'night-owl-light.jsonc'; + return customizeBundledTheme(ExpressiveCodeTheme.fromJSONString( + fs.readFileSync(new URL(`./themes/${bundledThemeFile}`, import.meta.url), 'utf-8') + )); + } + // Otherwise, just pass it through + return theme; + }); +} + +/** + * Customizes some settings of the bundled theme to make it fit better with Starlight. + */ +function customizeBundledTheme(theme: ExpressiveCodeTheme) { + theme.colors['titleBar.border'] = theme.colors['tab.activeBackground']; + theme.colors['editorGroupHeader.tabsBorder'] = theme.colors['tab.activeBackground']; + + // Add underline font style to link syntax highlighting tokens + // to match the new GitHub theme link style + theme.settings.forEach((s) => { + if (s.name?.includes('Link')) s.settings.fontStyle = 'underline'; + }); + + return theme; +} + +/** + * Modifies the given theme by applying Starlight's CSS variables to the colors of UI elements + * (backgrounds, buttons, shadows etc.). This ensures that code blocks match the site's theme. + */ +export function applyStarlightUiThemeColors(theme: ExpressiveCodeTheme) { + const isDark = theme.type === 'dark'; + const neutralMinimal = isDark ? '#ffffff17' : '#0000001a'; + const neutralDimmed = isDark ? '#ffffff40' : '#00000055'; + + // Make borders slightly transparent + const borderColor = 'color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)'; + theme.colors['titleBar.border'] = borderColor; + theme.colors['editorGroupHeader.tabsBorder'] = borderColor; + + // Use the same color for terminal title bar background and editor tab bar background + const backgroundColor = isDark ? 'var(--sl-color-black)' : 'var(--sl-color-gray-6)'; + theme.colors['titleBar.activeBackground'] = backgroundColor; + theme.colors['editorGroupHeader.tabsBackground'] = backgroundColor; + + // Use the same color for terminal titles and tab titles + theme.colors['titleBar.activeForeground'] = 'var(--sl-color-text)'; + theme.colors['tab.activeForeground'] = 'var(--sl-color-text)'; + + // Set tab border colors + const activeBorderColor = isDark ? 'var(--sl-color-accent-high)' : 'var(--sl-color-accent)'; + theme.colors['tab.activeBorder'] = 'transparent'; + theme.colors['tab.activeBorderTop'] = activeBorderColor; + + // Use neutral colors for scrollbars + theme.colors['scrollbarSlider.background'] = neutralMinimal; + theme.colors['scrollbarSlider.hoverBackground'] = neutralDimmed; + + // Set theme `bg` color property for contrast calculations + theme.bg = isDark ? '#23262f' : '#f6f7f9'; + // Set actual background color to the appropriate Starlight CSS variable + const editorBackgroundColor = isDark ? 'var(--sl-color-gray-6)' : 'var(--sl-color-gray-7)'; + + theme.styleOverrides.frames = { + // Use the same color for editor background, terminal background and active tab background + editorBackground: editorBackgroundColor, + terminalBackground: editorBackgroundColor, + editorActiveTabBackground: editorBackgroundColor, + terminalTitlebarDotsForeground: borderColor, + terminalTitlebarDotsOpacity: '0.75', + inlineButtonForeground: 'var(--sl-color-text)', + frameBoxShadowCssValue: 'none', + }; + + // Use neutral, semi-transparent colors for default text markers + // to avoid conflicts with the user's chosen background color + theme.styleOverrides.textMarkers = { + markBackground: neutralMinimal, + markBorderColor: neutralDimmed, + }; + + return theme; +} diff --git a/packages/starlight/integrations/expressive-code/translations.ts b/packages/starlight/integrations/expressive-code/translations.ts new file mode 100644 index 00000000000..1ff1c286931 --- /dev/null +++ b/packages/starlight/integrations/expressive-code/translations.ts @@ -0,0 +1,26 @@ +import { pluginFramesTexts } from 'astro-expressive-code'; +import type { StarlightConfig } from '../../types'; +import type { createTranslationSystemFromFs } from '../../utils/translations-fs'; + +export function addTranslations( + locales: StarlightConfig['locales'], + useTranslations: ReturnType +) { + for (const locale in locales) { + const lang = locales[locale]?.lang; + if (!lang) continue; + + const t = useTranslations(locale); + const translationKeys = [ + 'expressiveCode.copyButtonCopied', + 'expressiveCode.copyButtonTooltip', + 'expressiveCode.terminalWindowFallbackTitle', + ] as const; + translationKeys.forEach((key) => { + const translation = t(key); + if (!translation) return; + const ecId = key.replace(/^expressiveCode\./, ''); + pluginFramesTexts.overrideTexts(lang, { [ecId]: translation }); + }); + } +} diff --git a/packages/starlight/integrations/shared/pathToLocale.ts b/packages/starlight/integrations/shared/pathToLocale.ts new file mode 100644 index 00000000000..34673891d02 --- /dev/null +++ b/packages/starlight/integrations/shared/pathToLocale.ts @@ -0,0 +1,32 @@ +import type { StarlightConfig } from '../../types'; + +function slugToLocale( + slug: string | undefined, + localesConfig: StarlightConfig['locales'] +): string | undefined { + const locales = Object.keys(localesConfig || {}); + const baseSegment = slug?.split('/')[0]; + return baseSegment && locales.includes(baseSegment) ? baseSegment : undefined; +} + +/** Get current locale from the full file path. */ +export function pathToLocale( + path: string | undefined, + { + starlightConfig, + astroConfig, + }: { + starlightConfig: { locales: StarlightConfig['locales'] }; + astroConfig: { root: URL; srcDir: URL }; + } +): string | undefined { + const srcDir = new URL(astroConfig.srcDir, astroConfig.root); + const docsDir = new URL('content/docs/', srcDir); + const slug = path + // Format path to unix style path. + ?.replace(/\\/g, '/') + // Strip docs path leaving only content collection file ID. + // Example: /Users/houston/repo/src/content/docs/en/guide.md => en/guide.md + .replace(docsDir.pathname, ''); + return slugToLocale(slug, starlightConfig.locales); +} diff --git a/packages/starlight/package.json b/packages/starlight/package.json index 3ff8403eaf0..4ad3c2007c1 100644 --- a/packages/starlight/package.json +++ b/packages/starlight/package.json @@ -157,6 +157,7 @@ "./props": "./props.ts", "./schema": "./schema.ts", "./types": "./types.ts", + "./expressive-code": "./integrations/expressive-code/exports.ts", "./index.astro": "./index.astro", "./404.astro": "./404.astro", "./style/markdown.css": "./style/markdown.css" @@ -176,6 +177,7 @@ "@astrojs/sitemap": "^3.0.0", "@pagefind/default-ui": "^1.0.3", "@types/mdast": "^3.0.11", + "astro-expressive-code": "^0.29.0", "bcp-47": "^2.1.0", "execa": "^8.0.1", "hast-util-select": "^5.0.5", diff --git a/packages/starlight/schemas/expressiveCode.ts b/packages/starlight/schemas/expressiveCode.ts new file mode 100644 index 00000000000..fc4490a9aa3 --- /dev/null +++ b/packages/starlight/schemas/expressiveCode.ts @@ -0,0 +1,11 @@ +import { z } from 'astro/zod'; +import type { StarlightExpressiveCodeOptions } from '../integrations/expressive-code'; + +export const ExpressiveCodeSchema = () => + z + .union([ + z.custom((value) => typeof value === 'object' && value), + z.boolean(), + ]) + .describe('Define how code blocks are rendered by passing options to Expressive Code, or disable the integration by passing `false`.') + .optional(); diff --git a/packages/starlight/schemas/i18n.ts b/packages/starlight/schemas/i18n.ts index d1cd39750b8..0cf6496cf93 100644 --- a/packages/starlight/schemas/i18n.ts +++ b/packages/starlight/schemas/i18n.ts @@ -1,12 +1,16 @@ import { z } from 'astro/zod'; export function i18nSchema() { - return starlightI18nSchema().merge(pagefindI18nSchema()); + return starlightI18nSchema().merge(pagefindI18nSchema()).merge(expressiveCodeI18nSchema()); } export type i18nSchemaOutput = z.output>; export function builtinI18nSchema() { - return starlightI18nSchema().required().strict().merge(pagefindI18nSchema()); + return starlightI18nSchema() + .required() + .strict() + .merge(pagefindI18nSchema()) + .merge(expressiveCodeI18nSchema()); } function starlightI18nSchema() { @@ -162,3 +166,21 @@ function pagefindI18nSchema() { }) .partial(); } + +function expressiveCodeI18nSchema() { + return z + .object({ + 'expressiveCode.copyButtonCopied': z + .string() + .describe('Expressive Code UI translation. English default value: `"Copied!"`'), + + 'expressiveCode.copyButtonTooltip': z + .string() + .describe('Expressive Code UI translation. English default value: `"Copy to clipboard"`'), + + 'expressiveCode.terminalWindowFallbackTitle': z + .string() + .describe('Expressive Code UI translation. English default value: `"Terminal window"`'), + }) + .partial(); +} diff --git a/packages/starlight/utils/user-config.ts b/packages/starlight/utils/user-config.ts index ad1afdcd92a..a026c216e79 100644 --- a/packages/starlight/utils/user-config.ts +++ b/packages/starlight/utils/user-config.ts @@ -1,6 +1,7 @@ import { z } from 'astro/zod'; import { parse as bcpParse, stringify as bcpStringify } from 'bcp-47'; import { ComponentConfigSchema } from '../schemas/components'; +import { ExpressiveCodeSchema } from '../schemas/expressiveCode'; import { FaviconSchema } from '../schemas/favicon'; import { HeadConfigSchema } from '../schemas/head'; import { LogoConfigSchema } from '../schemas/logo'; @@ -183,6 +184,12 @@ const UserConfigSchema = z.object({ /** The default favicon for your site which should be a path to an image in the `public/` directory. */ favicon: FaviconSchema(), + /** + * Define how code blocks are rendered by passing options to Expressive Code, + * or disable the integration by passing `false`. + */ + expressiveCode: ExpressiveCodeSchema(), + /** Specify paths to components that should override Starlight’s default components */ components: ComponentConfigSchema(), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9946589d184..b712ee18075 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -147,6 +147,9 @@ importers: '@types/mdast': specifier: ^3.0.11 version: 3.0.11 + astro-expressive-code: + specifier: ^0.29.0 + version: 0.29.0(astro@3.2.3) bcp-47: specifier: ^2.1.0 version: 2.1.0 @@ -774,6 +777,11 @@ packages: prettier: 2.8.8 dev: true + /@ctrl/tinycolor@3.6.1: + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} + engines: {node: '>=10'} + dev: false + /@esbuild/android-arm64@0.18.17: resolution: {integrity: sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==} engines: {node: '>=12'} @@ -1144,6 +1152,38 @@ packages: requiresBuild: true optional: true + /@expressive-code/core@0.29.0: + resolution: {integrity: sha512-AGFPSKMEA3J6gdFOuuN+7AESmRESSMypC9twqe+hq2nYWXXtp95Nv6pK+qV3o7doYqEWgWBJ9Mivb19CK+HW0Q==} + dependencies: + '@ctrl/tinycolor': 3.6.1 + hast-util-to-html: 8.0.4 + hastscript: 7.2.0 + postcss: 8.4.29 + postcss-nested: 6.0.1(postcss@8.4.29) + dev: false + + /@expressive-code/plugin-frames@0.29.0: + resolution: {integrity: sha512-4wgua53ah9nBDKjHyhW8bDNEsXWjm5WvqznARmahn58CwTqjOdn44stc/56x0haL98wHpZTyksgyuiOdPzJ5eg==} + dependencies: + '@expressive-code/core': 0.29.0 + hastscript: 7.2.0 + dev: false + + /@expressive-code/plugin-shiki@0.29.0: + resolution: {integrity: sha512-+mS1rkW1E5yhUUMBxOQB8HJbFlf3lWen0Hm7mi14K0Q+PQru/G5PqKaa5Du9Ut+/bWSevTNc1up5UiF8fhS/9A==} + dependencies: + '@expressive-code/core': 0.29.0 + shiki: 0.14.4 + dev: false + + /@expressive-code/plugin-text-markers@0.29.0: + resolution: {integrity: sha512-9TwA91Zcjw3lyiVvsuh5MfcP9QRcg4/GJ2tZgLnNAmsCwPzbFM6iP1ZZJfigeeSD8bBqhfxyws7rydI2lGEVFA==} + dependencies: + '@expressive-code/core': 0.29.0 + hastscript: 7.2.0 + unist-util-visit-parents: 5.1.3 + dev: false + /@hapi/hoek@9.3.0: resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} dev: true @@ -1699,6 +1739,15 @@ packages: hasBin: true dev: false + /astro-expressive-code@0.29.0(astro@3.2.3): + resolution: {integrity: sha512-14DINm8EJYrusewcJumO3IsmTeqQYESCYZ3tVn0Wxup8hehYqy4I7HzT3XNKufRIo883ikDmTljbpAVhj8ls+g==} + peerDependencies: + astro: ^3.0.0-beta + dependencies: + astro: 3.2.3(@types/node@18.16.19) + remark-expressive-code: 0.29.0 + dev: false + /astro@3.2.3(@types/node@18.16.19): resolution: {integrity: sha512-1epnxQhTbfzgdmLP1yu51E8zjIOKYxZyA8hMTD4S2E+F5gMp/D81H4hekPbbq89GDxNJiHDRNZDHtS5vrU5E5w==} engines: {node: '>=18.14.1', npm: '>=6.14.0'} @@ -2938,6 +2987,15 @@ packages: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} + /expressive-code@0.29.0: + resolution: {integrity: sha512-Gl27zUVizrzjp1sLPDMJwyVQ4mws7JRkxQOiFjCWiUv2jvugM0Jhjr56337docIk7oZaKbL1IPdCq1yDNfMm5A==} + dependencies: + '@expressive-code/core': 0.29.0 + '@expressive-code/plugin-frames': 0.29.0 + '@expressive-code/plugin-shiki': 0.29.0 + '@expressive-code/plugin-text-markers': 0.29.0 + dev: false + /extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} @@ -5439,6 +5497,14 @@ packages: - supports-color dev: false + /remark-expressive-code@0.29.0: + resolution: {integrity: sha512-T36DPLBalqFDwIcExs2WCgy0SSCf99RNtuCQunrHQT0NE4aKiD4k8X+tPWDeCmI6dy4lX+yJO1xgV3IG54pnnA==} + dependencies: + expressive-code: 0.29.0 + hast-util-to-html: 8.0.4 + unist-util-visit: 4.1.2 + dev: false + /remark-gfm@3.0.1: resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==} dependencies: