Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
46362674
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
46362674
编写于
3月 24, 2017
作者:
M
Martin Aeschlimann
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[theme] support custom theme
上级
e1122824
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
275 addition
and
145 deletion
+275
-145
src/vs/editor/common/modes/tokenizationRegistry.ts
src/vs/editor/common/modes/tokenizationRegistry.ts
+8
-5
src/vs/workbench/services/themes/common/colorThemeSchema.ts
src/vs/workbench/services/themes/common/colorThemeSchema.ts
+50
-47
src/vs/workbench/services/themes/common/workbenchThemeService.ts
...workbench/services/themes/common/workbenchThemeService.ts
+3
-0
src/vs/workbench/services/themes/electron-browser/colorThemeData.ts
...kbench/services/themes/electron-browser/colorThemeData.ts
+124
-38
src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts
...services/themes/electron-browser/workbenchThemeService.ts
+90
-55
未找到文件。
src/vs/editor/common/modes/tokenizationRegistry.ts
浏览文件 @
46362674
...
...
@@ -8,6 +8,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
ColorId
,
ITokenizationRegistry
,
ITokenizationSupport
,
ITokenizationSupportChangedEvent
}
from
'
vs/editor/common/modes
'
;
import
{
Color
}
from
'
vs/base/common/color
'
;
import
*
as
objects
from
'
vs/base/common/objects
'
;
export
class
TokenizationRegistryImpl
implements
ITokenizationRegistry
{
...
...
@@ -49,11 +50,13 @@ export class TokenizationRegistryImpl implements ITokenizationRegistry {
}
public
setColorMap
(
colorMap
:
Color
[]):
void
{
this
.
_colorMap
=
colorMap
;
this
.
_onDidChange
.
fire
({
changedLanguages
:
Object
.
keys
(
this
.
_map
),
changedColorMap
:
true
});
if
(
!
objects
.
equals
(
colorMap
,
this
.
_colorMap
))
{
this
.
_colorMap
=
colorMap
;
this
.
_onDidChange
.
fire
({
changedLanguages
:
Object
.
keys
(
this
.
_map
),
changedColorMap
:
true
});
}
}
public
getColorMap
():
Color
[]
{
...
...
src/vs/workbench/services/themes/common/colorThemeSchema.ts
浏览文件 @
46362674
...
...
@@ -114,57 +114,51 @@ let textMateScopes = [
'
variable.parameter
'
];
const
schemaId
=
'
vscode://schemas/color-theme
'
;
const
schema
:
IJSONSchema
=
{
type
:
'
object
'
,
properties
:
{
colors
:
themingRegistry
.
getColorSchema
(),
tokenColors
:
{
type
:
'
array
'
,
description
:
nls
.
localize
(
'
schema.colors
'
,
'
Colors for syntax highlighting
'
),
items
:
{
export
const
colorsSchema
=
themingRegistry
.
getColorSchema
();
export
const
tokenColorsSchema
=
{
type
:
'
array
'
,
description
:
nls
.
localize
(
'
schema.colors
'
,
'
Colors for syntax highlighting
'
),
items
:
{
type
:
'
object
'
,
properties
:
{
name
:
{
type
:
'
string
'
,
description
:
nls
.
localize
(
'
schema.properties.name
'
,
'
Description of the rule
'
)
},
scope
:
{
anyOf
:
[
{
enum
:
textMateScopes
},
{
type
:
'
string
'
},
{
type
:
'
array
'
,
items
:
{
enum
:
textMateScopes
}
},
{
type
:
'
array
'
,
items
:
{
type
:
'
string
'
}
}
]
},
settings
:
{
type
:
'
object
'
,
properties
:
{
name
:
{
type
:
'
string
'
,
description
:
nls
.
localize
(
'
schema.properties.name
'
,
'
Description of the rule
'
)
foreground
:
{
type
:
'
string
'
},
scope
:
{
anyOf
:
[
{
enum
:
textMateScopes
},
{
type
:
'
string
'
},
{
type
:
'
array
'
,
items
:
{
enum
:
textMateScopes
}
},
{
type
:
'
array
'
,
items
:
{
type
:
'
string
'
}
}
]
background
:
{
type
:
'
string
'
},
settings
:
{
type
:
'
object
'
,
properties
:
{
foreground
:
{
type
:
'
string
'
},
background
:
{
type
:
'
string
'
},
fontStyle
:
{
type
:
'
string
'
,
description
:
nls
.
localize
(
'
schema.fontStyle
'
,
'
Font style of the rule: One or a combination of
\'
italic
\'
,
\'
bold
\'
and
\'
underline
\'
'
)
}
}
fontStyle
:
{
type
:
'
string
'
,
description
:
nls
.
localize
(
'
schema.fontStyle
'
,
'
Font style of the rule: One or a combination of
\'
italic
\'
,
\'
bold
\'
and
\'
underline
\'
'
)
}
}
}
...
...
@@ -172,6 +166,15 @@ const schema: IJSONSchema = {
}
};
const
schemaId
=
'
vscode://schemas/color-theme
'
;
const
schema
:
IJSONSchema
=
{
type
:
'
object
'
,
properties
:
{
colors
:
colorsSchema
,
tokenColors
:
tokenColorsSchema
}
};
export
function
register
()
{
let
schemaRegistry
=
<
IJSONContributionRegistry
>
Registry
.
as
(
JSONExtensions
.
JSONContribution
);
schemaRegistry
.
registerSchema
(
schemaId
,
schema
);
...
...
src/vs/workbench/services/themes/common/workbenchThemeService.ts
浏览文件 @
46362674
...
...
@@ -19,6 +19,9 @@ export const VS_HC_THEME = 'hc-black';
export
const
COLOR_THEME_SETTING
=
'
workbench.colorTheme
'
;
export
const
ICON_THEME_SETTING
=
'
workbench.iconTheme
'
;
export
const
CUSTOM_COLOR_THEME_SETTING
=
'
workbench.customColorTheme
'
;
export
const
CUSTOM_THEME_ID
=
'
Custom Theme
'
;
export
interface
IColorTheme
extends
ITheme
{
readonly
id
:
string
;
...
...
src/vs/workbench/services/themes/electron-browser/colorThemeData.ts
浏览文件 @
46362674
...
...
@@ -6,7 +6,7 @@
import
Paths
=
require
(
'
vs/base/common/paths
'
);
import
Json
=
require
(
'
vs/base/common/json
'
);
import
{
Color
}
from
'
vs/base/common/color
'
;
import
{
ExtensionData
,
ITokenColorizationRule
,
IColorTheme
,
IColorMap
,
VS_LIGHT_THEME
,
VS_HC_THEME
}
from
'
vs/workbench/services/themes/common/workbenchThemeService
'
;
import
{
ExtensionData
,
ITokenColorizationRule
,
IColorTheme
,
IColorMap
,
VS_LIGHT_THEME
,
VS_HC_THEME
,
VS_DARK_THEME
,
CUSTOM_THEME_ID
}
from
'
vs/workbench/services/themes/common/workbenchThemeService
'
;
import
{
convertSettings
}
from
'
vs/workbench/services/themes/electron-browser/themeCompatibility
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
getBaseThemeId
,
getSyntaxThemeId
,
isDarkTheme
,
isLightTheme
}
from
'
vs/platform/theme/common/themes
'
;
...
...
@@ -20,6 +20,8 @@ import pfs = require('vs/base/node/pfs');
import
{
Extensions
,
IColorRegistry
,
ColorIdentifier
,
editorBackground
,
editorForeground
}
from
'
vs/platform/theme/common/colorRegistry
'
;
import
{
ThemeType
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
Registry
}
from
'
vs/platform/platform
'
;
import
{
WorkbenchThemeService
,
IUserTheme
}
from
"
vs/workbench/services/themes/electron-browser/workbenchThemeService
"
;
import
{
IThemeExtensionPoint
}
from
"
vs/platform/theme/common/themeExtensionPoint
"
;
let
colorRegistry
=
<
IColorRegistry
>
Registry
.
as
(
Extensions
.
ColorContribution
);
...
...
@@ -33,6 +35,7 @@ export class ColorThemeData implements IColorTheme {
tokenColors
?:
ITokenColorizationRule
[];
isLoaded
:
boolean
;
path
?:
string
;
userThemeData
:
IUserTheme
;
extensionData
:
ExtensionData
;
colorMap
:
IColorMap
=
{};
defaultColorMap
:
IColorMap
=
{};
...
...
@@ -64,17 +67,22 @@ export class ColorThemeData implements IColorTheme {
return
color
===
null
?
defaultValue
===
null
:
color
.
equals
(
defaultValue
);
}
public
ensureLoaded
():
TPromise
<
void
>
{
public
ensureLoaded
(
themeService
:
WorkbenchThemeService
):
TPromise
<
void
>
{
if
(
!
this
.
isLoaded
)
{
let
tokenColors
=
[];
let
colorMap
=
{};
return
_loadThemeDocument
(
this
.
getBaseThemeId
(),
this
.
path
,
tokenColors
,
colorMap
).
then
(
_
=>
{
this
.
tokenColors
=
tokenColors
;
this
.
colorMap
=
colorMap
;
this
.
defaultColorMap
=
{};
this
.
isLoaded
=
true
;
completeTokenColors
(
this
);
});
this
.
tokenColors
=
[];
this
.
colorMap
=
{};
this
.
defaultColorMap
=
{};
if
(
this
.
path
)
{
return
_loadThemeDocumentFromFile
(
this
.
path
,
this
.
tokenColors
,
this
.
colorMap
).
then
(
_
=>
{
this
.
isLoaded
=
true
;
completeTokenColors
(
this
);
});
}
else
if
(
this
.
userThemeData
)
{
return
_loadThemeDocumentFromUserTheme
(
themeService
,
this
.
userThemeData
,
this
.
tokenColors
,
this
.
colorMap
).
then
(
_
=>
{
this
.
isLoaded
=
true
;
completeTokenColors
(
this
);
});
}
}
return
TPromise
.
as
(
null
);
}
...
...
@@ -151,33 +159,53 @@ export function fromStorageData(input: string): ColorThemeData {
return
theme
;
}
let
defaultThemeColors
:
{
[
baseTheme
:
string
]:
ITokenColorizationRule
[]
}
=
{
'
vs
'
:
[
{
scope
:
'
token.info-token
'
,
settings
:
{
foreground
:
'
#316bcd
'
}
},
{
scope
:
'
token.warn-token
'
,
settings
:
{
foreground
:
'
#cd9731
'
}
},
{
scope
:
'
token.error-token
'
,
settings
:
{
foreground
:
'
#cd3131
'
}
},
{
scope
:
'
token.debug-token
'
,
settings
:
{
foreground
:
'
purple
'
}
}
],
'
vs-dark
'
:
[
{
scope
:
'
token.info-token
'
,
settings
:
{
foreground
:
'
#6796e6
'
}
},
{
scope
:
'
token.warn-token
'
,
settings
:
{
foreground
:
'
#cd9731
'
}
},
{
scope
:
'
token.error-token
'
,
settings
:
{
foreground
:
'
#f44747
'
}
},
{
scope
:
'
token.debug-token
'
,
settings
:
{
foreground
:
'
#b267e6
'
}
}
],
'
hc-black
'
:
[
{
scope
:
'
token.info-token
'
,
settings
:
{
foreground
:
'
#6796e6
'
}
},
{
scope
:
'
token.warn-token
'
,
settings
:
{
foreground
:
'
#008000
'
}
},
{
scope
:
'
token.error-token
'
,
settings
:
{
foreground
:
'
#FF0000
'
}
},
{
scope
:
'
token.debug-token
'
,
settings
:
{
foreground
:
'
#b267e6
'
}
}
],
}
;
let
counter
=
0
;
export
function
fromUserTheme
(
userTheme
:
IUserTheme
):
ColorThemeData
{
let
baseTheme
=
VS_LIGHT_THEME
;
if
(
userTheme
.
type
===
'
dark
'
)
{
baseTheme
=
VS_DARK_THEME
;
}
else
if
(
userTheme
.
type
===
'
hc
'
)
{
baseTheme
=
VS_HC_THEME
;
}
let
themeId
=
'
customtheme
'
+
counter
++
;
let
theme
=
new
ColorThemeData
();
theme
.
id
=
baseTheme
+
'
'
+
themeId
;
theme
.
selector
=
baseTheme
+
'
.
'
+
themeId
;
theme
.
label
=
CUSTOM_THEME_ID
;
theme
.
settingsId
=
CUSTOM_THEME_ID
;
theme
.
userThemeData
=
userTheme
;
theme
.
isLoaded
=
false
;
return
theme
;
}
function
_loadThemeDocument
(
baseTheme
:
string
,
themePath
:
string
,
resultRules
:
ITokenColorizationRule
[],
resultColors
:
IColorMap
):
TPromise
<
any
>
{
export
function
fromExtensionTheme
(
theme
:
IThemeExtensionPoint
,
normalizedAbsolutePath
:
string
,
extensionData
:
ExtensionData
):
ColorThemeData
{
let
baseTheme
=
theme
.
uiTheme
||
'
vs-dark
'
;
let
themeSelector
=
toCSSSelector
(
extensionData
.
extensionId
+
'
-
'
+
Paths
.
normalize
(
theme
.
path
));
let
themeData
=
new
ColorThemeData
();
themeData
.
id
=
`
${
baseTheme
}
${
themeSelector
}
`
;
themeData
.
label
=
theme
.
label
||
Paths
.
basename
(
theme
.
path
);
themeData
.
settingsId
=
theme
.
id
||
themeData
.
label
;
themeData
.
selector
=
`
${
baseTheme
}
.
${
themeSelector
}
`
;
themeData
.
description
=
theme
.
description
;
themeData
.
path
=
normalizedAbsolutePath
;
themeData
.
extensionData
=
extensionData
;
themeData
.
isLoaded
=
false
;
return
themeData
;
}
function
toCSSSelector
(
str
:
string
)
{
str
=
str
.
replace
(
/
[^
_
\-
a-zA-Z0-9
]
/g
,
'
-
'
);
if
(
str
.
charAt
(
0
).
match
(
/
[
0-9
\-]
/
))
{
str
=
'
_
'
+
str
;
}
return
str
;
}
function
_loadThemeDocumentFromFile
(
themePath
:
string
,
resultRules
:
ITokenColorizationRule
[],
resultColors
:
IColorMap
):
TPromise
<
any
>
{
return
pfs
.
readFile
(
themePath
).
then
(
content
=>
{
if
(
resultRules
.
length
===
0
)
{
let
defaultRules
=
defaultThemeColors
[
baseTheme
]
||
[];
resultRules
.
push
(...
defaultRules
);
}
if
(
Paths
.
extname
(
themePath
)
===
'
.json
'
)
{
let
errors
:
Json
.
ParseError
[]
=
[];
let
contentValue
=
Json
.
parse
(
content
.
toString
(),
errors
);
...
...
@@ -186,7 +214,7 @@ function _loadThemeDocument(baseTheme: string, themePath: string, resultRules: I
}
let
includeCompletes
=
TPromise
.
as
(
null
);
if
(
contentValue
.
include
)
{
includeCompletes
=
_loadThemeDocument
(
baseTheme
,
Paths
.
join
(
Paths
.
dirname
(
themePath
),
contentValue
.
include
),
resultRules
,
resultColors
);
includeCompletes
=
_loadThemeDocument
FromFile
(
Paths
.
join
(
Paths
.
dirname
(
themePath
),
contentValue
.
include
),
resultRules
,
resultColors
);
}
return
includeCompletes
.
then
(
_
=>
{
if
(
Array
.
isArray
(
contentValue
.
settings
))
{
...
...
@@ -225,10 +253,41 @@ function _loadThemeDocument(baseTheme: string, themePath: string, resultRules: I
});
}
function
_loadThemeDocumentFromUserTheme
(
themeService
:
WorkbenchThemeService
,
userTheme
:
IUserTheme
,
resultRules
:
ITokenColorizationRule
[],
resultColors
:
IColorMap
):
TPromise
<
any
>
{
let
extendsCompletes
=
TPromise
.
as
(
null
);
if
(
userTheme
.
extends
)
{
extendsCompletes
=
themeService
.
findThemeDataBySettingsId
(
userTheme
.
extends
,
null
).
then
(
theme
=>
{
if
(
theme
&&
!
theme
.
userThemeData
)
{
return
theme
.
ensureLoaded
(
themeService
).
then
(
_
=>
{
resultRules
.
push
(...
theme
.
tokenColors
);
for
(
let
colorId
in
theme
.
colorMap
)
{
resultColors
[
colorId
]
=
theme
.
colorMap
[
colorId
];
}
});
}
return
null
;
});
}
return
extendsCompletes
.
then
(
_
=>
{
if
(
userTheme
.
tokenColors
)
{
resultRules
.
push
(...
userTheme
.
tokenColors
);
}
if
(
userTheme
.
colors
)
{
let
colors
=
userTheme
.
colors
;
for
(
let
colorId
in
colors
)
{
let
colorHex
=
colors
[
colorId
];
resultColors
[
colorId
]
=
Color
.
fromHex
(
colorHex
);
}
}
return
null
;
});
}
/**
* Make sure that the token colors contain the default fore and background
*/
function
completeTokenColors
(
theme
:
ColorThemeData
)
{
let
hasDefaultTokens
=
false
;
theme
.
tokenColors
.
forEach
(
rule
=>
{
if
(
!
rule
.
scope
)
{
if
(
!
rule
.
settings
.
background
)
{
...
...
@@ -237,6 +296,33 @@ function completeTokenColors(theme: ColorThemeData) {
if
(
!
rule
.
settings
.
foreground
)
{
rule
.
settings
.
foreground
=
theme
.
getColor
(
editorForeground
).
toRGBAHex
();
}
}
else
if
(
rule
.
scope
===
'
token.info-token
'
)
{
hasDefaultTokens
=
true
;
}
});
}
\ No newline at end of file
if
(
!
hasDefaultTokens
)
{
theme
.
tokenColors
.
push
(...
defaultThemeColors
[
theme
.
type
]);
}
}
let
defaultThemeColors
:
{
[
baseTheme
:
string
]:
ITokenColorizationRule
[]
}
=
{
'
light
'
:
[
{
scope
:
'
token.info-token
'
,
settings
:
{
foreground
:
'
#316bcd
'
}
},
{
scope
:
'
token.warn-token
'
,
settings
:
{
foreground
:
'
#cd9731
'
}
},
{
scope
:
'
token.error-token
'
,
settings
:
{
foreground
:
'
#cd3131
'
}
},
{
scope
:
'
token.debug-token
'
,
settings
:
{
foreground
:
'
#800080
'
}
}
],
'
dark
'
:
[
{
scope
:
'
token.info-token
'
,
settings
:
{
foreground
:
'
#6796e6
'
}
},
{
scope
:
'
token.warn-token
'
,
settings
:
{
foreground
:
'
#cd9731
'
}
},
{
scope
:
'
token.error-token
'
,
settings
:
{
foreground
:
'
#f44747
'
}
},
{
scope
:
'
token.debug-token
'
,
settings
:
{
foreground
:
'
#b267e6
'
}
}
],
'
hc
'
:
[
{
scope
:
'
token.info-token
'
,
settings
:
{
foreground
:
'
#6796e6
'
}
},
{
scope
:
'
token.warn-token
'
,
settings
:
{
foreground
:
'
#008000
'
}
},
{
scope
:
'
token.error-token
'
,
settings
:
{
foreground
:
'
#FF0000
'
}
},
{
scope
:
'
token.debug-token
'
,
settings
:
{
foreground
:
'
#b267e6
'
}
}
],
};
\ No newline at end of file
src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts
浏览文件 @
46362674
...
...
@@ -9,10 +9,11 @@ import nls = require('vs/nls');
import
Paths
=
require
(
'
vs/base/common/paths
'
);
import
Json
=
require
(
'
vs/base/common/json
'
);
import
*
as
types
from
'
vs/base/common/types
'
;
import
*
as
objects
from
'
vs/base/common/objects
'
;
import
{
IThemeExtensionPoint
}
from
'
vs/platform/theme/common/themeExtensionPoint
'
;
import
{
IExtensionService
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
ExtensionsRegistry
,
ExtensionMessageCollector
}
from
'
vs/platform/extensions/common/extensionsRegistry
'
;
import
{
IWorkbenchThemeService
,
IColorTheme
,
IFileIconTheme
,
ExtensionData
,
VS_LIGHT_THEME
,
VS_DARK_THEME
,
VS_HC_THEME
,
COLOR_THEME_SETTING
,
ICON_THEME_SETTING
}
from
'
vs/workbench/services/themes/common/workbenchThemeService
'
;
import
{
IWorkbenchThemeService
,
IColorTheme
,
IFileIconTheme
,
ExtensionData
,
VS_LIGHT_THEME
,
VS_DARK_THEME
,
VS_HC_THEME
,
COLOR_THEME_SETTING
,
ICON_THEME_SETTING
,
CUSTOM_COLOR_THEME_SETTING
,
ITokenColorizationRule
,
CUSTOM_THEME_ID
}
from
'
vs/workbench/services/themes/common/workbenchThemeService
'
;
import
{
IWindowIPCService
}
from
'
vs/workbench/services/window/electron-browser/windowService
'
;
import
{
IStorageService
,
StorageScope
}
from
'
vs/platform/storage/common/storage
'
;
import
{
ITelemetryService
}
from
'
vs/platform/telemetry/common/telemetry
'
;
...
...
@@ -26,7 +27,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
import
{
IMessageService
}
from
'
vs/platform/message/common/message
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
Severity
from
'
vs/base/common/severity
'
;
import
{
ColorThemeData
,
fromStorageData
}
from
'
./colorThemeData
'
;
import
{
ColorThemeData
,
fromStorageData
,
fromUserTheme
,
fromExtensionTheme
}
from
'
./colorThemeData
'
;
import
{
ITheme
,
Extensions
as
ThemingExtensions
,
IThemingRegistry
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
editorBackground
,
editorForeground
}
from
'
vs/platform/theme/common/colorRegistry
'
;
...
...
@@ -47,8 +48,6 @@ const DEFAULT_THEME_SETTING_VALUE = 'Default Dark+';
const
PERSISTED_THEME_STORAGE_KEY
=
'
colorThemeData
'
;
const
defaultBaseTheme
=
'
vs-dark
'
;
const
defaultThemeExtensionId
=
'
vscode-theme-defaults
'
;
const
oldDefaultThemeExtensionId
=
'
vscode-theme-colorful-defaults
'
;
...
...
@@ -167,6 +166,13 @@ interface IconThemeDocument extends IconsAssociation {
highContrast
?:
IconsAssociation
;
}
export
interface
IUserTheme
{
type
:
string
;
extends
?:
string
;
colors
?:
{
[
colorId
:
string
]:
string
;
};
tokenColors
?:
ITokenColorizationRule
[];
}
const
noFileIconTheme
:
IFileIconTheme
=
{
id
:
''
,
label
:
''
,
...
...
@@ -177,10 +183,15 @@ const noFileIconTheme: IFileIconTheme = {
extensionData
:
null
};
const
defaultUserTheme
:
IUserTheme
=
{
type
:
'
dark
'
};
export
class
WorkbenchThemeService
implements
IWorkbenchThemeService
{
_serviceBrand
:
any
;
private
knownColorThemes
:
ColorThemeData
[];
private
extensionsColorThemes
:
ColorThemeData
[];
private
userColorTheme
:
ColorThemeData
;
private
currentColorTheme
:
ColorThemeData
;
private
container
:
HTMLElement
;
private
onColorThemeChange
:
Emitter
<
IColorTheme
>
;
...
...
@@ -204,7 +215,8 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
@
IInstantiationService
private
instantiationService
:
IInstantiationService
)
{
this
.
container
=
container
;
this
.
knownColorThemes
=
[];
this
.
extensionsColorThemes
=
[];
this
.
userColorTheme
=
fromUserTheme
(
defaultUserTheme
);
this
.
onFileIconThemeChange
=
new
Emitter
<
IFileIconTheme
>
();
this
.
knownIconThemes
=
[];
this
.
onColorThemeChange
=
new
Emitter
<
IColorTheme
>
();
...
...
@@ -337,6 +349,11 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
private
initialize
():
TPromise
<
any
>
{
let
userTheme
=
this
.
configurationService
.
lookup
<
IUserTheme
>
(
CUSTOM_COLOR_THEME_SETTING
).
value
;
if
(
userTheme
)
{
this
.
updateUserTheme
(
userTheme
);
}
let
colorThemeSetting
=
this
.
configurationService
.
lookup
<
string
>
(
COLOR_THEME_SETTING
).
value
;
let
iconThemeSetting
=
this
.
configurationService
.
lookup
<
string
>
(
ICON_THEME_SETTING
).
value
||
''
;
...
...
@@ -367,6 +384,9 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
this
.
setFileIconTheme
(
theme
&&
theme
.
id
,
null
);
});
}
let
userTheme
=
this
.
configurationService
.
lookup
<
IUserTheme
>
(
CUSTOM_COLOR_THEME_SETTING
).
value
||
defaultUserTheme
;
this
.
updateUserTheme
(
userTheme
);
});
}
...
...
@@ -391,7 +411,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
return
this
.
findThemeData
(
themeId
,
DEFAULT_THEME_ID
).
then
(
themeData
=>
{
if
(
themeData
)
{
return
themeData
.
ensureLoaded
().
then
(
_
=>
{
return
themeData
.
ensureLoaded
(
this
).
then
(
_
=>
{
if
(
themeId
===
this
.
currentColorTheme
.
id
&&
!
this
.
currentColorTheme
.
isLoaded
&&
this
.
currentColorTheme
.
hasEqualData
(
themeData
))
{
// the loaded theme is identical to the perisisted theme. Don't need to send an event.
this
.
currentColorTheme
=
themeData
;
...
...
@@ -475,7 +495,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
});
}
p
rivate
findThemeDataBySettingsId
(
settingsId
:
string
,
defaultId
:
string
):
TPromise
<
ColorThemeData
>
{
p
ublic
findThemeDataBySettingsId
(
settingsId
:
string
,
defaultId
:
string
):
TPromise
<
ColorThemeData
>
{
return
this
.
getColorThemes
().
then
(
allThemes
=>
{
let
defaultTheme
:
IColorTheme
=
void
0
;
for
(
let
t
of
allThemes
)
{
...
...
@@ -492,10 +512,19 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
public
getColorThemes
():
TPromise
<
IColorTheme
[]
>
{
return
this
.
extensionService
.
onReady
().
then
(
isReady
=>
{
return
this
.
knownColorThemes
;
return
this
.
extensionsColorThemes
.
concat
([
this
.
userColorTheme
])
;
});
}
private
updateUserTheme
(
userTheme
:
IUserTheme
):
void
{
if
(
!
objects
.
equals
(
this
.
userColorTheme
.
userThemeData
,
userTheme
))
{
this
.
userColorTheme
=
fromUserTheme
(
userTheme
);
if
(
!!
this
.
currentColorTheme
.
userThemeData
)
{
this
.
setColorTheme
(
this
.
userColorTheme
.
id
,
null
);
}
}
}
private
onThemes
(
extensionFolderPath
:
string
,
extensionData
:
ExtensionData
,
themes
:
IThemeExtensionPoint
[],
collector
:
ExtensionMessageCollector
):
void
{
if
(
!
Array
.
isArray
(
themes
))
{
collector
.
error
(
nls
.
localize
(
...
...
@@ -520,24 +549,13 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
if
(
normalizedAbsolutePath
.
indexOf
(
extensionFolderPath
)
!==
0
)
{
collector
.
warn
(
nls
.
localize
(
'
invalid.path.1
'
,
"
Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.
"
,
themesExtPoint
.
name
,
normalizedAbsolutePath
,
extensionFolderPath
));
}
let
themeData
=
fromExtensionTheme
(
theme
,
normalizedAbsolutePath
,
extensionData
);
this
.
extensionsColorThemes
.
push
(
themeData
);
let
baseTheme
=
theme
.
uiTheme
||
defaultBaseTheme
;
let
themeSelector
=
toCSSSelector
(
extensionData
.
extensionId
+
'
-
'
+
Paths
.
normalize
(
theme
.
path
));
let
themeData
=
new
ColorThemeData
();
themeData
.
id
=
`
${
baseTheme
}
${
themeSelector
}
`
;
themeData
.
label
=
theme
.
label
||
Paths
.
basename
(
theme
.
path
);
themeData
.
settingsId
=
theme
.
id
||
themeData
.
label
;
themeData
.
selector
=
`
${
baseTheme
}
.
${
themeSelector
}
`
;
themeData
.
description
=
theme
.
description
;
themeData
.
path
=
normalizedAbsolutePath
;
themeData
.
extensionData
=
extensionData
;
themeData
.
isLoaded
=
false
;
this
.
knownColorThemes
.
push
(
themeData
);
colorThemeSetting
.
enum
.
push
(
themeData
.
settingsId
);
colorThemeSetting
.
enumDescriptions
.
push
(
themeData
.
description
||
''
);
colorThemeSettingSchema
.
enum
.
push
(
themeData
.
settingsId
);
colorThemeSettingSchema
.
enumDescriptions
.
push
(
themeData
.
description
||
''
);
extendsSchema
.
enum
.
push
(
themeData
.
settingsId
);
extendsSchema
.
enumDescriptions
.
push
(
themeData
.
description
||
''
);
});
}
...
...
@@ -586,23 +604,25 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
};
this
.
knownIconThemes
.
push
(
themeData
);
iconThemeSetting
.
enum
.
push
(
themeData
.
settingsId
);
iconThemeSetting
.
enumDescriptions
.
push
(
themeData
.
description
||
''
);
iconThemeSetting
Schema
.
enum
.
push
(
themeData
.
settingsId
);
iconThemeSetting
Schema
.
enumDescriptions
.
push
(
themeData
.
description
||
''
);
});
}
private
themeExtensionsActivated
=
new
Map
<
string
,
boolean
>
();
private
sendTelemetry
(
themeId
:
string
,
themeData
:
ExtensionData
,
themeType
:
string
)
{
let
key
=
themeType
+
themeData
.
extensionId
;
if
(
!
this
.
themeExtensionsActivated
.
get
(
key
))
{
this
.
telemetryService
.
publicLog
(
'
activatePlugin
'
,
{
id
:
themeData
.
extensionId
,
name
:
themeData
.
extensionName
,
isBuiltin
:
themeData
.
extensionIsBuiltin
,
publisherDisplayName
:
themeData
.
extensionPublisher
,
themeId
:
themeId
});
this
.
themeExtensionsActivated
.
set
(
key
,
true
);
if
(
themeData
)
{
let
key
=
themeType
+
themeData
.
extensionId
;
if
(
!
this
.
themeExtensionsActivated
.
get
(
key
))
{
this
.
telemetryService
.
publicLog
(
'
activatePlugin
'
,
{
id
:
themeData
.
extensionId
,
name
:
themeData
.
extensionName
,
isBuiltin
:
themeData
.
extensionIsBuiltin
,
publisherDisplayName
:
themeData
.
extensionPublisher
,
themeId
:
themeId
});
this
.
themeExtensionsActivated
.
set
(
key
,
true
);
}
}
}
...
...
@@ -867,16 +887,6 @@ function escapeCSS(str: string) {
return
window
[
'
CSS
'
].
escape
(
str
);
}
function
toCSSSelector
(
str
:
string
)
{
str
=
str
.
replace
(
/
[^
_
\-
a-zA-Z0-9
]
/g
,
'
-
'
);
if
(
str
.
charAt
(
0
).
match
(
/
[
0-9
\-]
/
))
{
str
=
'
_
'
+
str
;
}
return
str
;
}
let
colorThemeRulesClassName
=
'
contributedColorTheme
'
;
let
iconThemeRulesClassName
=
'
contributedIconTheme
'
;
...
...
@@ -923,15 +933,15 @@ class ConfigurationWriter {
// Configuration: Themes
const
configurationRegistry
=
Registry
.
as
<
IConfigurationRegistry
>
(
ConfigurationExtensions
.
Configuration
);
const
colorThemeSetting
:
IJSONSchema
=
{
const
colorThemeSetting
Schema
:
IJSONSchema
=
{
type
:
'
string
'
,
description
:
nls
.
localize
(
'
colorTheme
'
,
"
Specifies the color theme used in the workbench.
"
),
default
:
DEFAULT_THEME_SETTING_VALUE
,
enum
:
[],
enumDescriptions
:
[],
enum
:
[
CUSTOM_THEME_ID
],
enumDescriptions
:
[
nls
.
localize
(
'
customThemeDescription
'
,
"
Custom theme as defined in '{0}'
"
,
CUSTOM_COLOR_THEME_SETTING
)
],
errorMessage
:
nls
.
localize
(
'
colorThemeError
'
,
"
Theme is unknown or not installed.
"
),
};
const
iconThemeSetting
:
IJSONSchema
=
{
const
iconThemeSetting
Schema
:
IJSONSchema
=
{
type
:
[
'
string
'
,
'
null
'
],
default
:
null
,
description
:
nls
.
localize
(
'
iconTheme
'
,
"
Specifies the icon theme used in the workbench.
"
),
...
...
@@ -939,12 +949,37 @@ const iconThemeSetting: IJSONSchema = {
enumDescriptions
:
[
nls
.
localize
(
'
noIconThemeDesc
'
,
'
No file icons
'
)],
errorMessage
:
nls
.
localize
(
'
iconThemeError
'
,
"
File icon theme is unknown or not installed.
"
)
};
const
extendsSchema
:
IJSONSchema
=
{
description
:
nls
.
localize
(
'
customTheme.extends
'
,
"
theme to extend. This will inherit color and token colors from the selected theme.
"
),
type
:
'
string
'
,
enum
:
[],
enumDescriptions
:
[]
};
const
userThemeSettingSchema
:
IJSONSchema
=
{
type
:
'
object
'
,
description
:
nls
.
localize
(
'
customTheme
'
,
"
Custom theme.
"
),
properties
:
{
id
:
{
type
:
'
string
'
},
type
:
{
enum
:
[
'
light
'
,
'
dark
'
,
'
hc
'
]
},
extends
:
extendsSchema
,
colors
:
colorThemeSchema
.
colorsSchema
,
tokenColors
:
colorThemeSchema
.
tokenColorsSchema
},
required
:
[
'
type
'
]
};
configurationRegistry
.
registerConfiguration
({
id
:
'
workbench
'
,
order
:
7.1
,
type
:
'
object
'
,
properties
:
{
[
COLOR_THEME_SETTING
]:
colorThemeSetting
,
[
ICON_THEME_SETTING
]:
iconThemeSetting
[
COLOR_THEME_SETTING
]:
colorThemeSettingSchema
,
[
ICON_THEME_SETTING
]:
iconThemeSettingSchema
,
[
CUSTOM_COLOR_THEME_SETTING
]:
userThemeSettingSchema
}
});
\ No newline at end of file
});
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录