@@ -9,16 +9,18 @@ import * as stripJsonComments from 'strip-json-comments';
99
1010import { IWorkspaceService } from '../common/application/types' ;
1111import { IConfigurationService , ILogger } from '../common/types' ;
12- import { EXTENSION_ROOT_DIR } from '../constants' ;
1312import { DefaultTheme , Identifiers } from './constants' ;
1413import { ICodeCssGenerator , IThemeFinder } from './types' ;
1514
1615// tslint:disable:no-any
16+ const DarkTheme = 'dark' ;
17+ const LightTheme = 'light' ;
1718
1819// These are based on the colors generated by 'Default Light+' and are only set when we
1920// are ignoring themes.
20- //tslint:disable-next-line:no-multiline-string
21- const DefaultStyle = `
21+ //tslint:disable:no-multiline-string object-literal-key-quotes
22+ const DefaultCssVars : { [ key : string ] : string } = {
23+ LightTheme : `
2224 :root {
2325 --override-widget-background: #f3f3f3;
2426 --override-foreground: #000000;
@@ -28,7 +30,42 @@ const DefaultStyle = `
2830 --override-tabs-background: #f3f3f3;
2931 --override-progress-background: #0066bf;
3032 }
31- ` ;
33+ ` ,
34+ DarkTheme : `
35+ :root {
36+ --override-widget-background: #1e1e1e;
37+ --override-foreground: #d4d4d4;
38+ --override-background: #1e1e1e;
39+ --override-selection-background: #264f78;
40+ --override-watermark-color: #3f3f46;
41+ --override-tabs-background: #252526;
42+ --override-progress-background: #0066bf;
43+ }
44+ `
45+ } ;
46+
47+ // These colors below should match colors that come from either the Default Light+ theme or the Default Dark+ theme.
48+ // They are used when we can't find a theme json file.
49+ const DefaultColors : { [ key : string ] : string } = {
50+ 'light.comment' : '#008000' ,
51+ 'light.constant.numeric' : '#09885a' ,
52+ 'light.string' : '#a31515' ,
53+ 'light.keyword.control' : '#AF00DB' ,
54+ 'light.keyword.operator' : '#000000' ,
55+ 'light.variable' : '#001080' ,
56+ 'light.entity.name.type' : '#267f99' ,
57+ 'light.support.function' : '#795E26' ,
58+ 'light.punctuation' : '#000000' ,
59+ 'dark.comment' : '#6A9955' ,
60+ 'dark.constant.numeric' : '#b5cea8' ,
61+ 'dark.string' : '#ce9178' ,
62+ 'dark.keyword.control' : '#C586C0' ,
63+ 'dark.keyword.operator' : '#d4d4d4' ,
64+ 'dark.variable' : '#9CDCFE' ,
65+ 'dark.entity.name.type' : '#4EC9B0' ,
66+ 'dark.support.function' : '#DCDCAA' ,
67+ 'dark.punctuation' : '#1e1e1e'
68+ } ;
3269
3370// This class generates css using the current theme in order to colorize code.
3471//
@@ -45,17 +82,17 @@ export class CodeCssGenerator implements ICodeCssGenerator {
4582 @inject ( ILogger ) private logger : ILogger ) {
4683 }
4784
48- public generateThemeCss = async ( ) : Promise < string > = > {
85+ public async generateThemeCss ( isDark : boolean , theme : string ) : Promise < string > {
4986 let css : string = '' ;
5087 try {
5188 // First compute our current theme.
5289 const workbench = this . workspaceService . getConfiguration ( 'workbench' ) ;
5390 const ignoreTheme = this . configService . getSettings ( ) . datascience . ignoreVscodeTheme ? true : false ;
54- const theme = ignoreTheme ? DefaultTheme : workbench . get < string > ( 'colorTheme' ) ;
55- const terminalCursor = workbench . get < string > ( 'terminal.integrated.cursorStyle' , 'block' ) ;
91+ theme = ignoreTheme ? DefaultTheme : theme ;
92+ const terminalCursor = workbench ? workbench . get < string > ( 'terminal.integrated.cursorStyle' , 'block' ) : 'block' ;
5693 const editor = this . workspaceService . getConfiguration ( 'editor' , undefined ) ;
57- const font = editor . get < string > ( 'fontFamily' ) ;
58- const fontSize = editor . get < number > ( 'fontSize' ) ;
94+ const font = editor ? editor . get < string > ( 'fontFamily' , 'Consolas, \'Courier New\', monospace' ) : 'Consolas, \'Courier New\', monospace' ;
95+ const fontSize = editor ? editor . get < number > ( 'fontSize' , 14 ) : 14 ;
5996
6097 // Then we have to find where the theme resources are loaded from
6198 if ( theme ) {
@@ -65,7 +102,11 @@ export class CodeCssGenerator implements ICodeCssGenerator {
65102 // The tokens object then contains the necessary data to generate our css
66103 if ( tokenColors && font && fontSize ) {
67104 this . logger . logInformation ( 'Using colors to generate CSS ...' ) ;
68- css = this . generateCss ( theme , tokenColors , font , fontSize , terminalCursor , ignoreTheme ) ;
105+ css = this . generateCss ( theme , tokenColors , font , fontSize , terminalCursor , ignoreTheme ? LightTheme : undefined ) ;
106+ } else if ( tokenColors === null && font && fontSize ) {
107+ // No colors found. See if we can figure out what type of theme we have
108+ const style = isDark ? DarkTheme : LightTheme ;
109+ css = this . generateCss ( theme , null , font , fontSize , terminalCursor , style ) ;
69110 }
70111 }
71112 } catch ( err ) {
@@ -92,43 +133,48 @@ export class CodeCssGenerator implements ICodeCssGenerator {
92133 } ) ;
93134 }
94135
95- private getScopeStyle = ( tokenColors : JSONArray , scope : string , secondary ? : string ) : { color : string ; fontStyle : string } => {
136+ private getScopeStyle = ( tokenColors : JSONArray | null , scope : string , secondary : string , defaultStyle : string | undefined ) : { color : string ; fontStyle : string } => {
96137 // Search through the scopes on the json object
97- let match = this . matchTokenColor ( tokenColors , scope ) ;
98- if ( match < 0 && secondary ) {
99- match = this . matchTokenColor ( tokenColors , secondary ) ;
100- }
101- const found = match >= 0 ? tokenColors [ match ] as any : null ;
102- if ( found !== null ) {
103- const settings = found . settings ;
104- if ( settings && settings !== null ) {
105- const fontStyle = settings . fontStyle ? settings . fontStyle : 'normal' ;
106- const foreground = settings . foreground ? settings . foreground : 'var(--vscode-editor-foreground)' ;
107-
108- return { fontStyle, color : foreground } ;
138+ if ( tokenColors ) {
139+ let match = this . matchTokenColor ( tokenColors , scope ) ;
140+ if ( match < 0 && secondary ) {
141+ match = this . matchTokenColor ( tokenColors , secondary ) ;
142+ }
143+ const found = match >= 0 ? tokenColors [ match ] as any : null ;
144+ if ( found !== null ) {
145+ const settings = found . settings ;
146+ if ( settings && settings !== null ) {
147+ const fontStyle = settings . fontStyle ? settings . fontStyle : 'normal' ;
148+ const foreground = settings . foreground ? settings . foreground : 'var(--vscode-editor-foreground)' ;
149+
150+ return { fontStyle, color : foreground } ;
151+ }
109152 }
110153 }
111154
112155 // Default to editor foreground
113- return { color : 'var(--vscode-editor-foreground)' , fontStyle : 'normal' } ;
156+ return { color : this . getDefaultColor ( defaultStyle , scope ) , fontStyle : 'normal' } ;
157+ }
158+
159+ private getDefaultColor ( style : string | undefined , scope : string ) : string {
160+ return style ? DefaultColors [ `${ style } .${ scope } ` ] : 'var(--override-foreground, var(--vscode-editor-foreground))' ;
114161 }
115162
116163 // tslint:disable-next-line:max-func-body-length
117- private generateCss ( theme : string , tokenColors : JSONArray , fontFamily : string , fontSize : number , cursorType : string , generateDefaults : boolean ) : string {
164+ private generateCss ( theme : string , tokenColors : JSONArray | null , fontFamily : string , fontSize : number , cursorType : string , defaultStyle : string | undefined ) : string {
118165 const escapedThemeName = Identifiers . GeneratedThemeName ;
119166
120167 // There's a set of values that need to be found
121- const commentStyle = this . getScopeStyle ( tokenColors , 'comment' ) ;
122- const numericStyle = this . getScopeStyle ( tokenColors , 'constant.numeric' ) ;
123- const stringStyle = this . getScopeStyle ( tokenColors , 'string' ) ;
124- const keywordStyle = this . getScopeStyle ( tokenColors , 'keyword.control' , 'keyword' ) ;
125- const operatorStyle = this . getScopeStyle ( tokenColors , 'keyword.operator' , 'keyword' ) ;
126- const variableStyle = this . getScopeStyle ( tokenColors , 'variable' ) ;
127- const entityTypeStyle = this . getScopeStyle ( tokenColors , 'entity.name.type' ) ;
168+ const commentStyle = this . getScopeStyle ( tokenColors , 'comment' , 'comment' , defaultStyle ) ;
169+ const numericStyle = this . getScopeStyle ( tokenColors , 'constant.numeric' , 'constant' , defaultStyle ) ;
170+ const stringStyle = this . getScopeStyle ( tokenColors , 'string' , 'string' , defaultStyle ) ;
171+ const keywordStyle = this . getScopeStyle ( tokenColors , 'keyword.control' , 'keyword' , defaultStyle ) ;
172+ const operatorStyle = this . getScopeStyle ( tokenColors , 'keyword.operator' , 'keyword' , defaultStyle ) ;
173+ const variableStyle = this . getScopeStyle ( tokenColors , 'variable' , 'variable' , defaultStyle ) ;
174+ const entityTypeStyle = this . getScopeStyle ( tokenColors , 'entity.name.type' , 'entity.name.type' , defaultStyle ) ;
128175 // const atomic = this.getScopeColor(tokenColors, 'atomic');
129- const builtinStyle = this . getScopeStyle ( tokenColors , 'support.function' ) ;
130- const punctuationStyle = this . getScopeStyle ( tokenColors , 'punctuation' ) ;
131- const overrides = generateDefaults ? DefaultStyle : '' ;
176+ const builtinStyle = this . getScopeStyle ( tokenColors , 'support.function' , 'support.function' , defaultStyle ) ;
177+ const punctuationStyle = this . getScopeStyle ( tokenColors , 'punctuation' , 'punctuation' , defaultStyle ) ;
132178
133179 const def = 'var(--vscode-editor-foreground)' ;
134180
@@ -150,7 +196,7 @@ export class CodeCssGenerator implements ICodeCssGenerator {
150196 --code-font-size: ${ fontSize } px;
151197 }
152198
153- ${ overrides }
199+ ${ defaultStyle ? DefaultCssVars [ defaultStyle ] : undefined }
154200
155201 .cm-header, .cm-strong {font-weight: bold;}
156202 .cm-em {font-style: italic;}
@@ -206,7 +252,7 @@ export class CodeCssGenerator implements ICodeCssGenerator {
206252 return [ ] ;
207253 }
208254
209- private findTokenColors = async ( theme : string ) : Promise < JSONArray > => {
255+ private findTokenColors = async ( theme : string ) : Promise < JSONArray | null > => {
210256
211257 try {
212258 this . logger . logInformation ( 'Attempting search for colors ...' ) ;
@@ -256,8 +302,7 @@ export class CodeCssGenerator implements ICodeCssGenerator {
256302 this . logger . logError ( err ) ;
257303 }
258304
259- // We should return a default. The vscode-light theme
260- const defaultThemeFile = path . join ( EXTENSION_ROOT_DIR , 'resources' , 'defaultTheme.json' ) ;
261- return this . readTokenColors ( defaultThemeFile ) ;
305+ // Force the colors to the defaults
306+ return null ;
262307 }
263308}
0 commit comments