├── src ├── models │ ├── I18N │ │ ├── index.ts │ │ └── Translation.ts │ ├── themes │ │ ├── colors │ │ │ ├── index.ts │ │ │ └── workspaceColor.ts │ │ ├── tokens │ │ │ ├── index.ts │ │ │ ├── tokenScopes.ts │ │ │ └── token.ts │ │ ├── themeJsonOptions.ts │ │ ├── index.ts │ │ ├── italicThemes.ts │ │ └── fontStyle.ts │ ├── index.ts │ ├── themeConfiguration.ts │ └── advancedWorkspaceConfiguration.ts ├── themes │ ├── TokenGroups │ │ ├── index.ts │ │ └── italicGroups.ts │ ├── index.ts │ ├── generator │ │ ├── index.ts │ │ ├── constants.ts │ │ ├── workspaceColorGenerator.ts │ │ ├── tokenGenerator.ts │ │ └── jsonGenerator.ts │ ├── tokenGroups.ts │ └── workspaceColors.ts ├── messages │ ├── index.ts │ ├── reload.ts │ ├── start.ts │ ├── welcome.ts │ ├── update.ts │ └── configUpdate.ts ├── commands │ ├── restoreConfig.ts │ ├── index.ts │ └── activate.ts ├── i18n │ ├── lang-en.ts │ └── index.ts ├── extension.ts └── helpers │ ├── objects.ts │ ├── versioning.ts │ ├── change-detection.ts │ └── index.ts ├── .gitattributes ├── icon.png ├── images ├── icon.png ├── nebula-socket-js-img.PNG ├── nebula_python_screenshot.PNG ├── nebula-defaults-socket-js-img.PNG ├── nebula-customized-socket-js-img.PNG ├── nebula_console_python_screenshot.PNG └── nebula_configured_python_screenshot.PNG ├── .gitignore ├── scripts ├── helpers │ └── painter.ts └── themes │ └── generateJson.ts ├── .vscodeignore ├── tslint.json ├── tsconfig.json ├── .vscode ├── settings.json ├── tasks.json └── launch.json ├── samples ├── socket.io.js ├── screenshot.py ├── colortest.sh ├── reactjs.js ├── typescript.ts └── python.py ├── LICENSE ├── themes ├── Nebula-color-theme-console.json └── Nebula-color-theme.json ├── README.md ├── CHANGELOG.md └── package.json /src/models/I18N/index.ts: -------------------------------------------------------------------------------- 1 | export * from './translation'; 2 | -------------------------------------------------------------------------------- /src/themes/TokenGroups/index.ts: -------------------------------------------------------------------------------- 1 | export * from './italicGroups'; -------------------------------------------------------------------------------- /src/models/themes/colors/index.ts: -------------------------------------------------------------------------------- 1 | export * from './workspaceColor'; -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eating-coleslaw/vscode-nebula-theme/HEAD/icon.png -------------------------------------------------------------------------------- /src/models/themes/tokens/index.ts: -------------------------------------------------------------------------------- 1 | export * from './token'; 2 | export * from './tokenScopes'; -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eating-coleslaw/vscode-nebula-theme/HEAD/images/icon.png -------------------------------------------------------------------------------- /images/nebula-socket-js-img.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eating-coleslaw/vscode-nebula-theme/HEAD/images/nebula-socket-js-img.PNG -------------------------------------------------------------------------------- /images/nebula_python_screenshot.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eating-coleslaw/vscode-nebula-theme/HEAD/images/nebula_python_screenshot.PNG -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode-test/ 4 | *.vsix 5 | vsc-extension-quickstart.md 6 | 7 | *.7z 8 | *.zip 9 | python.py 10 | Archive/ -------------------------------------------------------------------------------- /images/nebula-defaults-socket-js-img.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eating-coleslaw/vscode-nebula-theme/HEAD/images/nebula-defaults-socket-js-img.PNG -------------------------------------------------------------------------------- /images/nebula-customized-socket-js-img.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eating-coleslaw/vscode-nebula-theme/HEAD/images/nebula-customized-socket-js-img.PNG -------------------------------------------------------------------------------- /images/nebula_console_python_screenshot.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eating-coleslaw/vscode-nebula-theme/HEAD/images/nebula_console_python_screenshot.PNG -------------------------------------------------------------------------------- /src/themes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tokenGroups'; 2 | export * from './generator'; 3 | export * from './workspaceColors'; 4 | export * from './TokenGroups'; -------------------------------------------------------------------------------- /images/nebula_configured_python_screenshot.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eating-coleslaw/vscode-nebula-theme/HEAD/images/nebula_configured_python_screenshot.PNG -------------------------------------------------------------------------------- /src/models/index.ts: -------------------------------------------------------------------------------- 1 | export * from './themes'; 2 | export * from './advancedWorkspaceConfiguration'; 3 | export * from './themeConfiguration'; 4 | export * from './i18N'; -------------------------------------------------------------------------------- /src/models/themes/themeJsonOptions.ts: -------------------------------------------------------------------------------- 1 | export interface ThemeJsonOptions { 2 | commentItalics?: boolean; 3 | themeItalics?: string; 4 | materialize?: boolean; 5 | } -------------------------------------------------------------------------------- /src/messages/index.ts: -------------------------------------------------------------------------------- 1 | export * from './reload'; 2 | export * from './start'; 3 | export * from './update'; 4 | export * from './welcome'; 5 | export * from './configUpdate'; -------------------------------------------------------------------------------- /src/themes/generator/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | export * from './jsonGenerator'; 3 | export * from './tokenGenerator'; 4 | export * from './workspaceColorGenerator'; -------------------------------------------------------------------------------- /src/models/themes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './colors'; 2 | export * from './tokens'; 3 | export * from './fontStyle'; 4 | export * from './italicThemes'; 5 | export * from './themeJsonOptions'; 6 | -------------------------------------------------------------------------------- /src/models/themes/italicThemes.ts: -------------------------------------------------------------------------------- 1 | export enum ItalicsTheme { 2 | None = '0 - none', 3 | Basic = '1 - basic', 4 | More = '2 - wavy', 5 | Operator = '3 - curly', 6 | NoRestraint = '4 - no restraint' 7 | } -------------------------------------------------------------------------------- /src/models/themes/tokens/tokenScopes.ts: -------------------------------------------------------------------------------- 1 | import{ TokenStyle } from './token'; 2 | 3 | export interface ITokenGroup { 4 | 5 | name?: string; 6 | 7 | scope?: string[]; 8 | 9 | settings?: TokenStyle; 10 | 11 | } -------------------------------------------------------------------------------- /src/themes/generator/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * File name of the JSON file that will be generated to the out folder. 3 | */ 4 | export const themeJsonName: string = 'nebula-color-theme.json'; 5 | 6 | export const lastNonConfigVer: string = '1.0.5'; -------------------------------------------------------------------------------- /scripts/helpers/painter.ts: -------------------------------------------------------------------------------- 1 | // colored console output 2 | export const red = (value: string) => `\x1b[35m${value}\x1b[0m`; 3 | export const green = (value: string) => `\x1b[36m${value}\x1b[0m`; 4 | export const yellow = (value: string) => `\x1b[33m${value}\x1b[0m`; 5 | -------------------------------------------------------------------------------- /src/models/themes/colors/workspaceColor.ts: -------------------------------------------------------------------------------- 1 | export interface IWorkspaceColor { 2 | 3 | scope: string; 4 | 5 | color: string; 6 | 7 | /** 8 | * Determines whether this color element will be hidden when theme is materialized. 9 | */ 10 | materialize?: boolean; 11 | 12 | } -------------------------------------------------------------------------------- /src/models/themes/tokens/token.ts: -------------------------------------------------------------------------------- 1 | import { FontStyle } from '../fontStyle'; 2 | import { ItalicsTheme } from '../italicThemes'; 3 | 4 | export interface TokenStyle { 5 | 6 | foreground?: string; 7 | 8 | fontStyle?: FontStyle; 9 | 10 | excludeIn?: ItalicsTheme[]; 11 | 12 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | out/**/*.map 5 | src/** 6 | tsconfig.json 7 | .gitignore 8 | vsc-extension-quickstart.md 9 | tslint.json 10 | **/*.ts 11 | 12 | out/previews/** 13 | test/** 14 | scripts/** 15 | **/*.map 16 | images/** 17 | package-lock.json 18 | /samples -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-string-throw": true, 4 | "no-unused-expression": true, 5 | "no-duplicate-variable": true, 6 | "curly": true, 7 | "class-name": true, 8 | "semicolon": [ 9 | true, 10 | "always" 11 | ], 12 | "triple-equals": true 13 | }, 14 | "defaultSeverity": "warning" 15 | } -------------------------------------------------------------------------------- /src/models/I18N/Translation.ts: -------------------------------------------------------------------------------- 1 | export interface Translation { 2 | themeInstalled?: string; 3 | howToActivate?: string; 4 | activate?: string; 5 | activated?: string; 6 | themeUpdated?: string; 7 | readChangelog?: string; 8 | confirmReload?: string; 9 | reload?: string; 10 | reloadAndOpen?: string; 11 | } 12 | -------------------------------------------------------------------------------- /src/models/themeConfiguration.ts: -------------------------------------------------------------------------------- 1 | import { ThemeJsonOptions, ITokenGroup } from './index'; 2 | 3 | export class ThemeConfiguration { 4 | colors?: { [s: string]: string; }; 5 | tokenColors?: ITokenGroup[]; 6 | options?: ThemeJsonOptions; 7 | 8 | constructor() { 9 | this.colors = {}; 10 | this.tokenColors = []; 11 | this.options = {}; 12 | } 13 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "sourceMap": true, 6 | "outDir": "out", 7 | "rootDir": ".", 8 | "noUnusedLocals": true, /* Report errors on unused locals. */ 9 | "lib": [ 10 | "es6", 11 | "dom" 12 | ] 13 | }, 14 | "exclude": [ 15 | "node_modules", 16 | ".vscode-test", 17 | "scripts" 18 | ] 19 | } -------------------------------------------------------------------------------- /src/models/themes/fontStyle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Defines the fontStyle attribute values that can be applied to a color token. 3 | */ 4 | export enum FontStyle { 5 | Italics = 'italic', 6 | Bold = 'bold', 7 | Normal = 'normal', 8 | Underline = 'underline', 9 | BoldUnderline = 'bold underline', 10 | BoldItalics = 'bold italic', 11 | ItalicsUnderline = 'italic underline', 12 | None = '' 13 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "out": false, // set this to true to hide the "out" folder with the compiled JS files 4 | "**/*.js": {"when": "$(basename).ts"}, 5 | "**/**.js": {"when": "$(basename).tx"} 6 | }, 7 | "search.exclude": { 8 | "out": true // set this to false to include "out" folder in search results 9 | }, 10 | "C_Cpp.dimInactiveRegions": true 11 | } -------------------------------------------------------------------------------- /src/models/advancedWorkspaceConfiguration.ts: -------------------------------------------------------------------------------- 1 | export interface AdvancedWorkspaceConfiguration { 2 | get(section: string, defaultValue?: T): T; 3 | has(section: string): boolean; 4 | [key: string]: any; 5 | inspect(section: string): { defaultValue: T, globalValue: T, key: string, workspaceValue: T } | undefined; 6 | update(section: string, value: any, global?: boolean): Thenable; 7 | } 8 | -------------------------------------------------------------------------------- /src/commands/restoreConfig.ts: -------------------------------------------------------------------------------- 1 | import * as helpers from './../helpers'; 2 | import { getDefaultThemeOptions } from '../themes/index'; 3 | 4 | /** Restore all configurations to default. */ 5 | export const restoreDefaultConfig = () => { 6 | const defaultOptions = getDefaultThemeOptions(); 7 | helpers.setThemeConfig('commentItalics', defaultOptions.commentItalics, true); 8 | helpers.setThemeConfig('themeItalics', defaultOptions.themeItalics, true); 9 | helpers.setThemeConfig('materialize', defaultOptions.materialize, true); 10 | }; -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "build", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /src/i18n/lang-en.ts: -------------------------------------------------------------------------------- 1 | import { Translation } from '../models'; 2 | 3 | export const translation: Translation = { 4 | 'themeInstalled': 'Nebula Theme has been installed.', 5 | 'howToActivate': 'How to activate color themes', 6 | 'activate': 'Activate', 7 | 'activated': 'Nebula Theme is active.', 8 | 'themeUpdated': 'Nebula Theme has been updated.', 9 | 'readChangelog': 'Read changelog', 10 | 'confirmReload': 'You have to reload VS Code to activate the changes to the theme.', 11 | 'reload': 'Reload', 12 | 'reloadAndOpen': 'Reload & View Changes' 13 | }; 14 | -------------------------------------------------------------------------------- /samples/socket.io.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Encode packet helpers for binary types 3 | */ 4 | 5 | function encodeArrayBuffer(packet, supportsBinary, callback) { 6 | if (!supportsBinary) { 7 | return exports.encodeBase64Packet(packet, callback); 8 | } 9 | 10 | var data = packet.data; 11 | var contentArray = new Uint8Array(data); 12 | var resultBuffer = new Uint8Array(1 + data.byteLength); 13 | 14 | resultBuffer[0] = packets[packet.type]; 15 | for (var i = 0; i < contentArray.length; i++) { 16 | resultBuffer[i + 1] = contentArray[i]; 17 | } 18 | 19 | return callback(resultBuffer.buffer); 20 | } -------------------------------------------------------------------------------- /src/commands/index.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import { activateColorTheme } from './activate'; 3 | import { restoreDefaultConfig } from './restoreConfig'; 4 | 5 | // Activate theme 6 | const activateThemeCommand = vscode.commands.registerCommand('nebula-theme.activateTheme', () => { 7 | activateColorTheme(); 8 | }); 9 | 10 | // Reset config 11 | const restoreDefaultConfigCommand = vscode.commands.registerCommand('nebula-theme.restoreDefaultConfig', () => { 12 | restoreDefaultConfig(); 13 | }); 14 | 15 | export const commands = [ 16 | activateThemeCommand, 17 | restoreDefaultConfigCommand 18 | ]; 19 | -------------------------------------------------------------------------------- /src/themes/generator/workspaceColorGenerator.ts: -------------------------------------------------------------------------------- 1 | import { IWorkspaceColor, ThemeConfiguration, ThemeJsonOptions } from '../../models/index'; 2 | 3 | export const getWorkspaceColorDefinitions = (wsColors: IWorkspaceColor[], config: ThemeConfiguration, options: ThemeJsonOptions): ThemeConfiguration => { 4 | let colors = {}; 5 | 6 | wsColors.forEach(wsColor => { 7 | let setColor: string; 8 | 9 | if (options.materialize) { 10 | setColor = wsColor.materialize ? NamedColor.Transparent : wsColor.color; 11 | } else { 12 | setColor = wsColor.color; 13 | } 14 | 15 | colors[wsColor.scope] = setColor; 16 | }); 17 | 18 | config.colors = colors; 19 | 20 | return config; 21 | }; 22 | 23 | const enum NamedColor { 24 | Transparent = '#0000' 25 | } -------------------------------------------------------------------------------- /src/messages/reload.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import * as i18n from './../i18N'; 3 | 4 | /** User has to confirm if he wants to reload the editor */ 5 | export const showConfirmToReloadMessage = (): Promise => { 6 | return new Promise((resolve, reject) => { 7 | 8 | vscode.window.showInformationMessage( 9 | i18n.translate('confirmReload'), 10 | i18n.translate('reload') 11 | ).then(value => { 12 | switch (value) { 13 | case i18n.translate('reload'): 14 | resolve(true); 15 | break; 16 | 17 | default: 18 | resolve(false); 19 | break; 20 | } 21 | }); 22 | }); 23 | }; 24 | -------------------------------------------------------------------------------- /scripts/themes/generateJson.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is only a script file that should only be executed by the npm scripts. 3 | */ 4 | import { createThemeFile } from './../../src/themes/index'; 5 | import * as path from 'path'; 6 | import * as fs from 'fs'; 7 | import * as painter from '../helpers/painter'; 8 | 9 | createThemeFile().then((fileName: string) => { 10 | const filePath = path.resolve('src', fileName); 11 | const out = path.resolve('out', 'src', fileName); 12 | fs.rename(filePath, out, (err) => { 13 | if (err) { 14 | console.error(painter.red(err.stack)); 15 | } else { 16 | console.log('> Nebula Color Theme:', painter.green(`Successfully generated color theme JSON file!`)); 17 | } 18 | }); 19 | }).catch(err => { 20 | console.error(painter.red(err)); 21 | }); 22 | -------------------------------------------------------------------------------- /src/commands/activate.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import * as helpers from './../helpers'; 3 | import * as i18n from './../i18N'; 4 | 5 | /** Activate the color theme by changing the settings for the colorTheme. */ 6 | export const activateColorTheme = () => { 7 | return setColorTheme(); 8 | }; 9 | 10 | /** Set the color theme in the config. */ 11 | const setColorTheme = () => { 12 | // global user config 13 | return helpers.getConfig().update('workbench.colorTheme', 'Nebula', true) 14 | .then(() => { 15 | // local workspace config 16 | if (helpers.getConfig().inspect('workbench.colorTheme').workspaceValue !== undefined) { 17 | helpers.getConfig().update('workbench.colorTheme', 'Nebula'); 18 | } 19 | vscode.window.showInformationMessage(i18n.translate('activated')); 20 | }); 21 | }; 22 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that launches the extension inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "--extensionDevelopmentPath=${workspaceFolder}" 15 | ], 16 | "outFiles": [ 17 | "${workspaceFolder}/out/**/*.js" 18 | ], 19 | "smartStep": true, 20 | "sourceMaps": true, 21 | "preLaunchTask": "npm: build" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /src/messages/start.ts: -------------------------------------------------------------------------------- 1 | import { showUpdateMessage } from './update'; 2 | import { showWelcomeMessage } from './welcome'; 3 | import { showConfigUpdateMessages } from './configUpdate'; 4 | import { ThemeStatus } from '../helpers/versioning'; 5 | import { reloadWindow } from '../helpers'; 6 | 7 | /** Initialization of the colors every time the theme get activated */ 8 | export const showStartMessages = (themeStatus: Promise) => { 9 | return themeStatus.then((status: ThemeStatus) => { 10 | if (status === ThemeStatus.updated) { 11 | showUpdateMessage(); 12 | } 13 | else if (status === ThemeStatus.neverUsedBefore) { 14 | showWelcomeMessage(); 15 | } 16 | else if (status === ThemeStatus.firstConfigurable) { 17 | showConfigUpdateMessages().then(() => { 18 | reloadWindow(); 19 | }); 20 | } 21 | }); 22 | }; 23 | -------------------------------------------------------------------------------- /samples/screenshot.py: -------------------------------------------------------------------------------- 1 | import urllib2 # html scraper 2 | import re # regex module 3 | import sys # exit quits program prematurely in event of error 4 | 5 | OPENER = urllib2.build_opener() 6 | OPENER.addheaders = [('User-agent', 'Mozilla/5.0')] 7 | 8 | def main(url): 9 | url = check_url_protocol(url) 10 | tease_html = scrape_html(url) 11 | print 'Did you think I would actually print that?' 12 | sys.exit(0) 13 | 14 | def check_url_protocol(url): 15 | """Ensures a given url has the http:// protocl.""" 16 | if re.compile('http://').match(url) == None: 17 | url = 'http://' + url 18 | return url 19 | else: 20 | return url 21 | 22 | def scrape_html(url): 23 | """Scrapes and returns html from a single url.""" 24 | html = None 25 | try: 26 | response = OPENER.open(url) 27 | if response.code == 200: 28 | html = response.read() 29 | else: 30 | print "Invalid URL: %s \n" % url 31 | except urllib2.HTTPError: 32 | print "Failed to open %s \n" % url 33 | return html 34 | 35 | main("michellezauner.bandcamp.com") 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 eating-coleslaw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /samples/colortest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # This file echoes a bunch of color codes to the 4 | # terminal to demonstrate what's available. Each 5 | # line is the color code of one forground color, 6 | # out of 17 (default + 16 escapes), followed by a 7 | # test use of that color on all nine background 8 | # colors (default + 8 escapes). 9 | # 10 | # Author: Giles Orr 11 | # URL: http://gilesorr.com/bashprompt/howto/c350.html 12 | # License: GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; 13 | # http://gilesorr.com/bashprompt/howto/a1004.html 14 | 15 | 16 | T='gYw' # The test text 17 | 18 | echo -e "\n 40m 41m 42m 43m\ 19 | 44m 45m 46m 47m"; 20 | 21 | for FGs in ' m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' ' 32m' \ 22 | '1;32m' ' 33m' '1;33m' ' 34m' '1;34m' ' 35m' '1;35m' \ 23 | ' 36m' '1;36m' ' 37m' '1;37m'; 24 | do FG=${FGs// /} 25 | echo -en " $FGs \033[$FG $T " 26 | for BG in 40m 41m 42m 43m 44m 45m 46m 47m; 27 | do echo -en "$EINS \033[$FG\033[$BG $T \033[0m"; 28 | done 29 | echo; 30 | done 31 | echo 32 | -------------------------------------------------------------------------------- /src/messages/welcome.ts: -------------------------------------------------------------------------------- 1 | import * as helpers from './../helpers'; 2 | import * as vscode from 'vscode'; 3 | import opn = require('opn'); 4 | import * as i18n from './../i18N'; 5 | import { activateColorTheme } from '../commands/activate'; 6 | 7 | /** Show the welcome message if the color theme has been installed the first time. */ 8 | export const showWelcomeMessage = () => { 9 | 10 | vscode.window.showInformationMessage( 11 | i18n.translate('themeInstalled'), 12 | 13 | // show 'Activate' button if icon theme is not active 14 | helpers.isThemeNotVisible() ? i18n.translate('activate') : i18n.translate('howToActivate') 15 | ).then(handleWelcomeMessageActions); 16 | }; 17 | 18 | /** Handle the actions of the welcome message. */ 19 | const handleWelcomeMessageActions = (value) => { 20 | switch (value) { 21 | case i18n.translate('activate'): 22 | activateColorTheme(); 23 | break; 24 | 25 | case i18n.translate('howToActivate'): 26 | opn('https://code.visualstudio.com/docs/getstarted/themes#_selecting-the-color-theme'); 27 | break; 28 | 29 | default: 30 | break; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /src/messages/update.ts: -------------------------------------------------------------------------------- 1 | import * as helpers from './../helpers'; 2 | import * as vscode from 'vscode'; 3 | import opn = require('opn'); 4 | import * as i18n from './../i18N'; 5 | import { activateColorTheme } from '../commands/activate'; 6 | 7 | /** Show the update message if the icon theme has been updated. */ 8 | export const showUpdateMessage = () => { 9 | 10 | vscode.window.showInformationMessage( 11 | i18n.translate('themeUpdated'), 12 | 13 | // show 'Activate' button if icon theme is not active 14 | helpers.isThemeNotVisible() 15 | ? i18n.translate('activate') : undefined, 16 | 17 | i18n.translate('readChangelog') 18 | ).then(handleUpdateMessageActions); 19 | }; 20 | 21 | /** Handle the actions of the update message. */ 22 | const handleUpdateMessageActions = (value) => { 23 | switch (value) { 24 | case i18n.translate('activate'): 25 | activateColorTheme(); 26 | break; 27 | 28 | case i18n.translate('readChangelog'): 29 | opn('https://marketplace.visualstudio.com/items/ChirtleLovesDolls.nebula-theme/changelog'); 30 | break; 31 | 32 | default: 33 | break; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as vscode from 'vscode'; 4 | import * as i18n from './i18N'; 5 | import * as commands from './commands'; 6 | import { showStartMessages } from './messages/start'; 7 | import { detectConfigChanges } from './helpers/change-detection'; 8 | import { checkThemeStatus } from './helpers/versioning'; 9 | 10 | /** 11 | * This method is called when the extension is activated. 12 | * It initializes the core functionality of the extension. 13 | */ 14 | export const activate = (context: vscode.ExtensionContext) => { 15 | // Load the translations 16 | i18n.initTranslations().then(() => { 17 | showStartMessages(checkThemeStatus(context.globalState)); 18 | }).catch(err => console.error(err)); 19 | 20 | // Add commands to the editor 21 | context.subscriptions.push(...commands.commands); 22 | 23 | // Initially trigger the config change detection 24 | detectConfigChanges().catch(e => { 25 | console.error(e); 26 | }); 27 | 28 | // Observe changes in the config 29 | vscode.workspace.onDidChangeConfiguration(detectConfigChanges); 30 | }; 31 | 32 | /** This method is called when the extension is deactivated */ 33 | export const deactivate = () => { 34 | }; 35 | -------------------------------------------------------------------------------- /themes/Nebula-color-theme-console.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Nebula - Console", 3 | "include": "./Nebula-color-theme.json", 4 | "colors": { 5 | "activityBar.background": "#f6f0ff", 6 | "activityBar.foreground": "#353551", 7 | "activityBar.border": "#FBD3E1", 8 | "statusBar.background": "#27273A", 9 | "statusBar.border": "#1F2330", 10 | "statusBar.noFolderBackground": "#1F2330", 11 | "statusBar.debuggingBackground": "#27273A", 12 | "panel.background": "#353551", 13 | "editorWidget.background": "#353551", 14 | "editorSuggestWidget.background": "#353551", 15 | "editorSuggestWidget.selectedBackground": "#f6f0ff30", 16 | "editorMarkerNavigation.background": "#353551", 17 | "dropdown.listBackground": "#27273A", 18 | "debugToolBar.background": "#353551", 19 | "inputValidation.infoBackground": "#353551", 20 | "inputValidation.warningBackground": "#353551", 21 | "inputValidation.errorBackground": "#353551", 22 | "notificationCenterHeader.background": "#353551", 23 | "sideBarSectionHeader.background": "#353551", 24 | "editorHoverWidget.background": "#353551", 25 | "peekViewTitle.background": "#353551", 26 | "peekViewResult.background": "#27273A", 27 | "peekViewResult.selectionBackground": "#f6f0ff30" 28 | } 29 | } -------------------------------------------------------------------------------- /src/messages/configUpdate.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import * as i18n from './../i18N'; 3 | import opn = require('opn'); 4 | 5 | /** User has to confirm if they want to reload the editor */ 6 | export const showConfigUpdateMessages = (): Promise => { 7 | return new Promise((resolve, reject) => { 8 | 9 | vscode.window.showInformationMessage( 10 | 'Restart VS Code to start using the latest Nebula features', 11 | i18n.translate('reload'), 12 | i18n.translate('readChangelog'), 13 | i18n.translate('reloadAndOpen') 14 | ).then(value => { 15 | switch (value) { 16 | case i18n.translate('reload'): 17 | resolve(true); 18 | break; 19 | 20 | case i18n.translate('readChangelog'): 21 | opn('https://marketplace.visualstudio.com/items/ChirtleLovesDolls.nebula-theme/changelog'); 22 | break; 23 | 24 | case i18n.translate('reloadAndOpen'): 25 | opn('https://marketplace.visualstudio.com/items/ChirtleLovesDolls.nebula-theme/changelog'); 26 | resolve(true); 27 | break; 28 | 29 | default: 30 | resolve(false); 31 | break; 32 | } 33 | }); 34 | }); 35 | }; 36 | -------------------------------------------------------------------------------- /src/helpers/objects.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the nested properties of an object 3 | * This solution is lighter than the lodash get-version and works fine for the translations. 4 | * Source: http://stackoverflow.com/a/6491621/6942210 5 | */ 6 | export const getObjectPropertyValue = (obj: Object, path: string) => { 7 | // convert indexes to properties 8 | path = path.replace(/\[(\w+)\]/g, '.$1'); 9 | 10 | // strip a leading dot 11 | path = path.replace(/^\./, ''); 12 | 13 | // separate paths in array 14 | let pathArray = path.split('.'); 15 | 16 | /** Avoid errors in the getValue function. */ 17 | const isObject = (object) => { 18 | return object === Object(object); 19 | }; 20 | 21 | for (let i = 0; i < pathArray.length; ++i) { 22 | let k = pathArray[i]; 23 | if (isObject(obj) && k in obj) { 24 | obj = obj[k]; 25 | } else { 26 | return; 27 | } 28 | } 29 | return obj; 30 | }; 31 | 32 | /** 33 | * Set a value for a nested object property. 34 | * @param obj Object 35 | * @param path Properties as string e.g. `'a.b.c'` 36 | * @param value Value to be set for the given property 37 | * Source: https://stackoverflow.com/a/13719799/6942210 38 | */ 39 | export const setObjectPropertyValue = (obj: Object, path, value) => { 40 | if (typeof path === 'string') { 41 | path = path.split('.'); 42 | } 43 | 44 | if (path.length > 1) { 45 | let e = path.shift(); 46 | setObjectPropertyValue(obj[e] = 47 | Object.prototype.toString.call(obj[e]) === '[object Object]' 48 | ? obj[e] 49 | : {}, 50 | path, 51 | value); 52 | } else { 53 | obj[path[0]] = value; 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /src/themes/generator/tokenGenerator.ts: -------------------------------------------------------------------------------- 1 | import { ThemeConfiguration, ThemeJsonOptions, ITokenGroup, FontStyle, ItalicsTheme } from '../../models/index'; 2 | import { commentScope, basicScopes, moreScopes, operatorScopes, noRestraintScopes } from '../TokenGroups/index'; 3 | 4 | 5 | export const getTokenStyleDefinitions = (tokenColors: ITokenGroup[], config: ThemeConfiguration, options: ThemeJsonOptions): ThemeConfiguration => { 6 | const italicTokenDefinitions = setItalicTokenDefinitions(options.commentItalics, options.themeItalics); 7 | 8 | config.tokenColors = [...tokenColors, ...italicTokenDefinitions.tokenColors]; 9 | 10 | return config; 11 | }; 12 | 13 | 14 | const setItalicTokenDefinitions = (italicComments: boolean, italicsTheme: string) => { 15 | let obj = { tokenColors: [] }; 16 | 17 | obj.tokenColors = [ 18 | { 19 | name: 'Compiled Italics', 20 | scope: [...getItalicScopeArray(italicComments, italicsTheme)], 21 | settings: { fontStyle: `${FontStyle.Italics}`} 22 | } 23 | ]; 24 | 25 | return obj; 26 | }; 27 | 28 | 29 | const getItalicScopeArray = (italicComments: boolean, italicsTheme: string): string[] => { 30 | let array: string[] = []; 31 | if (italicComments) { 32 | array = [...array, ...commentScope]; 33 | } 34 | 35 | if (italicsTheme === ItalicsTheme.None) { return array; } 36 | 37 | if (italicsTheme === ItalicsTheme.Basic) { 38 | array = [...array, ...basicScopes]; 39 | return array; 40 | } 41 | 42 | else if (italicsTheme === ItalicsTheme.More) { 43 | array = [...array, ...basicScopes, ...moreScopes]; 44 | return array; 45 | } 46 | 47 | else if (italicsTheme === ItalicsTheme.Operator) { 48 | array = [...array, ...basicScopes, ...moreScopes, ...operatorScopes]; 49 | return array; 50 | } 51 | 52 | else if (italicsTheme === ItalicsTheme.NoRestraint) { 53 | array = [...array, ...basicScopes, ...moreScopes, ...operatorScopes, ...noRestraintScopes]; 54 | return array; 55 | } 56 | 57 | // Default to Basic Scopes italic theme 58 | else { 59 | array = [...array, ...basicScopes]; 60 | return array; 61 | } 62 | }; -------------------------------------------------------------------------------- /src/themes/generator/jsonGenerator.ts: -------------------------------------------------------------------------------- 1 | import { workspaceColors } from '../workspaceColors'; 2 | import { tokenGroups } from '../tokenGroups'; 3 | import { getWorkspaceColorDefinitions } from './workspaceColorGenerator'; 4 | import { themeJsonName } from './constants'; 5 | import { ThemeJsonOptions, ThemeConfiguration, ItalicsTheme } from '../../models'; 6 | import * as path from 'path'; 7 | import * as fs from 'fs'; 8 | import { getTokenStyleDefinitions } from './tokenGenerator'; 9 | 10 | /** 11 | * Create the JSON file that is responsible for the theme's appearance in the editor. 12 | */ 13 | export const createThemeFile = (jsonOptions?: ThemeJsonOptions): Promise => { 14 | // override the default options with the new options 15 | const options = {...getDefaultThemeOptions(), ...jsonOptions}; 16 | 17 | const themeJsonPath = path.join(__dirname, '../../../', 'src', themeJsonName); 18 | 19 | const json = generateThemeConfigurationObject(options); 20 | 21 | return new Promise((resolve, reject) => { 22 | fs.writeFile(themeJsonPath, JSON.stringify(json, undefined, 2), (err) => { 23 | if (err) { 24 | reject(err); } 25 | else { 26 | resolve(themeJsonName); 27 | } 28 | }); 29 | }); 30 | }; 31 | 32 | /** 33 | * Generate the complete theme configuration object that can be written as JSON file. 34 | */ 35 | export const generateThemeConfigurationObject = (options: ThemeJsonOptions): ThemeConfiguration => { 36 | 37 | const themeConfig = new ThemeConfiguration(); 38 | 39 | themeConfig.options = {...themeConfig.options, ...options}; 40 | 41 | const workspaceColorsConfig = getWorkspaceColorDefinitions(workspaceColors, themeConfig, options); 42 | themeConfig.colors = workspaceColorsConfig.colors; 43 | 44 | const tokenColorsConfig = getTokenStyleDefinitions(tokenGroups, themeConfig, options); 45 | themeConfig.tokenColors = tokenColorsConfig.tokenColors; 46 | 47 | return themeConfig; 48 | }; 49 | 50 | /** 51 | * The options control the generator 52 | */ 53 | export const getDefaultThemeOptions = (): ThemeJsonOptions => ({ 54 | commentItalics: true, 55 | themeItalics: ItalicsTheme.More, 56 | materialize: false 57 | }); 58 | -------------------------------------------------------------------------------- /src/helpers/versioning.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import * as helpers from './index'; 3 | import semver = require('semver'); 4 | import { lastNonConfigVer } from '../themes/index'; 5 | 6 | export enum ThemeStatus { 7 | neverUsedBefore, 8 | firstConfigurable, 9 | updated, 10 | current 11 | } 12 | 13 | /** Check the current status of the theme */ 14 | export const checkThemeStatus = async (state: vscode.Memento) => { 15 | try { 16 | // get the version from the state 17 | const stateVersion = await state.get('nebula-theme.version'); 18 | const packageVersion = getCurrentExtensionVersion(); 19 | 20 | // check if the theme was used before 21 | if (stateVersion === undefined) { 22 | await updateExtensionVersionInMemento(state); 23 | if (!themeIsAlreadyActivated()) { 24 | return ThemeStatus.neverUsedBefore; 25 | } 26 | else if (semver.gt(packageVersion, lastNonConfigVer)) { 27 | return ThemeStatus.firstConfigurable; 28 | } 29 | else {return themeIsAlreadyActivated() ? ThemeStatus.updated : ThemeStatus.neverUsedBefore; } 30 | } 31 | 32 | // compare the version in the state with the package version 33 | else if (semver.lt(stateVersion, packageVersion)) { 34 | await updateExtensionVersionInMemento(state); 35 | return ThemeStatus.updated; 36 | } 37 | else { 38 | return ThemeStatus.current; 39 | } 40 | } 41 | catch (err) { 42 | console.error(err); 43 | } 44 | }; 45 | 46 | /** Check if the theme was used before */ 47 | const themeIsAlreadyActivated = () => { 48 | return helpers.isThemeActivated() || helpers.isThemeActivated(true); 49 | }; 50 | 51 | /** Update the version number to the current version in the memento. */ 52 | const updateExtensionVersionInMemento = async (state: vscode.Memento) => { 53 | return await state.update('nebula-theme.version', getCurrentExtensionVersion()); 54 | }; 55 | 56 | /** Get the current version of the extension */ 57 | const getCurrentExtensionVersion = (): string => { 58 | return vscode.extensions.getExtension('ChirtleLovesDolls.nebula-theme').packageJSON.version; 59 | }; -------------------------------------------------------------------------------- /src/helpers/change-detection.ts: -------------------------------------------------------------------------------- 1 | import { createThemeFile } from '../themes/index'; 2 | import { getObjectPropertyValue, setObjectPropertyValue } from './objects'; 3 | import { getExtensionConfiguration, promptToReload, getColorThemeJson, getThemeConfig } from '.'; 4 | import { green } from '../../scripts/helpers/painter'; 5 | 6 | /** Compare the workspace and the user configurations with the current setup of the theme. */ 7 | export const detectConfigChanges = () => { 8 | const configs = Object.keys(getExtensionConfiguration()) 9 | .map(c => c.split('.').slice(1).join('.')); 10 | 11 | return compareConfigs(configs).then(updatedOptions => { 12 | 13 | // if there's nothing to update 14 | if (!updatedOptions) { return; } 15 | 16 | // update theme json file with new options 17 | return createThemeFile(updatedOptions).then(() => { 18 | console.log(green('New theme configuration file successfully created!')); 19 | promptToReload(); 20 | }).catch(err => { 21 | console.error(err); 22 | }); 23 | }); 24 | }; 25 | 26 | /** 27 | * Compares a specific configuration in the settings with a current configuration state. 28 | * The current configuration state is read from the theme json file. 29 | * @param configs List of configuration names 30 | * @returns List of configurations that needs to be updated. 31 | */ 32 | const compareConfigs = (configs: string[]): Promise<{ [name: string]: any }> => { 33 | let updateRequired = false; 34 | 35 | return getColorThemeJson().then(json => { 36 | configs.forEach(configName => { 37 | let configValue = getThemeConfig(configName).globalValue; 38 | if (configValue === undefined) { 39 | configValue = getThemeConfig(configName).defaultValue; 40 | } 41 | 42 | const currentState = getObjectPropertyValue(json.options, configName); 43 | 44 | // If property is deleted, and it wasn't the default value, set it to the default value 45 | if (JSON.stringify(configValue) !== JSON.stringify(currentState)) { 46 | setObjectPropertyValue(json.options, configName, configValue); 47 | updateRequired = true; 48 | } 49 | }); 50 | 51 | return updateRequired ? json.options : undefined; 52 | }); 53 | }; 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nebula Theme for VS Code 2 | 🌌🌸Fresh colors on a dark, cold slate. An almost-material theme for Visual Studio Code. 3 | 4 | ![Theme Preview](https://raw.githubusercontent.com/eating-coleslaw/vscode-nebula-theme/master/images/nebula-defaults-socket-js-img.PNG) 5 | 6 | ## __Configuration__ 7 | 8 | Instead of bundling together several Nebula theme variants, there's only one main theme file that's dynamically generated based on a few configuration settings. Customize the theme to suit your preferences without leaving VS Code! 9 | 10 | ### _Comment Italics_ 11 | 12 | Toggle whether code comments are italicized using the `nebula-theme.commentItalics` setting. 13 | 14 | ### _Theme Italics_ 15 | 16 | Select the amount of italicized code you prefer, or disable code italics completely using the `nebula-theme.themeItalics` setting. Choose from five flavors: 17 | 18 | - `0 - None` 19 | - `1 - Basic` 20 | - `2 - Wavy` 21 | - `3 - Curly` 22 | - `4 - No Restraint` 23 | 24 | ### _Materialize_ 25 | 26 | For those that favor flat-style UIs, enable the `nebula-theme.materialize`. This will hide borders between workbench sections and a few other select elements. 27 | 28 | ![Comment Italics: False, Theme Italics: 3 - Curly, Materialize: True](https://raw.githubusercontent.com/eating-coleslaw/vscode-nebula-theme/master/images/nebula-customized-socket-js-img.PNG) 29 | 30 | > Comment Italics: False | Theme Italics: 3 - Curly | Materialize: True 31 | 32 | ## __Issues__ 33 | 34 | There's not much precedent for this style of theme configurability, so I expect a bumpy ride for these first few minor releases. If you notice any issues, particularly around the configuration options, updates, and activation, please write it up with reproduction steps on the github repo. Please be nice, though; I learned typescript with this development 😅. 35 | 36 | My primary concern after functional problems is accessibility-related problems. If there's something I could update or add, don't hesitate to write up an issue on the github repo with your suggestion. 37 | 38 | ## __Credits__ 39 | 40 | The configurability of this theme was made possibly thanks to Philipp Kief's generous licensing of the source code to his wonderful [Material Icon Theme](https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme). I highly recommend installing it alongside Nebula, using a folder color of `#CDF6FE`. 41 | 42 | >_Crafted with love, for you, by Chirtle_ 💕 -------------------------------------------------------------------------------- /samples/reactjs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import './App.css'; 5 | import uniqid from 'uniqid'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | class App extends Component { 15 | constructor(props) { 16 | super(props); 17 | 18 | this.state = { 19 | tasks: [], 20 | value: '', 21 | taskIndex: 0, 22 | }; 23 | 24 | this.handleChange = this.handleChange.bind(this); 25 | this.handleSubmit = this.handleSubmit.bind(this); 26 | } 27 | 28 | handleChange(event) { 29 | this.setState({ value: event.target.value }); 30 | } 31 | 32 | handleSubmit(event) { 33 | this.addTask(this.state.value) 34 | 35 | this.setState({ value: '' }); 36 | 37 | event.preventDefault(); 38 | } 39 | 40 | addTask(task) { 41 | this.setState({ taskIndex: this.state.taskIndex + 1 }); 42 | 43 | let keyedTask = { 44 | name: task, 45 | id: uniqid(), 46 | number: this.state.taskIndex, 47 | }; 48 | 49 | this.setState({ tasks: this.state.tasks.concat(keyedTask) }); 50 | } 51 | 52 | render() { 53 | return ( 54 |
55 |
56 | 57 | 63 | 64 |
65 | 66 |
67 | ); 68 | } 69 | } 70 | 71 | class Overview extends Component { 72 | // eslint-disable-next-line 73 | constructor(props) { 74 | super(props); 75 | } 76 | 77 | render() { 78 | const taskList = this.props.tasks.map((keyedTask) => { 79 | return 84 | }); 85 | 86 | return ( 87 |
    {taskList}
88 | ) 89 | } 90 | } 91 | 92 | const TaskRow = (props) => { 93 | return ( 94 |
  • 95 | {props.index + 1}. {props.task} 96 |
  • 97 | ); 98 | } -------------------------------------------------------------------------------- /samples/typescript.ts: -------------------------------------------------------------------------------- 1 | import { createThemeFile, getDefaultThemeOptions } from '../src/themes/index'; 2 | import { getObjectPropertyValue, setObjectPropertyValue } from '../src/helpers/objects'; 3 | import { getExtensionConfiguration, promptToReload, getColorThemeJson, getThemeConfig } from '../src/helpers/index'; 4 | import { green } from '../scripts/helpers/painter'; 5 | 6 | /** Compare the workspace and the user configurations with the current setup of the theme. */ 7 | export const detectConfigChanges = () => { 8 | const configs = Object.keys(getExtensionConfiguration()) 9 | .map(c => c.split('.').slice(1).join('.')); 10 | 11 | return compareConfigs(configs).then(updatedOptions => { 12 | 13 | // if there's nothing to update 14 | if (!updatedOptions) { return; } 15 | 16 | // update theme json file with new options 17 | return createThemeFile(updatedOptions).then(() => { 18 | console.log(green('New theme configuration file successfully created!')); 19 | promptToReload(); 20 | }).catch(err => { 21 | console.error(err); 22 | }); 23 | }); 24 | }; 25 | 26 | /** 27 | * Compares a specific configuration in the settings with a current configuration state. 28 | * The current configuration state is read from the theme json file. 29 | * @param configs List of configuration names 30 | * @returns List of configurations that needs to be updated. 31 | */ 32 | const compareConfigs = (configs: string[]): Promise<{ [name: string]: any }> => { 33 | let updateRequired = false; 34 | 35 | return getColorThemeJson().then(json => { 36 | const defaults = getDefaultThemeOptions(); 37 | 38 | configs.forEach(configName => { 39 | 40 | const configValue = getThemeConfig(configName).globalValue; 41 | const currentState = getObjectPropertyValue(json.options, configName); 42 | const configDefault = getObjectPropertyValue(defaults, configName); 43 | 44 | // If property is deleted, and it wasn't the default value, set it to the default value 45 | if (configValue === undefined && currentState !== configDefault) { 46 | setObjectPropertyValue(json.options, configName, configDefault); 47 | updateRequired = true; 48 | } 49 | 50 | else if (configValue !== undefined && currentState !== configValue) { 51 | setObjectPropertyValue(json.options, configName, configValue); 52 | updateRequired = true; 53 | } 54 | }); 55 | 56 | return updateRequired ? json.options : undefined; 57 | }); 58 | }; 59 | -------------------------------------------------------------------------------- /src/i18n/index.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import { getObjectPropertyValue } from '../helpers/objects'; 3 | 4 | // Get current language of the vs code workspace 5 | export const getCurrentLanguage = (): string => 6 | vscode.env.language; 7 | 8 | let currentTranslation; 9 | let fallbackTranslation; // default: en 10 | const PLACEHOLDER = '%'; 11 | 12 | /** 13 | * Initialize the translations 14 | * - Currently, messages are only available in English-US. 15 | */ 16 | export const initTranslations = async () => { 17 | try { 18 | currentTranslation = await loadTranslation('en'); 19 | fallbackTranslation = await loadTranslation('en'); 20 | } 21 | catch (error) { 22 | console.error(error); 23 | } 24 | }; 25 | 26 | /** Load the required translation */ 27 | const loadTranslation = (language: string): Promise => { 28 | return getTranslationObject(language) 29 | .catch(() => getTranslationObject('en')); 30 | }; 31 | 32 | /** Get the translation object of the separated translation files */ 33 | const getTranslationObject = async (language: string): Promise => { 34 | try { 35 | // tslint:disable-next-line:semicolon 36 | const lang = await import('./lang-' + language); 37 | return lang.translation; 38 | } 39 | catch (error) { 40 | console.log(error); 41 | } 42 | }; 43 | 44 | /** 45 | * We look up the matching translation in the translation files. 46 | * If we cannot find a matching key in the file we use the fallback. 47 | * With optional parameters you can configure both the translations 48 | * and the fallback (required for testing purposes). 49 | * */ 50 | export const getTranslationValue = (key: string, translations = currentTranslation, fallback = fallbackTranslation) => { 51 | return getObjectPropertyValue(translations, key) ? 52 | getObjectPropertyValue(translations, key) : 53 | getObjectPropertyValue(fallback, key) ? 54 | getObjectPropertyValue(fallback, key) : undefined; 55 | }; 56 | 57 | /** 58 | * The instant method is required for the translate pipe. 59 | * It helps to translate a word instantly. 60 | */ 61 | export const translate = (key: string, words?: string | string[]) => { 62 | const translation = getTranslationValue(key); 63 | 64 | if (!words) { return translation; } 65 | return replace(translation, words); 66 | }; 67 | 68 | /** 69 | * The replace function will replace the current placeholder with the 70 | * data parameter from the translation. You can give it one or more optional 71 | * parameters ('words'). 72 | */ 73 | export const replace = (value: string = '', words: string | string[]) => { 74 | let translation: string = value; 75 | 76 | const values: string[] = [].concat(words); 77 | values.forEach((e, i) => { 78 | translation = translation.replace(PLACEHOLDER.concat(i), e); 79 | }); 80 | 81 | return translation; 82 | }; 83 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the "nebula-theme" extension will be documented in this file. 4 | 5 | ## **[1.3.3]** - 2021-06-14 6 | ## Changed 7 | 8 | - Fixed the diff editor changed line background colors. Removed lines are now red, and new lines are now green. ([#6](https://github.com/eating-coleslaw/vscode-nebula-theme/issues/6)) 9 | 10 | ## **[1.3.2]** - 2018-11-24 11 | ## Added 12 | 13 | - Modified Tab Border colors. Enable via the Highlight Modified Tabs setting. 14 | - Foreground colors and darker background colors for Input Validation messages. 15 | - Snippet Tabstop border and background colors. 16 | 17 | ## **[1.3.1]** - 2018-09-12 18 | ### Added 19 | 20 | - Modified settings indicator color to match the badge background color 21 | 22 | ## **[1.3.0]** - 2018-09-05 23 | ### Added 24 | 25 | - Styling for the new (VSC 1.26.0) workbench theme colors: 26 | - Breadcrumbs & the breadcrump dropdown picker menu 27 | - Menus, context menus, and the menubar (preview features) 28 | - Enable by setting `window.titleBarStyle` to `custom` 29 | - New settings editor (preview feature) 30 | - Try it out with the **Preferences: Open Settings (Preview)** command 31 | 32 | ### Changed 33 | 34 | - Some punctuation elements are now more colorful (Mauve: `#E7ADFB`) 35 | - Square braces in JS and TS 36 | - Accessor periods (e.g. `object.property`) 37 | - Punctuation separators (e.g. commas between parameters in a function call) 38 | - Object code elements have been de-emphasized (`#F6F0FF` -> `#C0B9DF`) 39 | - This also affects T-SQL database names 40 | 41 | ## **[1.2.1]** - 2018-07-17 42 | ### Changed 43 | - Pick group labels are now legible 44 | - For example, the "light themes" and "dark themes" text in the color theme selection menu 45 | 46 | ## **[1.2.0]** - 2018-07-15 47 | ### Added 48 | - Error and warning colors to list text 49 | - Title bar foreground and border colors 50 | - Title bar border will be hidden when the 'nebula-theme.materialize' setting is enabled 51 | - These elements are visible when `window.titleBarStyle` is set to `custom` 52 | - Background colors for the new grid and centered layout features 53 | 54 | ### Changed 55 | - Input boxes and dropdown menus are now dark 56 | - Scrollbar slider is now dark 57 | 58 | ## **[1.1.1]** - 2018-05-03 59 | ### Added 60 | - `editorHint.foreground`: `#F2C88C` 61 | - `editorIndentGuide.activeBackground`: `#B2CFFB3A` 62 | 63 | ## **[1.1.0]** 64 | ### Added 65 | - Multiple new configuration options: 66 | - Remove workspace borders for a flatter appearance with the `nebula-theme.materialize` setting 67 | - Toggle italic comments on/off with the `nebula-theme.commentItalics` setting 68 | - Switch between 5-degrees of code italics with the `nebula-theme.themeItalics` setting 69 | 70 | ### Changed 71 | - Status bar is now more colorful when debugging and when opening an empty workspace (no-folder status) 72 | - Default italic settings have been revised to work better across more languages 73 | - Hover widgets and the peek editor background now match the main editor background color 74 | 75 | ## **[1.0.0]** - 2018-04-14 76 | - Initial release 77 | 78 | _Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file._ 79 | -------------------------------------------------------------------------------- /src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import * as path from 'path'; 3 | import * as fs from 'fs'; 4 | import * as reloadMessages from './../messages/reload'; 5 | import { AdvancedWorkspaceConfiguration } from '../models'; 6 | import { themeJsonName } from '../themes'; 7 | import { ThemeConfiguration } from '../models/index'; 8 | 9 | /** 10 | * Get configuration of vs code. 11 | */ 12 | export const getConfig = (section?: string) => { 13 | return vscode.workspace.getConfiguration(section) as AdvancedWorkspaceConfiguration; 14 | }; 15 | 16 | /** 17 | * Get list of configuration entries of package.json 18 | */ 19 | export const getExtensionConfiguration = (): { [config: string]: any } => { 20 | return vscode.extensions.getExtension('ChirtleLovesDolls.nebula-theme').packageJSON.contributes.configuration.properties; 21 | }; 22 | 23 | /** 24 | * Update configuration of vs code. 25 | */ 26 | export const setConfig = (section: string, value: any, global: boolean = false) => { 27 | return getConfig().update(section, value, global); 28 | }; 29 | 30 | 31 | export const getThemeConfig = (section: string) => { 32 | return getConfig('nebula-theme').inspect(section); 33 | }; 34 | 35 | /** 36 | * Set the config of the theme. 37 | */ 38 | export const setThemeConfig = (section: string, value: any, global: boolean = false) => { 39 | return getConfig('nebula-theme').update(section, value, global); 40 | }; 41 | 42 | /** 43 | * Is the theme already activated in the editor configuration? 44 | * @param{boolean} global false by default 45 | */ 46 | export const isThemeActivated = (global: boolean = false): boolean => { 47 | let curVal = global ? getConfig().inspect('workbench.colorTheme').globalValue 48 | : getConfig().inspect('workbench.colorTheme').workspaceValue; 49 | return (curVal === 'Nebula'); 50 | }; 51 | 52 | /** 53 | * Is the theme not visible for the user? 54 | */ 55 | export const isThemeNotVisible = (): boolean => { 56 | const config = getConfig().inspect('workbench.colorTheme'); 57 | return (!isThemeActivated(true) && config.workspaceValue === undefined) || // no workspace and not global 58 | (!isThemeActivated() && config.workspaceValue !== undefined); 59 | }; 60 | 61 | /** 62 | * Return the path of the extension in the file system. 63 | */ 64 | export const getExtensionPath = () => path.join(__dirname, '..', '..', '..'); 65 | 66 | /** 67 | * Get the configuration of the theme as JSON Object 68 | */ 69 | export const getColorThemeJson = (): Promise => { 70 | return new Promise((resolve, reject) => { 71 | const themeJsonPath = path.join(getExtensionPath(), 'out', 'src', themeJsonName); 72 | 73 | fs.readFile(themeJsonPath, 'utf8', (err, data) => { 74 | if (data) { 75 | resolve(JSON.parse(data)); 76 | } else { 77 | reject(err); 78 | } 79 | }); 80 | }); 81 | }; 82 | 83 | /** 84 | * Reload vs code window 85 | */ 86 | export const promptToReload = () => { 87 | return reloadMessages.showConfirmToReloadMessage().then(result => { 88 | if (result) { reloadWindow(); } 89 | }); 90 | }; 91 | 92 | export const reloadWindow = () => { 93 | return vscode.commands.executeCommand('workbench.action.reloadWindow'); 94 | }; 95 | -------------------------------------------------------------------------------- /src/themes/TokenGroups/italicGroups.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Each scope should only be referenced a SINGLE time across all of the 3 | * arrays in this file. This is to make maintaining the italic variants 4 | * easier. 5 | * 6 | * Also, please keep everything in alphabetical order :D 7 | */ 8 | 9 | export const commentScope: string[] = [ 10 | "comment" 11 | ]; 12 | 13 | /** 14 | * 1 - Basic 15 | */ 16 | export const basicScopes: string[] = [ 17 | "entity.other.attribute-name.pseudo-element.css", 18 | "entity.other.inherited-class", 19 | "markup.italic.markdown", 20 | "markup.quote", 21 | "meta.function.variable.css", 22 | "punctuation.definition.italic.markdown", 23 | "punctuation.definition.string.css", 24 | "storage.type.function", 25 | "string.quoted.double.css", 26 | "variable.argument.css" 27 | ]; 28 | 29 | /** 30 | * 2 - Wavy 31 | */ 32 | export const moreScopes: string[] = [ 33 | "entity.name.tag.custom", 34 | "entity.name.type.ts", 35 | "italic", 36 | "keyword.operator.type.annotation", 37 | "keyword.control.import", 38 | "modifier", 39 | "punctuation.section.embedded", 40 | "quote", 41 | "storage.type", 42 | "storage.type.class", 43 | "support.class", 44 | "support.class.builtin", 45 | "support.constant", 46 | "support.function.basic_functions", 47 | "support.function.builtin", 48 | "support.type.primitive", 49 | "support.type.property.css", 50 | "this", 51 | "type.function", 52 | "variable.parameter" 53 | ]; 54 | 55 | /** 56 | * 3 - Curly 57 | */ 58 | export const operatorScopes: string[] = [ 59 | "constant.language", 60 | "constant.other.color.rgb-value.hex.css", 61 | "constant.other.rgb-value.css", 62 | "entity.name.tag.doctype", 63 | "entity.name.tag.yaml", 64 | "keyword.control", 65 | "keyword.operator.expression.typeof", 66 | "language", 67 | "meta.parameter", 68 | "meta.parameters", 69 | "meta.tag.sgml.doctype", 70 | "meta.tag.sgml.doctype.html", 71 | "meta.var.expr storage.type", 72 | "parameter", 73 | "source.js.jsx keyword.control.flow.js", 74 | "storage", 75 | "support.constant.math", 76 | "support.type.vendored.property-name.css", 77 | "type.var", 78 | "variable.language", 79 | "variable.object.property.js", 80 | "variable.object.property.jsx", 81 | "variable.object.property.ts", 82 | "variable.object.property.tsx", 83 | "variable.other.less", 84 | "variable.parameter.url.sass", 85 | "variable.parameter.url.scss", 86 | "variable.sass", 87 | "variable.scss" 88 | ]; 89 | 90 | /** 91 | * 4 - No Restraint 92 | */ 93 | export const noRestraintScopes: string[] = [ 94 | ".type", 95 | "constant.character", 96 | "constant.other", 97 | "emphasis", 98 | "entity.name.function.ts", 99 | "entity.name.function.tsx", 100 | "entity.name.tag.script.html", 101 | "entity.other.attribute-name", 102 | "entity.other.attribute-name.pseudo-class.css", 103 | "entity.other.attribute-name.pseudo-selector.css", 104 | "entity.other.inherited-class entity.name.type.module", 105 | "entity.other.less.mixin", 106 | "keyword", 107 | "markup.italic", 108 | "meta.diff", 109 | "meta.diff.header", 110 | "meta.export.js variable.other", 111 | "meta.import.js variable.other", 112 | "meta.export.ts meta.block.ts variable.other.readwrite.alias.ts", 113 | "meta.export.tsx meta.block.tsx variable.other.readwrite.alias.tsx", 114 | "meta.import.ts meta.block.ts variable.other.readwrite.alias.ts", 115 | "meta.import.tsx meta.block.tsx variable.other.readwrite.alias.tsx", 116 | "meta.object-literal.key", 117 | "meta.selector.css entity.other.attribute-name.class", 118 | "punctuation.definition.blockquote.markdown", 119 | "punctuation.definition.comment", 120 | "source.json meta.structure.dictionary support.type.property-name.json", 121 | "source.java storage.type.annotation", 122 | "storage.modifier", 123 | "storage.type", 124 | "storage.type.annotation", 125 | "storage.type.class.js", 126 | "string", 127 | "string.quoted.docstring", 128 | "string.regexp", 129 | "support.constant.vendored.property-value.css", 130 | "support.module", 131 | "support.node", 132 | "support.type", 133 | "support.type.property-name.css", 134 | "text.html.markdown", 135 | "variable.language.this", 136 | "variable.language.this.js" 137 | ]; 138 | 139 | export const setCommentItalicsObject = (enabled: boolean = true) => { 140 | if (!enabled) { return { tokenColors: [] }; } 141 | let obj = { tokenColors: [] }; 142 | if (enabled) { 143 | obj.tokenColors = [ 144 | { 145 | name: 'comment', 146 | scope: ['comment'], 147 | settings: { fontStyle: 'italic' } 148 | } 149 | ]; 150 | } 151 | 152 | return obj; 153 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nebula-theme", 3 | "displayName": "Nebula Theme", 4 | "description": "🌌🌸 Fresh colors on a dark, cold slate. An almost-material theme for Visual Studio Code.", 5 | "version": "1.3.3", 6 | "publisher": "ChirtleLovesDolls", 7 | "engines": { 8 | "vscode": "^1.57.0" 9 | }, 10 | "homepage": "https://github.com/eating-coleslaw/vscode-nebula-theme/README.md", 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/eating-coleslaw/vscode-nebula-theme" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/eating-coleslaw/vscode-nebula-theme/issues" 17 | }, 18 | "icon": "icon.png", 19 | "galleryBanner": { 20 | "color": "#27273A", 21 | "theme": "dark" 22 | }, 23 | "license": "MIT", 24 | "categories": [ 25 | "Themes" 26 | ], 27 | "keywords": [ 28 | "color", 29 | "theme", 30 | "color-theme", 31 | "dark", 32 | "configuration" 33 | ], 34 | "activationEvents": [ 35 | "*" 36 | ], 37 | "main": "./out/src/extension", 38 | "contributes": { 39 | "themes": [ 40 | { 41 | "id": "Nebula", 42 | "label": "Nebula", 43 | "uiTheme": "vs-dark", 44 | "path": "./out/src/nebula-color-theme.json" 45 | }, 46 | { 47 | "label": "Nebula - Console", 48 | "uiTheme": "vs-dark", 49 | "path": "./themes/Nebula-color-theme-console.json" 50 | } 51 | ], 52 | "commands": [ 53 | { 54 | "command": "nebula-theme.activateTheme", 55 | "title": "Nebula Theme: Activate" 56 | }, 57 | { 58 | "command": "nebula-theme.restoreDefaultConfig", 59 | "title": "Nebula Theme: Reset to default configuration" 60 | } 61 | ], 62 | "configuration": { 63 | "type": "object", 64 | "title": "Nebula Theme Configuration", 65 | "properties": { 66 | "nebula-theme.commentItalics": { 67 | "type": "boolean", 68 | "default": true, 69 | "description": "Controls whether code comments are italicized. Default value = true: italicized comments. This setting is not affected by the nebula-theme.themeItalics setting." 70 | }, 71 | "nebula-theme.themeItalics": { 72 | "type": "string", 73 | "default": "2 - wavy", 74 | "description": "Controls the amount of non-comment code that gets italicized, where 0 - none has the least amount of italicized scopes and 4 - no restraint has the most italicized scopes. Accepted values are: 0 - none, 1 - basic, 2 - wavy, 3 - curly, and 4 - no restraint. 3 - curly is the intended Operator Mono setting. Default value = 2 - wavy.", 75 | "enum": [ 76 | "0 - none", 77 | "1 - basic", 78 | "2 - wavy", 79 | "3 - curly", 80 | "4 - no restraint" 81 | ] 82 | }, 83 | "nebula-theme.materialize": { 84 | "type": "boolean", 85 | "default": false, 86 | "description": "Controls whether workbench borders and other elements are hidden for a more material/flat appearance. Default value = false: visible workbench borders." 87 | } 88 | } 89 | } 90 | }, 91 | "scripts": { 92 | "vscode:prepublish": "npm run build", 93 | "prebuild": "npm run lint && npm run clean", 94 | "build": "npm run compile && npm run generateJson", 95 | "clean": "rimraf ./out", 96 | "compile": "tsc -p ./", 97 | "compile:watch": "tsc -watch -p ./", 98 | "generateJson": "ts-node ./scripts/themes/generateJson.ts", 99 | "postinstall": "node ./node_modules/vscode/bin/install", 100 | "lint": "tslint -c tslint.json ./src/**/*.ts ./scripts/**/*ts", 101 | "watch": "tsc -watch -p ./" 102 | }, 103 | "dependencies": { 104 | "opn": "^5.3.0", 105 | "semver": "^5.5.0" 106 | }, 107 | "devDependencies": { 108 | "@types/node": "^7.10.14", 109 | "@types/opn": "^5.1.0", 110 | "rimraf": "^2.6.2", 111 | "ts-node": "^6.2.0", 112 | "tslint": "^5.10.0", 113 | "typescript": "^4.3.2", 114 | "vscode": "^1.1.37" 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/themes/tokenGroups.ts: -------------------------------------------------------------------------------- 1 | import { ITokenGroup, FontStyle } from '../models/index'; 2 | 3 | export const tokenGroups: ITokenGroup[] = [ 4 | { 5 | name: 'Magnolia', 6 | scope: [ 7 | "meta.brace", 8 | "punctuation.definition.array", 9 | "punctuation.definition.binding-pattern", 10 | "punctuation.definition.block", 11 | "punctuation.definition.dictionary", 12 | "punctuation.definition.string", 13 | "punctuation.definition.tag", 14 | "punctuation.curlybrace", 15 | "punctuation.fullstop", 16 | "punctuation.section", 17 | "punctuation.support", 18 | "punctuation.terminator", 19 | "meta.structure.dictionary.json", 20 | "string.quoted.double.json", 21 | "constant.other.table-name.sql" 22 | ], 23 | settings: { 24 | foreground: '#F6F0FF' 25 | }, 26 | }, 27 | { 28 | name: 'Electric Blue', 29 | scope: [ 30 | "support.variable", 31 | "variable", 32 | "support.type.property-name", 33 | "variable.other.object.property", 34 | "meta.object-literal.key.js", 35 | "string.other.link.description.markdown" 36 | ], 37 | settings: { 38 | foreground: '#8DF9F9' 39 | }, 40 | }, 41 | { 42 | name: 'Sulu', 43 | scope: [ 44 | "keyword.var", 45 | "keyword.const", 46 | "constant", 47 | "keyword.struct", 48 | "keyword.interface", 49 | "keyword.function", 50 | "markup.inline.raw", 51 | "punctuation.parenthesis.named.begin.regexp", 52 | "punctuation.parenthesis.named.end.regexp", 53 | "punctuation.parenthesis.non-capturing.begin.regexp", 54 | "punctuation.parenthesis.non-capturing.end.regexp", 55 | "support.constant", 56 | "support.type", 57 | "support.class", 58 | "markup.inserted", 59 | "entity.name.type", 60 | "entity.name.class", 61 | "entity.other.inherited-class", 62 | "entity.other.attribute-name.id.css" 63 | ], 64 | settings: { 65 | foreground: '#97EE91' 66 | }, 67 | }, 68 | { 69 | name: 'Bali Hai', 70 | scope: [ 71 | "punctuation.terminator", 72 | "punctuation.section.function.begin.bracket.round.css", 73 | "punctuation.section.function.end.bracket.round.css", 74 | "punctuation.section.property-list.begin.bracket.curly.css", 75 | "punctuation.section.property-list.end.bracket.curly.css" 76 | ], 77 | settings: { 78 | foreground: '#919CB9' 79 | }, 80 | }, 81 | { 82 | name: 'Lavender Gray', 83 | scope: [ 84 | "constant.other.database-name.sql", 85 | "variable.other.object" 86 | ], 87 | settings: { 88 | foreground: '#C5B9DF' 89 | } 90 | }, 91 | { 92 | name: 'Deluge', 93 | scope: [ 94 | "comment" 95 | ], 96 | settings: { 97 | foreground: '#8059A2' 98 | }, 99 | }, 100 | { 101 | name: 'Malibu', 102 | scope: [ 103 | "string", 104 | "markup.quote", 105 | "markup.bold", 106 | "markup.italic", 107 | "string.quoted.single.js", 108 | "string.quoted.double.js", 109 | "meta.link.inline.markdown", 110 | "meta.image.inline.markdown", 111 | "markup.underline.link", 112 | "entity.name.type.js" 113 | ], 114 | settings: { 115 | foreground: '#50DFFE' 116 | }, 117 | }, 118 | { 119 | name: 'Mauve', 120 | scope: [ 121 | "string.quoted.docstring", 122 | "storage.type.function", 123 | "keyword.type", 124 | "storage.type", 125 | "punctuation.accessor", 126 | "punctuation.separator", 127 | "meta.brace.square.js", 128 | "meta.brace.square.ts" 129 | ], 130 | settings: { 131 | foreground: '#E7ADFB' 132 | }, 133 | }, 134 | { 135 | name: 'Froly', 136 | scope: [ 137 | "entity.name.class", 138 | "entity.name.function", 139 | "entity.name.type", 140 | "entity.other.attribute-name", 141 | "entity.other.inherited-class", 142 | "markup.heading.setext", 143 | "meta.function-call.generic", 144 | "support.function", 145 | "support.other.escape.special.regexp" 146 | ], 147 | settings: { 148 | foreground: '#F36F98' 149 | }, 150 | }, 151 | { 152 | name: 'Rajah', 153 | scope: [ 154 | "entity.name.tag", 155 | "storage", 156 | "support.function.builtin", 157 | "variable.language", 158 | "constant.numeric", 159 | "variable.parameter", 160 | "markup.bold", 161 | "markup.underline", 162 | "markup.italic", 163 | "string.quoted.double.css", 164 | "punctuation.definition.string.css" 165 | ], 166 | settings: { 167 | foreground: '#F8C275' 168 | }, 169 | }, 170 | { 171 | name: 'Deep Blush', 172 | scope: [ 173 | "entity.name.section", 174 | "keyword", 175 | "punctuation.definition.heading", 176 | "punctuation.definition.keyword", 177 | "keyword.other.DML.sql", 178 | "constant.character.escape.markdown", 179 | "entity.other.attribute-name.class.css" 180 | ], 181 | settings: { 182 | foreground: '#E752A1' 183 | }, 184 | }, 185 | { 186 | name: 'Classic Rose', 187 | scope: [ 188 | "meta.brace", 189 | "punctuation.definition.arguments", 190 | "punctuation.definition.array", 191 | "punctuation.definition.begin.bracket", 192 | "punctuation.definition.binding-pattern", 193 | "punctuation.definition.block", 194 | "punctuation.definition.bracket", 195 | "punctuation.definition.dict", 196 | "punctuation.definition.dictionary", 197 | "punctuation.definition.end.bracket", 198 | "punctuation.definition.list", 199 | "punctuation.definition.parameters", 200 | "punctuation.definition.string", 201 | "punctuation.definition.tag", 202 | "punctuation.other.comma", 203 | "punctuation.other.period", 204 | "punctuation.section", 205 | "punctuation.support", 206 | "punctuation.terminator", 207 | ], 208 | settings: { 209 | foreground: '#FBD3E1' 210 | }, 211 | }, 212 | { 213 | name: 'Cranberry', 214 | scope: [ 215 | "punctuation.definition.template-expression", 216 | "punctuation.section.embedded", 217 | "storage", 218 | "markup.deleted", 219 | "markup.heading", 220 | "entity.name.section.markdown", 221 | "token.error-token" 222 | ], 223 | settings: { 224 | foreground: '#E34F8C' 225 | }, 226 | }, 227 | { 228 | name: 'Texas', 229 | scope: [ 230 | "markup.changed", 231 | "entity.name.filename.find-in-files", 232 | "markup.quote", 233 | "keyword.other.unit.px.css", 234 | "keyword.other.unit.fr.css", 235 | "keyword.other.unit.s.css", 236 | "keyword.other.unit.percentage.css" 237 | ], 238 | settings: { 239 | foreground: '#FAFAA0' 240 | }, 241 | }, 242 | { 243 | name: 'Perfume', 244 | scope: [ 245 | "markup.fenced_code.block.markdown", 246 | "keyword.type", 247 | "keyword.other.alias.sql", 248 | "meta.functiona.variable.css", 249 | "variable.argument.css", 250 | "constant.numeric.line-number.find-in-files - match" 251 | ], 252 | settings: { 253 | foreground: '#C7ADFB' 254 | }, 255 | }, 256 | { 257 | name: 'White Pointer', 258 | scope: [ 259 | "variable", 260 | "text.html.markdown", 261 | "support.constant.property-value.css" 262 | ], 263 | settings: { 264 | foreground: '#FCF6FF' 265 | }, 266 | }, 267 | { 268 | name: 'Jaffa', 269 | scope: [ 270 | "beginning.punctuation.definition.list.markdown", 271 | "constant.language.null", 272 | "constant.language.boolean.true", 273 | "constant.language.boolean.false", 274 | "entity.other.attribute-name.pseudo-element.css" 275 | ], 276 | settings: { 277 | foreground: '#F39B35' 278 | }, 279 | }, 280 | { 281 | name: 'Anakiwa', 282 | scope: [ 283 | "meta.link.inline.markdown", 284 | "meta.image.inline.markdown", 285 | "markup.underline.link" 286 | ], 287 | settings: { 288 | foreground: '#99ddff' 289 | }, 290 | }, 291 | { 292 | name: 'Bold', 293 | scope: [ 294 | "markup.bold.markdown", 295 | "punctuation.definition.bold.markdown" 296 | ], 297 | settings: { 298 | fontStyle: FontStyle.Bold 299 | } 300 | }, 301 | { 302 | name: 'Underline', 303 | scope: [ 304 | "entity.other.inherited-class", 305 | "entity.name.type", 306 | "entity.name.class", 307 | "entity.other.inherited-class" 308 | ], 309 | settings: { 310 | fontStyle: FontStyle.Underline 311 | } 312 | } 313 | ]; -------------------------------------------------------------------------------- /samples/python.py: -------------------------------------------------------------------------------- 1 | import urllib2 # html scraper 2 | from bs4 import BeautifulSoup # html parser 3 | import re # regex module 4 | from collections import deque # keep track of urls to scrape & parse 5 | import heapq 6 | 7 | import sys # exit quits program prematurely in event of error 8 | import sqlite3 # allows interaction with sql database (henceforth db) 9 | import datetime # strptime and strftime convert between date formats 10 | import time # sleep allows slight pause after each request to bandcamp servers 11 | import numpy # random.exponential determines variable sleep time between server 12 | # requests (more human-like according to p4k master comment) 13 | import itertools # count function is convenient iterator 14 | 15 | 16 | '''Script Sequence: 17 | 1. go to music page of the source band 18 | 2. get tags and tag counts from all albums on music page 19 | 3. for given tag, get band page for all artists listed 20 | 4. repeat step 3 for all reference band tags 21 | 5. for given session artist, get go through all albums counting tags 22 | 6. repeat step 5 for all session artists 23 | 7. move information to database with (id, artist, tag, tag count) 24 | 8. sort database based on tag count''' 25 | 26 | 27 | SOURCE_URL = "spazzkid.bandcamp.com" # will become main program input 28 | URL_QUEUE = deque([]) 29 | TAG_QUEUE = deque([]) 30 | OPENER = urllib2.build_opener() 31 | OPENER.addheaders = [('User-agent', 'Mozilla/5.0')] 32 | MAX_TAG_PAGES = 1 33 | MAX_ALBUMS = 5 34 | SOURCE_TAGS = [] 35 | 36 | 37 | def main(): 38 | SOURCE_URL 39 | URL_QUEUE = deque([]) 40 | TAG_QUEUE = deque([]) 41 | SOURCE_TAGS = [] 42 | pass 43 | 44 | 45 | def prepare_source_band_url(url): 46 | """Cleans the user-input source url and turns it into a music page url.""" 47 | # check to ensure bandcamp.com link 48 | bandcamp_check = re.compile('(.*)(bandcamp\.com)(.*)$') 49 | if bandcamp_check.match(url) != None: 50 | clean_url = check_url_protocol(get_clean_band_url(url)) 51 | return make_music_page_url(clean_url) 52 | else: 53 | print '%s is not a bandcamp.com URL.' % url 54 | 55 | 56 | def make_music_page_url(url): 57 | if re.compile('/music').match(url) == None: 58 | return url + '/music' 59 | else: 60 | return url 61 | 62 | 63 | def check_url_protocol(url): 64 | """Ensures a given url has the http:// protocl.""" 65 | if re.compile('http://').match(url) == None: 66 | url = 'http://' + url 67 | return url 68 | else: 69 | return url 70 | 71 | 72 | def get_clean_band_url(url): 73 | """Convert album/track url to base band url.""" 74 | cleaner = re.compile('(/([a-z]{5})/)(.*)$') 75 | cleaned_band_url = re.sub(cleaner, "", url) 76 | print url 77 | print cleaned_band_url 78 | return cleaned_band_url 79 | 80 | 81 | def make_soup(url): 82 | return BeautifulSoup(scrape_html(url)) 83 | 84 | 85 | def get_source_artist_name(url): 86 | """Gets name of the source artist off of its music page.""" 87 | soup = make_soup(url) 88 | name = soup.find( 89 | 'p', id='band-name-location').find(class_='title').get_text() 90 | return name 91 | 92 | 93 | def scrape_html(url): 94 | """Scrapes html from a single url.""" 95 | html = None 96 | try: 97 | response = OPENER.open(url) 98 | if response.code == 200: 99 | #print "Scraping %s" % url 100 | html = response.read() 101 | else: 102 | print "Invalid URL: %s \n" % url 103 | except urllib2.HTTPError: 104 | print "Failed to open %s \n" % url 105 | return html 106 | 107 | 108 | def parse_music_page(soup, url): 109 | """Find/add all albumes on band's music page to URL_QUEUE.""" 110 | album_count = 0 111 | for tag in soup.find_all('li', class_='square '): 112 | for link in tag.find_all('a'): 113 | if album_count <= MAX_ALBUMS: 114 | album = link.get('href') 115 | URL_QUEUE.append(check_url_protocol(url) + album) 116 | album_count += 1 117 | else: 118 | return 119 | 120 | 121 | def get_album_tags(soup, artist): 122 | """Find album's tags and add their urls and name to TAG_QUEUE.""" 123 | for tag in soup.find_all('a', class_='tag'): 124 | tag_url = tag.get('href') 125 | pretag_url = re.compile('(.*)(.bandcamp.com/tag/)') 126 | tag_string = re.sub(pretag_url, "", tag_url).replace( 127 | "-", " ") # get the tag from the tag url 128 | #print tag_string + " --- " + tag_url 129 | if artist.same_artist(SESSION_ARTISTS.get_source_artist()): 130 | artist.update_tags(tag_string) 131 | if [tag_url, tag_string] not in TAG_QUEUE: 132 | SOURCE_TAGS.append(tag_string) 133 | TAG_QUEUE.append([tag_url, tag_string]) 134 | elif tag_string in SOURCE_TAGS: 135 | artist.update_tags(tag_string) 136 | 137 | 138 | def parse_tag_pages(url, tag): 139 | soup = make_soup(url) 140 | for album in soup.find_all("li", class_="item"): 141 | album_url = album.a.get("href") 142 | band_name = album.find(class_='itemsubtext').get_text() 143 | #print band_name 144 | band_url = get_clean_band_url(album_url) 145 | SESSION_ARTISTS.add_artist(band_name, band_url) 146 | #print band_name + " --- " + album_url 147 | try: 148 | next_page = soup.find(class_='nextprev next').a.get('href') 149 | if int(next_page[-1:]) <= MAX_TAG_PAGES: 150 | parse_tag_pages(url[:-7] + next_page, tag) 151 | else: 152 | pass 153 | #print "\nFinished scraping %s: page limit reached.\n" % tag 154 | except AttributeError: 155 | pass 156 | #print "\nFinished scraping %s: no more pages.\n" % tag 157 | 158 | 159 | def create_sql_db(db_name): 160 | print "Opening connection to %s." % (db_name + ".db") 161 | con = sqlite3.connect(db_name) 162 | sql = con.cursor() 163 | sql.execute("""CREATE TABLE IF NOT EXISTS artist_tags( 164 | id INTEGER PRIMARY KEY, 165 | artist TEXT, 166 | url TEXT, 167 | tag TEXT, 168 | count TEXT 169 | );""") 170 | return con, sql 171 | 172 | 173 | class TagCount: 174 | """Used to create aggregate values in sql table.""" 175 | 176 | def __init__(self): 177 | self.count = 0 178 | 179 | def step(self, value): 180 | self.count += value 181 | 182 | def finalize(self): 183 | return self.count 184 | 185 | 186 | class Artist: 187 | def __init__(self, name, url): 188 | self.artist_name = name 189 | self.artist_url = url 190 | self.tag_dictionary = {} 191 | self.total_common_tag_count = 0 192 | self.unique_common_tag_count = 0 193 | 194 | def update_tags(self, tag): 195 | # updates tag count or adds new tag to dictionary 196 | self.total_common_tag_count += 1 197 | if tag not in self.tag_dictionary: 198 | self.unique_common_tag_count += 1 199 | self.tag_dictionary[tag] = 1 200 | else: 201 | self.tag_dictionary[tag] = self.tag_dictionary[tag] + 1 202 | 203 | def same_artist(self, ref_artist): 204 | # use unique band url to check if two artists are the same 205 | if ref_artist.get_url() == self.artist_url: 206 | return True 207 | else: 208 | return False 209 | 210 | def get_index(self): 211 | try: 212 | return self.total_common_tag_count/self.unique_common_tag_count 213 | except ZeroDivisionError: 214 | return 0 215 | 216 | def get_unique_tag_count(self): 217 | return self.unique_common_tag_count 218 | 219 | def get_common_tag_count(self): 220 | return self.total_common_tag_count 221 | 222 | def get_name(self): 223 | return self.artist_name 224 | 225 | def get_url(self): 226 | return self.artist_url 227 | 228 | def get_tag_dictionary(self): 229 | return self.tag_dictionary 230 | 231 | def get_tag_count(self, tag): 232 | # returns current count of the specified tag 233 | return self.tag_dictionary[tag] 234 | 235 | 236 | class Session_Artists: 237 | def __init__(self, name, url): 238 | self.source_artist = Artist(name, url) 239 | self.artist_list = [] 240 | 241 | def set_source_artist(self, name, url): 242 | self.source_artist = Artist(name, url) 243 | 244 | def add_artist(self, name, url): 245 | new_artist = Artist(name, url) 246 | if not self.artist_included(new_artist) and not new_artist.same_artist(self.source_artist): 247 | self.artist_list.append(new_artist) 248 | 249 | def artist_included(self, new_artist): 250 | for artist in self.artist_list: 251 | if new_artist.same_artist(artist): 252 | return True 253 | return False 254 | 255 | def get_artist_list(self): 256 | return self.artist_list 257 | 258 | def get_source_artist(self): 259 | return self.source_artist 260 | 261 | def session_len(self): 262 | return len(self.artist_list) 263 | 264 | 265 | SOURCE_MUSIC_URL = prepare_source_band_url(SOURCE_URL) 266 | music_soup = make_soup(SOURCE_MUSIC_URL) 267 | parse_music_page(music_soup, SOURCE_URL) 268 | SOURCE_NAME = get_source_artist_name(SOURCE_MUSIC_URL) 269 | SESSION_ARTISTS = Session_Artists(SOURCE_NAME, SOURCE_MUSIC_URL) 270 | create_sql_db(SOURCE_NAME) 271 | 272 | #print tag 273 | # SOURCE_TAGS.append(tag) 274 | 275 | print "Source Artist:", SESSION_ARTISTS.get_source_artist().get_name() + "\n" 276 | 277 | """Get tags from all source artist's albums.""" 278 | 279 | print "Getting Source Artist tags.\n" 280 | while len(URL_QUEUE) > 0: 281 | try: 282 | album_soup = make_soup(URL_QUEUE.popleft()) 283 | get_album_tags(album_soup, SESSION_ARTISTS.get_source_artist()) 284 | except urllib2.URLError: 285 | pass 286 | 287 | 288 | """Get artists from all source tag pages.""" 289 | 290 | print "Going through tag pages.\n" 291 | while len(TAG_QUEUE) > 0: 292 | try: 293 | tag = TAG_QUEUE.popleft() 294 | tag_name = tag[1] 295 | tag_url = tag[0] 296 | parse_tag_pages(tag_url + '?page=1', tag_name) 297 | except urllib2.URLError: 298 | pass 299 | 300 | 301 | """Go through SESSION_ARTISTS' music pages -> albums -> tags.""" 302 | 303 | print "Going through artist pages.\n" 304 | print "SESSION_ARTISTS:", len(SESSION_ARTISTS.get_artist_list()) 305 | count = 0 306 | error_count = 0 307 | for artist in SESSION_ARTISTS.get_artist_list(): 308 | #print artist.get_name() 309 | try: 310 | music_soup = make_soup(make_music_page_url(artist.get_url())) 311 | parse_music_page(music_soup, artist.get_url()) 312 | while len(URL_QUEUE) > 0: 313 | count += 1 314 | #print count 315 | url = URL_QUEUE.popleft() 316 | #print url 317 | album_soup = make_soup(url) 318 | get_album_tags(album_soup, artist) 319 | if (count % 25 == 0): 320 | print count 321 | #print artist.get_name() 322 | except urllib2.URLError: 323 | error_count += 1 324 | pass 325 | 326 | print "\ndone looking at artists: %d errors\n" % error_count 327 | 328 | # for artist in SESSION_ARTISTS.get_artist_list(): 329 | #print artist.get_url() 330 | print SESSION_ARTISTS.session_len() 331 | #print artist.get_name() + ' --- ' + artist.get_tag_dictionary()[tag] 332 | 333 | print SESSION_ARTISTS.get_source_artist().get_tag_dictionary() 334 | print SOURCE_TAGS 335 | 336 | SESSION_HEAP = [] 337 | # heapq.heapify(SESSION_HEAP) 338 | for artist in SESSION_ARTISTS.get_artist_list(): 339 | #print artist.get_unique_tag_count() 340 | heapq.heappush(SESSION_HEAP, ((100-artist.get_common_tag_count()), 341 | artist.get_name(), artist.get_url())) 342 | for a in range(0, 11): 343 | print heapq.heappop(SESSION_HEAP) -------------------------------------------------------------------------------- /src/themes/workspaceColors.ts: -------------------------------------------------------------------------------- 1 | import { IWorkspaceColor } from "../models/index"; 2 | 3 | export const workspaceColors: IWorkspaceColor[] = [ 4 | { scope: "foreground", color: "#fcf6ff" }, 5 | { scope: "errorForeground", color: "#E34F8C" }, 6 | { scope: "focusBorder", color: "#B2CFFB3A" }, 7 | { scope: "descriptionForeground", color: "#919CB9" }, 8 | { scope: "textLink.foreground", color: "#40afee" }, 9 | { scope: "textLink.activeForeground", color: "#74D6E9" }, 10 | { scope: "pickerGroup.foreground", color: "#E752A1" }, 11 | { scope: "pickerGroup.border", color: "#B2CFFB1A" }, 12 | { scope: "editorLineNumber.activeForeground", color: "#24E8D8" }, 13 | { scope: "editorWhitespace.foreground", color: "#B2CFFB1A" }, 14 | { scope: "editorIndentGuide.background", color: "#B2CFFB1A" }, 15 | { scope: "editorIndentGuide.activeBackground", color: "#B2CFFB3A" }, 16 | { scope: "editorRuler.foreground", color: "#C7ADFB2f" }, 17 | { scope: "editorOverviewRuler.border", color: "#B2CFFB2A", materialize: true }, 18 | { scope: "progressBar.background", color: "#24E8D8" }, 19 | { scope: "badge.foreground", color: "#f8f8f2" }, 20 | { scope: "badge.background", color: "#E34F8C" }, 21 | { scope: "button.background", color: "#E34F8C" }, 22 | { scope: "button.hoverBackground", color: "#F661B1" }, 23 | { scope: "scrollbarSlider.background", color: "#06080E4A" }, 24 | { scope: "scrollbarSlider.hoverBackground", color: "#0F132090" }, 25 | { scope: "scrollbarSlider.activeBackground", color: "#0F1320C0" }, 26 | { scope: "scrollbar.shadow", color: "#0F1320" }, 27 | { scope: "editor.foreground", color: "#fcf6ff" }, 28 | { scope: "editor.selectionForeground", color: "#25313e" }, 29 | { scope: "editorCursor.foreground", color: "#97EE91" }, 30 | { scope: "editorBracketMatch.background", color: "#2A2A46" }, 31 | { scope: "editorBracketMatch.border", color: "#97EE91" }, 32 | { scope: "editor.background", color: "#27273A" }, 33 | { scope: "editorLineNumber.foreground", color: "#919CB9" }, 34 | { scope: "editor.lineHighlightBackground", color: "#2A2A46" }, 35 | { scope: "titleBar.activeBackground", color: "#1F2330" }, 36 | { scope: "titleBar.inactiveBackground", color: "#1F2330"}, 37 | { scope: "titleBar.activeForeground", color: "#D7D6DF"}, 38 | { scope: "titleBar.inactiveForeground", color: "#919CB9"}, 39 | { scope: "titleBar.border", color: "#0F1320", materialize: true }, 40 | { scope: "menu.background", color: "#27273A" }, 41 | { scope: "menu.foreground", color: "#919CB9" }, 42 | { scope: "menu.selectionBackground", color: "#899BBF3A" }, 43 | { scope: "menu.selectionForeground", color: "#FCF6FF" }, 44 | { scope: "menu.selectionBorder", color: "#0F13207A", materialize: true }, 45 | { scope: "menubar.selectionBackground", color: "#899BBF3A" }, 46 | { scope: "menubar.selectionForeground", color: "#FCF6FF" }, 47 | { scope: "menubar.selectionBorder", color: "#0F13200A", materialize: true }, 48 | { scope: "menu.separatorBackground", color: "#B2CFFB3A" }, 49 | { scope: "settings.headerForeground", color: "#24E8D8" }, 50 | { scope: "settings.modifiedItemForeground", color: "#E34F8C" }, 51 | { scope: "settings.modifiedItemIndicator", color: "#E34F8C" }, 52 | { scope: "settings.inactiveSelectedItemBorder", color: "#B2CFFB1A" }, 53 | { scope: "settings.dropdownBackground", color: "#1F2330" }, 54 | { scope: "settings.dropdownForeground", color: "#E7ADFB" }, 55 | { scope: "settings.dropdownBorder", color: "#B2CFFB1A" }, 56 | { scope: "settings.dropdownListBorder", color: "#B2CFFB1A" }, 57 | { scope: "settings.checkboxBackground", color: "#1F2330" }, 58 | { scope: "settings.checkboxForeground", color: "#97EE91" }, 59 | { scope: "settings.checkboxBorder", color: "#97EE9150" }, 60 | { scope: "settings.textInputBackground", color: "#1F2330" }, 61 | { scope: "settings.textInputForeground", color: "#50DFFE" }, 62 | { scope: "settings.textInputBorder", color: "#B2CFFB1A" }, 63 | { scope: "settings.numberInputBackground", color: "#1F2330" }, 64 | { scope: "settings.numberInputForeground", color: "#F8C275" }, 65 | { scope: "settings.numberInputBorder", color: "#B2CFFB1A" }, 66 | { scope: "extensionButton.prominentBackground", color: "#97EE91" }, 67 | { scope: "extensionButton.prominentForeground", color: "#0F1320" }, 68 | { scope: "extensionButton.prominentHoverBackground", color: "#AFFA90" }, 69 | { scope: "selection.background", color: "#94cbf87a" }, 70 | { scope: "editorOverviewRuler.selectionHighlightForeground", color: "#97EE91" }, 71 | { scope: "editor.selectionHighlightBackground", color: "#42557B50" }, 72 | { scope: "editor.selectionHighlightBorder", color: "#42557B" }, 73 | { scope: "editor.wordHighlightBackground", color: "#42557B30" }, 74 | { scope: "editor.selectionBackground", color: "#42557BC0" }, 75 | { scope: "editor.wordHighlightBorder", color: "#00000000" }, 76 | { scope: "editor.wordHighlightStrongBorder", color: "#00000000" }, 77 | { scope: "editor.wordHighlightStrongBackground", color: "#42557B30" }, 78 | { scope: "editor.rangeHighlightBackground", color: "#2A2A46" }, 79 | { scope: "editor.findMatchBackground", color: "#C7ADFB90" }, 80 | { scope: "editor.findMatchBorder", color: "#C7ADFB00" }, 81 | { scope: "editor.findMatchHighlightBackground", color: "#C7ADFB30" }, 82 | { scope: "editor.findRangeHighlightBackground", color: "#2A2A46" }, 83 | { scope: "editor.findMatchHighlightBorder", color: "#C7ADFB50" }, 84 | { scope: "editorGroupHeader.tabsBackground", color: "#1F2330" }, 85 | { scope: "editorGroup.border", color: "#0F1320", materialize: true }, 86 | { scope: "editorGroup.dropBackground", color: "#363C4C5f" }, 87 | { scope: "editorGroup.emptyBackground", color: "#1F2330" }, 88 | { scope: "editorPane.background", color: "#1F2330" }, 89 | { scope: "tab.activeBackground", color: "#27273A" }, 90 | { scope: "tab.activeBorder", color: "#0000" }, 91 | { scope: "tab.unfocusedActiveBorder", color: "#0000" }, 92 | { scope: "tab.activeForeground", color: "#24E8D8" }, 93 | { scope: "tab.unfocusedActiveForeground", color: "#47A9BC" }, 94 | { scope: "tab.inactiveBackground", color: "#1F2330" }, 95 | { scope: "tab.border", color: "#353551" }, 96 | { scope: "tab.hoverBorder", color: "#24E8D8" }, 97 | { scope: "tab.unfocusedHoverBorder", color: "#47A9BC" }, 98 | { scope: "tab.unfocusedInactiveForeground", color: "#79839C" }, 99 | { scope: "tab.inactiveForeground", color: "#919CB9" }, 100 | { scope: "tab.activeModifiedBorder", color: "#E34F8C" }, 101 | { scope: "tab.inactiveModifiedBorder", color: "#E34F8C90" }, 102 | { scope: "tab.unfocusedActiveModifiedBorder", color: "#E34F8CA0" }, 103 | { scope: "tab.unfocusedInactiveModifiedBorder", color: "#E34F8C70" }, 104 | { scope: "breadcrumb.foreground", color: "#919CB9" }, 105 | { scope: "breadcrumb.focusForeground", color: "#FCF6FF" }, 106 | { scope: "breadcrumb.activeSelectionForeground", color: "#FCF6FF" }, 107 | { scope: "breadcrumb.background", color: "#27273A" }, 108 | { scope: "breadcrumbPicker.background", color: "#27273A" }, 109 | { scope: "terminal.background", color: "#27273A" }, 110 | { scope: "terminalCursor.foreground", color: "#97EE91" }, 111 | { scope: "terminalCursor.background", color: "#0F1320" }, 112 | { scope: "terminal.selectionBackground", color: "#42557B5A" }, 113 | { scope: "terminal.foreground", color: "#f6f0ff" }, 114 | { scope: "terminal.ansiBlack", color: "#353551" }, 115 | { scope: "terminal.ansiBlue", color: "#C7ADFB" }, 116 | { scope: "terminal.ansiBrightBlack", color: "#919CB9" }, 117 | { scope: "terminal.ansiBrightBlue", color: "#74D6E9" }, 118 | { scope: "terminal.ansiBrightCyan", color: "#8DF9F9" }, 119 | { scope: "terminal.ansiBrightGreen", color: "#AFFA90" }, 120 | { scope: "terminal.ansiBrightMagenta", color: "#F799C7" }, 121 | { scope: "terminal.ansiBrightRed", color: "#F36F98" }, 122 | { scope: "terminal.ansiBrightWhite", color: "#D7D6DF" }, 123 | { scope: "terminal.ansiBrightYellow", color: "#FAFAA0" }, 124 | { scope: "terminal.ansiCyan", color: "#24E8D8" }, 125 | { scope: "terminal.ansiGreen", color: "#97F36D" }, 126 | { scope: "terminal.ansiMagenta", color: "#E752A1" }, 127 | { scope: "terminal.ansiRed", color: "#E34F8C" }, 128 | { scope: "terminal.ansiYellow", color: "#F8C275" }, 129 | { scope: "terminal.ansiWhite", color: "#FBD3E1" }, 130 | { scope: "activityBar.background", color: "#1F2330" }, 131 | { scope: "activityBar.foreground", color: "#f6f0ff" }, 132 | { scope: "activityBar.inactiveForeground", color: "#919CB9" }, 133 | { scope: "activityBar.border", color: "#0F1320", materialize: true }, 134 | { scope: "activityBar.dropBackground", color: "#0F1320" }, 135 | { scope: "activityBarBadge.background", color: "#E34F8C" }, 136 | { scope: "sideBarTitle.foreground", color: "#24E8D8" }, 137 | { scope: "sideBar.border", color: "#0F1320", materialize: true }, 138 | { scope: "sideBar.foreground", color: "#919CB9" }, 139 | { scope: "sideBar.background", color: "#27273A" }, 140 | { scope: "sideBarSectionHeader.foreground", color: "#f6f0ff" }, 141 | { scope: "sideBarSectionHeader.background", color: "#1F2330" }, 142 | { scope: "sideBarSectionHeader.border", color: "#27273A" }, 143 | { scope: "sideBar.dropBackground", color: "#363C4C5f" }, 144 | { scope: "editorMarkerNavigation.background", color: "#1F2330" }, 145 | { scope: "editorError.foreground", color: "#F36F98" }, 146 | { scope: "editorWarning.foreground", color: "#f2c88c" }, 147 | { scope: "editorHint.foreground", color: "#F2C88C" }, 148 | { scope: "widget.shadow", color: "#0F1320" }, 149 | { scope: "editorWidget.border", color: "#24E8D8" }, 150 | { scope: "editorWidget.background", color: "#1F2330" }, 151 | { scope: "editorSuggestWidget.border", color: "#24E8D8" }, 152 | { scope: "editorSuggestWidget.background", color: "#27273A" }, 153 | { scope: "editorSuggestWidget.foreground", color: "#919CB9" }, 154 | { scope: "editorSuggestWidget.selectedBackground", color: "#35355190" }, 155 | { scope: "editorSuggestWidget.highlightForeground", color: "#fcf6ff" }, 156 | { scope: "editorHoverWidget.background", color: "#27273A" }, 157 | { scope: "editorHoverWidget.border", color: "#24E8D8" }, 158 | { scope: "peekView.border", color: "#24E8D8" }, 159 | { scope: "peekViewTitle.background", color: "#1F2330" }, 160 | { scope: "peekViewEditor.background", color: "#27273A" }, 161 | { scope: "peekViewResult.background", color: "#27273A" }, 162 | { scope: "peekViewResult.selectionBackground", color: "#35355190" }, 163 | { scope: "peekViewResult.matchHighlightBackground", color: "#363C4C" }, 164 | { scope: "peekViewEditor.matchHighlightBackground", color: "#363C4C" }, 165 | { scope: "debugToolBar.border", color: "#24E8D8" }, 166 | { scope: "debugToolBar.background", color: "#1F2330" }, 167 | { scope: "debugExceptionWidget.border", color: "#24E8D8" }, 168 | { scope: "list.inactiveSelectionForeground", color: "#fcf6ff" }, 169 | { scope: "list.highlightForeground", color: "#f8f8f2" }, 170 | { scope: "list.dropBackground", color: "#f6f0ff15" }, 171 | { scope: "list.inactiveSelectionBackground", color: "#899BBF2c" }, 172 | { scope: "list.activeSelectionBackground", color: "#899BBF3a" }, 173 | { scope: "list.hoverBackground", color: "#919CB915" }, 174 | { scope: "list.hoverForeground", color: "#f6f0ffea" }, 175 | { scope: "list.focusBackground", color: "#899BBF30" }, 176 | { scope: "list.focusForeground", color: "#f6f0ff" }, 177 | { scope: "list.errorForeground", color: "#F36F98" }, 178 | { scope: "list.warningForeground", color: "#F2C88C" }, 179 | { scope: "panel.background", color: "#1F2330" }, 180 | { scope: "panel.border", color: "#0F1320", materialize: true }, 181 | { scope: "panelTitle.inactiveForeground", color: "#919CB9" }, 182 | { scope: "panelTitle.activeForeground", color: "#24E8D8" }, 183 | { scope: "panelTitle.activeBorder", color: "#24E8D8" }, 184 | { scope: "statusBar.background", color: "#1F2330" }, 185 | { scope: "statusBar.border", color: "#0F1320", materialize: true }, 186 | { scope: "statusBar.foreground", color: "#919CB9" }, 187 | { scope: "statusBar.noFolderForeground", color: "#FCF6FF" }, 188 | { scope: "statusBar.noFolderBackground", color: "#E34FBC" }, 189 | { scope: "statusBar.debuggingBackground", color: "#6EEEC4" }, 190 | { scope: "statusBar.debuggingForeground", color: "#27273A" }, 191 | { scope: "welcomePage.buttonBackground", color: "#353551" }, 192 | { scope: "welcomePage.buttonHoverBackground", color: "#919CB91c" }, 193 | { scope: "textBlockQuote.border", color: "#E34F8C" }, 194 | { scope: "textBlockQuote.background", color: "#919CB91c" }, 195 | { scope: "textPreformat.foreground", color: "#24E8D8" }, 196 | { scope: "textSeparator.foreground", color: "#919CB9" }, 197 | { scope: "notifications.border", color: "#24E8D8" }, 198 | { scope: "notificationCenter.border", color: "#24E8D8" }, 199 | { scope: "notificationToast.border", color: "#24E8D8" }, 200 | { scope: "notificationCenterHeader.background", color: "#1F2330" }, 201 | { scope: "dropdown.listBackground", color: "#27273A" }, 202 | { scope: "dropdown.border", color: "#B2CFFB3A" }, 203 | { scope: "dropdown.background", color: "#1F2330" }, 204 | { scope: "dropdown.foreground", color: "#D7D6DF" }, 205 | { scope: "input.border", color: "#B2CFFB1A" }, 206 | { scope: "input.background", color: "#1F2330" }, 207 | { scope: "input.placeholderForeground", color: "#919CB99c" }, 208 | { scope: "input.foreground", color: "#D7D6DF" }, 209 | { scope: "inputOption.activeBorder", color: "#363C4C" }, 210 | { scope: "inputValidation.infoBorder", color: "#919CB9" }, 211 | { scope: "inputValidation.infoForeground", color: "#D7D6DF" }, 212 | { scope: "inputValidation.infoBackground", color: "#1F2330" }, 213 | { scope: "inputValidation.warningBorder", color: "#F2C88C" }, 214 | { scope: "inputValidation.warningForeground", color: "#F2C88C" }, 215 | { scope: "inputValidation.warningBackground", color: "#1F2330" }, 216 | { scope: "inputValidation.errorBorder", color: "#E34F8C" }, 217 | { scope: "inputValidation.errorForeground", color: "#E34F8C" }, 218 | { scope: "inputValidation.errorBackground", color: "#1F2330" }, 219 | { scope: "diffEditor.insertedTextBackground", color: "#6EEEC425" }, 220 | { scope: "diffEditor.removedTextBackground", color: "#E34F8C25" }, 221 | { scope: "gitDecoration.modifiedResourceForeground", color: "#F2C88C" }, 222 | { scope: "gitDecoration.deletedResourceForeground", color: "#E34F8C55" }, 223 | { scope: "gitDecoration.untrackedResourceForeground", color: "#e7ADFBa0" }, 224 | { scope: "gitDecoration.submoduleResourceForeground", color: "#C7ADFB5f" }, 225 | { scope: "gitDecoration.conflictingResourceForeground", color: "#07ADFB" }, 226 | { scope: "gitDecoration.ignoredResourceForeground", color: "#919CB9af" }, 227 | { scope: "editor.snippetTabstopHighlightBackground", color: "#1F2330" }, 228 | { scope: "editor.snippetTabstopHighlightBorder", color: "#24E8D890" }, 229 | { scope: "editor.snippetFinalTabstopHighlightBackground", color: "#1F2330" }, 230 | { scope: "editor.snippetFinalTabstopHighlightBorder", color: "#24E8D890" } 231 | ]; 232 | -------------------------------------------------------------------------------- /themes/Nebula-color-theme.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": { 3 | "foreground": "#fcf6ff", 4 | "errorForeground": "#E34F8C", 5 | "focusBorder": "#B2CFFB3A", 6 | "descriptionForeground": "#919CB9", 7 | "textLink.foreground": "#40afee", 8 | "textLink.activeForeground": "#74D6E9", 9 | "pickerGroup.foreground": "#E752A1", 10 | "pickerGroup.border": "#B2CFFB1A", 11 | "editorLineNumber.activeForeground": "#24E8D8", 12 | "editorWhitespace.foreground": "#B2CFFB1A", 13 | "editorIndentGuide.background": "#B2CFFB1A", 14 | "editorIndentGuide.activeBackground": "#B2CFFB3A", 15 | "editorRuler.foreground": "#C7ADFB2f", 16 | "editorOverviewRuler.border": "#B2CFFB2A", 17 | "progressBar.background": "#24E8D8", 18 | "badge.foreground": "#f8f8f2", 19 | "badge.background": "#E34F8C", 20 | "button.background": "#E34F8C", 21 | "button.hoverBackground": "#F661B1", 22 | "scrollbarSlider.background": "#06080E4A", 23 | "scrollbarSlider.hoverBackground": "#0F132090", 24 | "scrollbarSlider.activeBackground": "#0F1320C0", 25 | "scrollbar.shadow": "#0F1320", 26 | "editor.foreground": "#fcf6ff", 27 | "editor.selectionForeground": "#25313e", 28 | "editorCursor.foreground": "#97EE91", 29 | "editorBracketMatch.background": "#2A2A46", 30 | "editorBracketMatch.border": "#97EE91", 31 | "editor.background": "#27273A", 32 | "editorLineNumber.foreground": "#919CB9", 33 | "editor.lineHighlightBackground": "#2A2A46", 34 | "titleBar.activeBackground": "#1F2330", 35 | "titleBar.inactiveBackground": "#1F2330", 36 | "titleBar.activeForeground": "#D7D6DF", 37 | "titleBar.inactiveForeground": "#919CB9", 38 | "titleBar.border": "#0F1320", 39 | "menu.background": "#27273A", 40 | "menu.foreground": "#919CB9", 41 | "menu.selectionBackground": "#899BBF3A", 42 | "menu.selectionForeground": "#FCF6FF", 43 | "menu.selectionBorder": "#0F13207A", 44 | "menubar.selectionBackground": "#899BBF3A", 45 | "menubar.selectionForeground": "#FCF6FF", 46 | "menubar.selectionBorder": "#0F13200A", 47 | "menu.separatorBackground": "#B2CFFB3A", 48 | "settings.headerForeground": "#24E8D8", 49 | "settings.modifiedItemForeground": "#E34F8C", 50 | "settings.modifiedItemIndicator": "#E34F8C", 51 | "settings.inactiveSelectedItemBorder": "#B2CFFB1A", 52 | "settings.dropdownBackground": "#1F2330", 53 | "settings.dropdownForeground": "#E7ADFB", 54 | "settings.dropdownBorder": "#B2CFFB1A", 55 | "settings.dropdownListBorder": "#B2CFFB1A", 56 | "settings.checkboxBackground": "#1F2330", 57 | "settings.checkboxForeground": "#97EE91", 58 | "settings.checkboxBorder": "#97EE9150", 59 | "settings.textInputBackground": "#1F2330", 60 | "settings.textInputForeground": "#50DFFE", 61 | "settings.textInputBorder": "#B2CFFB1A", 62 | "settings.numberInputBackground": "#1F2330", 63 | "settings.numberInputForeground": "#F8C275", 64 | "settings.numberInputBorder": "#B2CFFB1A", 65 | "extensionButton.prominentBackground": "#97EE91", 66 | "extensionButton.prominentForeground": "#0F1320", 67 | "extensionButton.prominentHoverBackground": "#AFFA90", 68 | "selection.background": "#94cbf87a", 69 | "editorOverviewRuler.selectionHighlightForeground": "#97EE91", 70 | "editor.selectionHighlightBackground": "#42557B50", 71 | "editor.selectionHighlightBorder": "#42557B", 72 | "editor.wordHighlightBackground": "#42557B30", 73 | "editor.selectionBackground": "#42557BC0", 74 | "editor.wordHighlightBorder": "#00000000", 75 | "editor.wordHighlightStrongBorder": "#00000000", 76 | "editor.wordHighlightStrongBackground": "#42557B30", 77 | "editor.rangeHighlightBackground": "#2A2A46", 78 | "editor.findMatchBackground": "#C7ADFB90", 79 | "editor.findMatchBorder": "#C7ADFB00", 80 | "editor.findMatchHighlightBackground": "#C7ADFB30", 81 | "editor.findRangeHighlightBackground": "#2A2A46", 82 | "editor.findMatchHighlightBorder": "#C7ADFB50", 83 | "editorGroupHeader.tabsBackground": "#1F2330", 84 | "editorGroup.border": "#0F1320", 85 | "editorGroup.dropBackground": "#363C4C5f", 86 | "editorGroup.emptyBackground": "#1F2330", 87 | "editorPane.background": "#1F2330", 88 | "tab.activeBackground": "#27273A", 89 | "tab.activeBorder": "#0000", 90 | "tab.unfocusedActiveBorder": "#0000", 91 | "tab.activeForeground": "#24E8D8", 92 | "tab.unfocusedActiveForeground": "#47A9BC", 93 | "tab.inactiveBackground": "#1F2330", 94 | "tab.border": "#353551", 95 | "tab.hoverBorder": "#24E8D8", 96 | "tab.unfocusedHoverBorder": "#47A9BC", 97 | "tab.unfocusedInactiveForeground": "#79839C", 98 | "tab.inactiveForeground": "#919CB9", 99 | "tab.activeModifiedBorder": "#E34F8C", 100 | "tab.inactiveModifiedBorder": "#E34F8C90", 101 | "tab.unfocusedActiveModifiedBorder": "#E34F8CA0", 102 | "tab.unfocusedInactiveModifiedBorder": "#E34F8C70", 103 | "breadcrumb.foreground": "#919CB9", 104 | "breadcrumb.focusForeground": "#FCF6FF", 105 | "breadcrumb.activeSelectionForeground": "#FCF6FF", 106 | "breadcrumb.background": "#27273A", 107 | "breadcrumbPicker.background": "#27273A", 108 | "terminal.background": "#27273A", 109 | "terminalCursor.foreground": "#97EE91", 110 | "terminalCursor.background": "#0F1320", 111 | "terminal.selectionBackground": "#42557B5A", 112 | "terminal.foreground": "#f6f0ff", 113 | "terminal.ansiBlack": "#353551", 114 | "terminal.ansiBlue": "#C7ADFB", 115 | "terminal.ansiBrightBlack": "#919CB9", 116 | "terminal.ansiBrightBlue": "#74D6E9", 117 | "terminal.ansiBrightCyan": "#8DF9F9", 118 | "terminal.ansiBrightGreen": "#AFFA90", 119 | "terminal.ansiBrightMagenta": "#F799C7", 120 | "terminal.ansiBrightRed": "#F36F98", 121 | "terminal.ansiBrightWhite": "#D7D6DF", 122 | "terminal.ansiBrightYellow": "#FAFAA0", 123 | "terminal.ansiCyan": "#24E8D8", 124 | "terminal.ansiGreen": "#97F36D", 125 | "terminal.ansiMagenta": "#E752A1", 126 | "terminal.ansiRed": "#E34F8C", 127 | "terminal.ansiYellow": "#F8C275", 128 | "terminal.ansiWhite": "#FBD3E1", 129 | "activityBar.background": "#1F2330", 130 | "activityBar.foreground": "#f6f0ff", 131 | "activityBar.inactiveForeground": "#919CB9", 132 | "activityBar.border": "#0F1320", 133 | "activityBar.dropBackground": "#0F1320", 134 | "activityBarBadge.background": "#E34F8C", 135 | "sideBarTitle.foreground": "#24E8D8", 136 | "sideBar.border": "#0F1320", 137 | "sideBar.foreground": "#919CB9", 138 | "sideBar.background": "#27273A", 139 | "sideBarSectionHeader.foreground": "#f6f0ff", 140 | "sideBarSectionHeader.background": "#1F2330", 141 | "sideBarSectionHeader.border": "#27273A", 142 | "sideBar.dropBackground": "#363C4C5f", 143 | "editorMarkerNavigation.background": "#1F2330", 144 | "editorError.foreground": "#F36F98", 145 | "editorWarning.foreground": "#f2c88c", 146 | "editorHint.foreground": "#F2C88C", 147 | "widget.shadow": "#0F1320", 148 | "editorWidget.border": "#24E8D8", 149 | "editorWidget.background": "#1F2330", 150 | "editorSuggestWidget.border": "#24E8D8", 151 | "editorSuggestWidget.background": "#27273A", 152 | "editorSuggestWidget.foreground": "#919CB9", 153 | "editorSuggestWidget.selectedBackground": "#35355190", 154 | "editorSuggestWidget.highlightForeground": "#fcf6ff", 155 | "editorHoverWidget.background": "#27273A", 156 | "editorHoverWidget.border": "#24E8D8", 157 | "peekView.border": "#24E8D8", 158 | "peekViewTitle.background": "#1F2330", 159 | "peekViewEditor.background": "#27273A", 160 | "peekViewResult.background": "#27273A", 161 | "peekViewResult.selectionBackground": "#35355190", 162 | "peekViewResult.matchHighlightBackground": "#363C4C", 163 | "peekViewEditor.matchHighlightBackground": "#363C4C", 164 | "debugToolBar.border": "#24E8D8", 165 | "debugToolBar.background": "#1F2330", 166 | "debugExceptionWidget.border": "#24E8D8", 167 | "list.inactiveSelectionForeground": "#fcf6ff", 168 | "list.highlightForeground": "#f8f8f2", 169 | "list.dropBackground": "#f6f0ff15", 170 | "list.inactiveSelectionBackground": "#899BBF2c", 171 | "list.activeSelectionBackground": "#899BBF3a", 172 | "list.hoverBackground": "#919CB915", 173 | "list.hoverForeground": "#f6f0ffea", 174 | "list.focusBackground": "#899BBF30", 175 | "list.focusForeground": "#f6f0ff", 176 | "list.errorForeground": "#F36F98", 177 | "list.warningForeground": "#F2C88C", 178 | "panel.background": "#1F2330", 179 | "panel.border": "#0F1320", 180 | "panelTitle.inactiveForeground": "#919CB9", 181 | "panelTitle.activeForeground": "#24E8D8", 182 | "panelTitle.activeBorder": "#24E8D8", 183 | "statusBar.background": "#1F2330", 184 | "statusBar.border": "#0F1320", 185 | "statusBar.foreground": "#919CB9", 186 | "statusBar.noFolderForeground": "#FCF6FF", 187 | "statusBar.noFolderBackground": "#E34FBC", 188 | "statusBar.debuggingBackground": "#6EEEC4", 189 | "statusBar.debuggingForeground": "#27273A", 190 | "welcomePage.buttonBackground": "#353551", 191 | "welcomePage.buttonHoverBackground": "#919CB91c", 192 | "textBlockQuote.border": "#E34F8C", 193 | "textBlockQuote.background": "#919CB91c", 194 | "textPreformat.foreground": "#24E8D8", 195 | "textSeparator.foreground": "#919CB9", 196 | "notifications.border": "#24E8D8", 197 | "notificationCenter.border": "#24E8D8", 198 | "notificationToast.border": "#24E8D8", 199 | "notificationCenterHeader.background": "#1F2330", 200 | "dropdown.listBackground": "#27273A", 201 | "dropdown.border": "#B2CFFB3A", 202 | "dropdown.background": "#1F2330", 203 | "dropdown.foreground": "#D7D6DF", 204 | "input.border": "#B2CFFB1A", 205 | "input.background": "#1F2330", 206 | "input.placeholderForeground": "#919CB99c", 207 | "input.foreground": "#D7D6DF", 208 | "inputOption.activeBorder": "#363C4C", 209 | "inputValidation.infoBorder": "#919CB9", 210 | "inputValidation.infoForeground": "#D7D6DF", 211 | "inputValidation.infoBackground": "#1F2330", 212 | "inputValidation.warningBorder": "#F2C88C", 213 | "inputValidation.warningForeground": "#F2C88C", 214 | "inputValidation.warningBackground": "#1F2330", 215 | "inputValidation.errorBorder": "#E34F8C", 216 | "inputValidation.errorForeground": "#E34F8C", 217 | "inputValidation.errorBackground": "#1F2330", 218 | "diffEditor.insertedTextBackground": "#6EEEC425", 219 | "diffEditor.removedTextBackground": "#E34F8C25", 220 | "gitDecoration.modifiedResourceForeground": "#F2C88C", 221 | "gitDecoration.deletedResourceForeground": "#E34F8C55", 222 | "gitDecoration.untrackedResourceForeground": "#e7ADFBa0", 223 | "gitDecoration.submoduleResourceForeground": "#C7ADFB5f", 224 | "gitDecoration.conflictingResourceForeground": "#07ADFB", 225 | "gitDecoration.ignoredResourceForeground": "#919CB9af", 226 | "editor.snippetTabstopHighlightBackground": "#1F2330", 227 | "editor.snippetTabstopHighlightBorder": "#24E8D890", 228 | "editor.snippetFinalTabstopHighlightBackground": "#1F2330", 229 | "editor.snippetFinalTabstopHighlightBorder": "#24E8D890" 230 | }, 231 | "tokenColors": [ 232 | { 233 | "name": "Compiled Italics", 234 | "scope": [ 235 | "entity.other.attribute-name.pseudo-element.css", 236 | "entity.other.inherited-class", 237 | "markup.italic.markdown", 238 | "markup.quote", 239 | "meta.function.variable.css", 240 | "punctuation.definition.italic.markdown", 241 | "punctuation.definition.string.css", 242 | "storage.type.function", 243 | "string.quoted.double.css", 244 | "variable.argument.css", 245 | "entity.name.tag.custom", 246 | "entity.name.type.ts", 247 | "italic", 248 | "keyword.operator.type.annotation", 249 | "keyword.control.import", 250 | "modifier", 251 | "punctuation.section.embedded", 252 | "quote", 253 | "storage.type", 254 | "storage.type.class", 255 | "support.class", 256 | "support.class.builtin", 257 | "support.constant", 258 | "support.function.basic_functions", 259 | "support.function.builtin", 260 | "support.type.primitive", 261 | "support.type.property.css", 262 | "this", 263 | "type.function", 264 | "variable.parameter" 265 | ], 266 | "settings": { 267 | "fontStyle": "italic" 268 | } 269 | }, 270 | { 271 | "name": "Magnolia", 272 | "scope": [ 273 | "meta.brace", 274 | "punctuation.definition.array", 275 | "punctuation.definition.binding-pattern", 276 | "punctuation.definition.block", 277 | "punctuation.definition.dictionary", 278 | "punctuation.definition.string", 279 | "punctuation.definition.tag", 280 | "punctuation.curlybrace", 281 | "punctuation.fullstop", 282 | "punctuation.section", 283 | "punctuation.support", 284 | "punctuation.terminator", 285 | "meta.structure.dictionary.json", 286 | "string.quoted.double.json", 287 | "constant.other.table-name.sql" 288 | ], 289 | "settings": { 290 | "foreground": "#F6F0FF" 291 | } 292 | }, 293 | { 294 | "name": "Electric Blue", 295 | "scope": [ 296 | "support.variable", 297 | "variable", 298 | "support.type.property-name", 299 | "variable.other.object.property", 300 | "meta.object-literal.key.js", 301 | "string.other.link.description.markdown" 302 | ], 303 | "settings": { 304 | "foreground": "#8DF9F9" 305 | } 306 | }, 307 | { 308 | "name": "Sulu", 309 | "scope": [ 310 | "keyword.var", 311 | "keyword.const", 312 | "constant", 313 | "keyword.struct", 314 | "keyword.interface", 315 | "keyword.function", 316 | "markup.inline.raw", 317 | "punctuation.parenthesis.named.begin.regexp", 318 | "punctuation.parenthesis.named.end.regexp", 319 | "punctuation.parenthesis.non-capturing.begin.regexp", 320 | "punctuation.parenthesis.non-capturing.end.regexp", 321 | "support.constant", 322 | "support.type", 323 | "support.class", 324 | "markup.inserted", 325 | "entity.name.type", 326 | "entity.name.class", 327 | "entity.other.inherited-class", 328 | "entity.other.attribute-name.id.css" 329 | ], 330 | "settings": { 331 | "foreground": "#97EE91" 332 | } 333 | }, 334 | { 335 | "name": "Bali Hai", 336 | "scope": [ 337 | "punctuation.terminator", 338 | "punctuation.section.function.begin.bracket.round.css", 339 | "punctuation.section.function.end.bracket.round.css", 340 | "punctuation.section.property-list.begin.bracket.curly.css", 341 | "punctuation.section.property-list.end.bracket.curly.css" 342 | ], 343 | "settings": { 344 | "foreground": "#919CB9" 345 | } 346 | }, 347 | { 348 | "name": "Lavender Gray", 349 | "scope": [ 350 | "constant.other.database-name.sql", 351 | "variable.other.object" 352 | ], 353 | "settings": { 354 | "foreground": "#C5B9DF" 355 | } 356 | }, 357 | { 358 | "name": "Deluge", 359 | "scope": [ 360 | "comment" 361 | ], 362 | "settings": { 363 | "foreground": "#8059A2" 364 | } 365 | }, 366 | { 367 | "name": "Malibu", 368 | "scope": [ 369 | "string", 370 | "markup.quote", 371 | "markup.bold", 372 | "markup.italic", 373 | "string.quoted.single.js", 374 | "string.quoted.double.js", 375 | "meta.link.inline.markdown", 376 | "meta.image.inline.markdown", 377 | "markup.underline.link", 378 | "entity.name.type.js" 379 | ], 380 | "settings": { 381 | "foreground": "#50DFFE" 382 | } 383 | }, 384 | { 385 | "name": "Mauve", 386 | "scope": [ 387 | "string.quoted.docstring", 388 | "storage.type.function", 389 | "keyword.type", 390 | "storage.type", 391 | "punctuation.accessor", 392 | "punctuation.separator", 393 | "meta.brace.square.js", 394 | "meta.brace.square.ts" 395 | ], 396 | "settings": { 397 | "foreground": "#E7ADFB" 398 | } 399 | }, 400 | { 401 | "name": "Froly", 402 | "scope": [ 403 | "entity.name.class", 404 | "entity.name.function", 405 | "entity.name.type", 406 | "entity.other.attribute-name", 407 | "entity.other.inherited-class", 408 | "markup.heading.setext", 409 | "meta.function-call.generic", 410 | "support.function", 411 | "support.other.escape.special.regexp" 412 | ], 413 | "settings": { 414 | "foreground": "#F36F98" 415 | } 416 | }, 417 | { 418 | "name": "Rajah", 419 | "scope": [ 420 | "entity.name.tag", 421 | "storage", 422 | "support.function.builtin", 423 | "variable.language", 424 | "constant.numeric", 425 | "variable.parameter", 426 | "markup.bold", 427 | "markup.underline", 428 | "markup.italic", 429 | "string.quoted.double.css", 430 | "punctuation.definition.string.css" 431 | ], 432 | "settings": { 433 | "foreground": "#F8C275" 434 | } 435 | }, 436 | { 437 | "name": "Deep Blush", 438 | "scope": [ 439 | "entity.name.section", 440 | "keyword", 441 | "punctuation.definition.heading", 442 | "punctuation.definition.keyword", 443 | "keyword.other.DML.sql", 444 | "constant.character.escape.markdown", 445 | "entity.other.attribute-name.class.css" 446 | ], 447 | "settings": { 448 | "foreground": "#E752A1" 449 | } 450 | }, 451 | { 452 | "name": "Classic Rose", 453 | "scope": [ 454 | "meta.brace", 455 | "punctuation.definition.arguments", 456 | "punctuation.definition.array", 457 | "punctuation.definition.begin.bracket", 458 | "punctuation.definition.binding-pattern", 459 | "punctuation.definition.block", 460 | "punctuation.definition.bracket", 461 | "punctuation.definition.dict", 462 | "punctuation.definition.dictionary", 463 | "punctuation.definition.end.bracket", 464 | "punctuation.definition.list", 465 | "punctuation.definition.parameters", 466 | "punctuation.definition.string", 467 | "punctuation.definition.tag", 468 | "punctuation.other.comma", 469 | "punctuation.other.period", 470 | "punctuation.section", 471 | "punctuation.support", 472 | "punctuation.terminator" 473 | ], 474 | "settings": { 475 | "foreground": "#FBD3E1" 476 | } 477 | }, 478 | { 479 | "name": "Cranberry", 480 | "scope": [ 481 | "punctuation.definition.template-expression", 482 | "punctuation.section.embedded", 483 | "storage", 484 | "markup.deleted", 485 | "markup.heading", 486 | "entity.name.section.markdown", 487 | "token.error-token" 488 | ], 489 | "settings": { 490 | "foreground": "#E34F8C" 491 | } 492 | }, 493 | { 494 | "name": "Texas", 495 | "scope": [ 496 | "markup.changed", 497 | "entity.name.filename.find-in-files", 498 | "markup.quote", 499 | "keyword.other.unit.px.css", 500 | "keyword.other.unit.fr.css", 501 | "keyword.other.unit.s.css", 502 | "keyword.other.unit.percentage.css" 503 | ], 504 | "settings": { 505 | "foreground": "#FAFAA0" 506 | } 507 | }, 508 | { 509 | "name": "Perfume", 510 | "scope": [ 511 | "markup.fenced_code.block.markdown", 512 | "keyword.type", 513 | "keyword.other.alias.sql", 514 | "meta.functiona.variable.css", 515 | "variable.argument.css", 516 | "constant.numeric.line-number.find-in-files - match" 517 | ], 518 | "settings": { 519 | "foreground": "#C7ADFB" 520 | } 521 | }, 522 | { 523 | "name": "White Pointer", 524 | "scope": [ 525 | "variable", 526 | "text.html.markdown", 527 | "support.constant.property-value.css" 528 | ], 529 | "settings": { 530 | "foreground": "#FCF6FF" 531 | } 532 | }, 533 | { 534 | "name": "Jaffa", 535 | "scope": [ 536 | "beginning.punctuation.definition.list.markdown", 537 | "constant.language.null", 538 | "constant.language.boolean.true", 539 | "constant.language.boolean.false", 540 | "entity.other.attribute-name.pseudo-element.css" 541 | ], 542 | "settings": { 543 | "foreground": "#F39B35" 544 | } 545 | }, 546 | { 547 | "name": "Anakiwa", 548 | "scope": [ 549 | "meta.link.inline.markdown", 550 | "meta.image.inline.markdown", 551 | "markup.underline.link" 552 | ], 553 | "settings": { 554 | "foreground": "#99ddff" 555 | } 556 | }, 557 | { 558 | "name": "Bold", 559 | "scope": [ 560 | "markup.bold.markdown", 561 | "punctuation.definition.bold.markdown" 562 | ], 563 | "settings": { 564 | "fontStyle": "bold" 565 | } 566 | }, 567 | { 568 | "name": "Underline", 569 | "scope": [ 570 | "entity.other.inherited-class", 571 | "entity.name.type", 572 | "entity.name.class", 573 | "entity.other.inherited-class" 574 | ], 575 | "settings": { 576 | "fontStyle": "underline" 577 | } 578 | } 579 | ], 580 | "options": { 581 | "commentItalics": false, 582 | "themeItalics": "2 - wavy", 583 | "materialize": false 584 | } 585 | } --------------------------------------------------------------------------------