I'm creating a VScode theme.
My project structure is very simple:
mytheme
|_ .vscode
|_ launch.json
|_ assets
|_ ...some png files
|_ themes
|_ mytheme.json
.vscodeignore
package.json
README.md
The mytheme.json
is something like this:
{
"name": "mytheme",
"type": "dark",
"colors": {
//////////////////////////////
// CONTRAST COLOR
// The contrast colors are typically only set for high contrast themes.
// If set, they add an additional border around items across the UI to increase the contrast.
//////////////////////////////
// An extra border around active elements to separate them from others for greater contrast.
"contrastActiveBorder": "#fa0000",
// "contrastActiveBorder": "#FFFFFF00",
// An extra border around elements to separate them from others for greater contrast.
//"contrastBorder": "#fa0000",
//////////////////////////////
// BASE COLORS
//////////////////////////////
// Overall border color for focused elements. This color is only used if not overridden by a component.
"focusBorder": "#9B6DFF66",
// Overall foreground color. This color is only used if not overridden by a component.
"foreground": "#D9E0E8",
// Shadow color of widgets such as Find/Replace inside the editor.
"widget.shadow": "#1F2330",
// Background color of text selections in the workbench (for input fields or text areas, does not apply to selections within the editor and the terminal).
"selection.background": "#9B6DFF99",
// Foreground color for description text providing additional information, for example for a label.
"descriptionForeground": "#808182",
// Overall foreground color for error messages (this color is only used if not overridden by a component).
"errorForeground": "#9B6DFF",
// The default color for icons in the workbench.
"icon.foreground": "#D9E0E8",
...
}
}
and my package.json
:
{
"name": "mytheme",
"version": "1.0.0",
"publisher": "...",
"icon": "assets/logo_square.png",
"galleryBanner": {
"color": "#1F2330",
"theme": "dark"
},
"engines": {
"vscode": "^1.42.0"
},
"displayName": "Mytheme",
"description": "...",
"categories": [
"Themes"
],
"contributes": {
"themes": [
{
"label": "Mytheme",
"uiTheme": "vs-dark",
"path": "./themes/mytheme.json"
}
]
},
"repository": {
"type": "git",
"URL": "....git"
},
"bugs": {
"URL": "..."
},
"author": {
"name": "...",
"email": "...",
},
"license": "MIT",
"keywords": [
"vscode",
"theme",
"color-theme",
"dark"
],
"private": false
}
Very simple. It works like a charm. But there is a big problem: it's very difficult to maintain because mytheme.json
is a very very long file and it's a simple .json and If I want to modify for example the accent color, I need to do a find and replace.
I would like to develop my theme in a smarter way, I would like to use variables, save my N colors in variables and use them. json format doesn't support variables so I ask you how can I do that? I don't know if there is a standard way to do that, I imagine developing in js and then running a script that transforms my work into a valid json but how?
For example:
const PURPLE = "#9B6DFF"
const baseColors = {
...
errorForeground: PURPLE,
...
}
return ...
I didn't find a guide to follow.
Following the suggestion of @rioV8, I created these files:
.vscode/launch.json
:
{
"version": "0.2.0",
"configurations": [
{
"type": "extensionHost",
"request": "launch",
"name": "Launch Extension",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "parseToJson",
},
],
}
.vscode/tasks.json
:
{
"version": "2.0.0",
"tasks": [
{
"label": "parseToJson",
"command": "tsc",
"type": "shell",
"presentation": {
"reveal": "silent",
"panel": "new"
},
"args": [
"--target",
"ES5",
"--outDir",
"js",
"--sourceMap",
"--watch",
"parse.ts"
],
"problemMatcher": "$tsc"
}
]
}
.vscode/parse.ts
:
const PURPLE = "#9B6DFF"
const baseColors = {
errorForeground: PURPLE,
}
// create json
const mytheme = {
"name": "mytheme",
"type": "dark",
"colors": {...baseColors}
}
function createJsonTheme() {
// save to json
const file = new File(mytheme, "../themes/mytheme.json", {
type: "text/plain",
});
}
createJsonTheme()
When I run it, I get:
error TS6053: File 'parse.ts' not found. The file is in the program because: Root file specified for compilation
The path seems ok to me, where is The problem?
The createJsonTheme
function goal is to create an object to save then in a json file inside themes
folder.
CodePudding user response:
Variables won't help. The theme file is a mapping of token values to color values. A theme editor tool could help you to be more productive, but I don't know any.
CodePudding user response:
I solved doing like this:
launch.json
:
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"preLaunchTask": "npm: build"
},
{
"name": "Run Extension Without Build",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
]
}
]
}
tasks.json
:
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [],
"label": "npm: start",
"detail": "nodemon --watch src src/index.js"
},
{
"type": "npm",
"script": "build",
"group": "build",
"problemMatcher": [],
"label": "npm: build",
"detail": "node src/index.js"
}
]
}
package.json
:
...
"scripts": {
"start": "nodemon --watch src src/index.js",
"build": "node src/index.js && mkdir -p build",
"prepublishOnly": "npm run build && vsce publish"
}
...
src/index.js
:
const fs = require('fs').promises
const getTheme = require('./theme')
const ohlalaTheme = getTheme({
theme: 'dark',
name: 'Mytheme',
})
// write theme
fs.mkdir('./themes', { recursive: true })
.then(() =>
Promise.all([
fs.writeFile('./themes/mytheme.json', JSON.stringify(ohlalaTheme, null, 2)),
])
)
.catch(() => process.exit(1))
src/theme.js
const { colors } = require('./colors')
function getTheme({ theme, name }) {
const themes = (options) => options[theme]
return {
name: name,
colors: {
focusBorder: colors.green,
},
semanticHighlighting: true,
...
}
}
module.exports = getTheme
src/colors.js
:
const colors = {
green: '#......',
}
module.exports = { colors }