Last active
July 22, 2023 09:51
-
-
Save hangxingliu/c18a96779b538001607672bb70d369af to your computer and use it in GitHub Desktop.
A script for fix Solarized theme in VSCode from 1.12.0 looks like sxxt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
//@ts-check | |
/// <reference types="node" /> | |
// https://github.com/microsoft/vscode/blob/main/extensions/theme-solarized-light/themes/solarized-light-color-theme.json | |
const VERSION = "2023-07-22"; | |
const AUTHOR = "Liu Yue <[email protected]>"; | |
const IS_WINDOWS = process.platform == "win32"; | |
const IS_OSX = process.platform == "darwin"; | |
const VSCODE_PATH_WIN = [ | |
"C:/Program Files (x86)/Microsoft VS Code", | |
"C:/Program Files/Microsoft VS Code", | |
]; | |
const VSCODE_PATH_OSX = ["/Applications/Visual Studio Code.app/Contents"]; | |
const VSCODE_PATH_LINUX = ["/usr/share/code"]; | |
const VSCODE_PATH_WSL = [ | |
"/mnt/c/Program Files (x86)/Microsoft VS Code", | |
"/mnt/c/Program Files/Microsoft VS Code", | |
]; | |
const RESOURCE_DIR = IS_OSX ? "Resources" : "resources"; | |
const EXTENSION_DIR = `${RESOURCE_DIR}/app/extensions`; | |
const THEME_FILE = `${EXTENSION_DIR}/theme-solarized-light/themes/solarized-light-color-theme.json`; | |
/** @type {string[]} */ | |
const VSCODE_PATH = []; | |
if (IS_WINDOWS) VSCODE_PATH.push(...VSCODE_PATH_WIN); | |
else if (IS_OSX) VSCODE_PATH.push(...VSCODE_PATH_OSX); | |
else VSCODE_PATH.push(...VSCODE_PATH_LINUX.concat(VSCODE_PATH_WSL)); | |
const WELCOME_INFO = [ | |
`Version: ${VERSION}`, | |
`Author: ${AUTHOR}`, | |
"Description: A script for fixing the VSCode Solarized theme that looks like sxxt since version 1.12.0", | |
"Details:", | |
" 1. Remove all shit color in blocks of VSCode", | |
" 2. Change comments from italic to normal", | |
"Usage:", | |
" You can provide a parameter to this script as a custom path for VSCode", | |
" The default paths to locate VSCode are:", | |
"", | |
...VSCODE_PATH.map((it) => " " + it), | |
"", | |
]; | |
const { join } = require("path"); | |
const { existsSync, writeFileSync, readFileSync } = require("fs"); | |
const dim = (str = "") => `\u001b[2m${str}\u001b[22m`; | |
const highlight = (str = "") => `\u001b[36m${str}\u001b[39m`; | |
(function main() { | |
const args = process.argv.slice(2); | |
console.log(WELCOME_INFO.join("\n")); | |
if (args.includes("-h") || args.includes("--help")) return; | |
if (args[0] === "--debug") return foundThemeFile(args[1]); | |
let vscodeDirs = VSCODE_PATH; | |
if (args.length > 0) { | |
vscodeDirs = args; | |
console.log("Use the following user-provided path to locate VSCode:"); | |
vscodeDirs.forEach((path) => console.log(dim(` ${path}`))); | |
} | |
const filePath = vscodeDirs | |
.map((it) => join(it, THEME_FILE)) | |
.filter((it) => existsSync(it))[0]; | |
if (!filePath) return fatal(`Can't find VSCode from the paths`); | |
console.log(`Found VSCode theme file from:\n ${highlight(filePath)}`); | |
foundThemeFile(filePath); | |
})(); | |
/** @param {string} filePath */ | |
function foundThemeFile(filePath) { | |
let json = readText(filePath); | |
backup(); | |
modify(); | |
function backup() { | |
console.log("Backing up the theme file ..."); | |
let backupFile = filePath + ".backup"; | |
if (existsSync(backupFile)) return; | |
writeText(backupFile, json); | |
console.log(dim(`Backed up original file to:\n ${backupFile}`)); | |
} | |
function modify() { | |
//remove comments in JSON | |
json = json.replace(/\/\/.+$/gm, ""); | |
const obj = JSON.parse(json); | |
const { colors, tokenColors } = obj; | |
if (!colors) fatal("`colors` doesn't exist"); | |
if (!Array.isArray(tokenColors)) | |
return fatal("`tokenColors` is not an array"); | |
/** | |
* @param {string[]} names | |
* @param {(it:any)=>boolean|undefined} callback | |
*/ | |
const modifyTokenColor = (names, callback) => { | |
const items = tokenColors.filter((it) => names.includes(it.name)); | |
if (items.length < 1) | |
fatal(`Could not find any item about [${names}] from \`tokenColors\``); | |
items.forEach((it) => { | |
if (callback(it) === false) return; | |
console.log(dim(` Updated: ${JSON.stringify(it)}`)); | |
}); | |
}; | |
const modifyColor = (name = "", newValue = "") => { | |
const prev = colors[name]; | |
if (prev === newValue) return; | |
if (!newValue) { | |
console.log(dim(` Deleted: ${name}`)); | |
delete colors[name]; | |
} else { | |
const log = ` Updated: ${name} = "${newValue}"`; | |
const comment = prev ? `# original color: ${prev}` : `# new`; | |
console.log(dim(log.padEnd(64) + comment)); | |
colors[name] = newValue; | |
} | |
}; | |
console.log("Fixing comment font ..."); | |
modifyTokenColor(["Comment", "Comments"], (it) => { | |
if (it.settings.fontStyle !== "italic") return false; | |
it.settings.fontStyle = "normal"; | |
}); | |
console.log("Fixing color for class name ..."); | |
modifyTokenColor(["Class name"], (it) => { | |
if (!it.settings.foreground) return false; | |
it.settings.foreground = "#268BD2"; | |
}); | |
console.log("Fixing color for `Support.construct` ..."); | |
modifyTokenColor(["Support.construct"], (it) => { | |
if (!it.settings.foreground) return false; | |
it.settings.foreground = "#D30102"; | |
}); | |
console.log("Fixing default foreground color ..."); | |
const items = tokenColors.filter((it) => !it.name && !it.scope); | |
if (items.length < 1) | |
return fatal("Could not find default setting in `tokenColors`"); | |
items.forEach((it) => { | |
if (!it.settings.foreground) return; | |
it.settings.foreground = "#586E75"; | |
console.log(dim(` Updated: ${JSON.stringify(it)}`)); | |
}); | |
console.log("Removing terminal colors overwrite ..."); | |
for (const colorName of Object.keys(colors)) | |
if (colorName.startsWith("terminal.")) modifyColor(colorName, ""); | |
console.log("Overwriting editor colors ..."); | |
modifyColor("editor.background", "#FDF6E3"); | |
modifyColor("editor.selectionBackground", "#586E75"); | |
modifyColor("editor.inactiveSelectionBackground", "#EEE8D5"); | |
modifyColor("badge.background", "#007ACC"); | |
modifyColor("activityBarBadge.background", "#007ACC"); | |
modifyColor("editorSuggestWidget.background", "#FFFDF9"); // background - 0.05 | |
modifyColor("editorSuggestWidget.selectedBackground", "#FDF6E3"); // background | |
modifyColor("editorHoverWidget.background", "#FFFDF9"); // background - 0.05 | |
modifyColor("sideBar.background", "#F4F1E5"); // "sideBar.background": "#EEE8D5" - 0.05 | |
console.log("Saving modified theme ..."); | |
writeText(filePath, JSON.stringify(obj, null, "\t")); | |
console.log( | |
"\nSuccess: The theme has been saved! (please reload VSCode for applying)\n" | |
); | |
} | |
} | |
function fatal(reason = "") { | |
console.error(`\n\u001b[31mError: ${reason}\u001b[39m\n`); | |
return process.exit(1); | |
} | |
function onPermissionError(reason = "") { | |
const admin = IS_WINDOWS ? "administrator" : "root"; | |
const msg = `You have not permission to ${reason}, Please make sure you are ${admin}`; | |
return fatal(msg); | |
} | |
function writeText(filePath, content) { | |
try { | |
writeFileSync(filePath, content); | |
} catch (error) { | |
console.error(`\u001b[31mError: ${error.message}\u001b[39m`); | |
return onPermissionError(`edit ${filePath}`); | |
} | |
} | |
function readText(filePath) { | |
try { | |
return readFileSync(filePath, "utf-8"); | |
} catch (error) { | |
console.error(`\u001b[31mError: ${error.message}\u001b[39m`); | |
if (error.code !== "ENOENT") return fatal(`file doesn't exist`); | |
return onPermissionError(`read file`); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment