Okay, let's structure a VS Code extension for the Cyberdream
theme, taking inspiration from the Noctis
structure while using the Cyberdream
palette and TextMate definitions.
Goal: Create a VS Code extension providing Cyberdream
(dark) and Cyberdream Light
color themes.
Strategy:
- Adopt Structure: Mimic the
noctis
project structure (src/
,themes/
,package.json
, build script). - Extract Palette: Define the Cyberdream dark and light color palettes in a dedicated file (
src/colors.mjs
). - Translate Syntax: Convert the provided
cyberdream.tmTheme
andcyberdream-light.tmTheme
files into VS Code'stokenColors
JSON format. Add basic semantic highlighting rules. - Define Workbench UI: Create workbench color definitions (
src/workbench/*.mjs
) for both variants, mapping the Cyberdream palette to VS Code UI elements. Incorporate the "borderless picker" style. - Build Script: Create a simple build script (
src/build.mjs
) to combine syntax and workbench definitions into the final theme JSON files in thethemes/
directory. - Package: Create
package.json
,README.md
,CHANGELOG.md
, and.vscodeignore
.
Proposed Directory Structure:
βββ vscode-cyberdream/
βββ README.md
βββ CHANGELOG.md
βββ LICENSE # Copied from cyberdream-codebase
βββ package.json
βββ .vscodeignore
βββ images/ # For README screenshots (add later)
β βββ cyberdream-dark.png
β βββ cyberdream-light.png
βββ src/
β βββ build.mjs # Main build script
β βββ buildTheme.mjs # Helper to build a single theme file
β βββ colors.mjs # Cyberdream color palettes
β βββ syntax.mjs # TextMate and Semantic token color rules
β βββ workbench/
β βββ cyberdream.mjs # Workbench colors for dark theme
β βββ cyberdream-light.mjs # Workbench colors for light theme
βββ themes/ # Output directory for generated themes
βββ cyberdream.json
βββ cyberdream-light.json
File Contents:
1. src/colors.mjs
(Extracting from cyberdream-codebase/lua/cyberdream/colors.lua
)
// src/colors.mjs
export default {
cyberdream: {
name: "Cyberdream",
type: "dark",
palette: {
bg: "#16181a",
bg_alt: "#1e2124",
bg_highlight: "#3c4048",
fg: "#ffffff",
grey: "#7b8496",
blue: "#5ea1ff",
green: "#5eff6c",
cyan: "#5ef1ff",
red: "#ff6e5e",
yellow: "#f1ff5e",
magenta: "#ff5ef1",
pink: "#ff5ea0",
orange: "#ffbd5e",
purple: "#bd5eff",
},
},
cyberdreamLight: {
name: "Cyberdream Light",
type: "light",
palette: {
bg: "#ffffff",
bg_alt: "#eaeaea",
bg_highlight: "#acacac",
fg: "#16181a",
grey: "#7b8496",
blue: "#0057d1",
green: "#008b0c",
cyan: "#008c99",
red: "#d11500",
yellow: "#997b00",
magenta: "#d100bf",
pink: "#f40064",
orange: "#d17c00",
purple: "#a018ff",
},
},
};
2. src/syntax.mjs
(Translating .tmTheme
and adding semantic rules)
Self-Correction: Manually converting the entire .tmTheme
is tedious and error-prone. A better approach is to programmatically convert it during the build or find an online converter. For this example, I'll represent a subset of the rules manually and add semantic tokens. In a real project, use a converter or script this part.
// src/syntax.mjs
// --- TextMate Rules (Partial Example - Convert full .tmTheme for real use) ---
// NOTE: Italic comments are handled here based on the Cyberdream config.
const createTmSyntax = (colors, italicComments = false) => [
{
name: "Comment",
scope: ["comment", "punctuation.definition.comment"],
settings: {
foreground: colors.grey,
fontStyle: italicComments ? "italic" : "",
},
},
{
name: "String",
scope: ["string", "punctuation.definition.string"],
settings: {
foreground: colors.green,
},
},
{
name: "Number",
scope: "constant.numeric",
settings: {
foreground: colors.orange, // Cyberdream uses orange for numbers in Neovim config
},
},
{
name: "Built-in constant",
scope: "constant.language", // true, false, null
settings: {
foreground: colors.cyan, // Using cyan for booleans like in base.lua
},
},
{
name: "User-defined constant",
scope: ["constant.character", "constant.other"],
settings: {
foreground: colors.pink, // Mapping Constant to pink like in base.lua
},
},
{
name: "Variable",
scope: ["variable", "support.variable"],
settings: {
foreground: colors.fg,
},
},
{
name: "Variable Parameter",
scope: "variable.parameter",
settings: {
foreground: colors.fg, // Often same as variable, but could be different
// fontStyle: "italic" // Optional: if parameters should be italic
},
},
{
name: "Keyword",
scope: ["keyword", "keyword.control"],
settings: {
foreground: colors.orange,
fontStyle: "", // Ensure keywords aren't italic by default
},
},
{
name: "Storage",
scope: ["storage", "storage.type"],
settings: {
foreground: colors.magenta, // Mapping Statement to magenta like in base.lua
fontStyle: "",
},
},
{
name: "Storage Type", // e.g., class, function, let, const
scope: "storage.type",
settings: {
foreground: colors.magenta,
// fontStyle: "italic" // Optional: if types should be italic
},
},
{
name: "Class name",
scope: ["entity.name.type", "entity.name.class", "support.type", "support.class"],
settings: {
foreground: colors.purple, // Mapping Type to purple like in base.lua
// fontStyle: "italic" // Optional: if class names should be italic
},
},
{
name: "Inherited class",
scope: "entity.other.inherited-class",
settings: {
foreground: colors.purple,
// fontStyle: "italic underline" // Optional styling
},
},
{
name: "Function name",
scope: ["entity.name.function", "support.function"],
settings: {
foreground: colors.blue,
fontStyle: "",
},
},
{
name: "Function argument", // Covered by variable.parameter
scope: "variable.parameter",
settings: {
foreground: colors.fg,
// fontStyle: "italic"
},
},
{
name: "Tag name",
scope: "entity.name.tag",
settings: {
foreground: colors.pink, // Using pink for HTML tags
},
},
{
name: "Tag attribute",
scope: "entity.other.attribute-name",
settings: {
foreground: colors.yellow, // Using yellow for attributes
},
},
{
name: "Operator",
scope: "keyword.operator",
settings: {
foreground: colors.purple, // Mapping Operator to purple like in base.lua
},
},
{
name: "Punctuation",
scope: [
"punctuation",
"meta.brace",
"meta.delimiter",
"meta.bracket"
],
settings: {
foreground: colors.grey // Subtle punctuation
}
},
{
name: "Invalid",
scope: "invalid",
settings: {
foreground: colors.red,
// background: colors.red, // Optional background for more emphasis
fontStyle: "bold",
},
},
{
name: "Deprecated",
scope: "invalid.deprecated",
settings: {
foreground: colors.grey,
fontStyle: "strikethrough",
},
},
// --- Markdown Specific ---
{
name: "Markdown Heading",
scope: "markup.heading",
settings: {
foreground: colors.orange,
fontStyle: "bold",
},
},
{
name: "Markdown Link Text",
scope: "markup.underline.link, string.other.link",
settings: {
foreground: colors.blue,
fontStyle: "underline",
},
},
{
name: "Markdown Code",
scope: "markup.inline.raw, markup.fenced_code.block",
settings: {
foreground: colors.cyan,
},
},
{
name: "Markdown Bold",
scope: "markup.bold",
settings: {
foreground: colors.pink,
fontStyle: "bold",
},
},
{
name: "Markdown Italic",
scope: "markup.italic",
settings: {
foreground: colors.magenta,
fontStyle: "italic",
},
},
{
name: "Markdown Quote",
scope: "markup.quote",
settings: {
foreground: colors.grey,
fontStyle: "italic",
},
},
];
// --- Semantic Token Rules ---
const createSemanticSyntax = (colors) => ({
enabled: true, // Enable semantic highlighting by default
rules: {
"namespace": colors.cyan,
"class": colors.purple,
"enum": colors.purple,
"interface": { foreground: colors.purple, fontStyle: "italic" },
"struct": colors.purple,
"typeParameter": { foreground: colors.cyan, fontStyle: "italic" },
"type": colors.purple,
"parameter": { foreground: colors.fg, fontStyle: "italic" },
"variable": colors.fg,
"property": colors.yellow, // Match attribute-name
"enumMember": colors.pink,
"event": colors.yellow,
"function": colors.blue,
"method": colors.blue,
"macro": colors.orange,
"label": colors.orange,
"comment": colors.grey,
"string": colors.green,
"keyword": colors.orange,
"number": colors.orange,
"regexp": colors.red,
"operator": colors.purple,
// Modifiers
"*.declaration": { fontStyle: "bold" }, // Make declarations stand out slightly
"*.readonly": { foreground: colors.pink }, // Constants
"*.modification": colors.fg, // Variables being modified
"*.async": { fontStyle: "italic" },
"*.static": { fontStyle: "italic" },
},
});
export { createTmSyntax, createSemanticSyntax };
3. src/workbench/cyberdream.mjs
(Workbench colors for Dark Theme)
// src/workbench/cyberdream.mjs
import C from "../colors.mjs";
const { palette: T } = C.cyberdream; // T for Theme colors
export default (tokenColors, semanticTokenColors) => ({
name: "Cyberdream",
type: "dark",
semanticHighlighting: true,
colors: {
// Base Colors
focusBorder: T.blue, // Border around focused elements
foreground: T.fg, // Default foreground
disabledForeground: T.grey, // Foreground for disabled elements
"widget.shadow": "#00000040", // Shadow around widgets like Find/Replace
"selection.background": T.bg_highlight, // Background of selected text in editor
descriptionForeground: T.grey, // Descriptions in settings, keybindings
errorForeground: T.red, // Errors in editor (e.g., squiggles)
"icon.foreground": T.cyan, // Default icon color
// Text Colors
"textBlockQuote.background": T.bg_alt,
"textBlockQuote.border": T.grey,
"textCodeBlock.background": T.bg_alt,
"textLink.activeForeground": T.blue,
"textLink.foreground": T.blue,
"textPreformat.foreground": T.cyan, // Code snippets in hovers/markdown
"textSeparator.foreground": T.grey,
// Buttons
"button.background": T.blue,
"button.foreground": T.bg, // Text on button
"button.hoverBackground": T.cyan, // Slightly lighter blue on hover
// Dropdowns
"dropdown.background": T.bg_alt,
"dropdown.listBackground": T.bg_alt,
"dropdown.border": T.bg_highlight,
"dropdown.foreground": T.fg,
// Inputs
"input.background": T.bg_alt,
"input.border": T.bg_highlight, // Borderless picker style
"input.foreground": T.fg,
"input.placeholderForeground": T.grey,
"inputOption.activeBackground": T.blue,
"inputOption.activeBorder": T.cyan,
"inputValidation.errorBackground": T.red,
"inputValidation.errorForeground": T.bg,
"inputValidation.errorBorder": T.red,
"inputValidation.infoBackground": T.blue,
"inputValidation.infoForeground": T.bg,
"inputValidation.infoBorder": T.blue,
"inputValidation.warningBackground": T.orange,
"inputValidation.warningForeground": T.bg,
"inputValidation.warningBorder": T.orange,
// Scrollbar
"scrollbar.shadow": "#00000080",
"scrollbarSlider.background": `${T.blue}50`, // Semi-transparent blue
"scrollbarSlider.hoverBackground": `${T.blue}80`,
"scrollbarSlider.activeBackground": `${T.blue}B0`,
// Badges (e.g., search count)
"badge.background": T.blue,
"badge.foreground": T.bg,
// Progress Bar
"progressBar.background": T.cyan,
// Lists (File Explorer, Command Palette, etc.)
"list.activeSelectionBackground": T.bg_highlight, // Selected item when list is focused
"list.activeSelectionForeground": T.fg,
"list.inactiveSelectionBackground": T.bg_alt, // Selected item when list is unfocused
"list.inactiveSelectionForeground": T.grey,
"list.hoverBackground": T.bg_alt, // Item on hover
"list.hoverForeground": T.fg,
"list.focusBackground": T.bg_highlight, // Focused item (usually same as active selection)
"list.focusForeground": T.fg,
"list.highlightForeground": T.cyan, // Matches in quick open
"list.errorForeground": T.red,
"list.warningForeground": T.orange,
"listFilterWidget.background": T.bg_alt, // Find widget within lists
"listFilterWidget.outline": T.blue,
"listFilterWidget.noMatchesOutline": T.red,
"tree.indentGuidesStroke": T.bg_highlight, // File explorer indent lines
// Activity Bar (Leftmost bar)
"activityBar.background": T.bg,
"activityBar.foreground": T.cyan, // Icon color
"activityBar.inactiveForeground": T.grey, // Dimmed icon color
"activityBar.border": T.bg_highlight, // Border separating from sidebar
"activityBarBadge.background": T.blue, // Notification badge background
"activityBarBadge.foreground": T.bg, // Notification badge text
"activityBar.activeBorder": T.cyan, // Border on the side of the active icon
"activityBar.activeBackground": T.bg_alt, // Background behind the active icon
// Side Bar (File Explorer, Search, etc.)
"sideBar.background": T.bg,
"sideBar.foreground": T.grey, // Default text color in sidebar
"sideBar.border": T.bg_highlight, // Border separating from editor
"sideBarTitle.foreground": T.fg, // "Explorer", "Search" titles
"sideBarSectionHeader.background": T.bg_alt,
"sideBarSectionHeader.foreground": T.fg,
"sideBarSectionHeader.border": T.bg_highlight,
// Editor Groups & Tabs
"editorGroup.border": T.bg_highlight, // Border between editor splits
"editorGroupHeader.tabsBackground": T.bg_alt, // Background of the tab bar
"editorGroupHeader.tabsBorder": T.bg_highlight, // Border below the tab bar
"editorGroupHeader.noTabsBackground": T.bg_alt, // Background if tabs are disabled
"tab.activeBackground": T.bg, // Background of the active tab
"tab.activeForeground": T.fg, // Text color of the active tab
"tab.inactiveBackground": T.bg_alt, // Background of inactive tabs
"tab.inactiveForeground": T.grey, // Text color of inactive tabs
"tab.border": T.bg, // Border between tabs
"tab.activeBorder": T.bg, // Border below the active tab (overrides tabsBorder)
"tab.unfocusedActiveBorder": T.bg, // Border below active tab in unfocused group
"tab.activeModifiedBorder": T.orange, // Top border indicating unsaved changes
"tab.inactiveModifiedBorder": T.orange,
"tab.unfocusedActiveModifiedBorder": T.orange,
"tab.unfocusedInactiveModifiedBorder": T.orange,
// Editor
"editor.background": T.bg,
"editor.foreground": T.fg,
"editorLineNumber.foreground": T.grey, // Line numbers
"editorLineNumber.activeForeground": T.cyan, // Active line number
"editorCursor.foreground": T.cyan, // Cursor color
"editor.selectionBackground": T.bg_highlight, // Text selection background
"editor.selectionHighlightBackground": `${T.cyan}30`, // Background of other occurrences of selected text
"editor.inactiveSelectionBackground": `${T.bg_highlight}80`, // Selection in unfocused editor
"editor.wordHighlightBackground": `${T.blue}30`, // Background of other occurrences of the word under cursor
"editor.wordHighlightStrongBackground": `${T.blue}50`, // Background for write-access occurrences
"editor.findMatchBackground": `${T.yellow}40`, // Current search match
"editor.findMatchHighlightBackground": `${T.yellow}20`, // Other search matches
"editor.findRangeHighlightBackground": `${T.purple}20`, // Limit find scope range
"editor.hoverHighlightBackground": `${T.blue}40`, // Highlighted symbol in hover
"editor.lineHighlightBackground": T.bg_alt, // Active line background
"editor.lineHighlightBorder": T.bg_alt, // Active line number border (none)
"editorLink.activeForeground": T.cyan, // Active link
"editorWhitespace.foreground": T.bg_highlight, // Whitespace characters
"editorIndentGuide.background": T.bg_highlight, // Indent guide lines
"editorIndentGuide.activeBackground": T.grey, // Active indent guide line
"editorRuler.foreground": T.bg_highlight, // Editor rulers
"editorCodeLens.foreground": T.grey, // CodeLens text
"editorBracketMatch.background": `${T.cyan}20`, // Background of matching brackets
"editorBracketMatch.border": T.cyan, // Border of matching brackets
// Overview Ruler (Scrollbar annotations)
"editorOverviewRuler.border": T.bg,
"editorOverviewRuler.findMatchForeground": T.yellow,
"editorOverviewRuler.errorForeground": T.red,
"editorOverviewRuler.warningForeground": T.orange,
"editorOverviewRuler.infoForeground": T.blue,
// Errors, Warnings, Info
"editorError.foreground": T.red,
"editorWarning.foreground": T.orange,
"editorInfo.foreground": T.blue,
"editorHint.foreground": T.green, // For unused code hints
"problemsErrorIcon.foreground": T.red,
"problemsWarningIcon.foreground": T.orange,
"problemsInfoIcon.foreground": T.blue,
// Gutter (Line modifications)
"editorGutter.modifiedBackground": T.orange,
"editorGutter.addedBackground": T.green,
"editorGutter.deletedBackground": T.red,
// Diff Editor
"diffEditor.insertedTextBackground": `${T.green}20`,
"diffEditor.removedTextBackground": `${T.red}20`,
// Editor Widgets (Find/Replace, Suggest)
"editorWidget.background": T.bg_alt,
"editorWidget.border": T.blue, // Border for Find widget, etc.
"editorSuggestWidget.background": T.bg_alt,
"editorSuggestWidget.border": T.bg_highlight, // Borderless picker style
"editorSuggestWidget.foreground": T.fg,
"editorSuggestWidget.highlightForeground": T.cyan,
"editorSuggestWidget.selectedBackground": T.bg_highlight,
"editorHoverWidget.background": T.bg_alt,
"editorHoverWidget.border": T.grey,
// Peek View (Go to Definition, etc.)
"peekView.border": T.blue,
"peekViewEditor.background": T.bg_alt, // Background of editor inside peek view
"peekViewEditorGutter.background": T.bg_alt,
"peekViewEditor.matchHighlightBackground": `${T.yellow}40`,
"peekViewResult.background": T.bg, // Background of the results list
"peekViewResult.fileForeground": T.fg,
"peekViewResult.lineForeground": T.grey,
"peekViewResult.matchHighlightBackground": `${T.yellow}40`,
"peekViewResult.selectionBackground": T.bg_highlight,
"peekViewResult.selectionForeground": T.fg,
"peekViewTitle.background": T.bg_alt, // Background of the peek view title area
"peekViewTitleDescription.foreground": T.grey,
"peekViewTitleLabel.foreground": T.cyan,
// Merge Conflicts
"merge.currentHeaderBackground": `${T.cyan}50`,
"merge.currentContentBackground": `${T.cyan}20`,
"merge.incomingHeaderBackground": `${T.purple}50`,
"merge.incomingContentBackground": `${T.purple}20`,
"editorOverviewRuler.currentContentForeground": T.cyan,
"editorOverviewRuler.incomingContentForeground": T.purple,
// Panel (Terminal, Output, Debug Console)
"panel.background": T.bg,
"panel.border": T.bg_highlight,
"panelTitle.activeBorder": T.cyan, // Border under the active panel title (e.g., TERMINAL)
"panelTitle.activeForeground": T.fg,
"panelTitle.inactiveForeground": T.grey,
// Status Bar (Bottom bar)
"statusBar.background": T.bg,
"statusBar.foreground": T.grey,
"statusBar.border": T.bg_highlight, // Top border
"statusBar.debuggingBackground": T.purple, // Status bar color when debugging
"statusBar.debuggingForeground": T.bg,
"statusBar.noFolderBackground": T.bg, // Status bar when no folder is open
"statusBarItem.activeBackground": T.bg_highlight,
"statusBarItem.hoverBackground": T.bg_alt,
"statusBarItem.prominentBackground": T.blue, // e.g., Remote indicator background
"statusBarItem.prominentHoverBackground": T.cyan,
"statusBarItem.remoteBackground": T.blue, // Remote indicator background
"statusBarItem.remoteForeground": T.bg,
// Title Bar (macOS only or custom)
"titleBar.activeBackground": T.bg,
"titleBar.activeForeground": T.fg,
"titleBar.inactiveBackground": T.bg,
"titleBar.inactiveForeground": T.grey,
"titleBar.border": T.bg_highlight,
// Menu Bar (Custom Title Bar on Win/Linux)
"menubar.selectionForeground": T.cyan,
"menubar.selectionBackground": T.bg_alt,
"menu.foreground": T.grey,
"menu.background": T.bg_alt,
"menu.selectionForeground": T.cyan,
"menu.selectionBackground": T.bg_highlight,
"menu.separatorBackground": T.grey,
// Notifications
"notificationCenterHeader.foreground": T.cyan,
"notificationCenterHeader.background": T.bg_alt,
"notifications.foreground": T.fg,
"notifications.background": T.bg_alt,
"notifications.border": T.blue,
"notificationLink.foreground": T.blue,
"notificationsErrorIcon.foreground": T.red,
"notificationsWarningIcon.foreground": T.orange,
"notificationsInfoIcon.foreground": T.blue,
// Extensions
"extensionButton.prominentForeground": T.bg,
"extensionButton.prominentBackground": T.blue,
"extensionButton.prominentHoverBackground": T.cyan,
"extensionBadge.remoteBackground": T.blue,
"extensionBadge.remoteForeground": T.bg,
// Quick Picker (Command Palette)
"pickerGroup.border": T.bg_highlight, // Borderless picker style
"pickerGroup.foreground": T.cyan, // Category titles (e.g., "recently opened")
// Integrated Terminal
"terminal.background": T.bg,
"terminal.foreground": T.fg,
"terminal.ansiBlack": T.bg_alt, // Use bg_alt for black to distinguish from bg
"terminal.ansiRed": T.red,
"terminal.ansiGreen": T.green,
"terminal.ansiYellow": T.yellow,
"terminal.ansiBlue": T.blue,
"terminal.ansiMagenta": T.magenta, // Use magenta instead of purple for terminal
"terminal.ansiCyan": T.cyan,
"terminal.ansiWhite": T.fg,
"terminal.ansiBrightBlack": T.grey,
"terminal.ansiBrightRed": T.red, // Often same as normal
"terminal.ansiBrightGreen": T.green,
"terminal.ansiBrightYellow": T.yellow,
"terminal.ansiBrightBlue": T.blue,
"terminal.ansiBrightMagenta": T.magenta,
"terminal.ansiBrightCyan": T.cyan,
"terminal.ansiBrightWhite": T.fg,
"terminal.selectionBackground": T.bg_highlight,
"terminalCursor.background": T.cyan,
"terminalCursor.foreground": T.bg,
// Debugging
"debugToolBar.background": T.bg_alt,
"debugIcon.startForeground": T.green,
"debugIcon.pauseForeground": T.orange,
"debugIcon.stopForeground": T.red,
"debugIcon.disconnectForeground": T.grey,
"debugIcon.restartForeground": T.green,
"debugIcon.stepOverForeground": T.blue,
"debugIcon.stepIntoForeground": T.blue,
"debugIcon.stepOutForeground": T.blue,
"debugIcon.continueForeground": T.blue,
"debugIcon.stepBackForeground": T.blue,
// Welcome Page
"welcomePage.buttonBackground": T.bg_alt,
"welcomePage.buttonHoverBackground": T.bg_highlight,
// Git Decorations
"gitDecoration.addedResourceForeground": T.green,
"gitDecoration.modifiedResourceForeground": T.blue,
"gitDecoration.deletedResourceForeground": T.red,
"gitDecoration.untrackedResourceForeground": T.cyan,
"gitDecoration.ignoredResourceForeground": T.grey,
"gitDecoration.conflictingResourceForeground": T.orange,
},
semanticTokenColors: semanticTokenColors,
tokenColors: tokenColors,
});
4. src/workbench/cyberdream-light.mjs
(Workbench colors for Light Theme)
// src/workbench/cyberdream-light.mjs
import C from "../colors.mjs";
const { palette: T } = C.cyberdreamLight; // T for Theme colors
export default (tokenColors, semanticTokenColors) => ({
name: "Cyberdream Light",
type: "light",
semanticHighlighting: true,
colors: {
// Base Colors
focusBorder: T.blue,
foreground: T.fg,
disabledForeground: T.grey,
"widget.shadow": "#00000020",
"selection.background": T.bg_highlight,
descriptionForeground: T.grey,
errorForeground: T.red,
"icon.foreground": T.cyan,
// Text Colors
"textBlockQuote.background": T.bg_alt,
"textBlockQuote.border": T.grey,
"textCodeBlock.background": T.bg_alt,
"textLink.activeForeground": T.blue,
"textLink.foreground": T.blue,
"textPreformat.foreground": T.cyan,
"textSeparator.foreground": T.grey,
// Buttons
"button.background": T.blue,
"button.foreground": T.bg,
"button.hoverBackground": T.cyan,
// Dropdowns
"dropdown.background": T.bg_alt,
"dropdown.listBackground": T.bg_alt,
"dropdown.border": T.bg_highlight,
"dropdown.foreground": T.fg,
// Inputs
"input.background": T.bg_alt,
"input.border": T.bg_highlight, // Borderless picker style
"input.foreground": T.fg,
"input.placeholderForeground": T.grey,
"inputOption.activeBackground": T.blue,
"inputOption.activeBorder": T.cyan,
"inputValidation.errorBackground": T.red,
"inputValidation.errorForeground": T.bg,
"inputValidation.errorBorder": T.red,
"inputValidation.infoBackground": T.blue,
"inputValidation.infoForeground": T.bg,
"inputValidation.infoBorder": T.blue,
"inputValidation.warningBackground": T.orange,
"inputValidation.warningForeground": T.bg,
"inputValidation.warningBorder": T.orange,
// Scrollbar
"scrollbar.shadow": "#00000030",
"scrollbarSlider.background": `${T.blue}50`,
"scrollbarSlider.hoverBackground": `${T.blue}80`,
"scrollbarSlider.activeBackground": `${T.blue}B0`,
// Badges
"badge.background": T.blue,
"badge.foreground": T.bg,
// Progress Bar
"progressBar.background": T.cyan,
// Lists
"list.activeSelectionBackground": T.bg_highlight,
"list.activeSelectionForeground": T.fg,
"list.inactiveSelectionBackground": T.bg_alt,
"list.inactiveSelectionForeground": T.grey,
"list.hoverBackground": T.bg_alt,
"list.hoverForeground": T.fg,
"list.focusBackground": T.bg_highlight,
"list.focusForeground": T.fg,
"list.highlightForeground": T.cyan,
"list.errorForeground": T.red,
"list.warningForeground": T.orange,
"listFilterWidget.background": T.bg_alt,
"listFilterWidget.outline": T.blue,
"listFilterWidget.noMatchesOutline": T.red,
"tree.indentGuidesStroke": T.bg_highlight,
// Activity Bar
"activityBar.background": T.bg,
"activityBar.foreground": T.cyan,
"activityBar.inactiveForeground": T.grey,
"activityBar.border": T.bg_highlight,
"activityBarBadge.background": T.blue,
"activityBarBadge.foreground": T.bg,
"activityBar.activeBorder": T.cyan,
"activityBar.activeBackground": T.bg_alt,
// Side Bar
"sideBar.background": T.bg,
"sideBar.foreground": T.grey,
"sideBar.border": T.bg_highlight,
"sideBarTitle.foreground": T.fg,
"sideBarSectionHeader.background": T.bg_alt,
"sideBarSectionHeader.foreground": T.fg,
"sideBarSectionHeader.border": T.bg_highlight,
// Editor Groups & Tabs
"editorGroup.border": T.bg_highlight,
"editorGroupHeader.tabsBackground": T.bg_alt,
"editorGroupHeader.tabsBorder": T.bg_highlight,
"editorGroupHeader.noTabsBackground": T.bg_alt,
"tab.activeBackground": T.bg,
"tab.activeForeground": T.fg,
"tab.inactiveBackground": T.bg_alt,
"tab.inactiveForeground": T.grey,
"tab.border": T.bg,
"tab.activeBorder": T.bg,
"tab.unfocusedActiveBorder": T.bg,
"tab.activeModifiedBorder": T.orange,
"tab.inactiveModifiedBorder": T.orange,
"tab.unfocusedActiveModifiedBorder": T.orange,
"tab.unfocusedInactiveModifiedBorder": T.orange,
// Editor
"editor.background": T.bg,
"editor.foreground": T.fg,
"editorLineNumber.foreground": T.grey,
"editorLineNumber.activeForeground": T.cyan,
"editorCursor.foreground": T.blue,
"editor.selectionBackground": T.bg_highlight,
"editor.selectionHighlightBackground": `${T.cyan}30`,
"editor.inactiveSelectionBackground": `${T.bg_highlight}80`,
"editor.wordHighlightBackground": `${T.blue}30`,
"editor.wordHighlightStrongBackground": `${T.blue}50`,
"editor.findMatchBackground": `${T.yellow}40`,
"editor.findMatchHighlightBackground": `${T.yellow}20`,
"editor.findRangeHighlightBackground": `${T.purple}20`,
"editor.hoverHighlightBackground": `${T.blue}40`,
"editor.lineHighlightBackground": T.bg_alt,
"editor.lineHighlightBorder": T.bg_alt,
"editorLink.activeForeground": T.cyan,
"editorWhitespace.foreground": T.bg_highlight,
"editorIndentGuide.background": T.bg_highlight,
"editorIndentGuide.activeBackground": T.grey,
"editorRuler.foreground": T.bg_highlight,
"editorCodeLens.foreground": T.grey,
"editorBracketMatch.background": `${T.cyan}20`,
"editorBracketMatch.border": T.cyan,
// Overview Ruler
"editorOverviewRuler.border": T.bg,
"editorOverviewRuler.findMatchForeground": T.yellow,
"editorOverviewRuler.errorForeground": T.red,
"editorOverviewRuler.warningForeground": T.orange,
"editorOverviewRuler.infoForeground": T.blue,
// Errors, Warnings, Info
"editorError.foreground": T.red,
"editorWarning.foreground": T.orange,
"editorInfo.foreground": T.blue,
"editorHint.foreground": T.green,
"problemsErrorIcon.foreground": T.red,
"problemsWarningIcon.foreground": T.orange,
"problemsInfoIcon.foreground": T.blue,
// Gutter
"editorGutter.modifiedBackground": T.orange,
"editorGutter.addedBackground": T.green,
"editorGutter.deletedBackground": T.red,
// Diff Editor
"diffEditor.insertedTextBackground": `${T.green}20`,
"diffEditor.removedTextBackground": `${T.red}20`,
// Editor Widgets
"editorWidget.background": T.bg_alt,
"editorWidget.border": T.blue,
"editorSuggestWidget.background": T.bg_alt,
"editorSuggestWidget.border": T.bg_highlight, // Borderless picker style
"editorSuggestWidget.foreground": T.fg,
"editorSuggestWidget.highlightForeground": T.cyan,
"editorSuggestWidget.selectedBackground": T.bg_highlight,
"editorHoverWidget.background": T.bg_alt,
"editorHoverWidget.border": T.grey,
// Peek View
"peekView.border": T.blue,
"peekViewEditor.background": T.bg_alt,
"peekViewEditorGutter.background": T.bg_alt,
"peekViewEditor.matchHighlightBackground": `${T.yellow}40`,
"peekViewResult.background": T.bg,
"peekViewResult.fileForeground": T.fg,
"peekViewResult.lineForeground": T.grey,
"peekViewResult.matchHighlightBackground": `${T.yellow}40`,
"peekViewResult.selectionBackground": T.bg_highlight,
"peekViewResult.selectionForeground": T.fg,
"peekViewTitle.background": T.bg_alt,
"peekViewTitleDescription.foreground": T.grey,
"peekViewTitleLabel.foreground": T.cyan,
// Merge Conflicts
"merge.currentHeaderBackground": `${T.cyan}50`,
"merge.currentContentBackground": `${T.cyan}20`,
"merge.incomingHeaderBackground": `${T.purple}50`,
"merge.incomingContentBackground": `${T.purple}20`,
"editorOverviewRuler.currentContentForeground": T.cyan,
"editorOverviewRuler.incomingContentForeground": T.purple,
// Panel
"panel.background": T.bg,
"panel.border": T.bg_highlight,
"panelTitle.activeBorder": T.cyan,
"panelTitle.activeForeground": T.fg,
"panelTitle.inactiveForeground": T.grey,
// Status Bar
"statusBar.background": T.bg,
"statusBar.foreground": T.grey,
"statusBar.border": T.bg_highlight,
"statusBar.debuggingBackground": T.purple,
"statusBar.debuggingForeground": T.bg,
"statusBar.noFolderBackground": T.bg,
"statusBarItem.activeBackground": T.bg_highlight,
"statusBarItem.hoverBackground": T.bg_alt,
"statusBarItem.prominentBackground": T.blue,
"statusBarItem.prominentHoverBackground": T.cyan,
"statusBarItem.remoteBackground": T.blue,
"statusBarItem.remoteForeground": T.bg,
// Title Bar
"titleBar.activeBackground": T.bg,
"titleBar.activeForeground": T.fg,
"titleBar.inactiveBackground": T.bg,
"titleBar.inactiveForeground": T.grey,
"titleBar.border": T.bg_highlight,
// Menu Bar
"menubar.selectionForeground": T.cyan,
"menubar.selectionBackground": T.bg_alt,
"menu.foreground": T.grey,
"menu.background": T.bg_alt,
"menu.selectionForeground": T.cyan,
"menu.selectionBackground": T.bg_highlight,
"menu.separatorBackground": T.grey,
// Notifications
"notificationCenterHeader.foreground": T.cyan,
"notificationCenterHeader.background": T.bg_alt,
"notifications.foreground": T.fg,
"notifications.background": T.bg_alt,
"notifications.border": T.blue,
"notificationLink.foreground": T.blue,
"notificationsErrorIcon.foreground": T.red,
"notificationsWarningIcon.foreground": T.orange,
"notificationsInfoIcon.foreground": T.blue,
// Extensions
"extensionButton.prominentForeground": T.bg,
"extensionButton.prominentBackground": T.blue,
"extensionButton.prominentHoverBackground": T.cyan,
"extensionBadge.remoteBackground": T.blue,
"extensionBadge.remoteForeground": T.bg,
// Quick Picker
"pickerGroup.border": T.bg_highlight, // Borderless picker style
"pickerGroup.foreground": T.cyan,
// Integrated Terminal
"terminal.background": T.bg,
"terminal.foreground": T.fg,
"terminal.ansiBlack": T.bg_alt,
"terminal.ansiRed": T.red,
"terminal.ansiGreen": T.green,
"terminal.ansiYellow": T.yellow,
"terminal.ansiBlue": T.blue,
"terminal.ansiMagenta": T.magenta,
"terminal.ansiCyan": T.cyan,
"terminal.ansiWhite": T.fg,
"terminal.ansiBrightBlack": T.grey,
"terminal.ansiBrightRed": T.red,
"terminal.ansiBrightGreen": T.green,
"terminal.ansiBrightYellow": T.yellow,
"terminal.ansiBrightBlue": T.blue,
"terminal.ansiBrightMagenta": T.magenta,
"terminal.ansiBrightCyan": T.cyan,
"terminal.ansiBrightWhite": T.fg,
"terminal.selectionBackground": T.bg_highlight,
"terminalCursor.background": T.blue,
"terminalCursor.foreground": T.bg,
// Debugging
"debugToolBar.background": T.bg_alt,
"debugIcon.startForeground": T.green,
"debugIcon.pauseForeground": T.orange,
"debugIcon.stopForeground": T.red,
"debugIcon.disconnectForeground": T.grey,
"debugIcon.restartForeground": T.green,
"debugIcon.stepOverForeground": T.blue,
"debugIcon.stepIntoForeground": T.blue,
"debugIcon.stepOutForeground": T.blue,
"debugIcon.continueForeground": T.blue,
"debugIcon.stepBackForeground": T.blue,
// Welcome Page
"welcomePage.buttonBackground": T.bg_alt,
"welcomePage.buttonHoverBackground": T.bg_highlight,
// Git Decorations
"gitDecoration.addedResourceForeground": T.green,
"gitDecoration.modifiedResourceForeground": T.blue,
"gitDecoration.deletedResourceForeground": T.red,
"gitDecoration.untrackedResourceForeground": T.cyan,
"gitDecoration.ignoredResourceForeground": T.grey,
"gitDecoration.conflictingResourceForeground": T.orange,
},
semanticTokenColors: semanticTokenColors,
tokenColors: tokenColors,
});
5. src/buildTheme.mjs
(Helper - Can be identical to Noctis's)
// src/buildTheme.mjs
import fs from "fs";
import { promisify } from "util";
/**
* Writes the theme JSON object to the specified file path.
* @param {string} path - The output file path (e.g., './themes/cyberdream.json').
* @param {object} themeJson - The complete theme JSON object.
* @param {string} themeName - The name of the theme being built (for logging).
* @returns {Promise<void>}
*/
export async function buildTheme(path, themeJson, themeName) {
const writeFileAsync = promisify(fs.writeFile);
try {
// Use 3 spaces for indentation like the original Noctis example
await writeFileAsync(path, JSON.stringify(themeJson, null, 3));
console.log(`β ${themeName} theme built successfully to ${path}`);
} catch (error) {
console.error(`β Error building ${themeName} theme: ${error}`);
}
}
6. src/build.mjs
(Main build script)
// src/build.mjs
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import C from "./colors.mjs";
import { createTmSyntax, createSemanticSyntax } from "./syntax.mjs";
import createCyberdreamWorkbench from "./workbench/cyberdream.mjs";
import createCyberdreamLightWorkbench from "./workbench/cyberdream-light.mjs";
import { buildTheme } from "./buildTheme.mjs";
// Helper to get __dirname in ES modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const THEMES_DIR = path.join(__dirname, '..', 'themes');
// Ensure themes directory exists
if (!fs.existsSync(THEMES_DIR)) {
fs.mkdirSync(THEMES_DIR);
console.log(`Created themes directory: ${THEMES_DIR}`);
}
// --- Define Themes to Build ---
const themesToBuild = [
{
name: C.cyberdream.name,
fileName: "cyberdream.json",
palette: C.cyberdream.palette,
workbenchFn: createCyberdreamWorkbench,
italicComments: true, // From cyberdream config
},
{
name: C.cyberdreamLight.name,
fileName: "cyberdream-light.json",
palette: C.cyberdreamLight.palette,
workbenchFn: createCyberdreamLightWorkbench,
italicComments: true, // From cyberdream config
},
];
// --- Build Process ---
async function buildAll() {
console.log("Starting theme build process...");
for (const themeInfo of themesToBuild) {
console.log(`Building ${themeInfo.name}...`);
// Generate syntax rules for this theme's palette
const tmSyntax = createTmSyntax(themeInfo.palette, themeInfo.italicComments);
const semanticSyntax = createSemanticSyntax(themeInfo.palette);
// Generate the full theme JSON using the workbench function
const fullThemeJson = themeInfo.workbenchFn(tmSyntax, semanticSyntax);
// Define the output path
const outputPath = path.join(THEMES_DIR, themeInfo.fileName);
// Write the theme file
await buildTheme(outputPath, fullThemeJson, themeInfo.name);
}
console.log("Theme build process completed.");
}
buildAll().catch(err => {
console.error("Build failed:", err);
process.exit(1);
});
7. package.json
{
"name": "cyberdream-vscode",
"displayName": "Cyberdream",
"description": "A high-contrast, futuristic & vibrant VS Code theme based on the Neovim colorscheme.",
"version": "0.1.0",
"publisher": "your-publisher-name", // CHANGE THIS
"engines": {
"vscode": "^1.70.0" // Set a reasonable minimum VS Code version
},
"categories": [
"Themes"
],
"keywords": [
"theme",
"dark theme",
"light theme",
"cyberdream",
"cyberpunk",
"vibrant",
"high contrast"
],
"icon": "images/icon.png", // Add an icon later if you wish
"repository": {
"type": "git",
"url": "https://github.com/your-username/vscode-cyberdream.git" // CHANGE THIS
},
"license": "MIT", // Match original license
"scripts": {
"build": "node ./src/build.mjs",
"vscode:prepublish": "npm run build" // Ensure themes are built before publishing
},
"contributes": {
"themes": [
{
"label": "Cyberdream",
"uiTheme": "vs-dark",
"path": "./themes/cyberdream.json"
},
{
"label": "Cyberdream Light",
"uiTheme": "vs",
"path": "./themes/cyberdream-light.json"
}
]
}
}
8. README.md
(Adapt from Cyberdream's Neovim README)
# Cyberdream for VS Code
<p align="center">
<img src="https://github.com/scottmckendry/cyberdream.nvim/assets/39483124/e758f47a-32eb-4eac-a008-eb59272badef" alt="Cyberdream Logo">
<br>
<b><i>A high-contrast, futuristic & vibrant theme for VS Code</i></b>
</p>
<p align="center">
<!-- Add VS Code Marketplace badges later -->
<a href="https://github.com/<your-username>/vscode-cyberdream/blob/main/LICENSE">
<img alt="License" src="https://img.shields.io/github/license/scottmckendry/cyberdream.nvim?style=for-the-badge&logo=github&color=%235ef1ff">
</a>
</p>
---
Based on the popular [cyberdream.nvim](https://github.com/scottmckendry/cyberdream.nvim) theme by Scott McKendry. This extension brings the high-contrast, futuristic, and vibrant aesthetic to Visual Studio Code.
## β¨ Features
* **Two Variants:** Includes both `Cyberdream` (dark) and `Cyberdream Light` themes.
* **High Contrast:** Carefully chosen colors for readability and visual appeal.
* **Semantic Highlighting:** Provides more accurate syntax highlighting for supported languages (JavaScript, TypeScript, Java, etc.).
* **Borderless Pickers:** A clean, modern look for UI elements like the Command Palette and Quick Open.
## πΈ Screenshots
**Cyberdream (Dark)**
 <!-- Add your screenshot -->
**Cyberdream Light**
 <!-- Add your screenshot -->
*(Font used in screenshots: [Your Font Name])* <!-- Specify the font you use -->
## π¦ Installation
1. Open **Extensions** side view in VS Code (`Ctrl+Shift+X` or `Cmd+Shift+X`).
2. Search for `Cyberdream`.
3. Click **Install**.
4. Open the Command Palette (`Ctrl+Shift+P` or `Cmd+Shift+P`), type `Preferences: Color Theme`, and select `Cyberdream` or `Cyberdream Light`.
## βοΈ Customization
While the theme aims to match the original Neovim version, some features are best handled via VS Code settings:
* **Transparency:** To enable a transparent background, add the following to your `settings.json` (`Ctrl+,` or `Cmd+,`):
```json
"workbench.colorCustomizations": {
"[Cyberdream]": { // Or "[Cyberdream Light]"
"editor.background": "#16181a00", // Dark theme example with alpha
"sideBar.background": "#16181a00",
"activityBar.background": "#16181a00",
"panel.background": "#16181a00",
"statusBar.background": "#16181a00",
// Add other elements as needed
}
},
// You might also need this for full transparency effect
"window.titleBarStyle": "native" // Or custom depending on OS and preference
```
*Adjust the hex code and alpha value (`00` for fully transparent) as needed.*
* **Saturation:** To adjust color saturation (e.g., for a more muted look), you can override specific token colors in your `settings.json`. Desaturating colors manually or using an online tool might be necessary.
```json
"editor.tokenColorCustomizations": {
"[Cyberdream]": { // Or "[Cyberdream Light]"
"textMateRules": [
{
"scope": "string",
"settings": {
"foreground": "#desaturated_green_hex" // Replace with your desaturated color
}
},
{
"scope": "keyword",
"settings": {
"foreground": "#desaturated_orange_hex"
}
}
// Add more rules as needed
]
}
}
```
* **Italic Comments:** Italic comments are enabled by default, matching one of the original theme's options.
## π Credits
* Original [cyberdream.nvim](https://github.com/scottmckendry/cyberdream.nvim) theme by **Scott McKendry**.
* Theme structure and build process inspired by [Noctis](https://github.com/liviuschera/noctis) by Liviu Schera.
## π License
[MIT License](./LICENSE)
9. CHANGELOG.md
# Changelog
## [0.1.0] - YYYY-MM-DD
### Added
- Initial release of Cyberdream for VS Code.
- Includes `Cyberdream` (dark) and `Cyberdream Light` themes.
- Basic syntax highlighting based on original TextMate themes.
- Semantic highlighting for improved accuracy.
- Workbench UI theming inspired by Cyberdream palette.
- Borderless picker style.
10. .vscodeignore
.vscode/**
.github/**
src/**
node_modules/**
*.mjs
*.lock
*.tsbuildinfo
11. LICENSE
Copy the content from cyberdream-codebase/LICENSE
.
Next Steps:
- Install Dependencies: You'll need Node.js and npm/pnpm/yarn. Run
npm install
(or equivalent) in thevscode-cyberdream
directory (though this simple build script has no external dependencies yet). - Complete Syntax Translation: Use an online converter (like tmTheme Editor - export as JSON) or write a script to fully convert
cyberdream.tmTheme
andcyberdream-light.tmTheme
into thesrc/syntax.mjs
createTmSyntax
function. - Refine Workbench Colors: Go through the VS Code Theme Color Reference and map more Cyberdream palette colors to UI elements in
src/workbench/*.mjs
for a more complete theme. Test thoroughly in VS Code. - Build: Run
npm run build
(ornode src/build.mjs
). This will generate thethemes/*.json
files. - Test:
- Open the
vscode-cyberdream
folder in VS Code. - Press
F5
to launch a new Extension Development Host window. - In the new window, open the Command Palette (
Ctrl+Shift+P
), typePreferences: Color Theme
, and selectCyberdream
orCyberdream Light
. - Open various file types (JS, TS, Python, HTML, CSS, JSON, Markdown) to check syntax highlighting.
- Inspect UI elements (Activity Bar, Sidebar, Status Bar, Panel, Tabs, etc.).
- Open the
- Screenshots: Take screenshots using the themes and add them to the
images/
folder andREADME.md
. - Publish (Optional): If you want to share it, replace
"your-publisher-name"
inpackage.json
and follow the VS Code publishing guide.
This provides a solid foundation for the Cyberdream VS Code theme extension, leveraging the best parts of both the original theme and the Noctis structure. Remember that the most time-consuming part will be accurately translating the syntax highlighting and refining the workbench colors.